diff --git js/swfupload_widget.js js/swfupload_widget.js
index b3949bc..d34df38 100755
--- js/swfupload_widget.js
+++ js/swfupload_widget.js
@@ -1,946 +1,956 @@
 /**
- * 
+ *
  */
-function SWFU(id, settings) {
-  var ref = {};
-  ref.settings = {};
 
-  ref.ajax_settings = {};
-  ref.queue = {};
-  ref.stats = {};
-  ref.instance = {};
-  ref.upload_stack_length = 0;
-  ref.max_queue_size = 0;
-  ref.upload_stack = {};
-  ref.upload_stack_obj;
-  ref.upload_button_obj;
-  ref.upload_stack_size = 0;
-  ref.wrapper_obj;
-  ref.wrapper_id;
-  ref.num_elements;
-  ref.key_pressed;
-  ref.message_wrapper_obj;
-  ref.messages_timeout;
 
-  /**
-   * 
-   */
-  ref.init = function() {
-    ref.settings = settings;
-    ref.upload_button_obj = $('#' + ref.settings.upload_button_id);
-    ref.instance = {name:settings.file_post_name};
-    ref.ajax_settings = {
-      type:"post",
-      url:ref.settings.upload_url,
-      data:{
-        op:'init',
-        file_path:ref.settings.post_params.file_path,
-        instance:ref.toJson(ref.instance),
-        widget:ref.settings.post_params.widget
-      },
-      success:function(result) {
-        ref.ajaxResponse(result);
-      }
-    };
-
-    ref.prepareSWFButton();
-    // Get the instance data by an AJAX request in order to let other modules change the callbacks and elements for this instance (using hook_swfupload);
-    $.ajax(ref.ajax_settings);
+/**
+ * Overwrite for the TableDrag markChanged function
+ * Allows to place the marker in an other table drawer than the first one.
+ */
+Drupal.tableDrag.prototype.row.prototype.markChanged = function() {
+  var marker = Drupal.theme('tableDragChangedMarker');
+  var cell = ($('td.drag .wrapper', this.element)) || $('td:first', this.element);
+  if ($('span.tabledrag-changed', cell).length == 0) {
+    cell.append(marker);
   };
+};
 
-  /**
-   * Prepares the swfupload button.
-   */
-  ref.prepareSWFButton = function() {
-    // Create a copy of the button to get it's dimensions.
-    // If we'd use the original button, we could end up with dimensions equal to 0px when the button is inside a hidden fieldset.
-    var tmp_button = ref.upload_button_obj.clone().css({'position':'absolute'}).prependTo('body');
+/**
+ * Disables text selection on the DOM element the behavior is attached to.
+*/
+jQuery.fn.disableTextSelect = function() {
+  return this.each(function() {
+    jQuery(this).css({
+      'MozUserSelect' : 'none'
+    }).bind('selectstart', function() {
+      return false;
+    }).mousedown(function() {
+      return false;
+    });
+  });
+};
 
-    // Set the dimensions of the swf so it matches exactly the dimensions of the upload button
-    // swfupload.swf will be placed exactly over the upload button
-    ref.settings.button_width = (tmp_button.find('.left').width() + tmp_button.find('.center').width() + tmp_button.find('.right').width());
-    ref.settings.button_height = tmp_button.find('.center').height();
-    tmp_button.remove();
+(function($) {
+  function SWFU(id, settings) {
+    var ref = {};
+    ref.settings = {};
 
-    // Add the other button settings to the settings object
-    ref.settings.button_placeholder_id = ref.settings.file_post_name + '-swfwrapper';
-    ref.settings.button_window_mode = SWFUpload.WINDOW_MODE.TRANSPARENT;
-    ref.settings.button_cursor = SWFUpload.CURSOR.HAND;
-  };
+    ref.ajax_settings = {};
+    ref.queue = {};
+    ref.stats = {};
+    ref.instance = {};
+    ref.upload_stack_length = 0;
+    ref.max_queue_size = 0;
+    ref.upload_stack = {};
+    ref.upload_stack_obj;
+    ref.upload_button_obj;
+    ref.upload_stack_size = 0;
+    ref.wrapper_obj;
+    ref.wrapper_id;
+    ref.num_elements;
+    ref.key_pressed;
+    ref.message_wrapper_obj;
+    ref.messages_timeout;
 
-  /**
-   * Creates a hidden input field which will contain a JSON formatted string containing all uploaded files
-   */
-  ref.createStackObj = function() {
-    var upload_stack_value = settings.custom_settings.upload_stack_value;
-    ref.max_queue_size = settings.custom_settings.max_queue_size;
-    ref.upload_stack_obj = $('<input type="hidden" />').attr('name', ref.instance.name).val(upload_stack_value).prependTo(ref.upload_button_obj);
-    ref.upload_stack = Drupal.parseJson(upload_stack_value);
-    ref.upload_stack_length = ref.objectLength(ref.upload_stack);
-  };
+    /**
+     *
+     */
+    ref.init = function() {
+      ref.settings = settings;
+      ref.upload_button_obj = $('#' + ref.settings.upload_button_id);
+      ref.instance = {name:settings.file_post_name, language:$.parseJSON(settings.post_params.instance).language};
+      ref.ajax_settings = {
+        type:"post",
+        url:ref.settings.upload_url,
+        data:{
+          op:'init',
+          file_path:ref.settings.post_params.file_path,
+          instance:ref.toJson(ref.instance),
+          widget:ref.settings.post_params.widget
+        },
+        success:function(result) {
+          ref.ajaxResponse(result);
+        }
+      };
 
-  /**
-   * 
-   */
-  ref.newSWFUpload = function() {
-    ref.swfu = new SWFUpload(ref.settings);
-  };
+      ref.prepareSWFButton();
+      // Get the instance data by an AJAX request in order to let other modules change the callbacks and elements for this instance (using hook_swfupload);
+      $.ajax(ref.ajax_settings);
+    };
 
-  /**
-   * 
-   */
-  ref.ajaxResponse = function(result) {
-    var result = Drupal.parseJson(result);
+    /**
+     * Prepares the swfupload button.
+     */
+    ref.prepareSWFButton = function() {
+      // Create a copy of the button to get it's dimensions.
+      // If we'd use the original button, we could end up with dimensions equal to 0px when the button is inside a hidden fieldset.
+      var tmp_button = ref.upload_button_obj.clone().css({'position':'absolute'}).prependTo('body');
 
-    switch (result.op) {
-      case 'init':
-        ref.instance = result.instance;
-        ref.num_elements = ref.objectLength(ref.instance.elements);
-        $.each(result.instance.callbacks, function(setting, callback) {
-          ref.settings[setting] = eval(callback);
-        });
-        ref.newSWFUpload();
-        ref.settings.init_complete_handler(result);
-        break;
+      // Set the dimensions of the swf so it matches exactly the dimensions of the upload button
+      // swfupload.swf will be placed exactly over the upload button
+      ref.settings.button_width = (tmp_button.find('.left').width() + tmp_button.find('.center').width() + tmp_button.find('.right').width());
+      ref.settings.button_height = tmp_button.find('.center').height();
+      tmp_button.remove();
+
+      // Add the other button settings to the settings object
+      ref.settings.button_placeholder_id = ref.settings.file_post_name + '-swfwrapper';
+      ref.settings.button_window_mode = SWFUpload.WINDOW_MODE.TRANSPARENT;
+      ref.settings.button_cursor = SWFUpload.CURSOR.HAND;
     };
-    ref.addEventHandlers(result.op);
-  };
 
-  /**
-   * Custom function for when the initialization is complete
-   * This event handler is defined in swfupload.module as an instance callback function 
-   */
-  ref.initComplete = function(result) {
-    ref.createWrapper(result.instance.name);
-    ref.createStackObj();
-    ref.addStoredFiles();
+    /**
+     * Creates a hidden input field which will contain a JSON formatted string containing all uploaded files
+     */
+    ref.createStackObj = function() {
+      var upload_stack_value = settings.custom_settings.upload_stack_value;
+      ref.max_queue_size = settings.custom_settings.max_queue_size;
+      ref.upload_stack_obj = $('<input type="hidden" />').attr('name', ref.instance.name + '[' + ref.instance.language + '][0][raw_value]').val(upload_stack_value).prependTo(ref.upload_button_obj);
+      ref.upload_stack = jQuery.parseJSON(upload_stack_value);
+      ref.upload_stack_length = ref.objectLength(ref.upload_stack);
+    };
 
-    // Enable the upload button if the current stack is smaller than the allowed stack size,
-    // or when there's no limit at all.
-    if ((ref.settings.file_upload_limit && (ref.upload_stack_length < ref.settings.file_upload_limit)) || ref.settings.file_upload_limit === 0) {
-      ref.upload_button_obj.removeClass('disabled').css({opacity:1});
-    }
-    else {
-      ref.upload_button_obj.addClass('disabled').css({opacity:0.4});
+    /**
+     *
+     */
+    ref.newSWFUpload = function() {
+      ref.swfu = new SWFUpload(ref.settings);
     };
-  };
 
-  /**
-   * This will process all file elements stored in the upload stack.
-   * The upload represents all files submitted in the upload form.
-   * For all files in the stack, a file element will be added to the wrapper using ref.addFileItem().
-   */
-  ref.addStoredFiles = function() {
-    for(var i in ref.upload_stack) {
-      if (ref.upload_stack[i] == 0) {
-        break;
-      };
-      ref.upload_stack[i].id = i;
-      ref.upload_stack[i].fid = i;
-      ref.upload_stack[i].extension = ref.getExtension(ref.upload_stack[i].filename);
-      ref.addFileItem(ref.upload_stack[i]);
+    /**
+     *
+     */
+    ref.ajaxResponse = function(result) {
+      var result = jQuery.parseJSON(result);
 
-      // Adjust the bytes in the stack.
-      ref.upload_stack_size += parseInt(ref.upload_stack[i].filesize);
+      switch (result.op) {
+        case 'init':
+          ref.instance = result.instance;
+          ref.num_elements = ref.objectLength(ref.instance.elements);
+          $.each(result.instance.callbacks, function(setting, callback) {
+            ref.settings[setting] = eval(callback);
+          });
+          ref.newSWFUpload();
+          ref.settings.init_complete_handler(result);
+          break;
+      };
+      ref.addEventHandlers(result.op);
     };
-    ref.addEventHandlers('drag_enable');
-  };
 
-  /**
-   * Places the wrapper markup above the upload button
-   * Depending on what type isset by the instance, a table or a list element is created.
-   */
-  ref.createWrapper = function(field_name) {
-    var use_header = false;
-    var element;
+    /**
+     * Custom function for when the initialization is complete
+     * This event handler is defined in swfupload.module as an instance callback function
+     */
+    ref.initComplete = function(result) {
+      ref.createWrapper(result.instance.name);
+      ref.createStackObj();
+      ref.addStoredFiles();
 
-    if (ref.num_elements > 1 && ref.instance.type == 'table') {
-      // First we'll check if we need to create a header 
-      for (var name in ref.instance.elements) {
-        if (ref.instance.elements[name].title) {
-           use_header = true;
-        };
+      // Enable the upload button if the current stack is smaller than the allowed stack size,
+      // or when there's no limit at all.
+      if ((ref.settings.file_upload_limit && (ref.upload_stack_length < ref.settings.file_upload_limit)) || ref.settings.file_upload_limit === 0) {
+        ref.upload_button_obj.removeClass('disabled').css({opacity:1});
+      }
+      else {
+        ref.upload_button_obj.addClass('disabled').css({opacity:0.4});
       };
+    };
 
-      ref.wrapper_id = 'swfupload_file_wrapper-' + field_name;
-      ref.wrapper_obj = $('<table />').attr({'id': ref.wrapper_id, 'class':'swfupload'});
-      if (use_header) {
-        ref.wrapper_obj.append($('<thead />').append(ref.tableRow(true)));
-      };
-      ref.wrapper_obj.append($('<tbody />').append(ref.tableRow()));
-      ref.upload_button_obj.before(ref.wrapper_obj);
+    /**
+     * This will process all file elements stored in the upload stack.
+     * The upload represents all files submitted in the upload form.
+     * For all files in the stack, a file element will be added to the wrapper using ref.addFileItem().
+     */
+    ref.addStoredFiles = function() {
+      for(var i in ref.upload_stack) {
+        if (ref.upload_stack[i] == 0) {
+          break;
+        };
+        ref.upload_stack[i].id = i;
+        ref.upload_stack[i].fid = i;
+        ref.upload_stack[i].extension = ref.getExtension(ref.upload_stack[i].filename);
+        ref.addFileItem(ref.upload_stack[i]);
 
-      if (!Drupal.settings.tableDrag) {
-        Drupal.settings.tableDrag = {};
+        // Adjust the bytes in the stack.
+        ref.upload_stack_size += parseInt(ref.upload_stack[i].filesize);
       };
-
-      Drupal.settings.tableDrag['swfupload_file_wrapper-' + field_name] = {};
+      ref.addEventHandlers('drag_enable');
     };
-  };    
-
-  /**
-   * Creates or changes a tablerow
-   * @param header Boolean Wheter or not the tablerow should contain th's. If sety to false, td's will be generated.
-   * @param file Object A completed file object 
-   *   - If this is not set, a row is created including the progressbar, which replaces the td's with contains_progressbar set to true.
-   *   - If file is set, the progressbar will be replaced with the appropriate td's
-   */
-  ref.tableRow = function(header, file) {
-    var counter = 0;
-    var colspan = 0;
-    var fid = (file) ? file.fid : 0;
-    var progress_td_counter = 0;
-    var element, colum, content, input, progress_td, elem_value, value;
 
-    var tr = (file) ? $('#' + file.fid) : $('<tr />');
-    var wrapper = $('<div />').addClass('wrapper');
-    var left_span = $('<div />').addClass('left').html('&nbsp;');
-    var center_span = $('<div />').addClass('center');
-    var right_span = $('<div />').addClass('right').html('&nbsp;');
+    /**
+     * Places the wrapper markup above the upload button
+     * Depending on what type isset by the instance, a table or a list element is created.
+     */
+    ref.createWrapper = function(field_name) {
+      var use_header = false;
+      var element;
 
-    // A tablerow will be created containing all elements defined in ref.instance.elements.
-    // If file is set, all elements will be skipped exept the ones with 'contains_progressbar'
-    // If file isn't set, this tablerow will be hidden.
-    for (var name in ref.instance.elements) {
-      counter++;
-      element = ref.instance.elements[name];
+      if (ref.num_elements > 1 && ref.instance.type == 'table') {
+        // First we'll check if we need to create a header
+        for (var name in ref.instance.elements) {
+          if (ref.instance.elements[name].title) {
+             use_header = true;
+          };
+        };
 
-      if (file) {
-        if(!element.contains_progressbar) {
-          // The current td doesn't have to be replaced.
-          // We only need to replace fid of the id and name of the input field
-          tr.find('#edit-' + name + '_0').attr({'name':name +'_' + fid, 'id':'edit-' + name + '_' + fid});
-          continue;
+        ref.wrapper_id = 'swfupload_file_wrapper-' + field_name;
+        ref.wrapper_obj = $('<table />').attr({'id': ref.wrapper_id, 'class':'swfupload tabledrag'});
+        if (use_header) {
+          ref.wrapper_obj.append($('<thead />').append(ref.tableRow(true)));
         };
-      }
-      else {
-        if (!header && element.contains_progressbar) {
-          if (!progress_td) {
-            progress_td = $('<td />').addClass('progress').append($('<div />').addClass('sfwupload-list-progressbar').append($('<div />').addClass('sfwupload-list-progressbar-status')).append($('<div />').addClass('sfwupload-list-progressbar-glow'))).appendTo(tr);
-          };
-          progress_td_counter++;
-          continue;
+        ref.wrapper_obj.append($('<tbody />').append(ref.tableRow()));
+        ref.upload_button_obj.before(ref.wrapper_obj);
+
+        if (!Drupal.settings.tableDrag) {
+          Drupal.settings.tableDrag = {};
         };
+
+        Drupal.settings.tableDrag['swfupload_file_wrapper-' + field_name] = {};
       };
+    };
+
+    /**
+     * Creates or changes a tablerow
+     * @param header Boolean Wheter or not the tablerow should contain th's. If sety to false, td's will be generated.
+     * @param file Object A completed file object
+     *   - If this is not set, a row is created including the progressbar, which replaces the td's with contains_progressbar set to true.
+     *   - If file is set, the progressbar will be replaced with the appropriate td's
+     */
+    ref.tableRow = function(header, file) {
+      var counter = 0;
+      var colspan = 0;
+      var fid = (file) ? file.fid : 0;
+      var progress_td_counter = 0;
+      var element, colum, content, input, progress_td, elem_value, value;
 
-      column = $((header ? '<th />' : '<td />'));
-      content = wrapper.clone().appendTo(column);
-      input = $((element.type == 'textarea' ? '<textarea />' : '<input type="' + element.type + '" />')).attr({'name':name +'_' + fid, 'id':'edit-' + name + '_' + fid}).addClass('form-' + element.type);
+      var tr = (file) ? $('#' + file.fid) : $('<tr />');
+      var wrapper = $('<div />').addClass('wrapper');
+      var left_span = $('<div />').addClass('left').html('&nbsp;');
+      var center_span = $('<div />').addClass('center');
+      var right_span = $('<div />').addClass('right').html('&nbsp;');
 
-      if (header) {
-        // Keep track of colspans 
-        if (colspan > 0) colspan--;
-        if (element.colspan) {
-          colspan = element.colspan;
+      // A tablerow will be created containing all elements defined in ref.instance.elements.
+      // If file is set, all elements will be skipped exept the ones with 'contains_progressbar'
+      // If file isn't set, this tablerow will be hidden.
+      for (var name in ref.instance.elements) {
+        counter++;
+        element = ref.instance.elements[name];
+
+        if (file) {
+          if(!element.contains_progressbar) {
+            // The current td doesn't have to be replaced.
+            // We only need to replace fid of the id and name of the input field
+            tr.find('#edit-' + name + '_0').attr({'name':name +'_' + fid, 'id':'edit-' + name + '_' + fid});
+            continue;
+          };
         }
-        else if (colspan !== 0) {
-          continue;
+        else {
+          if (!header && element.contains_progressbar) {
+            if (!progress_td) {
+              progress_td = $('<td />').addClass('progress').append($('<div />').addClass('sfwupload-list-progressbar').append($('<div />').addClass('sfwupload-list-progressbar-status')).append($('<div />').addClass('sfwupload-list-progressbar-glow'))).appendTo(tr);
+            };
+            progress_td_counter++;
+            continue;
+          };
         };
 
-        // Add the colspan if set.
-        if (element.colspan) {
-          column.attr({'colSpan':element.colspan});
+        column = $((header ? '<th />' : '<td />'));
+        content = wrapper.clone().appendTo(column);
+        input = $((element.type == 'textarea' ? '<textarea />' : '<input type="' + element.type + '" />')).attr({'name':name +'_' + fid, 'id':'edit-' + name + '_' + fid}).addClass('form-' + element.type);
+
+        if (header) {
+          // Keep track of colspans
+          if (colspan > 0) colspan--;
+          if (element.colspan) {
+            colspan = element.colspan;
+          }
+          else if (colspan !== 0) {
+            continue;
+          };
+
+          // Add the colspan if set.
+          if (element.colspan) {
+            column.attr({'colSpan':element.colspan});
+          };
+
+          // Add a separator only if we're not dealing with the first or last column
+          if (counter !== ref.num_elements && (counter + (colspan - 1) !== ref.num_elements) && element.add_separator) {
+            content.append(left_span.clone()).append(right_span.clone());
+          };
+
+          content.append(center_span.clone().html((element.title ? element.title : '&nbsp;')));
+        }
+        else {
+          elem_value = (element.value) || element.default_value;
+          // Create the content for this td
+          // Depending on the type the appropriate input field is appended to store the values of this type
+          switch (element.type) {
+            case 'icon':
+            case 'cancel':
+              content.append($('<div />').addClass('sfwupload-list-' + (element.type == 'icon' ? 'mime' : element.type)));
+              break;
+            case 'textfield':
+            case 'textarea':
+              value = (file ? ref.replaceMacros(elem_value, file) : elem_value);
+              content.append($('<span />').html((value !== '' ? value : '&nbsp;'))).append(input.css({'display':'none'}).val((value ? value : '')));
+              break;
+            case 'checkbox':
+              value = (file[name] !== undefined) ? (typeof(file[name]) == 'string' ? (file[name] == '1') : file[name]) : elem_value;
+              // For IE we need to check the checkbox after the content has been added to the tr.
+              // We'll temporarily store it's value in a classname
+              content.append(input.addClass('checkbox ' + (value ? 'checked' : '')));
+              break;
+            case 'markup':
+              value = (file) ? (file[name] !== undefined) ? file[name] : ref.replaceMacros(elem_value, file) : elem_value;
+              content.append($('<div />').addClass('swfupload-markup').attr('id', 'swfupload-markup-' + name).html(value));
+              break;
+            default:
+              break;
+          };
         };
 
-        // Add a separator only if we're not dealing with the first or last column
-        if (counter !== ref.num_elements && (counter + (colspan - 1) !== ref.num_elements) && element.add_separator) {
-          content.append(left_span.clone()).append(right_span.clone());
+        // Add a classname if set.
+        if (element.classname) {
+          column.addClass(element.classname);
         };
 
-        content.append(center_span.clone().html((element.title ? element.title : '&nbsp;')));
-      }
-      else {
-        elem_value = (element.value) || element.default_value;
-        // Create the content for this td
-        // Depending on the type the appropriate input field is appended to store the values of this type
-        switch (element.type) {
-          case 'icon':
-          case 'cancel':
-            content.append($('<div />').addClass('sfwupload-list-' + (element.type == 'icon' ? 'mime' : element.type)));
-            break;
-          case 'textfield':
-          case 'textarea':
-            value = (file ? ref.replaceMacros(elem_value, file) : elem_value);
-            content.append($('<span />').html((value !== '' ? value : '&nbsp;'))).append(input.css({'display':'none'}).val((value ? value : '')));
-            break;
-          case 'checkbox':
-            value = (file[name] !== undefined) ? (typeof(file[name]) == 'string' ? (file[name] == '1') : file[name]) : elem_value;
-            // For IE we need to check the checkbox after the content has been added to the tr.
-            // We'll temporarily store it's value in a classname
-            content.append(input.addClass('checkbox ' + (value ? 'checked' : '')));
-            break;
-          case 'markup':
-            value = (file) ? (file[name] !== undefined) ? file[name] : ref.replaceMacros(elem_value, file) : elem_value;
-            content.append($('<div />').addClass('swfupload-markup').attr('id', 'swfupload-markup-' + name).html(value));
-            break;
-          default:
-            break;
+        if (file && element.contains_progressbar) {
+          column.insertBefore(tr.find('td.progress'));
+        }
+        else {
+          tr.append(column);
         };
       };
 
-      // Add a classname if set.
-      if (element.classname) {
-        column.addClass(element.classname);
+      if (!header && !file) {
+        // Hide the tablerow
+        tr.addClass('hidden');
       };
 
-      if (file && element.contains_progressbar) {
-        column.insertBefore(tr.find('td.progress'));
-      }
-      else {
-        tr.append(column);
+      if (progress_td) {
+        progress_td.attr({'colSpan':progress_td_counter});
       };
-    };
 
-    if (!header && !file) {
-      // Hide the tablerow
-      tr.addClass('hidden');
-    };
+      // Update the checked value of all added checkboxes
+      tr.find('input.checkbox').each(function() {
+        $(this).attr('checked', $(this).hasClass('checked'));
+      });
 
-    if (progress_td) {
-      progress_td.attr({'colSpan':progress_td_counter});
+      if (file) {
+        tr.addClass('processed').find('td.progress').remove();
+      }
+      else {
+        // Create borders
+        var border = $(header ? '<th />' : '<td />').addClass('border').append($('<img />').attr({'src':Drupal.settings.basePath + ref.settings.module_path + '/images/spacer.gif'}).css({'width':'1px'}));
+        tr.prepend(border.clone()).append(border);
+        return tr;
+      };
     };
 
-    // Update the checked value of all added checkboxes 
-    tr.find('input.checkbox').each(function() {
-      $(this).attr('checked', $(this).hasClass('checked'));
-    });
+    /**
+     * A file has been selected. This function creates the markup referring to the new file object
+     */
+    ref.addFileItem = function(file) {
+      // Create the markup for the new file by copying the hidden template
+      var new_file_obj = ref.wrapper_obj.find('.hidden').clone().attr({'id':file.id}).appendTo(ref.wrapper_obj);
+      var dom_obj, value, elem_value;
 
-    if (file) {
-      tr.addClass('processed').find('td.progress').remove();
-    }
-    else {
-      // Create borders
-      var border = $(header ? '<th />' : '<td />').addClass('border').append($('<img />').attr({'src':Drupal.settings.basePath + ref.settings.module_path + '/images/spacer.gif'}).css({'width':'1px'}));
-      tr.prepend(border.clone()).append(border);
-      return tr;
-    };
-  };
+      // Remove tabledrag elements
+      new_file_obj.find('a.tabledrag-handle').remove();
 
-  /**
-   * A file has been selected. This function creates the markup referring to the new file object
-   */
-  ref.addFileItem = function(file) {
-    // Create the markup for the new file by copying the hidden template 
-    var new_file_obj = ref.wrapper_obj.find('.hidden').clone().attr({'id':file.id}).appendTo(ref.wrapper_obj);
-    var dom_obj, value, elem_value;
-
-    // Remove tabledrag elements
-    new_file_obj.find('a.tabledrag-handle').remove();
+      // If it is a file earlier stored (a file in the upload_stack), remove it's progressbar.
+      if (file.filestatus !== -1) {
+        ref.tableRow(false, file);
+      };
 
-    // If it is a file earlier stored (a file in the upload_stack), remove it's progressbar.
-    if (file.filestatus !== -1) {
-      ref.tableRow(false, file);
-    };
+      // Replace macro's
+      for (var name in ref.instance.elements) {
+        dom_obj = new_file_obj.find('#edit-' + name + '_' + (file.fid || '0') + ', #swfupload-markup-' + name);
+        if (dom_obj.size() > 0) {
+          elem_value = (ref.instance.elements[name].value) || ref.instance.elements[name].default_value;
+          value = (file[name] !== undefined) ? file[name] : ref.replaceMacros(elem_value, file);
 
-    // Replace macro's
-    for (var name in ref.instance.elements) {
-      dom_obj = new_file_obj.find('#edit-' + name + '_' + (file.fid || '0') + ', #swfupload-markup-' + name);
-      if (dom_obj.size() > 0) {
-        elem_value = (ref.instance.elements[name].value) || ref.instance.elements[name].default_value;
-        value = (file[name] !== undefined) ? file[name] : ref.replaceMacros(elem_value, file);
+          if (dom_obj[0].tagName.toLowerCase() == 'input' || dom_obj[0].tagName.toLowerCase() == 'textarea') {
+            dom_obj.val(value);
+          }
+          else {
+            dom_obj.html(value).show();
+          };
 
-        if (dom_obj[0].tagName.toLowerCase() == 'input' || dom_obj[0].tagName.toLowerCase() == 'textarea') {
-          dom_obj.val(value);
-        }
-        else {
-          dom_obj.html(value).show();
+          // If the inputfield is hidden, we're dealing with a string.
+          // Look if there is a span of which the text can be replaced
+          if (dom_obj.css('display') == 'none') {
+            dom_obj.parent().find('span').text(value);
+          };
         };
+      };
 
-        // If the inputfield is hidden, we're dealing with a string. 
-        // Look if there is a span of which the text can be replaced
-        if (dom_obj.css('display') == 'none') {
-          dom_obj.parent().find('span').text(value);
-        };
+      if (file.thumb) {
+        // Attach the thumbnail image
+        new_file_obj.find('.sfwupload-list-mime').css({'background-image': 'url(' + file.thumb + ')'});
+      }
+      else {
+        // Add the extension to the mime icon
+        new_file_obj.find('.sfwupload-list-mime').addClass(file.extension);
       };
-    };
 
-    if (file.thumb) {
-      // Attach the thumbnail image
-      new_file_obj.find('.sfwupload-list-mime').css({'background-image': 'url(' + file.thumb + ')'});
-    }
-    else {
-      // Add the extension to the mime icon
-      new_file_obj.find('.sfwupload-list-mime').addClass(file.extension);
-    };
+      // Fix transparency for IE6
+      if ($.cssPNGFix) {
+        new_file_obj.find('.sfwupload-list-mime').cssPNGFix();
+      };
 
-    // Fix transparency for IE6
-    if ($.cssPNGFix) {
-      new_file_obj.find('.sfwupload-list-mime').cssPNGFix();
+      new_file_obj.removeClass('hidden').addClass('draggable');
+      ref.addEventHandlers((file.filestatus == -1 ? 'file_queued' : 'file_added'), file);
     };
 
-    new_file_obj.removeClass('hidden').addClass('draggable');
-    ref.addEventHandlers((file.filestatus == -1 ? 'file_queued' : 'file_added'), file);
-  };
-
-  /**
-   * Attaches all event handlers to the loaded markup
-   */
-  ref.addEventHandlers = function(op, file) {
-    switch (op) {
-      case 'flash_loaded':
-        ref.upload_button_obj.find('.swfupload-wrapper .swfupload').mousedown(function() {
-          $(this).parent().parent().addClass('active');
-        }).mouseup(function() {
-          $(this).parent().parent().removeClass('active');
-        });
-        break;
+    /**
+     * Attaches all event handlers to the loaded markup
+     */
+    ref.addEventHandlers = function(op, file) {
+      switch (op) {
+        case 'flash_loaded':
+          ref.upload_button_obj.find('.swfupload-wrapper .swfupload').mousedown(function() {
+            $(this).parent().parent().addClass('active');
+          }).mouseup(function() {
+            $(this).parent().parent().removeClass('active');
+          });
+          break;
 
-      case 'file_queued':
-        $('#' + file.id).find('.sfwupload-list-cancel').click(function() {
-          ref.cancelUpload(file);
-        });
-        break;
+        case 'file_queued':
+          $('#' + file.id).find('.sfwupload-list-cancel').click(function() {
+            ref.cancelUpload(file);
+          });
+          break;
 
-      case 'file_added':
-        var file_element_obj = $('#' + file.fid);
-        file_element_obj.find('.sfwupload-list-cancel').unbind('click').click(function() {
-          ref.removeFileItem(file);
-        }).disableTextSelect();
-        file_element_obj.find('input:checkbox').bind('click', function() {
-          ref.updateStack(file);
-        });
-        file_element_obj.find('input:text, textarea').blur(function() {
-          ref.toggleInput($(this), false, file);
-        }).keydown(function(e) {
-          ref.key_pressed = e.keyCode;
-          if ((e.keyCode == 27) || (e.keyCode == 13 && $(this).get(0).tagName.toLowerCase() !== 'textarea')) {
-            $(this).blur();
+        case 'file_added':
+          var file_element_obj = $('#' + file.fid);
+          file_element_obj.find('.sfwupload-list-cancel').unbind('click').click(function() {
+            ref.removeFileItem(file);
+          }).disableTextSelect();
+          file_element_obj.find('input:checkbox').bind('click', function() {
+            ref.updateStack(file);
+          });
+          file_element_obj.find('input:text, textarea').blur(function() {
+            ref.toggleInput($(this), false, file);
+          }).keydown(function(e) {
+            ref.key_pressed = e.keyCode;
+            if ((e.keyCode == 27) || (e.keyCode == 13 && $(this).get(0).tagName.toLowerCase() !== 'textarea')) {
+              $(this).blur();
+              return false;
+            };
+          }).parents('td').dblclick(function() {
+            ref.toggleInput($(this).find('span'), true, file);
+          }).find('.wrapper').append($('<a href="#" />').text(Drupal.t('edit')).addClass('toggle-editable').click(function() {
+            ref.toggleInput($(this).parent().find('span'), true, file);
             return false;
-          };
-        }).parents('td').dblclick(function() {
-          ref.toggleInput($(this).find('span'), true, file);
-        }).find('.wrapper').append($('<a href="#" />').text(Drupal.t('edit')).addClass('toggle-editable').click(function() {
-          ref.toggleInput($(this).parent().find('span'), true, file);
-          return false;
-        }));
-        break;
+          }));
+          break;
 
-      case 'drag_enable':
-        // Attach the tabledrag behavior
-        // This will we only executed once.
-        Drupal.attachBehaviors(ref.wrapper_obj);
-    
-        $('tbody tr', ref.wrapper_obj).not('.hidden, .tabledrag-handle-swfupload-moved').each(function() {
-    
-          if (!$('a.tabledrag-handle', $(this)).size()) {
-            Drupal.tableDrag[ref.wrapper_id].makeDraggable(this);
-          };
-    
-          $('a.tabledrag-handle', $(this)).not('.tabledrag-handle-swfupload-moved').each(function() {
-            $(this).appendTo($(this).parents('tr').addClass('tabledrag-handle-swfupload-moved').find('td.drag div.wrapper')).bind('mousedown', function() {
-              $(this).parents('tr').addClass('dragging');
+        case 'drag_enable':
+          // Attach the tabledrag behavior
+          // This will we only executed once.
+          Drupal.attachBehaviors(ref.wrapper_obj);
+/*
+          $('tbody tr', ref.wrapper_obj).not('.hidden, .tabledrag-handle-swfupload-moved').each(function() {
+
+            if (!$('a.tabledrag-handle', $(this)).size()) {
+              Drupal.tableDrag[ref.wrapper_id].makeDraggable(this);
+            };
+
+            $('a.tabledrag-handle', $(this)).not('.tabledrag-handle-swfupload-moved').each(function() {
+              $(this).appendTo($(this).parents('tr').addClass('tabledrag-handle-swfupload-moved').find('td.drag div.wrapper')).bind('mousedown', function() {
+                $(this).parents('tr').addClass('dragging');
+              });
             });
           });
-        });
-    
-        $(document).unbind('mouseup', ref.tableDragStop).bind('mouseup', ref.tableDragStop);
-        break;
 
-      default:
-        break;
-    };
-  };
-
-  /**
-   * Triggered when the user has stopped dragging a tablerow.
-   */
-  ref.tableDragStop = function() {
-    $('tr', ref.wrapper_obj).removeClass('dragging');
-    $(ref.wrapper_obj).parent().children('.warning').css({'visibility':'hidden'}).remove();
-    ref.updateStack();
-  };
+          $(document).unbind('mouseup', ref.tableDragStop).bind('mouseup', ref.tableDragStop);
+*/
+          break;
 
-  /**
-   * Toggles editability of text spans inside tablerows
-   */
-  ref.toggleInput = function(obj, start, file) {
-    obj.hide().parent().toggleClass('editable-enabled');
-    if (start) {
-      obj.hide().parent().find('input:text, textarea').show().focus().select();
-    }
-    else {
-      if (ref.key_pressed == 27) {
-        obj.val(obj.parent().find('span').html()).hide().parent().find('span').show();
-        return;
-      };
-
-      var value = obj.val();
-      if (value == '') {
-        obj.hide().parent().find('span').html('&nbsp;').show();
-      }
-      else {
-        obj.hide().parent().find('span').text((value == '&nbsp;' ? '' : value)).show();
+        default:
+          break;
       };
     };
-    ref.updateStack(file);
-  };
 
-  /**
-   * Launched when the swf has been loaded.
-   */
-  ref.swfUploadLoaded = function() {
-    // Update the stats object in order to let SWFUpload know we've already got some files stored
-    ref.swfu.setStats({successful_uploads: ref.upload_stack_length});
-    ref.addEventHandlers('flash_loaded');
-  };
-
-  /**
-   * The file(s) have been selected.
-   */
-  ref.dialogComplete = function(files_selected, files_queued) {
-    if (ref.settings.file_upload_limit && ref.settings.file_upload_limit !== 0 && (files_selected > ref.settings.file_upload_limit)) {
-      ref.displayMessage(Drupal.t('You can upload only !num !file!', {'!num':ref.settings.file_upload_limit, '!file': Drupal.formatPlural(ref.settings.file_upload_limit, 'file', 'files')}), 'error');
-    }
-    else {
-      ref.uploadNextInQueue();
+    /**
+     * Triggered when the user has stopped dragging a tablerow.
+     */
+    ref.tableDragStop = function() {
+      $('tr', ref.wrapper_obj).removeClass('dragging');
+      $(ref.wrapper_obj).parent().children('.warning').css({'visibility':'hidden'}).remove();
+      ref.updateStack();
     };
-  };
 
-  /**
-   * The file(s) have been selected by the user and added to the upload queue
-   */
-  ref.fileQueued = function(file) {
-    if (ref.settings.file_upload_limit && ref.settings.file_upload_limit !== 0) {
-      // Check if the queued file(s) do not exceed the max number of files
-      var stats = ref.swfu.getStats();
-      if ((ref.upload_stack_length + stats.files_queued) > ref.settings.file_upload_limit) {
-        ref.swfu.cancelUpload(file.id);
-        var queue_space = (ref.settings.file_upload_limit - ref.upload_stack_length);
-        if (queue_space == 0) {
-          ref.displayMessage(Drupal.t('You are not allowed to add more than !num !file!', {'!num':ref.settings.file_upload_limit, '!file': Drupal.formatPlural(ref.settings.file_upload_limit, 'file', 'files')}), 'error');
+    /**
+     * Toggles editability of text spans inside tablerows
+     */
+    ref.toggleInput = function(obj, start, file) {
+      obj.hide().parent().toggleClass('editable-enabled');
+      if (start) {
+        obj.hide().parent().find('input:text, textarea').show().focus().select();
+      }
+      else {
+        if (ref.key_pressed == 27) {
+          obj.val(obj.parent().find('span').html()).hide().parent().find('span').show();
+          return;
+        };
+
+        var value = obj.val();
+        if (value == '') {
+          obj.hide().parent().find('span').html('&nbsp;').show();
         }
         else {
-          ref.displayMessage(Drupal.t('You can upload only !num more !file!', {'!num':queue_space, '!file':Drupal.formatPlural(queue_space, 'file', 'files')}), 'error');
+          obj.hide().parent().find('span').text((value == '&nbsp;' ? '' : value)).show();
         };
-        return;
       };
+      ref.updateStack(file);
     };
-    if (ref.max_queue_size && ref.max_queue_size !== 0) {
-      // Check if the new file does not exceed the max queue size
-      if ((ref.upload_stack_size + file.size) > ref.max_queue_size) {
-        var max_queue_mbs = ref.getMbs(ref.max_queue_size);
-        var file_mbs = ((file.size / 1024) / 1024);
-        ref.swfu.cancelUpload(file.id);
-        ref.displayMessage(Drupal.t('The file size (!num1 MB) exceeds the upload size (!num2 MB) for this page!', {'!num1':file_mbs.toFixed(2), '!num2':max_queue_mbs.toFixed(2)}), 'error');
-        return;
-      };
+
+    /**
+     * Launched when the swf has been loaded.
+     */
+    ref.swfUploadLoaded = function() {
+      // Update the stats object in order to let SWFUpload know we've already got some files stored
+      ref.swfu.setStats({successful_uploads: ref.upload_stack_length});
+      ref.addEventHandlers('flash_loaded');
     };
-    // No problems found, add the new file to the stack.
-    file.extension = ref.getExtension(file.name);
-    ref.queue[file.id] = file;
-    ref.addFileItem(file);
-  };
 
-  /**
-   * Responds on file queue errors 
-   */
-  ref.fileQueueError = function(file, code, message) {
-    switch (code) {
-      case -110: // The file selected is too large
-        var max_file_mbs = ref.getMbs(ref.settings.file_size_limit);
-        var file_mbs = ((file.size / 1024) / 1024);
-        ref.displayMessage(Drupal.t('The file size (!num1 MB) exceeds the file size limit (!num2 MB)!', {'!num1':file_mbs.toFixed(2), '!num2':max_file_mbs.toFixed(2)}), 'error');
-        break;
-      default:
-        break;
+    /**
+     * The file(s) have been selected.
+     */
+    ref.dialogComplete = function(files_selected, files_queued) {
+      if (ref.settings.file_upload_limit && ref.settings.file_upload_limit !== 0 && (files_selected > ref.settings.file_upload_limit)) {
+        ref.displayMessage(Drupal.t('You can upload only !num !file!', {'!num':ref.settings.file_upload_limit, '!file': Drupal.formatPlural(ref.settings.file_upload_limit, 'file', 'files')}), 'error');
+      }
+      else {
+        ref.uploadNextInQueue();
+      };
     };
-  };
 
-  /**
-   * Calculates the MB's from a given string
-   */
-  ref.getMbs = function(size) {
-    // B, KB, MB and GB
-    if (size.indexOf('MB') > -1) {
-      return parseInt(size);
-    }
-    else if (size.indexOf('GB') > -1) {
-      return (parseInt(size) * 1024);
-    }
-    else if (size.indexOf('KB') > -1) {
-      return (parseInt(size) / 1024);
-    }
-    else if (size.indexOf('B') > -1) {
-      return ((parseInt(size) / 1024) / 1024);
+    /**
+     * The file(s) have been selected by the user and added to the upload queue
+     */
+    ref.fileQueued = function(file) {
+      if (ref.settings.file_upload_limit && ref.settings.file_upload_limit !== 0) {
+        // Check if the queued file(s) do not exceed the max number of files
+        var stats = ref.swfu.getStats();
+        if ((ref.upload_stack_length + stats.files_queued) > ref.settings.file_upload_limit) {
+          ref.swfu.cancelUpload(file.id);
+          var queue_space = (ref.settings.file_upload_limit - ref.upload_stack_length);
+          if (queue_space == 0) {
+            ref.displayMessage(Drupal.t('You are not allowed to add more than !num !file!', {'!num':ref.settings.file_upload_limit, '!file': Drupal.formatPlural(ref.settings.file_upload_limit, 'file', 'files')}), 'error');
+          }
+          else {
+            ref.displayMessage(Drupal.t('You can upload only !num more !file!', {'!num':queue_space, '!file':Drupal.formatPlural(queue_space, 'file', 'files')}), 'error');
+          };
+          return;
+        };
+      };
+      if (ref.max_queue_size && ref.max_queue_size !== 0) {
+        // Check if the new file does not exceed the max queue size
+        if ((ref.upload_stack_size + file.size) > ref.max_queue_size) {
+          var max_queue_mbs = ref.getMbs(ref.max_queue_size);
+          var file_mbs = ((file.size / 1024) / 1024);
+          ref.swfu.cancelUpload(file.id);
+          ref.displayMessage(Drupal.t('The file size (!num1 MB) exceeds the upload size (!num2 MB) for this page!', {'!num1':file_mbs.toFixed(2), '!num2':max_queue_mbs.toFixed(2)}), 'error');
+          return;
+        };
+      };
+      // No problems found, add the new file to the stack.
+      file.extension = ref.getExtension(file.name);
+      ref.queue[file.id] = file;
+      ref.addFileItem(file);
     };
-    return false;
-  };
 
-  /**
-   * Displays messages
-   */
-  ref.displayMessage = function(messages, type) {
-    if (typeof(messages) == 'object') {
-      var multiple = (messages.length > 1);
-      var messages_tmp = (multiple ? '<ul>' : '');
-      for (var i in messages) {
-        messages_tmp += (multiple ? '<li>' + messages[i] + '</li>' : messages[i]);
+    /**
+     * Responds on file queue errors
+     */
+    ref.fileQueueError = function(file, code, message) {
+      switch (code) {
+        case -110: // The file selected is too large
+          var max_file_mbs = ref.getMbs(ref.settings.file_size_limit);
+          var file_mbs = ((file.size / 1024) / 1024);
+          ref.displayMessage(Drupal.t('The file size (!num1 MB) exceeds the file size limit (!num2 MB)!', {'!num1':file_mbs.toFixed(2), '!num2':max_file_mbs.toFixed(2)}), 'error');
+          break;
+        default:
+          break;
       };
-      messages = (multiple ? messages_tmp + '</ul>' : messages_tmp);
     };
 
-    if (!ref.message_wrapper_obj) {
-      ref.message_wrapper_obj = $('<div />').addClass('swfupload-messages').insertAfter(ref.wrapper_obj);
-      ref.messages_timeout = setTimeout(function() {ref.hideMessages();}, 5000);
+    /**
+     * Calculates the MB's from a given string
+     */
+    ref.getMbs = function(size) {
+      // B, KB, MB and GB
+      if (size.indexOf('MB') > -1) {
+        return parseInt(size);
+      }
+      else if (size.indexOf('GB') > -1) {
+        return (parseInt(size) * 1024);
+      }
+      else if (size.indexOf('KB') > -1) {
+        return (parseInt(size) / 1024);
+      }
+      else if (size.indexOf('B') > -1) {
+        return ((parseInt(size) / 1024) / 1024);
+      };
+      return false;
     };
 
-    if (!$('div.' + type, ref.message_wrapper_obj).size()) {
-      ref.message_wrapper_obj.append($('<div />').css({'height':'auto', 'opacity':1}).addClass('messages ' + type).html(messages));
-    }
-    else {
-      // The messagewrapper already exists. Add the new message to the wrapper and reset the timeout.
+    /**
+     * Displays messages
+     */
+    ref.displayMessage = function(messages, type) {
+      if (typeof(messages) == 'object') {
+        var multiple = (messages.length > 1);
+        var messages_tmp = (multiple ? '<ul>' : '');
+        for (var i in messages) {
+          messages_tmp += (multiple ? '<li>' + messages[i] + '</li>' : messages[i]);
+        };
+        messages = (multiple ? messages_tmp + '</ul>' : messages_tmp);
+      };
 
-      // Check if the message isn't already displayed
-      if (ref.message_wrapper_obj.html().indexOf(messages) > -1) {
-        return;
+      if (!ref.message_wrapper_obj) {
+        ref.message_wrapper_obj = $('<div />').addClass('swfupload-messages').insertAfter(ref.wrapper_obj);
+        ref.messages_timeout = setTimeout(function() {ref.hideMessages();}, 5000);
       };
 
-      // If the new type differs from the current type, we'll remove the old message.
-      if ((ref.message_wrapper_obj.hasClass('status') && type !== 'status') || (ref.message_wrapper_obj.hasClass('error') && type !== 'error')) {
-        ref.message_wrapper_obj.removeClass('status error').addClass(type).html(messages);
+      if (!$('div.' + type, ref.message_wrapper_obj).size()) {
+        ref.message_wrapper_obj.append($('<div />').css({'height':'auto', 'opacity':1}).addClass('messages ' + type).html(messages));
       }
       else {
-        ref.message_wrapper_obj.append('<br />' + messages);
+        // The messagewrapper already exists. Add the new message to the wrapper and reset the timeout.
+
+        // Check if the message isn't already displayed
+        if (ref.message_wrapper_obj.html().indexOf(messages) > -1) {
+          return;
+        };
+
+        // If the new type differs from the current type, we'll remove the old message.
+        if ((ref.message_wrapper_obj.hasClass('status') && type !== 'status') || (ref.message_wrapper_obj.hasClass('error') && type !== 'error')) {
+          ref.message_wrapper_obj.removeClass('status error').addClass(type).html(messages);
+        }
+        else {
+          ref.message_wrapper_obj.append('<br />' + messages);
+        };
+        clearInterval(ref.messages_timeout);
+        ref.messages_timeout = setTimeout(function() {ref.hideMessages();}, 5000);
       };
-      clearInterval(ref.messages_timeout);
-      ref.messages_timeout = setTimeout(function() {ref.hideMessages();}, 5000);
     };
-  };
-
-  /**
-   * Slowly hides the messages wrapper
-   */
-  ref.hideMessages = function() {
-    ref.message_wrapper_obj.animate({'height':'0px', 'opacity':0}, 'slow', function() {
-      ref.message_wrapper_obj.remove();
-      ref.message_wrapper_obj = false;
-    });
-  };
 
-  /**
-   * Triggers a new upload.
-   */
-  ref.uploadNextInQueue = function() {
-		try {
-		  ref.swfu.startUpload();
-		}
-		catch (err) {
-		  ref.swfu.debug(err);
-		};
-  };
+    /**
+     * Slowly hides the messages wrapper
+     */
+    ref.hideMessages = function() {
+      ref.message_wrapper_obj.animate({'height':'0px', 'opacity':0}, 'slow', function() {
+        ref.message_wrapper_obj.remove();
+        ref.message_wrapper_obj = false;
+      });
+    };
 
-  /**
-   * Adjusts the progress indicator.
-   */
-  ref.uploadProgress = function(file, complete, total) {
-     // We don't want this one to end up to 100% when all bytes are loaded. The progressbar will have an width of 100% on uploadFileComplete
-    var done = Math.round((96 / total)  * complete);
-    $('#' + file.id + ' .sfwupload-list-progressbar-status').css({'width': done + '%'});
-  };
+    /**
+     * Triggers a new upload.
+     */
+    ref.uploadNextInQueue = function() {
+      try {
+        ref.swfu.startUpload();
+      }
+      catch (err) {
+        ref.swfu.debug(err);
+      };
+    };
 
-  /**
-   * Handles upload errors
-   */
-  ref.uploadError = function(file, code, message) {
-    // Check for messages which can be handled as 'status' messages
-    switch (code) {
-      case -240:
-        ref.displayMessage(Drupal.t('The upload limit (!num) has been reached!', {'!num': ref.settings.file_upload_limit}), 'status');
-        return;
-      case -200:
-        message = Drupal.t('Server error!', {'!num': ref.settings.file_upload_limit});
+    /**
+     * Adjusts the progress indicator.
+     */
+    ref.uploadProgress = function(file, complete, total) {
+       // We don't want this one to end up to 100% when all bytes are loaded. The progressbar will have an width of 100% on uploadFileComplete
+      var done = Math.round((96 / total)  * complete);
+      $('#' + file.id + ' .sfwupload-list-progressbar-status').css({'width': done + '%'});
     };
 
-    // Give the user some visual indicators of the event
-    $('#' + file.id + ' .sfwupload-list-progressbar').addClass('stopped').find('.sfwupload-list-progressbar-status').css({'width':'100%'});
-    $('#' + file.id + ' .sfwupload-list-progressbar-glow').append((typeof(message) == 'object' ? message[0] : message));
+    /**
+     * Handles upload errors
+     */
+    ref.uploadError = function(file, code, message) {
+      // Check for messages which can be handled as 'status' messages
+      switch (code) {
+        case -240:
+          ref.displayMessage(Drupal.t('The upload limit (!num) has been reached!', {'!num': ref.settings.file_upload_limit}), 'status');
+          return;
+        case -200:
+          message = Drupal.t('Server error!', {'!num': ref.settings.file_upload_limit});
+      };
+
+      // Give the user some visual indicators of the event
+      $('#' + file.id + ' .sfwupload-list-progressbar').addClass('stopped').find('.sfwupload-list-progressbar-status').css({'width':'100%'});
+      $('#' + file.id + ' .sfwupload-list-progressbar-glow').append((typeof(message) == 'object' ? message[0] : message));
 
-    // If a file is set, we need to remove the added file DOM element
-    if (file) {
-      setTimeout(function() {
-        ref.removeFileItem(file);
-      }, 2000);
+      // If a file is set, we need to remove the added file DOM element
+      if (file) {
+        setTimeout(function() {
+          ref.removeFileItem(file);
+        }, 2000);
+      };
     };
-  };
 
-  /**
-   * Triggered after the upload is succesfully completed.
-   */
-  ref.uploadComplete = function(file) {
-    if (ref.queue[file.id] && !ref.queue[file.id].cancelled) {
-      setTimeout(function() {
-        $('#' + ref.queue[file.id].fid).find('.sfwupload-list-progressbar').animate({'opacity':0}, "slow", function() {
-          file.fid = ref.queue[file.id].fid;
-          ref.tableRow(false, file);
-          ref.updateStack(file);
-          ref.addEventHandlers('file_added', file);
+    /**
+     * Triggered after the upload is succesfully completed.
+     */
+    ref.uploadComplete = function(file) {
+      if (ref.queue[file.id] && !ref.queue[file.id].cancelled) {
+        setTimeout(function() {
+          $('#' + ref.queue[file.id].fid).find('.sfwupload-list-progressbar').animate({'opacity':0}, "slow", function() {
+            file.fid = ref.queue[file.id].fid;
+            ref.tableRow(false, file);
+            ref.updateStack(file);
+            ref.addEventHandlers('file_added', file);
 
-          if (ref.queue[file.id].thumb) {
-            $('.sfwupload-list-mime', $('#' + ref.queue[file.id].fid)).css({'background-image': 'url(' + ref.queue[file.id].thumb + ')'});
-          };
-          ref.upload_button_obj.removeClass('swfupload-error');
-        });
-      }, 1000);
+            if (ref.queue[file.id].thumb) {
+              $('.sfwupload-list-mime', $('#' + ref.queue[file.id].fid)).css({'background-image': 'url(' + ref.queue[file.id].thumb + ')'});
+            };
+            ref.upload_button_obj.removeClass('swfupload-error');
+          });
+        }, 1000);
+      };
+      ref.uploadNextInQueue();
     };
-		ref.uploadNextInQueue();
-  };
 
-  /**
-   * Retrieves the data returned by the server
-   */
-  ref.uploadSuccess = function(file, server_data) {
-    var server_data = Drupal.parseJson(server_data);
+    /**
+     * Retrieves the data returned by the server
+     */
+    ref.uploadSuccess = function(file, server_data) {
+      var server_data = jQuery.parseJSON(server_data);
 
-    // Check for messages returned by the server.
-    if (server_data.messages) {
-
-      // Check if the server returned status messages
+      // Check for messages returned by the server.
       if (server_data.messages) {
-        for (var type in server_data.messages) {
-          if (type !== 'swfupload_error') {
-            ref.displayMessage(server_data.messages[type], type);
+
+        // Check if the server returned status messages
+        if (server_data.messages) {
+          for (var type in server_data.messages) {
+            if (type !== 'swfupload_error') {
+              ref.displayMessage(server_data.messages[type], type);
+            };
           };
         };
-      };
 
-      // Check if the server returned an error
-      if (server_data.messages.swfupload_error) {
-        ref.uploadError(file, null, server_data.messages.swfupload_error);
-        ref.queue[file.id].cancelled = true;
-        return;
+        // Check if the server returned an error
+        if (server_data.messages.swfupload_error) {
+          ref.uploadError(file, null, server_data.messages.swfupload_error);
+          ref.queue[file.id].cancelled = true;
+          return;
+        };
       };
-    };
 
-    // No errors. Complete the fileupload.
-    ref.queue[file.id].fid = server_data.file.fid;
-    $('#' + file.id).attr({'id':server_data.file.fid}).find('.sfwupload-list-progressbar-status').css({'width':'100%'}).parent().addClass('complete');
+      // No errors. Complete the fileupload.
+      ref.queue[file.id].fid = server_data.file.fid;
+      $('#' + file.id).attr({'id':server_data.file.fid}).find('.sfwupload-list-progressbar-status').css({'width':'100%'}).parent().addClass('complete');
 
-    if (server_data.file.thumb) {
-      ref.queue[file.id].thumb = server_data.file.thumb;
+      if (server_data.file.thumb) {
+        ref.queue[file.id].thumb = server_data.file.thumb;
+      };
     };
-  };
 
-  /**
-   * Updates the value of the hidden input field which stores all uploaded files
-   */
-  ref.updateStack = function(file) {
-    var fid, input_field, element;
-    var old_upload_stack = ref.upload_stack;
-    var total_size = 0;
-    ref.upload_stack = {};
+    /**
+     * Updates the value of the hidden input field which stores all uploaded files
+     */
+    ref.updateStack = function(file) {
+      var fid, input_field, element;
+      var old_upload_stack = ref.upload_stack;
+      var total_size = 0;
+      ref.upload_stack = {};
 
-    ref.wrapper_obj.find('.processed').each(function() {
-      fid = $(this).attr('id');
+      ref.wrapper_obj.find('.processed').each(function() {
+        fid = $(this).attr('id');
 
-      // If no file is secified, the function is called after sorting
-      // There are no new values so the file object is not needed
-      // We only need to change the order of the stack 
-      if (!file) {
-        ref.upload_stack[fid] = old_upload_stack[fid];
-      }
-      else {
-        ref.upload_stack[fid] = {filename:file.filename || file.name, fid:fid};
-        total_size += parseInt(file.size);
-        for (var name in ref.instance.elements) {
-          input_field = $('#edit-' + name + '_' + fid);
-          if (input_field.size() !== 0) {
-            ref.upload_stack[fid][name] = (input_field.attr('type') == 'checkbox') ? input_field.attr('checked') : input_field.val();
+        // If no file is specified, the function is called after sorting
+        // There are no new values so the file object is not needed
+        // We only need to change the order of the stack
+        if (!file) {
+          ref.upload_stack[fid] = old_upload_stack[fid];
+        }
+        else {
+          // Don't overwrite other rows with the current filename.
+          if (fid == file.fid) {
+            ref.upload_stack[fid] = {filename:file.filename || file.name, fid:fid};
+          } else {
+            ref.upload_stack[fid] = old_upload_stack[fid];
+          }
+          total_size += parseInt(file.size);
+          for (var name in ref.instance.elements) {
+            input_field = $('#edit-' + name + '_' + fid);
+            if (input_field.size() !== 0) {
+              ref.upload_stack[fid][name] = (input_field.attr('type') == 'checkbox') ? input_field.attr('checked') : input_field.val();
+            };
           };
         };
-      };
-    });
-    ref.upload_stack_size = total_size;
-    ref.upload_stack_length = ref.objectLength(ref.upload_stack);
-    ref.upload_stack_obj.val(ref.toJson(ref.upload_stack));
-    ref.addEventHandlers('drag_enable');
+      });
+      ref.upload_stack_size = total_size;
+      ref.upload_stack_length = ref.objectLength(ref.upload_stack);
+      ref.upload_stack_obj.val(ref.toJson(ref.upload_stack));
+      ref.addEventHandlers('drag_enable');
 
-    if ((ref.settings.file_upload_limit > ref.upload_stack_length) || ref.settings.file_upload_limit === 0) {
-      ref.upload_button_obj.removeClass('disabled').css({opacity:1});
-    }
-    else {
-      ref.upload_button_obj.addClass('disabled').css({opacity:0.4});
+      if ((ref.settings.file_upload_limit > ref.upload_stack_length) || ref.settings.file_upload_limit === 0) {
+        ref.upload_button_obj.removeClass('disabled').css({opacity:1});
+      }
+      else {
+        ref.upload_button_obj.addClass('disabled').css({opacity:0.4});
+      };
     };
-  };
 
-  /**
-   * Aborts a file upload
-   */
-  ref.cancelUpload = function(file) {
-    // Check if the file is still being uploaded.
-    if (ref.swfu.getFile(file.id)) {
-      // Abort the upload
-      ref.swfu.cancelUpload(file.id);
-      ref.queue[file.id].cancelled = true;
-      setTimeout(function() {
-        ref.removeFileItem(file);
-      }, 1000);
+    /**
+     * Aborts a file upload
+     */
+    ref.cancelUpload = function(file) {
+      // Check if the file is still being uploaded.
+      if (ref.swfu.getFile(file.id)) {
+        // Abort the upload
+        ref.swfu.cancelUpload(file.id);
+        ref.queue[file.id].cancelled = true;
+        setTimeout(function() {
+          ref.removeFileItem(file);
+        }, 1000);
+      };
     };
-  };
 
-  /**
-   * Removes a file form the list
-   */
-  ref.removeFileItem = function(file) {
-    var file_tr = $('#' + (file.fid ? file.fid : file.id)).removeClass('processed');
-    var file_tds = file_tr.find('td');
-    var current_height = file_tr.height();
-    var cleared = false;
+    /**
+     * Removes a file form the list
+     */
+    ref.removeFileItem = function(file) {
+      var file_tr = $('#' + (file.fid ? file.fid : file.id)).removeClass('processed');
+      var file_tds = file_tr.find('td');
+      var current_height = file_tr.height();
+      var cleared = false;
 
-    // Delete the file from the queue
-    delete(ref.queue[file.id]);
+      // Delete the file from the queue
+      delete(ref.queue[file.id]);
 
-    // Animate the deletion of the file's table row
-    // First fade out the contents of the td's
-    file_tds.find('div, input').animate({opacity:0}, 'fast', function() {
-      file_tds.each(function() {
-        // The contents are not visible anymore, so we can remove it.
-        $(this).html('');
-      });
+      // Animate the deletion of the file's table row
+      // First fade out the contents of the td's
+      file_tds.find('div, input').animate({opacity:0}, 'fast', function() {
+        file_tds.each(function() {
+          // The contents are not visible anymore, so we can remove it.
+          $(this).html('');
+        });
 
-      // Since animate({height:0}) does not work for tr and td's, we need to declare our own interval
-      var intv = setInterval(function() {
-        current_height -= 5;
-        file_tds.height(current_height);
-        file_tr.css({opacity: current_height * 4});
+        // Since animate({height:0}) does not work for tr and td's, we need to declare our own interval
+        var intv = setInterval(function() {
+          current_height -= 5;
+          file_tds.height(current_height);
+          file_tr.css({opacity: current_height * 4});
 
-        // The animation is complete
-        if(current_height <= 5) {
-          if (!cleared) {
-            cleared = true;
-            file_tr.remove();
-            clearInterval(intv);
+          // The animation is complete
+          if(current_height <= 5) {
+            if (!cleared) {
+              cleared = true;
+              file_tr.remove();
+              clearInterval(intv);
 
-            // Reset the successfull upload queue
-            var stats = ref.swfu.getStats();
-            stats.successful_uploads--;
-            ref.swfu.setStats(stats);
+              // Reset the successfull upload queue
+              var stats = ref.swfu.getStats();
+              stats.successful_uploads--;
+              ref.swfu.setStats(stats);
 
-            if (file_tr) {
-              // Update the hidden input field
-              ref.updateStack(file);
+              if (file_tr) {
+                // Update the hidden input field
+                ref.updateStack(file);
+              };
             };
           };
-        };
-      }, 50);
-    });
-  };
+        }, 50);
+      });
+    };
 
-  /**
-   * Retrieve the number of elements in an object
-   */
-  ref.objectLength = function(obj) {
-    if (obj.status !== undefined && obj.status == 0) return 0;
+    /**
+     * Retrieve the number of elements in an object
+     */
+    ref.objectLength = function(obj) {
+      if (obj.status !== undefined && obj.status == 0) return 0;
 
-    var count = 0;
-    for (var i in obj)
-    count++;
-    return count;
-  };
+      var count = 0;
+      for (var i in obj)
+      count++;
+      return count;
+    };
 
-  /**
-   * Parses an object to a json formatted string
-   */
-  ref.toJson = function(v) {
-    switch (typeof v) {
-      case 'boolean':
-        return v == true ? 'true' : 'false';
-      case 'number':
-        return v;
-      case 'string':
-        return '"'+ v.replace(/\n/g, '\\n') +'"';
-      case 'object':
-        var output = '';
-        for(i in v) {
-          output += (output ? ',' : '') + '"' + i + '":' + ref.toJson(v[i]);
-        }
-        return '{' + output + '}';
-      default:
-        return 'null';
+    /**
+     * Parses an object to a json formatted string
+     */
+    ref.toJson = function(v) {
+      switch (typeof v) {
+        case 'boolean':
+          return v == true ? 'true' : 'false';
+        case 'number':
+          return v;
+        case 'string':
+          return '"'+ v.replace(/\n/g, '\\n') +'"';
+        case 'object':
+          var output = '';
+          for(i in v) {
+            output += (output ? ',' : '') + '"' + i + '":' + ref.toJson(v[i]);
+          }
+          return '{' + output + '}';
+        default:
+          return 'null';
+      };
     };
-  };
 
-  /**
-   * 
-   */
-  ref.getExtension = function(file_name) {
-    return file_name.substring(file_name.lastIndexOf('.') + 1).toLowerCase();
-  };
+    /**
+     *
+     */
+    ref.getExtension = function(file_name) {
+      return file_name.substring(file_name.lastIndexOf('.') + 1).toLowerCase();
+    };
 
-  /**
-   * Replaces default values from ref.instance.elements to file values
-   * @see ref.uploadComplete
-   */
-  ref.replaceMacros = function(value, file) {
-    if (!value || value == 0) {
-      return false;
-    }
-    else if (value == 1) {
-      return true;
-    }
-    else {
-      var macros = {'[filename]':file.name, '{fid}':file.fid};
-      for (var i in macros) {
-        value = value.replace(i, macros[i]);
+    /**
+     * Replaces default values from ref.instance.elements to file values
+     * @see ref.uploadComplete
+     */
+    ref.replaceMacros = function(value, file) {
+      if (!value || value == 0) {
+        return false;
+      }
+      else if (value == 1) {
+        return true;
+      }
+      else {
+        var macros = {'[filename]':file.name, '{fid}':file.fid};
+        for (var i in macros) {
+          value = value.replace(i, macros[i]);
+        };
+        return value;
       };
-      return value;
     };
-  };
 
-  /**
-   * Reverses the order of an object
-   */
-  ref.objReverse = function(obj) {
-    var temp_arr = [];
-    var temp_obj = {};
+    /**
+     * Reverses the order of an object
+     */
+    ref.objReverse = function(obj) {
+      var temp_arr = [];
+      var temp_obj = {};
 
-    for (var i in obj) {
-      temp_arr.push({key:i, data:obj[i]});
+      for (var i in obj) {
+        temp_arr.push({key:i, data:obj[i]});
+      };
+      temp_arr = temp_arr.reverse();
+      for (var i in temp_arr) {
+        temp_obj[temp_arr[i].key] = temp_arr[i].data;
+      };
+      return temp_obj;
     };
-    temp_arr = temp_arr.reverse();
-    for (var i in temp_arr) {
-      temp_obj[temp_arr[i].key] = temp_arr[i].data;
-    };    
-    return temp_obj;
-  };
 
-  return ref;
-};
-
-/**
- * Overwrite for the TableDrag markChanged function
- * Allows to place the marker in an other table drawer than the first one.
- */
-Drupal.tableDrag.prototype.row.prototype.markChanged = function() {
-  var marker = Drupal.theme('tableDragChangedMarker');
-  var cell = ($('td.drag .wrapper', this.element)) || $('td:first', this.element);
-  if ($('span.tabledrag-changed', cell).length == 0) {
-    cell.append(marker);
+    return ref;
   };
-};
 
-/**
- * Disables text selection on the DOM element the behavior is attached to.
- */
-jQuery.fn.disableTextSelect = function() {
-  return this.each(function() {
-    $(this).css({
-      'MozUserSelect' : 'none'
-    }).bind('selectstart', function() {
-      return false;
-    }).mousedown(function() {
-      return false;
-    });
-  });
-};
+  $(function() {
+    if (Drupal.settings.swfupload_settings) {
+      Drupal.swfu = {};
+      var settings = Drupal.settings.swfupload_settings;
 
-$(function() {
-  if (Drupal.settings.swfupload_settings) {
-    Drupal.swfu = {};
-    var settings = Drupal.settings.swfupload_settings;
-
-    for (var id in settings) {
-      Drupal.swfu[id] = new SWFU(id, settings[id]);
-      Drupal.swfu[id].init();
+      for (var id in settings) {
+        Drupal.swfu[id] = new SWFU(id, settings[id]);
+        Drupal.swfu[id].init();
+      };
     };
-  };
-});
+  });
+})(jQuery);
\ No newline at end of file
diff --git swfupload.admin.inc swfupload.admin.inc
index 22c07d3..3e3c917 100755
--- swfupload.admin.inc
+++ swfupload.admin.inc
@@ -11,13 +11,16 @@
  */
 function swfupload_js() {
   $p = (object) $_POST;
+
   $op = $p->op;
-  $file = json_decode($p->file);
+  $file = (property_exists($p, 'file')) ? json_decode($p->file) : new stdClass();
   $instance = json_decode($p->instance);
   $widget = json_decode($p->widget);
   $file_path = $p->file_path;
   unset($p);
 
+  $instance->elements = array();
+
   switch ($op) {
     case 'init':
       // Add the default callback functions for the SWF Upload
@@ -32,7 +35,7 @@ function swfupload_js() {
         'upload_progress_handler' => 'ref.uploadProgress',
         'upload_error_handler' => 'ref.uploadError',
         'upload_complete_handler' => 'ref.uploadComplete',
-        'init_complete_handler' => 'ref.initComplete',// This custom javascript callback function is used to place the markup inside the dom
+        'init_complete_handler' => 'ref.initComplete', // This custom javascript callback function is used to place the markup inside the dom
       );
       $instance->elements = array(
         'drag' => array(
@@ -68,7 +71,7 @@ function swfupload_js() {
 
       // Allow other modules to change the file_path an validators
       foreach (module_implements('swfupload') as $module) {
-        $function = $module .'_swfupload';
+        $function = $module . '_swfupload';
         $function($file, $op, $instance, $widget);
       }
 
@@ -77,12 +80,15 @@ function swfupload_js() {
   }
   // Allow other modules to change the returned data
   foreach (module_implements('swfupload') as $module) {
-    $function = $module .'_swfupload';
+    $function = $module . '_swfupload';
     $function($file, $op, $instance, $widget);
 
     // We want to make sure the last column of each tablerow contains the 'cancel' or 'delete' button.
     if ($op == 'init') {
-      $instance->elements['cancel'] = array('class' => 'last', 'type' => 'cancel');
+      $instance->elements['cancel'] = array(
+        'class' => 'last',
+        'type' => 'cancel',
+      );
     }
   }
 
@@ -90,7 +96,7 @@ function swfupload_js() {
   if (is_array($instance->elements)) {
     array_walk($instance->elements, '_class_to_classname');
   }
-  
+
   $p->op = $op;
   $p->file = $file;
   $p->file_path = $file_path;
@@ -104,24 +110,25 @@ function swfupload_js() {
 /**
  * Theme function for the swfupload form element
  */
-function theme_swfupload_widget($element) {
-  drupal_add_css(drupal_get_path('module', 'swfupload') .'/swfupload.css');
+function theme_swfupload_widget($variables) {
+  $element = $variables['element'];
+  drupal_add_css(drupal_get_path('module', 'swfupload') . '/swfupload.css');
 
   // Force the classes swfupload_button and disabled to be added to the button
   _form_set_class($element, array('swfupload_button', 'disabled'));
   $element['#attributes']['class'] = str_replace(' error', ' swfupload-error', $element['#attributes']['class']);
 
   $title = ($element['#title']) ? $element['#title'] : t('Upload new !file', array('!file' => ($element['#max_files'] > 1 ? t('file(s)') : t('file'))));
-  $output[] = '<div id="'. $element['#id'] .'" '. drupal_attributes($element['#attributes']) .'>';
+  $output[] = '<div id="' . $element['#id'] . '" ' . drupal_attributes($element['#attributes']) . '>';
   $output[] = '  <div class="swfupload-wrapper">';
-  $output[] = '    <div id="'. $element['#name'] .'-swfwrapper">&nbsp;</div>';
+  $output[] = '    <div id="' . $element['#field_name'] . '-swfwrapper">&nbsp;</div>';
   $output[] = '  </div>';
   $output[] = '  <div class="left">&nbsp;</div>';
-  $output[] = '  <div class="center">'. $title .'</div>';
+  $output[] = '  <div class="center">' . $title . '</div>';
   $output[] = '  <div class="right">&nbsp;</div><br />';
   $output[] = '</div>';
   if ($element['#description']) {
-    $output[] = '  <div class="description">'. $element['#description'] .'</div>';
+    $output[] = '  <div class="description">' . $element['#description'] . '</div>';
   }
   return join("\n", $output);
 }
@@ -138,51 +145,16 @@ function _class_to_classname(&$element) {
 /**
  * Create a thumbnail to be shown in the swfupload table
  */
-function swfupload_thumb($file) {
-  if (!is_file($file->filepath)) {
-    return FALSE;
-  }
-  $short_path = preg_replace('/^' . preg_quote(file_directory_path(), '/') . '/', '', $file->filepath);
-  $destination_path = file_directory_path() . '/imagefield_thumbs' . $short_path;
-
-  $info = image_get_info($file->filepath);
+function swfupload_thumb($file, $destination) {
   $size = explode('x', variable_get('swfupload_thumb_size', '32x32'));
-
-  // Check if the destination image needs to be regenerated to match a new size.
-  if (is_file($destination_path)) {
-    $thumb_info = image_get_info($destination_path);
-    if ($thumb_info['width'] != $size[0] && $thumb_info['height'] != $size[1] && ($info['width'] > $size[0] || $info['height'] > $size[1])) {
-      unlink($destination_path);
-    }
-    else {
-      return;
-    }
-  }
-
-  // Ensure the destination directory exists and is writable.
-  $directories = explode('/', $destination_path);
-  array_pop($directories); // Remove the file itself.
-  // Get the file system directory.
-  $file_system = file_directory_path();
-  foreach ($directories as $directory) {
-    $full_path = isset($full_path) ? $full_path . '/' . $directory : $directory;
-    // Don't check directories outside the file system path.
-    if (strpos($full_path, $file_system) === 0) {
-      field_file_check_directory($full_path, FILE_CREATE_DIRECTORY);
-    }
-  }
-
-  // Create the thumbnail.
-  if ($info['width'] <= $size[0] && $info['height'] <= $size[1]) {
-    file_copy($file->filepath, $destination_path);
-  }
-  elseif (image_get_toolkit() && @image_scale($file->filepath, $destination_path, $size[0], $size[1])) {
-    // Set permissions. This is done for us when using file_copy().
-    @chmod($destination, 0664);
+  $image_path = !empty($file->destination) ? $file->destination : $file->uri;
+  $image = image_load($image_path);
+  if (file_prepare_directory(dirname($destination), FILE_CREATE_DIRECTORY) && @image_scale($image, $size[0], $size[1])) {
+    image_save($image, $destination);
   }
   else {
     drupal_set_message(t('An image thumbnail was not able to be created.'), 'error');
     return FALSE;
   }
-  return $destination_path;
+  return $destination;
 }
diff --git swfupload.info swfupload.info
index 1545075..f24ae4d 100644
--- swfupload.info
+++ swfupload.info
@@ -1,9 +1,7 @@
 name = SWFupload Widget
-description = A widget for CCK's Filefield which enables multiple file uploads using the SWFUpload library.
+description = A widget for File fields which enables multiple file uploads using the SWFUpload library.
 package = CCK
 version = VERSION
-dependencies[] = filefield
-dependencies[] = jqp
-core = 6.x
-
-
+dependencies[] = file
+dependencies[] = libraries
+core = 7.x
diff --git swfupload.module swfupload.module
index 4a45080..117e21c 100644
--- swfupload.module
+++ swfupload.module
@@ -1,21 +1,26 @@
 <?php
-include_once dirname(__FILE__) . '/swfupload_widget.inc';
+module_load_include('inc', 'swfupload', 'swfupload_widget');
 
 /**
  * @file
  *
- * A widget for CCK's Filefield which enables multiple file uploads using the SWFUpload library.
+ * A widget for File fields which enables multiple file uploads using the SWFUpload library.
  */
 
 /**
- * Implementation of hook_perm().
+ * Implements hook_permission().
  */
-function swfupload_perm() {
-  return array('upload files with swfupload');
+function swfupload_permission() {
+  return array(
+    'upload files with swfupload' => array(
+      'title' => t('Upload files with SWFUpload'),
+      'description' => t('Allows the user to upload multiple files using SWFUpload.'),
+    ),
+  );
 }
 
 /**
- * Implementation of hook_menu().
+ * Implements hook_menu().
  */
 function swfupload_menu() {
   $items['swfupload'] = array(
@@ -38,7 +43,7 @@ function swfupload_upload_access() {
   if (!empty($p->sid)) {
     // $hash_arr[0] is the uid the user wants to athenticate for.
     // $hash_arr[1] is the md5-hashed sid of drupals authetication token.
-    $hash_arr = split("\*", hex2bin($p->sid));
+    $hash_arr = explode("*", hex2bin($p->sid));
     $uid = $hash_arr[0];
     $token = $hash_arr[1];
 
@@ -49,18 +54,21 @@ function swfupload_upload_access() {
     }
 
     // Get all session for the provided user
-    $result = db_query("SELECT sid FROM {sessions} WHERE uid = %d", $uid);
+    $result = db_select('sessions', 's')
+      ->fields('s', array('sid'))
+      ->condition('uid', $uid)
+      ->execute();
     // There is no user with that uid, deny permission.
-    if($result == false) {
-      return false;
-    } 
+    if ($result == FALSE) {
+      return FALSE;
+    }
 
     $valid_sids = array();
     // create our hashes we need for verification
-    while ($row = db_fetch_object($result)) {
+    foreach ($result as $row) {
       $valid_sids[$row->sid] = md5($row->sid);
     }
-    
+
     // If the hashed session is is present in the stored hashed session ids from the database,
     // and if there weren't more that 5 invalid attempts for matching,
     // make the user account global so other modules can use its credentials.
@@ -70,6 +78,9 @@ function swfupload_upload_access() {
 
       // Now load the global user object to "login". We use the $uid provided, as we verfified
       // that the token is correct (and matches this user)
+      // TODO Convert "user_load" to "user_load_multiple" if "$uid" is other than a uid.
+      // To return a single user object, wrap "user_load_multiple" with "array_shift" or equivalent.
+      // Example: array_shift(user_load_multiple(array(), $uid))
       $user = user_load($uid);
 
       // This is needed. Most people forget about this - thats why forms wont work anymore ... the validation fails (token).
@@ -91,34 +102,58 @@ function swfupload_upload_access() {
 }
 
 /**
- * Implementation of hook_widget().
+ * Implements hook_field_widget_form().
  */
-function swfupload_widget(&$form, &$form_state, $field, $items, $delta = 0) {
-  $element = array(
-    '#type' => 'swfupload_widget',
-    '#default_value' => $items,
-  );
+function swfupload_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+  if (module_exists('image') && $field['type'] == 'image') {
+    $element += image_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
+  } else {
+    $element += file_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
+  }
+
+  if (!empty($items)) {
+    $default_values = array();
+    foreach ($items as $key => $file) {
+      $default_values[$file['fid']] = $file + array(
+        'thumb' => '/'. swfupload_thumb_path($file),
+      );
+      unset($element[$key]);
+    }
+
+    $element['#value'] = $default_values;
+    unset($element[$key + 1]);
+  } else {
+    // Remove child elements because we don't want their callbacks to fire
+    unset($element[0]);
+  }
+
+  $element['#theme'] = 'swfupload_widget';
+  $element['#after_build'] = array('swfupload_add_js');
+  $element['#element_validate'] = array('swfupload_widget_validate');
+  //$element['#process'] = array('swfupload_widget_process');
+  //$element['#value_callback'] = 'swfupload_widget_value';
+
   return $element;
 }
 
 /**
- * Implementation of hook_theme().
+ * Implements hook_theme().
  */
 function swfupload_theme() {
   return array(
     'swfupload_widget' => array(
-      'arguments' => array('element' => NULL),
+      'render element' => 'element',
       'file' => 'swfupload.admin.inc',
     ),
   );
 }
 
 /**
- * Implementation of hook_elements().
+ * Implements hook_element_info().
  */
-function swfupload_elements() {
-  $filefield_elements = module_invoke('filefield', 'elements');
-  $elements['swfupload_widget'] = $filefield_elements['filefield_widget'];
+function swfupload_element_info() {
+  $file_field_elements = module_invoke('file', 'element_info');
+  $elements['swfupload_widget'] = $file_field_elements['managed_file'];
   $elements['swfupload_widget']['#process'] = array('swfupload_widget_process');
   $elements['swfupload_widget']['#element_validate'] = array('swfupload_widget_validate');
 
@@ -133,55 +168,58 @@ function swfupload_elements() {
  * This function is called after the FAPI element is processed.
  * Here we can safely attach our javascript
  */
-function swfupload_add_js($element) {
+function swfupload_add_js($element, $form_state) {
   // Get the path to the swfupload module.
-  $path = drupal_get_path('module', 'swfupload');
+  $module_path = drupal_get_path('module', 'swfupload');
+
+  $field = $form_state['field'][$element['#field_name']][$element['#language']]['field'];
+  $instance = $form_state['field'][$element['#field_name']][$element['#language']]['instance'];
 
-  $field = content_fields($element['#field_name'], $element['#type_name']);
-  $swfupload_library = jqp_library_load('swfupload');
+  $library_path = libraries_get_path('swfupload');
+  if (file_exists($library_path . '/swfupload.js') !== FALSE) {
+    drupal_add_js($library_path .'/swfupload.js');
 
-  if (drupal_add_library('swfupload', '2.2.0.1') !== FALSE) {
     // Put the values of the list field and description field in the widget array
     // so we can pass it to our hook_swfupload implementation.
-    $field['widget']['list_field'] = $field['list_field'];
-    $field['widget']['list_default'] = $field['list_default'];
-    $field['widget']['description_field'] = $field['description_field'];
-  
-    $limit = ($field['multiple'] == 1 ? 0 : ($field['multiple'] == 0 ? 1 : $field['multiple']));
+    $field['widget']['display_field'] = isset($field['settings']['display_field']) ? $field['settings']['display_field'] : 0;
+    $field['widget']['display_default'] = isset($field['settings']['display_default']) ? $field['settings']['display_default'] : 0;
+    $field['widget']['description_field'] = isset($field['settings']['description_field']) ? $instance['settings']['description_field'] : 0;
+    $field['widget']['file_extensions'] = $instance['settings']['file_extensions'];
+    $field['widget']['max_filesize_per_file'] = $instance['settings']['max_filesize'];
+    $field['widget']['max_filesize_per_node'] = 0;
+    $field['widget']['max_resolution'] = isset($instance['settings']['max_resolution']) ? $instance['settings']['max_resolution'] : 0;
+    $field['widget']['min_resolution'] = isset($instance['settings']['min_resolution']) ? $instance['settings']['min_resolution'] : 0;
 
-    // We need to store the variable $flash_url statically while the 2nd time the script is loaded,
-    // $swfupload_library->scripts['2.2.0.1'] will be empty.
-    static $flash_url;
-    if (!$flash_url) {
-      $flash_url = base_path() . str_replace('.js', '.swf', array_shift($swfupload_library->scripts['2.2.0.1']));
-    }
+    $limit = ($field['cardinality'] == -1) ? 0 : $field['cardinality'];
+
+    $flash_url = '/'. $library_path .'/swfupload.swf';
 
     $settings['swfupload_settings'][$element['#id']] = array(
-      'module_path' => $path,
+      'module_path' => $module_path,
       'flash_url' => $flash_url,
-      'upload_url' => url('swfupload'),  // Relative to the SWF file
+      'upload_url' => url('swfupload'), // Relative to the SWF file
       'upload_button_id' => $element['#id'],
-      'file_post_name' => $element['#name'],
+      'file_post_name' => $element['#field_name'],
       'file_queue_limit' => $limit,
       'post_params' => array(
         'sid' => _post_key(),
-        'file_path' => file_directory_path() .'/'. $field['widget']['file_path'],
+        'file_path' => $field['settings']['uri_scheme'] . '://' . $instance['settings']['file_directory'],
         'op' => 'move_uploaded_file',
-        'instance' => swfupload_to_js(array('name' => $element['#field_name'])),
+        'instance' => swfupload_to_js(array('name' => $element['#field_name'], 'language' => $element['#language'])),
         'widget' => swfupload_to_js($field['widget']),
       ),
-      'file_size_limit' => ($field['widget']['max_filesize_per_file'] ? (parse_size($field['widget']['max_filesize_per_file']) / 1048576) .'MB' : 0),
-      'file_types' => (empty($field['widget']['file_extensions']) ? '' : '*.'. str_replace(" ", ";*.", $field['widget']['file_extensions'])),
+      'file_size_limit' => ($instance['settings']['max_filesize'] ? (parse_size($instance['settings']['max_filesize']) / 1048576) . 'MB' : 0),
+      'file_types' => (empty($instance['settings']['file_extensions']) ? '' : '*.' . str_replace(" ", ";*.", $instance['settings']['file_extensions'])),
       'file_types_description' => ($element['#description'] ? $element['#description'] : ''),
       'file_upload_limit' => $limit,
       'custom_settings' => array(
         'upload_stack_value' => (!empty($element['#value'])) ? swfupload_to_js($element['#value']) : '[]',
-        'max_queue_size' => ($field['widget']['max_filesize_per_node'] ? $field['widget']['max_filesize_per_node'] : 0),
+        'max_queue_size' => 0,
       ),
     );
-    drupal_add_js('misc/tabledrag.js', 'core');
-    drupal_add_js("$path/js/swfupload_widget.js");
-    drupal_add_js($settings, 'setting');
+    drupal_add_js('misc/tabledrag.js', array('type' => 'file', 'weight' => JS_LIBRARY));
+    drupal_add_js("$module_path/js/swfupload_widget.js");
+    drupal_add_js($settings, array('type' => 'setting', 'scope' => JS_DEFAULT));
   }
 
   return $element;
@@ -192,7 +230,7 @@ function swfupload_add_js($element) {
  */
 function _post_key() {
   global $user;
-  return bin2hex("$user->uid*". md5(($user->uid && $user->sid) ? $user->sid : $_SERVER['REMOTE_ADDR']));
+  return bin2hex("$user->uid*" . md5(($user->uid && $user->sid) ? $user->sid : $_SERVER['REMOTE_ADDR']));
 }
 
 /**
@@ -210,7 +248,7 @@ function hex2bin($h) {
 }
 
 /**
- * Implementation of our own API hook_swfupload().
+ * Implements hook_swfupload().
  */
 function swfupload_swfupload(&$file, $op, &$instance, $widget) {
   switch ($op) {
@@ -222,22 +260,25 @@ function swfupload_swfupload(&$file, $op, &$instance, $widget) {
         $instance->elements['drag']['title'] = t('Description');
         unset($instance->elements['filename']);
       }
-      if ($widget->list_field) {
-        $instance->elements['list'] = array(
+      if ($widget->display_field) {
+        $instance->elements['display'] = array(
           'title' => t('List'),
           'type' => 'checkbox',
-          'default_value' => $widget->list_default,
+          'default_value' => $widget->display_default,
           'class' => 'checkbox',
           'contains_progressbar' => TRUE,
           'add_separator' => TRUE,
         );
         $columns++;
       }
-      foreach (array('alt' => t('Alt'), 'title' => t('Title')) as $elem => $title) {
-        if ($widget->{"custom_$elem"}) {
+      foreach (array(
+        'alt' => t('Alt'),
+        'title' => t('Title'),
+      ) as $elem => $title) {
+        if (property_exists($widget, "custom_$elem") && $widget->{"custom_$elem"}) {
           $instance->elements[$elem] = array(
             'title' => $title,
-            'type' => ($widget->{$elem .'_type'} ? $widget->{$elem .'_type'} : 'textfield'),
+            'type' => ($widget->{$elem . '_type'} ? $widget->{$elem . '_type'} : 'textfield'),
             'default_value' => $widget->{$elem},
             'class' => 'text',
             'contains_progressbar' => TRUE,
@@ -268,23 +309,24 @@ function swfupload_swfupload(&$file, $op, &$instance, $widget) {
         return;
       }
 
-      $_FILES['files']['name'][$instance->name] = $_FILES[$instance->name]['name'];
-      $_FILES['files']['type'][$instance->name] = $_FILES[$instance->name]['type'];
-      $_FILES['files']['tmp_name'][$instance->name] = $_FILES[$instance->name]['tmp_name'];
-      $_FILES['files']['error'][$instance->name] = $_FILES[$instance->name]['error'];
-      $_FILES['files']['size'][$instance->name] = $_FILES[$instance->name]['size'];
+      $upload_name = $instance->name;
+      $_FILES['files']['name'][$upload_name] = $_FILES[$instance->name]['name'];
+      $_FILES['files']['type'][$upload_name] = $_FILES[$instance->name]['type'];
+      $_FILES['files']['tmp_name'][$upload_name] = $_FILES[$instance->name]['tmp_name'];
+      $_FILES['files']['error'][$upload_name] = $_FILES[$instance->name]['error'];
+      $_FILES['files']['size'][$upload_name] = $_FILES[$instance->name]['size'];
 
       // Replace tokens.
       if (module_exists('token')) {
-        $file->file_path = token_replace($file->file_path, 'user');
+        $file->file_path = token_replace($file->file_path, array('user' => NULL));
       }
 
       // Check if the file directory exists
-      field_file_check_directory($file->file_path, FILE_CREATE_DIRECTORY);
+      file_prepare_directory($file->file_path, FILE_CREATE_DIRECTORY);
 
-      if (user_access('upload files with swfupload') && ($file = file_save_upload($instance->name, $file->validators, $file->file_path))) {
-        if (image_get_info($file->filepath)) {
-          $file->thumb = file_create_url(drupal_urlencode(swfupload_thumb_path($file, TRUE)));
+      if (user_access('upload files with swfupload') && ($file = file_save_upload($upload_name, $file->validators, $file->file_path))) {
+        if (image_get_info($file->destination)) {
+          $file->thumb = file_create_url(drupal_encode_path(swfupload_thumb_path($file, TRUE)));
         }
         break;
       }
@@ -307,27 +349,13 @@ function swfupload_filefield_paths_process_file($new, $file, $settings, $node, $
 }
 
 /**
- * Implementation of hook_jqp().
- */
-function swfupload_jqp() {
-  $libraries['swfupload'] = array(
-    'name' => 'SWFUpload',
-    'description' => 'This library allows you to upload multiple files at once by ctrl/shift-selecting in dialog boxed.',
-    'project_url' => 'http://code.google.com/p/swfupload/',
-    'scripts' => array(
-      '2.2.0.1' => array('sites/all/libraries/swfupload/swfupload.js'),
-    ),
-  );
-  return $libraries;
-}
-
-/**
  * Given a file, return the path the image thumbnail used while editing.
  */
 function swfupload_thumb_path($file, $create_thumb = FALSE) {
   $file = (object) $file;
-  $short_path = preg_replace('/^' . preg_quote(file_directory_path(), '/') . '/', '', $file->filepath);
-  $filepath = file_directory_path() . '/imagefield_thumbs' . $short_path;
+  $destination = !empty($file->destination) ? $file->destination : $file->uri;
+  $short_path = substr($destination, strpos($destination, '://')+3);
+  $filepath = file_directory_path() .'/imagefield_thumbs/' . $short_path;
 
   if ($create_thumb) {
     module_load_include('inc', 'swfupload', 'swfupload.admin');
@@ -345,6 +373,6 @@ function swfupload_to_js($var) {
     return str_replace(array('<', '>', '&'), array('\u003c', '\u003e', '\u0026'), json_encode($var));
   }
   else {
-    return str_replace(array('\x3c', '\x3e', '\x26'), array('\u003c', '\u003e', '\u0026'), drupal_to_js($var));
+    return str_replace(array('\x3c', '\x3e', '\x26'), array('\u003c', '\u003e', '\u0026'), drupal_json_encode($var));
   }
 }
diff --git swfupload_widget.inc swfupload_widget.inc
index d227603..03962fb 100755
--- swfupload_widget.inc
+++ swfupload_widget.inc
@@ -6,90 +6,72 @@
  */
 
 /**
- * Implementation of hook_widget_info().
+ * Implements hook_field_widget_info().
  */
-function swfupload_widget_info() {
+function swfupload_field_widget_info() {
   return array(
     'swfupload_widget' => array(
       'label' => t('SWFUpload'),
-      'field types' => array('filefield'),
-      'multiple values' => CONTENT_HANDLE_MODULE,
-      'callbacks' => array(
-        'default value' => CONTENT_CALLBACK_CUSTOM,
+      'field types' => array('file', 'image'),
+      'settings' => array(
+        'progress_indicator' => 'throbber',
+        'preview_image_style' => 'thumbnail',
+      ),
+      'behaviors' => array(
+        'multiple values' => FIELD_BEHAVIOR_CUSTOM,
+        'default value' => FIELD_BEHAVIOR_NONE,
       ),
     ),
   );
 }
 
 /**
- * Implementation of CCK's hook_widget_settings().
- *
- * Delegated to filefield.
- */
-function swfupload_widget_settings($op, $widget) {
-  module_load_include('inc', 'swfupload', 'swfupload_widget');
-  switch ($op) {
-    case 'form':
-      return swfupload_widget_settings_form($widget);
-    case 'validate':
-      return swfupload_widget_settings_validate($widget);
-    case 'save':
-      return swfupload_widget_settings_save($widget);
-  }
-}
-
-/**
- * An #element_validate callback for the filefield_widget field.
+ * An #element_validate callback for the file_field_widget field.
  */
 function swfupload_widget_validate(&$element, &$form_state) {
-
-  $element_value = $element['#value'];
-  if (!empty($element_value)) {
-    foreach (array_values($element_value) as $key => $file) {
-      $form_state['values'][$element['#field_name']][$key] = array_merge(
-        field_file_load($file['fid']), // Load all fields, such as 'filepath'.
-        array(
-          'list' => $file['list'],
-          'data' => array(
-            'description' => $file['description'],
-            'alt' => $file['alt'],
-            'title' => $file['title'],
-          ),
-        )
-      );
-      unset($form_state['values'][$element['#field_name']][$file['fid']]);
-    }
-    unset($form_state['values'][$element['#field_name']]['data']);
+  $raw_value = $form_state['input'][$element['#field_name']][$element['#language']][0]['raw_value'];
+  $files = json_decode($raw_value);
+  $values = array();
+  foreach ($files as $file) {
+    $values[] = array(
+      'fid' => $file->fid,
+      'filename' => $file->filename,
+      'display' => (empty($file->display)) ? 0 : 1,
+      'description' => '',
+    );
   }
+
+  $form_state['input'][$element['#field_name']][$element['#language']] = $values;
+  $form_state['values'][$element['#field_name']][$element['#language']] = $values;
 }
 
 /**
  * The #value_callback for the swfupload_widget type element.
  */
-function swfupload_widget_value($element, $edit = FALSE) {
-  if (is_string($edit)) {
-    $edit = json_decode($edit, TRUE);
+function swfupload_widget_value($element, $input = FALSE, $form_state) {
+  if (!empty($input) && is_string($input['raw_value'])) {
+    $input = json_decode($input['raw_value'], TRUE);
   }
 
-  if ($edit === false) {
+  if ($input === FALSE) {
     $default_value = array();
 
     if (is_array($element['#default_value'])) {
       foreach ($element['#default_value'] as $tmp_file) {
         if ($tmp_file) {
           // Due to a bug in CCK or filefield, the fileobject store in the CCK cache (cache_content) is not stored fully
-          // that means some fields are simply missing (filepath etc.). We need to properly restore it here 
+          // that means some fields are simply missing (filepath etc.). We need to properly restore it here
           $file = field_file_load($tmp_file['fid']);
           $file += array(
             'description' => $tmp_file['data']['description'] ? $tmp_file['data']['description'] : '',
             'alt' => $tmp_file['data']['alt'],
             'title' => $tmp_file['data']['title'],
-            'list' => $tmp_file['list'],
+            'display' => $tmp_file['display'],
           );
 
           // If we're dealing with an image, create a thumbpath
           if (image_get_info($file['filepath'])) {
-            $file['thumb'] = file_create_url(drupal_urlencode(swfupload_thumb_path($file)));
+            $file['thumb'] = file_create_url(drupal_encode_path(swfupload_thumb_path($file)));
           }
           $default_value[$file['fid']] = $file;
         }
@@ -98,7 +80,7 @@ function swfupload_widget_value($element, $edit = FALSE) {
     return $default_value;
   }
   else {
-    return $edit;
+    return $input;
   }
 }
 
@@ -110,15 +92,15 @@ function swfupload_widget_value($element, $edit = FALSE) {
  *
  * The $fields array is in $form['#field_info'][$element['#field_name']].
  */
-function swfupload_widget_process($element, $edit, $form_state, $form) {
-  if (module_exists('imagefield')) {
-    $element += imagefield_widget_process($element, $edit, $form_state, $form);
+function swfupload_widget_process($element, &$form_state, $form) {
+  if (module_exists('image')) {
+    $element += image_field_widget_process($element, $form_state, $form);
     unset($element['#theme']);
   }
-  
+
   // Make sure that the thumbnails exist. $element['#value'] is
   // structured differently in our widget, so this is not handled by
-  // imagefield_widget_process().
+  // image_field_widget_process().
   if (is_array($element['#value'])) {
     foreach (element_children($element['#value']) as $key) {
       if (isset($element['#value'][$key]['filepath'])) {
@@ -133,35 +115,18 @@ function swfupload_widget_process($element, $edit, $form_state, $form) {
 }
 
 /**
- * Implementation of CCK's hook_widget_settings($op = 'form').
+ * Implements hook_field_widget_settings_form().
  */
-function swfupload_widget_settings_form($widget) {
-  if (module_exists('imagefield')) {
-    module_load_include('inc', 'imagefield', 'imagefield_widget');
-    $form = imagefield_widget_settings_form($widget);
+function swfupload_field_widget_settings_form($field, $instance) {
+  if (module_exists('image') && $field['type'] == 'image') {
+    module_load_include('inc', 'image', 'image.field');
+    $form = image_field_widget_settings_form($field, $instance);
   }
   else {
-    $form = module_invoke('filefield', 'widget_settings', 'form', $widget);
+    $form = module_invoke('file', 'field_widget_settings_form', $field, $instance);
   }
-  return $form;
-}
 
-/**
- * Implementation of CCK's hook_widget_settings($op = 'validate').
- */
-function swfupload_widget_settings_validate($widget) {
-  // Check that set resolutions are valid.
-  foreach (array('min_resolution', 'max_resolution') as $resolution) {
-    if (!empty($widget[$resolution]) && !preg_match('/^[0-9]+x[0-9]+$/', $widget[$resolution])) {
-      form_set_error($resolution, t('Please specify a resolution in the format WIDTHxHEIGHT (e.g. 640x480).'));
-    }
-  }
-}
+  $form['#submit'][] = 'swfupload_field_widget_settings_submit';
 
-/**
- * Implementation of CCK's hook_widget_settings($op = 'save').
- */
-function swfupload_widget_settings_save($widget) {
-  $filefield_settings = module_invoke('filefield', 'widget_settings', 'save', $widget);
-  return array_merge($filefield_settings, array('max_resolution', 'min_resolution', 'alt',  'custom_alt', 'title', 'custom_title', 'title_type', 'default_image', 'use_default_image'));
+  return $form;
 }
