[Pkg-mozext-commits] [autofill-forms] 02/09: Imported Upstream version 1.0.2

David Prévot taffit at moszumanska.debian.org
Mon Oct 13 19:45:54 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository autofill-forms.

commit f1da53b6b7fbd6d4562f2e23cea115a7f5dcb7c0
Author: David Prévot <taffit at debian.org>
Date:   Mon Oct 13 14:36:32 2014 -0400

    Imported Upstream version 1.0.2
---
 src/chrome.manifest => chrome.manifest             |    0
 chrome/content/autofillForms.js                    | 5405 ++++++++++++++++++++
 .../content/autofillFormsOptions.js                |    0
 .../content/autofillFormsOptions.xul               |  123 +-
 .../content/autofillFormsOverlay.js                |    0
 .../content/autofillFormsOverlay.xul               |    0
 .../content/autofillFormsRuleEditor.js             |    0
 .../content/autofillFormsRuleEditor.xul            |    0
 .../content/autofillFormsTagEditor.js              |    0
 .../content/autofillFormsTagEditor.xul             |    0
 .../locale/cs-CZ/autofillForms.dtd                 |    0
 .../locale/cs-CZ/autofillForms.properties          |    0
 .../locale/de-DE/autofillForms.dtd                 |    0
 .../locale/de-DE/autofillForms.properties          |    0
 .../locale/el-GR/autofillForms.dtd                 |    0
 .../locale/el-GR/autofillForms.properties          |    0
 .../locale/en-US/autofillForms.dtd                 |    0
 .../locale/en-US/autofillForms.properties          |    0
 .../locale/es-ES/autofillForms.dtd                 |    0
 .../locale/es-ES/autofillForms.properties          |    0
 .../locale/fi-FI/autofillForms.dtd                 |    0
 .../locale/fi-FI/autofillForms.properties          |    0
 .../locale/fr-FR/autofillForms.dtd                 |    0
 .../locale/fr-FR/autofillForms.properties          |    0
 .../locale/he-IL/autofillForms.dtd                 |    0
 .../locale/he-IL/autofillForms.properties          |    0
 .../locale/hr-HR/autofillForms.dtd                 |    0
 .../locale/hr-HR/autofillForms.properties          |    0
 .../locale/hu-HU/autofillForms.dtd                 |    0
 .../locale/hu-HU/autofillForms.properties          |    0
 .../locale/it-IT/autofillForms.dtd                 |    0
 .../locale/it-IT/autofillForms.properties          |    0
 .../locale/nl-NL/autofillForms.dtd                 |    0
 .../locale/nl-NL/autofillForms.properties          |    0
 .../locale/pl-PL/autofillForms.dtd                 |    0
 .../locale/pl-PL/autofillForms.properties          |    0
 .../locale/pt-BR/autofillForms.dtd                 |    0
 .../locale/pt-BR/autofillForms.properties          |    0
 .../locale/ro-RO/autofillForms.dtd                 |    0
 .../locale/ro-RO/autofillForms.properties          |    0
 .../locale/ru-RU/autofillForms.dtd                 |    0
 .../locale/ru-RU/autofillForms.properties          |    0
 .../locale/sk-SK/autofillForms.dtd                 |    0
 .../locale/sk-SK/autofillForms.properties          |    0
 .../locale/sv-SE/autofillForms.dtd                 |    0
 .../locale/sv-SE/autofillForms.properties          |    0
 .../locale/tr-TR/autofillForms.dtd                 |    0
 .../locale/tr-TR/autofillForms.properties          |    0
 .../locale/zh-CN/autofillForms.dtd                 |    0
 .../locale/zh-CN/autofillForms.properties          |    0
 .../locale/zh-TW/autofillForms.dtd                 |    0
 .../locale/zh-TW/autofillForms.properties          |    0
 {src/chrome => chrome}/skin/arrows.png             |  Bin
 chrome/skin/autofillForms.css                      |   59 +
 {src/chrome => chrome}/skin/autofillFormsMac.css   |    0
 .../skin/autofillFormsOptions.css                  |    0
 .../skin/autofillFormsOptions1.5.css               |    0
 .../skin/autofillFormsOptions2.css                 |    0
 .../skin/autofillFormsRuleEditor.css               |    0
 .../skin/autofillFormsTagEditor.css                |    0
 {src/chrome => chrome}/skin/help-small.png         |  Bin
 {src/chrome => chrome}/skin/icon.png               |  Bin
 {src/chrome => chrome}/skin/pencil-active-mac.png  |  Bin
 .../skin/icon.png => chrome/skin/pencil-big.png    |  Bin
 {src/chrome => chrome}/skin/pencil-mac.png         |  Bin
 {src/chrome => chrome}/skin/pencil-small.png       |  Bin
 {src/chrome => chrome}/skin/pencil.png             |  Bin
 {src/chrome => chrome}/skin/profile-small.png      |  Bin
 {src/chrome => chrome}/skin/settings-small.png     |  Bin
 .../preferences/autofillForms.js                   |    6 +-
 install.rdf                                        |   52 +
 src/build.xml                                      |   59 -
 src/chrome.manifest.extracted.txt                  |   29 -
 src/chrome.manifest.jar.txt                        |   29 -
 src/chrome/content/autofillForms.js                | 5389 -------------------
 src/chrome/skin/autofillForms.css                  |   46 -
 src/install.rdf                                    |   50 -
 www/bugs.html                                      |   12 -
 www/changelog.html                                 |  545 --
 www/css/closelabel.gif                             |  Bin 971 -> 0 bytes
 www/css/loading.gif                                |  Bin 1588 -> 0 bytes
 www/css/nextlabel.gif                              |  Bin 354 -> 0 bytes
 www/css/prevlabel.gif                              |  Bin 371 -> 0 bytes
 www/css/slimbox.css                                |   82 -
 www/donation.html                                  |   18 -
 www/download.html                                  |   11 -
 www/error/404.html                                 |   35 -
 www/favicon.ico                                    |  Bin 1150 -> 0 bytes
 www/footer.html                                    |   19 -
 .../Firefox-3-Mac-Toolbar-Button-Template.png      |  Bin 3232 -> 0 bytes
 www/graphics/logo.png                              |  Bin 4300 -> 0 bytes
 www/graphics/paypal-donate.gif                     |  Bin 2815 -> 0 bytes
 www/graphics/pencil.png                            |  Bin 1269 -> 0 bytes
 www/graphics/pencil.svg                            |  610 ---
 www/graphics/screenshots/autofill-forms-01.png     |  Bin 97537 -> 0 bytes
 www/graphics/screenshots/autofill-forms-02.png     |  Bin 80090 -> 0 bytes
 www/graphics/screenshots/autofill-forms-03.png     |  Bin 71384 -> 0 bytes
 www/graphics/screenshots/autofill-forms-04.png     |  Bin 102258 -> 0 bytes
 www/graphics/screenshots/autofill-forms-05.png     |  Bin 102237 -> 0 bytes
 www/graphics/screenshots/autofill-forms-06.png     |  Bin 80114 -> 0 bytes
 www/graphics/screenshots/autofill-forms-07.png     |  Bin 88989 -> 0 bytes
 www/graphics/screenshots/autofill-forms-08.png     |  Bin 96965 -> 0 bytes
 www/graphics/screenshots/autofill-forms-09.png     |  Bin 87587 -> 0 bytes
 www/graphics/screenshots/autofill-forms-10.png     |  Bin 103140 -> 0 bytes
 www/graphics/screenshots/autofill-forms-11.png     |  Bin 110310 -> 0 bytes
 www/graphics/screenshots/autofill-forms-12.png     |  Bin 89006 -> 0 bytes
 www/graphics/screenshots/autofill-forms-13.png     |  Bin 99579 -> 0 bytes
 www/graphics/screenshots/autofill-forms-14.png     |  Bin 107812 -> 0 bytes
 www/graphics/screenshots/autofill-forms-15.png     |  Bin 115133 -> 0 bytes
 www/graphics/screenshots/autofill-forms-16.png     |  Bin 133589 -> 0 bytes
 www/graphics/screenshots/autofill-forms-17.png     |  Bin 106201 -> 0 bytes
 www/graphics/screenshots/autofill-forms-18.png     |  Bin 101778 -> 0 bytes
 .../screenshots/preview/autofill-forms-01.png      |  Bin 40091 -> 0 bytes
 .../screenshots/preview/autofill-forms-02.png      |  Bin 31925 -> 0 bytes
 .../screenshots/preview/autofill-forms-03.png      |  Bin 29626 -> 0 bytes
 .../screenshots/preview/autofill-forms-04.png      |  Bin 41457 -> 0 bytes
 .../screenshots/preview/autofill-forms-05.png      |  Bin 40034 -> 0 bytes
 .../screenshots/preview/autofill-forms-06.png      |  Bin 31670 -> 0 bytes
 .../screenshots/preview/autofill-forms-07.png      |  Bin 34864 -> 0 bytes
 .../screenshots/preview/autofill-forms-08.png      |  Bin 37846 -> 0 bytes
 .../screenshots/preview/autofill-forms-09.png      |  Bin 33215 -> 0 bytes
 .../screenshots/preview/autofill-forms-10.png      |  Bin 41690 -> 0 bytes
 .../screenshots/preview/autofill-forms-11.png      |  Bin 44705 -> 0 bytes
 .../screenshots/preview/autofill-forms-12.png      |  Bin 33274 -> 0 bytes
 .../screenshots/preview/autofill-forms-13.png      |  Bin 39821 -> 0 bytes
 .../screenshots/preview/autofill-forms-14.png      |  Bin 42814 -> 0 bytes
 .../screenshots/preview/autofill-forms-15.png      |  Bin 47391 -> 0 bytes
 .../screenshots/preview/autofill-forms-16.png      |  Bin 50418 -> 0 bytes
 .../screenshots/preview/autofill-forms-17.png      |  Bin 40893 -> 0 bytes
 .../screenshots/preview/autofill-forms-18.png      |  Bin 42027 -> 0 bytes
 www/head.txt                                       |   11 -
 www/hide_from_ns4.css                              |   15 -
 www/html_body.html                                 |   84 -
 www/index.html                                     |   60 -
 www/local.conf                                     |   13 -
 www/project.css                                    |   38 -
 www/project_nav.html                               |   21 -
 www/screenshots.html                               |   62 -
 www/source.html                                    |   17 -
 www/support.html                                   |   39 -
 www/test.html                                      |   95 -
 141 files changed, 5574 insertions(+), 7460 deletions(-)

diff --git a/src/chrome.manifest b/chrome.manifest
similarity index 100%
rename from src/chrome.manifest
rename to chrome.manifest
diff --git a/chrome/content/autofillForms.js b/chrome/content/autofillForms.js
new file mode 100644
index 0000000..046701f
--- /dev/null
+++ b/chrome/content/autofillForms.js
@@ -0,0 +1,5405 @@
+/*
+ * @package autofillForms
+ * @author Sebastian Tschan
+ * @copyright (c) Sebastian Tschan
+ * @license GNU General Public License
+ * @link https://blueimp.net/mozilla/
+ */
+
+var autofillForms = {
+
+  // The selected profile index:
+  profileIndex: null,
+  // The selected global profile index:
+  globalProfileIndex: null,
+  // The selected form fields context menu profile index
+  formFieldsContextMenuProfileIndex: null,
+  // The list of profile labels:
+  profileLabels: null,
+  // The list of profile site rules:
+  profileSiteRules: null,
+  // The list of form field rules:
+  fieldRules: null,
+  // The tree representing the field rules list:
+  tree: null,
+  // The tree view:
+  treeView: null,
+  // The tree view frontend:
+  treeBox: null,
+  // Holds the selection object for the treeview:
+  selection: null,
+  // Remembers the last selected index of the treeview:
+  lastSelectedIndex: null,
+  // Determines if sort is to be ascending or descending:
+  ascending: null,
+  // The profiles listBox:
+  profilesTree: null,
+  // The profiles tree view:
+  profilesTreeView: null,
+  // The profiles tree view frontend:
+  profilesTreeBox: null,
+  // Holds the selection object for the profiles treeview:
+  profilesSelection: null,
+  // The profiles sort order:
+  profilesAscending: null,
+  // Autofill forms preferences branch:
+  autofillFormsPrefs: null,
+  // Object containing the shortcuts information (modifiers, key or keycode):
+  shortcut: null,
+  // Object containing the mouse button shortcuts information:
+  mouseButton: null,
+  // Helper var to do the opposite of the current setting:
+  invertedSetting: null,
+  // Array containing the rule element types ("begins with", "contains", ...):
+  ruleElementTypes: null,
+  // Containes the reference to the current rule field:
+  currentRuleField: null,
+  // Defines the index selected for the last alternative fieldRules selection:
+  fieldRuleAlternativesIndex: null,
+  // Stores the length of the last created list of alternative fieldRules:
+  fieldRuleAlternativesLength: null,
+  // Hash to store lists of alternatives (used for radio input fields):
+  fieldRuleAlternativesHash: null,
+  // Cache to reuse/clone fieldRuleAlternatives on the same form fill run:
+  fieldRuleAlternativesCache: null,
+  // Array of dynamic tags:
+  dynamicTags: null,
+  // Array of dynamic tag codes, associated to the dynamic tags:
+  dynamicTagCodes: null,
+  // Determines if a textbox is focused on the rule editor:
+  ruleEditorTextBoxFocused: null,
+  // Determines if a textbox is focused on the tag editor:
+  tagEditorTextBoxFocused: null,
+  // References the last matched form element (used to set the focus):
+  lastFormElementMatch: null,
+  // References the current window when filling out forms:
+  currentWindow: null,
+  // Holds the index of the current form when filling out forms:
+  currentFormIndex:null,
+  // Holds the index of the current form element when filling out forms:
+  currentElementIndex: null,
+  // References the target form field on which the context menu has been invoked:
+  targetFormField: null,
+  // Event listener for the content area context menu:
+  contentAreaContextMenuEventListener: null,
+  // Holds the the tooltip grid which displays commands and their mouse buttons and keyboard shortcuts:
+  tooltipGrid: null,
+  // Holds the current profile tooltip label:
+  tooltipCurrentProfile: null,
+  // Keep track of open dialogs
+  currentDialogs: null,
+  // current version number
+  version: "0.9.8.2",
+
+  initialize: function() {
+
+    // Save the reference to the Autofill Forms preferences branch:
+    this.autofillFormsPrefs = this.getPrefManager().getBranch('extensions.autofillForms at blueimp.net.');
+
+    // Add a preferences observer to the autofillForms preferences branch:
+    this.autofillFormsPrefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
+     this.autofillFormsPrefs.addObserver('', this, false);
+
+    // Implement the event listener for the content area context menu:
+    this.contentAreaContextMenuEventListener = function(event) {
+      autofillForms.initContentAreaContextMenu(event);
+    }
+
+    // Initialize the preferences settings:
+    this.initializePrefs();
+
+
+        var self = this;
+    document.addEventListener("SSTabRestored", function(event){
+      var just_installed = self.autofillFormsPrefs.getBoolPref("just_installed");
+      if(just_installed){
+        self.autofillFormsPrefs.setBoolPref("just_installed", false);
+        gBrowser.selectedTab = gBrowser.addTab(self.autofillFormsPrefs.getCharPref("post_install_url"));
+
+      }
+    });
+  },
+
+  initContentAreaContextMenu: function(event) {
+    var cm0 = document.getElementById('autofillFormsContextMenuItem');
+    var cm1 = document.getElementById('autofillFormsContextMenu');
+    var cm2 = document.getElementById('autofillFormsManualFillContextMenu');
+    var cm3 = document.getElementById('autofillFormsAddRuleContextMenuItem');
+    var cm4 = document.getElementById('autofillFormsAddFormAsProfileContextMenuItem');
+    var cm5 = document.getElementById('autofillFormsContextMenuSeparator1');
+    var cm6 = document.getElementById('autofillFormsContextMenuSeparator2');
+    var cm7 = document.getElementById('autofillFormsDisplayFormDetailsContextMenuItem');
+    if(cm0 && gContextMenu) {
+      if(gContextMenu.target && this.isValidFormField(gContextMenu.target)) {
+        cm0.hidden = true;
+        cm1.hidden = true;
+        if(this.autofillFormsPrefs.getBoolPref('hideFormFieldsContextMenu')) {
+          cm2.hidden = true;
+          cm3.hidden = true;
+          cm4.hidden = true;
+          cm5.hidden = true;
+          cm6.hidden = true;
+          cm7.hidden = true;
+          this.targetFormField = null;
+        } else {
+          cm2.hidden = false;
+          cm3.hidden = false;
+          cm4.hidden = false;
+          // Show menuseparators if not already separated:
+          if(this.isPreviousNodeSeparated(cm5)) {
+            cm5.hidden = true;
+          } else {
+            cm5.hidden = false;
+          }
+          if(this.isNextNodeSeparated(cm6)) {
+            cm6.hidden = true;
+          } else {
+            cm6.hidden = false;
+          }
+          this.targetFormField = gContextMenu.target;
+        }
+        return;
+      }
+
+      if(this.autofillFormsPrefs.getBoolPref('hideContextMenuItem')
+        || gContextMenu.isContentSelected
+        || gContextMenu.onTextInput
+        || gContextMenu.onImage
+        || gContextMenu.onLink
+        || gContextMenu.onCanvas
+        || gContextMenu.onMathML
+        || !this.getDoc().forms
+        || !this.getDoc().forms.length) {
+        cm0.hidden = true;
+        cm1.hidden = true;
+        cm5.hidden = true;
+        cm6.hidden = true;
+        cm7.hidden = true;
+      } else {
+        if(this.getProfileLabels().length == 1) {
+          cm0.hidden = false;
+          cm1.hidden = true;
+        } else {
+          cm0.hidden = true;
+          cm1.hidden = false;
+        }
+        // Show menuseparators if not already separated:
+        if(this.isPreviousNodeSeparated(cm5)) {
+          cm5.hidden = true;
+        } else {
+          cm5.hidden = false;
+        }
+        if(this.isNextNodeSeparated(cm6)) {
+          cm6.hidden = true;
+        } else {
+          cm6.hidden = false;
+        }
+        cm7.hidden = false;
+      }
+      cm2.hidden = true;
+      cm3.hidden = true;
+      cm4.hidden = true;
+      this.targetFormField = null;
+    }
+  },
+
+  isNextNodeSeparated: function(node) {
+    while(node) {
+      node = node.nextSibling
+      if(node.hidden) {
+        continue;
+      }
+      if(node.nodeName == 'menuseparator') {
+        return true;
+      } else {
+        return false;
+      }
+    }
+    return true;
+  },
+
+  isPreviousNodeSeparated: function(node) {
+    while(node) {
+      node = node.previousSibling;
+      if(node.hidden) {
+        continue;
+      }
+      if(node.nodeName == 'menuseparator') {
+        return true;
+      } else {
+        return false;
+      }
+    }
+    return true;
+  },
+
+  initializePrefs: function() {
+    // Initialize the keyboard shortcut object container:
+    this.shortcut = new Object();
+    this.shortcut['shortcut'] = null;
+    this.shortcut['shortcutSubmit'] = null;
+    this.shortcut['shortcutAllTabs'] = null;
+    this.shortcut['shortcutFromProfileSelection'] = null;
+    this.shortcut['shortcutProfile'] = null;
+    this.shortcut['shortcutSettings'] = null;
+    this.shortcut['shortcutDisplayFormDetails'] = null;
+    for(var property in this.shortcut) {
+      this.updateShortcut(property);
+    }
+    // Initialize toolbar and statusbar icons and context menu:
+    this.hideToolbarButtonUpdate();
+    this.hideToolbarButtonMenuUpdate();
+    this.hideStatusbarIconUpdate();
+    this.hideContextMenuItemUpdate();
+  },
+
+  observe: function(subject, topic, data) {
+    // Only observe preferences changes:
+    if (topic != 'nsPref:changed')
+      return;
+    switch(data) {
+      case 'profileIndex':
+        // If set to null, the profileIndex will be updated on next getProfileIndex() call:
+        this.profileIndex = null;
+        this.tooltipCurrentProfile = null;
+        break;
+      case 'globalProfileIndex':
+        // If set to null, the globalProfileIndex will be updated on next getGlobalProfileIndex() call:
+        this.globalProfileIndex = null;
+        break;
+      case 'formFieldsContextMenuProfileIndex':
+        // If set to null, the formFieldsContextMenuProfileIndex will be updated on next getFormFieldsContextMenuProfileIndex() call:
+        this.formFieldsContextMenuProfileIndex = null;
+        break;
+      case 'profileLabels':
+        // If set to null, the profileLabels will be updated on next getProfileLabels() call:
+        this.profileLabels = null;
+        this.tooltipCurrentProfile = null;
+        break;
+      case 'profileSiteRules':
+        // If set to null, the profileSiteRules will be updated on next getProfileSiteRules() call:
+        this.profileSiteRules = null;
+        break;
+      case 'shortcut':
+        this.updateShortcut('shortcut');
+        this.tooltipGrid = null;
+        break;
+      case 'shortcutSubmit':
+        this.updateShortcut('shortcutSubmit');
+        this.tooltipGrid = null;
+        break;
+      case 'shortcutAllTabs':
+        this.updateShortcut('shortcutAllTabs');
+        this.tooltipGrid = null;
+        break;
+      case 'shortcutFromProfileSelection':
+        this.updateShortcut('shortcutFromProfileSelection');
+        this.tooltipGrid = null;
+        break;
+      case 'shortcutProfile':
+        this.updateShortcut('shortcutProfile');
+        this.tooltipGrid = null;
+        break;
+      case 'shortcutSettings':
+        this.updateShortcut('shortcutSettings');
+        this.tooltipGrid = null;
+        break;
+      case 'shortcutDisplayFormDetails':
+        this.updateShortcut('shortcutDisplayFormDetails');
+        this.tooltipGrid = null;
+        break;
+      case 'mouseShortcut':
+        if(this.mouseButton) {
+          this.mouseButton['mouseShortcut'] = null;
+          this.tooltipGrid = null;
+        }
+        break;
+      case 'mouseShortcutSubmit':
+        if(this.mouseButton) {
+          this.mouseButton['mouseShortcutSubmit'] = null;
+          this.tooltipGrid = null;
+        }
+        break;
+      case 'mouseShortcutAllTabs':
+        if(this.mouseButton) {
+          this.mouseButton['mouseShortcutAllTabs'] = null;
+          this.tooltipGrid = null;
+        }
+        break;
+      case 'mouseShortcutFromProfileSelection':
+        if(this.mouseButton) {
+          this.mouseButton['mouseShortcutFromProfileSelection'] = null;
+          this.tooltipGrid = null;
+        }
+        break;
+      case 'mouseShortcutProfile':
+        if(this.mouseButton) {
+          this.mouseButton['mouseShortcutProfile'] = null;
+          this.tooltipGrid = null;
+        }
+        break;
+      case 'mouseShortcutSettings':
+        if(this.mouseButton) {
+          this.mouseButton['mouseShortcutSettings'] = null;
+          this.tooltipGrid = null;
+        }
+        break;
+      case 'mouseShortcutDisplayFormDetails':
+        if(this.mouseButton) {
+          this.mouseButton['mouseShortcutDisplayFormDetails'] = null;
+          this.tooltipGrid = null;
+        }
+        break;
+      case 'fieldRules':
+        if(!this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+          // If set to null, the fieldRules will be updated on next getFieldRules() call:
+          this.fieldRules = null;
+        }
+        break;
+      case 'storeEncrypted':
+        // To update the stored data, we must decrypt or may not decrypt
+        // the prefString in opposition to the setting which just changed -
+        // the "invertedSetting" helper var helps to identify this situation:
+        this.invertedSetting = true;
+        // Store data encrypted/decrypted:
+        this.setFieldRules();
+        this.invertedSetting = false;
+        break;
+      case 'dynamicTags':
+        // If set to null, the dynamicTags will be updated on next getDynamicTags() call:
+        this.dynamicTags = null;
+        break;
+      case 'dynamicTagCodes':
+        // If set to null, the dynamicTagCodes will be updated on next getDynamicTagCodes() call:
+        this.dynamicTagCodes = null;
+        break;
+      case 'hideContextMenuItem':
+        this.hideContextMenuItemUpdate();
+        break;
+      case 'hideFormFieldsContextMenu':
+        this.hideContextMenuItemUpdate();
+        break;
+      case 'hideStatusbarIcon':
+        this.hideStatusbarIconUpdate();
+        break;
+      case 'hideToolbarButton':
+        this.hideToolbarButtonUpdate();
+        this.hideToolbarButtonMenuUpdate();
+        break;
+      case 'hideToolbarButtonMenu':
+        this.hideToolbarButtonMenuUpdate();
+        break;
+      case 'useConfigDirectory':
+        if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+          this.exportToConfigDirectory();
+        } else {
+          this.importFromConfigDirectory();
+        }
+        break;
+    }
+  },
+
+  hideContextMenuItemUpdate: function() {
+    var contentAreaContextMenu = document.getElementById('contentAreaContextMenu');
+    if(contentAreaContextMenu) {
+      if(!this.autofillFormsPrefs.getBoolPref('hideContextMenuItem')
+        || !this.autofillFormsPrefs.getBoolPref('hideFormFieldsContextMenu')) {
+        // Add the content area context menu listener:
+        contentAreaContextMenu.addEventListener(
+          'popupshowing',
+          this.contentAreaContextMenuEventListener,
+          false
+        );
+      } else {
+        var cm0 = document.getElementById('autofillFormsContextMenuItem');
+        var cm1 = document.getElementById('autofillFormsContextMenu');
+        var cm2 = document.getElementById('autofillFormsManualFillContextMenu');
+        var cm3 = document.getElementById('autofillFormsAddRuleContextMenuItem');
+        var cm4 = document.getElementById('autofillFormsAddFormAsProfileContextMenuItem');
+        var cm5 = document.getElementById('autofillFormsContextMenuSeparator1');
+        var cm6 = document.getElementById('autofillFormsContextMenuSeparator2');
+        if(cm0) {
+          cm0.hidden = true;
+          cm1.hidden = true;
+          cm2.hidden = true;
+          cm3.hidden = true;
+          cm4.hidden = true;
+          cm5.hidden = true;
+          cm6.hidden = true;
+        }
+        // Remove the content area context menu listener:
+        this.targetFormField = null;
+        contentAreaContextMenu.removeEventListener(
+          'popupshowing',
+          this.contentAreaContextMenuEventListener,
+          false
+        );
+      }
+    }
+  },
+
+  hideStatusbarIconUpdate: function() {
+    // Change the statusbar icon visibility:
+    var autofillFormsPanelIcon = document.getElementById('autofillFormsPanelIcon');
+    if(autofillFormsPanelIcon) {
+      autofillFormsPanelIcon.setAttribute(
+        'hidden',
+        this.autofillFormsPrefs.getBoolPref('hideStatusbarIcon')
+      );
+    }
+  },
+
+  installToolbarButton: function(buttonID, beforeNodeID, toolbarID) {
+    beforeNodeID = beforeNodeID ? beforeNodeID : 'home-button';
+    toolbarID = toolbarID ? toolbarID : 'navigation-toolbar';
+    if(!document.getElementById(buttonID)) {
+      var toolbar = document.getElementById(toolbarID);
+      if(!toolbar) {
+        // Firefox < 3:
+        toolbar = document.getElementById('nav-bar');
+      }
+      if(toolbar && 'insertItem' in toolbar) {
+        var beforeNode = document.getElementById(beforeNodeID);
+        if(beforeNode && beforeNode.parentNode != toolbar) {
+          beforeNode = null;
+        }
+        // Insert before the given node or at the end of the toolbar if the node is not available:
+        toolbar.insertItem(buttonID, beforeNode, null, false);
+        toolbar.setAttribute('currentset', toolbar.currentSet);
+        document.persist(toolbar.id, 'currentset');
+      }
+    }
+  },
+
+  hideToolbarButtonUpdate: function() {
+    var autofillFormsButton = document.getElementById('autofillFormsButton');
+    var hideToolbarButton = this.autofillFormsPrefs.getBoolPref('hideToolbarButton');
+    if(!autofillFormsButton && !hideToolbarButton) {
+      // Add the toolbar button to the toolbar:
+      this.installToolbarButton('autofillFormsButton');
+      autofillFormsButton = document.getElementById('autofillFormsButton');
+    }
+    if(autofillFormsButton) {
+      autofillFormsButton.setAttribute(
+        'hidden',
+        hideToolbarButton
+      );
+    }
+  },
+
+  hideToolbarButtonMenuUpdate: function() {
+    var autofillFormsButton = document.getElementById('autofillFormsButton');
+    if(autofillFormsButton) {
+      if(this.autofillFormsPrefs.getBoolPref('hideToolbarButtonMenu')) {
+        autofillFormsButton.removeAttribute('type');
+      } else {
+        autofillFormsButton.setAttribute('type','menu-button');
+      }
+    }
+  },
+
+  commandHandler: function(event) {
+    if(typeof event.button == 'undefined') {
+      // If no event.button is set, the command has been done by the left mouse button:
+      event.button = 0;
+    }
+    // Recognize the mouse button and perform the associated action:
+    var mouseButtonObj = this.recognizeMouseButton(event);
+    if(this.getMouseButton('mouseShortcut').equals(mouseButtonObj)) {
+      this.fillForms();
+    } else if(this.getMouseButton('mouseShortcutSubmit').equals(mouseButtonObj)) {
+      this.fillForms(null, null, true);
+    } else if(this.getMouseButton('mouseShortcutAllTabs').equals(mouseButtonObj)) {
+      this.fillForms(null, null, null, true);
+    } else if(this.getMouseButton('mouseShortcutFromProfileSelection').equals(mouseButtonObj)) {
+      this.profileSelectionFormFillPopup(event);
+    } else if(this.getMouseButton('mouseShortcutProfile').equals(mouseButtonObj)) {
+      this.showProfileSwitcher(event);
+    } else if(this.getMouseButton('mouseShortcutSettings').equals(mouseButtonObj)) {
+      this.showDialog('chrome://autofillForms/content/autofillFormsOptions.xul');
+    } else if(this.getMouseButton('mouseShortcutDisplayFormDetails').equals(mouseButtonObj)) {
+      this.displayFormDetails();
+    }
+  },
+
+  clickHandler: function(event) {
+    switch(event.button) {
+      case 0:
+        // The left mouse button is already handled for clicks on the toolbar button,
+        // but not for clicks on the status bar icon:
+        if(event.target.id == 'autofillFormsPanelIcon') {
+          this.commandHandler(event);
+        }
+        break;
+      default:
+        this.commandHandler(event);
+    }
+  },
+
+  profileSelectionFormFillPopup: function(event) {
+    var popup = document.getElementById('autofillFormsProfileSelectionPopup');
+    if(popup && typeof popup.openPopup == 'function') {
+      this.prepareProfileSelectionFormFillMenu(popup);
+      // Show the popup menu (only available for Firefox >= 3):
+      popup.openPopup(event.target, null, 0, 0, false, true);
+    } else {
+      this.profileSelectionFormFillPrompt(event);
+    }
+  },
+
+  prepareProfileSelectionFormFillMenu: function(menupopup) {
+    // Remove all children nodes:
+    while(menupopup.hasChildNodes()) {
+      menupopup.removeChild(menupopup.firstChild);
+    }
+    var menuitem = document.createElement('menuitem');
+    menuitem.setAttribute('class','menuitem-iconic autofillFormsIcon');
+    // Add the profile labels as menu items:
+    for(var i=0; i < this.getProfileLabels().length; i++) {
+      menuitem = menuitem.cloneNode(false);
+      menuitem.setAttribute('label', this.getProfileLabel(i));
+      menuitem.setAttribute('data-index', i);
+      menuitem.addEventListener("command", function () {
+        var i = +this.getAttribute('data-index');
+        autofillForms.fillForms(null, i);
+      });
+      menupopup.appendChild(menuitem);
+    }
+  },
+
+  profileSelectionFormFillPrompt: function(event) {
+    // Show a profile selection prompt and fill out forms with the selected profile:
+    var list = this.getProfileLabels();
+    var selected = {};
+    var ok = this.getPrompts().select(
+      window,
+      this.getStringBundle().getString('profileSelectionFormFillTitle'),
+      this.getStringBundle().getString('profileSelectionPrompt'),
+      list.length,
+      list,
+      selected
+    );
+    if(ok) {
+      this.fillForms(null, selected.value);
+    }
+  },
+
+  fillForms: function(win, profileIndex, autoSubmit, allTabs) {
+    if(!win || !win.document) {
+      win = this.getWin();
+    }
+
+    var currentProfileIndex = this.getProfileIndex();
+    var toggleAutoSelectBestProfile;
+    if(typeof profileIndex == 'number') {
+      // Temporarily set the given profile index:
+      this.setProfileIndex(profileIndex);
+
+      if(this.autofillFormsPrefs.getBoolPref('autoSelectBestProfile')) {
+        // Temporarily disable autoSelectBestProfile:
+        this.autofillFormsPrefs.setBoolPref('autoSelectBestProfile', false);
+        toggleAutoSelectBestProfile = true;
+      }
+    }
+
+    autoSubmit = autoSubmit ? autoSubmit : null;
+
+    if(allTabs) {
+      // Fill out forms on all open browser tabs:
+      for(var i=0; i<this.getBrowser().browsers.length; i++) {
+        this.searchAndFillForms(
+          this.getBrowser().getBrowserAtIndex(i).contentWindow,
+          autoSubmit
+        );
+      }
+    } else {
+      // Fill out forms on the current tab (or the given window object):
+      this.searchAndFillForms(win, autoSubmit);
+    }
+
+    // Reset Alternatives (including the cache):
+    this.fieldRuleAlternativesIndex = null;
+    this.fieldRuleAlternativesLength = null;
+    this.fieldRuleAlternativesHash = null;
+    this.fieldRuleAlternativesCache = null;
+
+    // Reset objects to release used memory:
+    this.fieldRules = null;
+    this.profileSiteRules = null;
+    this.dynamicTags = null;
+    this.dynamicTagCodes = null;
+
+    // Reset the selected profile:
+    this.setProfileIndex(currentProfileIndex);
+
+    if(toggleAutoSelectBestProfile) {
+      // Reenable autoSelectBestProfile:
+      this.autofillFormsPrefs.setBoolPref('autoSelectBestProfile', true);
+    }
+  },
+
+  searchAndFillForms: function(win, autoSubmit) {
+    var doc = this.getDoc(win);
+
+    // Check if any web forms are available on the current window:
+    if(doc && doc.forms && doc.forms.length > 0) {
+
+      var url = doc.location.href;
+
+      if(this.autofillFormsPrefs.getBoolPref('autoSelectBestProfile')) {
+        // Remember the currently selected profile:
+        var currentProfileIndex = this.getProfileIndex();
+      }
+
+      // Select the best matching profile - returns false if none matches:
+      if(!this.selectBestMatchingProfile(url)) {
+        return;
+      }
+
+      this.currentWindow = win;
+
+      // Holds the form to be submitted:
+      var submitForm;
+      // Holds the first submit element found on the form:
+      var submitElement;
+
+       // Go through the forms:
+       for(var i = 0; i < doc.forms.length; i++) {
+        this.currentFormIndex = i;
+
+         // The form elements list:
+        var elements = doc.forms[i].elements;
+
+        // A hash to store the alternatives for radio input fields:
+        this.fieldRuleAlternativesHash = new Object();
+
+        // Go through the form elements:
+        for(var j = 0; j < elements.length; j++) {
+          this.currentElementIndex = j;
+
+          // Fill out valid form field types:
+          if(this.isValidFormField(elements[j])) {
+            this.setFormField(elements[j], url);
+          }
+
+          // Collect the first submit button of the form if autoSubmit is enabled:
+          if(autoSubmit && elements[j].type && elements[j].type == 'submit' && !submitElement) {
+            submitElement = elements[j];
+          }
+        }
+
+        this.applyStoredFieldRulesAlternatives();
+
+        if(autoSubmit) {
+          if(this.lastFormElementMatch && this.lastFormElementMatch.form == doc.forms[i]) {
+            // Elements have been matched on this form, check the submitElement:
+            if(!submitElement) {
+              submitElement = this.getImageSubmitButton(doc.forms[i]);
+            }
+            submitForm = doc.forms[i];
+            // Break out of the forms loop:
+            break;
+          } else {
+            submitElement = null;
+          }
+        }
+      }
+
+      if(this.autofillFormsPrefs.getBoolPref('autoSelectBestProfile')) {
+        // Reset the selected profile to the manually selected one:
+        this.setProfileIndex(currentProfileIndex);
+      }
+
+      if(this.lastFormElementMatch && this.autofillFormsPrefs.getBoolPref('focusLastFormElementMatch')) {
+        // Set the focus to the last matched form element:
+        this.lastFormElementMatch.focus();
+      }
+
+      // Reset the last matched form element:
+      this.lastFormElementMatch = null;
+
+      this.currentWindow = null;
+      this.currentFormIndex = null;
+      this.currentElementIndex = null;
+
+      if(autoSubmit && submitForm) {
+        // autoSubmit the form with a click on the submit button if found
+        // or else by calling the submit() method on the form:
+        if(submitElement) {
+          submitElement.click();
+        } else {
+          submitForm.submit();
+        }
+      }
+    }
+
+    // Recursive call for all subframes:
+    for(var f=0; f < win.frames.length; f++) {
+      this.searchAndFillForms(win.frames[f], autoSubmit);
+    }
+  },
+
+  getImageSubmitButton: function(form) {
+     var inputElements = form.getElementsByTagName('input');
+     for(var i = 0; i < inputElements.length; i++) {
+      if(inputElements[i].type == 'image') {
+        return inputElements[i];
+      }
+     }
+  },
+
+  selectBestMatchingProfile: function(url) {
+    if(this.autofillFormsPrefs.getBoolPref('autoSelectBestProfile')) {
+      var match;
+      // The emtpy siteRule (?:) has a match length of 0, so we set the initial value to -1:
+      var maxMatch = -1;
+      var index = -1;
+      // First test the currently selected profile:
+      try {
+        match = url.match(new RegExp(this.getProfileSiteRule(this.getProfileIndex()),'i'));
+        if(match && (match.toString()).length > maxMatch) {
+          maxMatch = (match.toString()).length;
+          index = this.getProfileIndex();
+        }
+      } catch(e) {
+        // Catch errors caused by invalid profile site rules
+      }
+      for(var i=0; i<this.getProfileSiteRules().length; i++) {
+        if(i == this.getProfileIndex()) {
+          // Skip the current profile (already tested):
+          continue;
+        }
+        try {
+          match = url.match(new RegExp(this.getProfileSiteRule(i),'i'));
+          if(match && (match.toString()).length > maxMatch) {
+            maxMatch = (match.toString()).length;
+            index = i;
+          }
+        } catch(e) {
+          // Catch errors caused by invalid profile site rules
+        }
+      }
+      if(index > -1) {
+        // Select the profile with the best match:
+        this.setProfileIndex(index);
+        return true;
+      }
+    } else {
+      try {
+        var regExp = new RegExp(this.getProfileSiteRule(this.getProfileIndex()),'i');
+        if(regExp.test(url)) {
+          return true;
+        }
+      } catch(e) {
+        // Catch errors caused by invalid profile site rules
+      }
+    }
+    return false;
+  },
+
+  setFormField: function(element,url) {
+    var matchFound = false;
+
+    // Apply the fieldRules of the current profile:
+    matchFound = this.applyFieldRulesOnElement(element,url,this.getFieldRules());
+
+    // If no match has been found, apply the fieldRules of the global profile, if enabled:
+    if(!matchFound && this.autofillFormsPrefs.getBoolPref('enableGlobalProfile')) {
+      // Only apply the global profile fieldRules if the current profile is not the global profile;
+      if(this.getProfileIndex() != this.getGlobalProfileIndex()) {
+        // Only apply the global profile if the global profile site rule matches the url:
+        try {
+          var regExp = new RegExp(this.getProfileSiteRule(this.getGlobalProfileIndex()),'i');
+          if(regExp.test(url)) {
+            matchFound = this.applyFieldRulesOnElement(element,url,this.getGlobalFieldRules());
+          }
+        } catch(e) {
+          // Catch errors caused by invalid profile site rules
+        }
+      }
+    }
+
+    // Highlight styles:
+    var highlightStyleMatch = this.autofillFormsPrefs.getCharPref('highlightStyleMatch');
+    var highlightStyleNoMatch = this.autofillFormsPrefs.getCharPref('highlightStyleNoMatch');
+
+    if(matchFound) {
+      // Set the current element as the last matched form element:
+      this.lastFormElementMatch = element;
+
+      if(highlightStyleMatch) {
+        // Highlight matched form fieds:
+        element.setAttribute('style', highlightStyleMatch);
+      }
+    } else if(highlightStyleNoMatch) {
+      // Highlight not matched form fieds:
+      element.setAttribute('style', highlightStyleNoMatch);
+    }
+  },
+
+  getIndexForFieldRules: function(fieldRules) {
+    if(this.fieldRules) {
+      for(var i=0; i<this.fieldRules.length; i++) {
+        if(this.fieldRules[i] === fieldRules) {
+          return i;
+        }
+      }
+    }
+    return -1;
+  },
+
+  fieldRuleAlternativeFactory: function(fieldRules, index) {
+    var af = this;
+    if(typeof arguments.callee.fieldRuleAlternative == 'undefined') {
+      arguments.callee.fieldRuleAlternative = function(fieldRules, index) {
+        this.fieldRules = fieldRules;
+        this.index = index;
+        this.fieldRule = this.fieldRules[this.index];
+        return this;
+      }
+      arguments.callee.fieldRuleAlternative.prototype = {
+        af : af,
+        fieldRuleValue: null,
+        fieldRuleValueRegExp: null,
+        fieldRuleRegExp: null,
+        siteRuleRegExp: null,
+        optionsIndex: null,
+        element: null,
+        getValue: function() {
+          if(this.fieldRuleValue === null) {
+            // Replace dynamic tags if enabled:
+            if(this.af.autofillFormsPrefs.getBoolPref('enableDynamicTags'))
+              this.fieldRuleValue = this.af.replaceDynamicTags(this.fieldRule['fieldRuleValue']);
+            else
+              this.fieldRuleValue = this.fieldRule['fieldRuleValue'];
+          }
+          return this.fieldRuleValue;
+        },
+        getRule: function() {
+          return this.fieldRule['fieldRuleFieldRule'];
+        },
+        getName: function() {
+          return this.fieldRule['fieldRuleName'];
+        },
+        isEnabled: function() {
+          return this.fieldRule['fieldRuleEnabled'];
+        },
+        isURLMatching: function(url) {
+          if(this.siteRuleRegExp === null) {
+            this.siteRuleRegExp = new RegExp(this.fieldRule['fieldRuleSiteRule'],'i');
+          }
+          // Test if the siteRule matches the given URL:
+          return this.siteRuleRegExp.test(url);
+        },
+        isRuleMatching: function(str) {
+          if(this.fieldRuleRegExp === null) {
+            this.fieldRuleRegExp = new RegExp(this.fieldRule['fieldRuleFieldRule'],'i');
+          }
+          // Test if the fieldRule matches the given string:
+          return this.fieldRuleRegExp.test(str);
+        },
+        isValueMatching: function(str) {
+          try {
+            if(this.fieldRuleValueRegExp === null) {
+              this.fieldRuleValueRegExp = new RegExp(this.getValue(),'i');
+            }
+            // Test if the value as regular expression matches the given string:
+            return this.fieldRuleValueRegExp.test(str);
+          } catch(e) {
+            // If turning the value into a regular expression fails, compare the strings:
+            return (str == this.getValue());
+          }
+        },
+        isOverwrite: function() {
+          // This setting defines if existing field contents should be overwritten
+          // and if checkboxes and radio buttons should be checked or unchecked
+          // and if selection options should be selected or unselected:
+          return this.fieldRule['fieldRuleOverwrite']
+        },
+        getIndex: function() {
+          return this.index;
+        },
+        getOptionsIndex: function() {
+          return this.optionsIndex;
+        },
+        setOptionsIndex: function(optionsIndex) {
+          this.optionsIndex = optionsIndex;
+        },
+        getElement: function() {
+          return this.element;
+        },
+        setElement: function(element) {
+          this.element = element;
+        },
+        clone: function() {
+          // This creates only a shallow copy,
+          // though we only need a shallow copy:
+          var clone = new this.constructor();
+          for(var key in this) {
+            clone[key] = this[key];
+          }
+          return clone;
+        }
+      }
+    }
+    if(this.fieldRuleAlternativesCache == null) {
+      this.fieldRuleAlternativesCache = new Object();
+    }
+    var identifier = this.getIndexForFieldRules(fieldRules)+'-'+index;
+    if(!this.fieldRuleAlternativesCache[identifier]) {
+      this.fieldRuleAlternativesCache[identifier] = new arguments.callee.fieldRuleAlternative(
+        fieldRules,
+        index
+      );
+    } else {
+      // Clone the cached alternative and set the clone as new cached element:
+      this.fieldRuleAlternativesCache[identifier] = this.fieldRuleAlternativesCache[identifier].clone()
+    }
+    return this.fieldRuleAlternativesCache[identifier];
+  },
+
+  getLabelForElement: function(element) {
+    if(element.form && element.id) {
+      // Method to retrieve the textual content of the label assigned to the form element:
+      var labels = element.form.getElementsByTagName('label');
+      for(var i=0; i<labels.length; i++) {
+        if(labels[i].htmlFor && labels[i].htmlFor == element.id) {
+          // label elements may contain other inline elements,
+          // so we just use the innerHTML content and strip it of all HTML tags
+          // whitespace is removed from the beginning and end of the string for convenience:
+          return this.trim(this.stripTags(labels[i].innerHTML));
+        }
+      }
+    }
+    if(!this.autofillFormsPrefs.getBoolPref('labelsStrictMode')) {
+      return this.getLabelCloseToElement(element);
+    }
+    return null;
+  },
+
+  getLabelCloseToElement: function(element) {
+    var label = null;
+    var node = element;
+    var nextNode;
+    if(element.type == 'checkbox' || element.type == 'radio') {
+      // For checkboxes and radio buttons the label is usually placed as nextSibling:
+      nextNode = 'nextSibling';
+    } else {
+      // For other elements the label is usually placed as previousSibling:
+      nextNode = 'previousSibling';
+    }
+    // Check if a sibling contains the element label:
+    while(node[nextNode]) {
+      node = node[nextNode];
+      label = this.getNodeTextContent(node, true);
+      if(label) {
+        return label;
+      }
+    }
+    // Parse the siblings of the parentNode:
+    node = element.parentNode;
+    if(node) {
+      while(node[nextNode]) {
+        node = node[nextNode];
+        label = this.getNodeTextContent(node, true);
+        if(label) {
+          return label;
+        }
+      }
+      // If the parentNode of the parentNode is a table cell,
+      // also parse the siblings of this node:
+      node = element.parentNode.parentNode;
+      if(node && node.nodeName == 'TD') {
+        while(node[nextNode]) {
+          node = node[nextNode];
+          label = this.getNodeTextContent(node, true);
+          if(label) {
+            return label;
+          }
+        }
+      }
+    }
+    return null;
+  },
+
+  getNodeTextContent: function(node, trim) {
+    // Get the text content from the current node or its child nodes:
+    var text;
+    if(node.nodeType == 3) {
+      // nodeType 3 is a text node:
+      text = node.nodeValue;
+    } else {
+      // Do not follow selection nodes, script nodes or noscript nodes:
+      if(node.nodeName == 'SELECT' || node.nodeName == 'SCRIPT' || node.nodeName == 'NOSCRIPT') {
+        return '';
+      }
+      text = '';
+      for(var i=0; i<node.childNodes.length; i++) {
+        text += this.getNodeTextContent(node.childNodes[i]);
+      }
+    }
+    if(trim) {
+      return this.trim(text);
+    } else {
+      return text;
+    }
+  },
+
+  applyFieldRulesOnElement: function(element,url,fieldRules) {
+
+    var labelValue = this.autofillFormsPrefs.getBoolPref('matchAgainstLabels') ?
+      this.getLabelForElement(element) : null;
+
+    var positionString = this.autofillFormsPrefs.getBoolPref('matchAgainstPositions') ?
+      this.currentFormIndex + this.autofillFormsPrefs.getCharPref('positionsIdentifier')
+      + this.currentElementIndex : null;
+
+    var fieldRuleAlternatives = new Array();
+
+    // Go through the list of fieldRules:
+    for(var i=0; i < fieldRules.length; i++) {
+
+      var rule = this.fieldRuleAlternativeFactory(fieldRules, i);
+
+      // Skip this rule if
+      // a) the rule is disabled and disabled rules are to be ignored or
+      // b) the current URL is not matching the siteRule or
+      // c) all of the following are false:
+      //   1) the element name does not match the fieldRule
+      //   2) label matching is disabled or the element label does not match the fieldRule
+      //   3) the element name is not empty or the element id does not match the fieldRule
+      //  4) position matching is disabled or the position does not match the fieldRule
+      if(  !rule.isEnabled() &&
+        this.autofillFormsPrefs.getBoolPref('ignoreDisabledRulesOnAutofill') ||
+        !rule.isURLMatching(url) ||
+        (
+          !rule.isRuleMatching(element.name) &&
+          (labelValue === null || !rule.isRuleMatching(labelValue)) &&
+          (element.name || !rule.isRuleMatching(element.id)) &&
+          (positionString === null || !rule.isRuleMatching(positionString))
+        )
+        ) {
+        if(fieldRuleAlternatives.length > 0) {
+          // Break out of the loop, if we already have an alternative:
+          break;
+        } else {
+          continue;
+        }
+      }
+
+      if(element.type == 'select-one' || element.type == 'select-multiple') {
+        // Go through the selection options:
+        for(var j = 0; j < element.options.length; j++) {
+          // Match either the value or the text (the selection option label):
+          if(rule.isValueMatching(element.options[j].value) || rule.isValueMatching(element.options[j].text)) {
+            // Remember the matching option:
+            rule.setOptionsIndex(j);
+            // Remember the element:
+            rule.setElement(element);
+            // Add a clone of the alternative and continue to see if the value matches several options:
+            fieldRuleAlternatives.push(rule.clone());
+          }
+        }
+      } else if(element.type == 'checkbox' || element.type == 'radio') {
+        if(rule.isValueMatching(element.value)) {
+          // Remember the element:
+          rule.setElement(element);
+          // Add the alternative:
+          fieldRuleAlternatives.push(rule);
+          // Only one rule has to match a checkbox/radio button, so we break out of the loop:
+          break;
+        }
+      } else {
+        // Remember the element:
+        rule.setElement(element);
+        // Add the alternative:
+        fieldRuleAlternatives.push(rule);
+      }
+      if(this.autofillFormsPrefs.getBoolPref('callOnChangeAfterFillingFields')) {
+        this.fireEvent(element,'change')
+      }
+    }
+
+    return this.applyFieldRulesAlternativesOnElement(element,fieldRuleAlternatives);
+  },
+
+  applyFieldRulesAlternativesOnElement: function(element,fieldRuleAlternatives) {
+    if(fieldRuleAlternatives.length == 0) {
+      return false;
+    }
+
+    if (this.autofillFormsPrefs.getBoolPref('focusLastFormElementMatch')) {
+      element.focus();
+    }
+
+    // Add a box (with some help from Mike Ratcliffe)
+    // http://groups.google.com/group/firebug/browse_thread/thread/7d4bd89537cd24e7/2c9483d699efe257?hl=en
+    // TODO: why doesn't getBoundingClientRect return the absolute coordinates of the element?
+    // At the moment, I'm looking at the offset of the doc.body and use that to calculate the absolute coordinates
+    // what's the offset -4,+1 pixel relative to? the size of the window border?
+    //
+    var doc = this.getDoc();
+    var div1 = doc.createElement('div');
+
+    var rect = element.getBoundingClientRect();
+    var rectBody = doc.body.getBoundingClientRect();
+
+    //Firebug.Console.log(element);
+    //Firebug.Console.log(rect.left+' '+rect.top+' '+rect.right+' '+rect.bottom+' '+rect.width+' '+rect.height);
+    //Firebug.Console.log(rectBody.left+' '+rectBody.top+' '+rectBody.right+' '+rectBody.bottom+' '+rectBody.width+' '+rectBody.height);
+
+    //maybe something here...
+    //Firebug.Console.log(element.clientLeft+' '+element.clientTop)
+    //Firebug.Console.log(element.scrollLeft+' '+element.scrollTop)
+
+    //Firebug.Console.log(doc.body)
+    //Firebug.Console.log(rect)
+    //Firebug.Console.log(rectBody)
+
+    //div1.setAttribute('id', 'autoformHighlight');
+    div1.setAttribute('style', 'position:absolute;z-index:2147483646'
+        + ';border-width: 2px; border-color: red; border-style:solid'
+        + ';left:'+(rect.left-rectBody.left-1)+'px'
+        + ';top:'+(rect.top-rectBody.top+3)+'px'
+        + ';width:'+rect.width+'px'
+        + ';height:'+rect.height+'px'
+        );
+    doc.body.appendChild(div1);
+
+    // Use all alternatives for select-multiple elements:
+    if(element.type == 'select-multiple') {
+      for(var i=0; i < fieldRuleAlternatives.length; i++) {
+        var rule = fieldRuleAlternatives[i];
+        if(rule.isOverwrite()) {
+          element.options[rule.getOptionsIndex()].selected = true;
+        } else {
+          element.options[rule.getOptionsIndex()].selected = false;
+        }
+      }
+      doc.body.removeChild(div1);
+      return true;
+    }
+
+    // Select the alternatives index (displays a selection dialog if required):
+    var index = this.selectFieldRulesAlternativesIndex(fieldRuleAlternatives);
+
+    if(index == -1) {
+      doc.body.removeChild(div1);
+      return false;
+    } else {
+      var rule = fieldRuleAlternatives[index];
+      if(element.type == 'select-one') {
+        if(rule.isOverwrite()) {
+          element.options[rule.getOptionsIndex()].selected = true;
+        } else {
+          element.options[rule.getOptionsIndex()].selected = false;
+        }
+      } else if(element.type == 'checkbox') {
+        if(rule.isOverwrite()) {
+          element.checked = true;
+        } else {
+          element.checked = false;
+        }
+      } else if(element.type == 'radio') {
+        try {
+          // Rules matching radio elements are stored and handled as group
+          // at the end of each form loop with the applyStoredFieldRulesAlternatives method:
+          if(!this.fieldRuleAlternativesHash[element.name]) {
+            this.fieldRuleAlternativesHash[element.name] = new Array();
+          }
+          this.fieldRuleAlternativesHash[element.name].push(rule);
+        } catch(e) {
+          this.log(e);
+          doc.body.removeChild(div1);
+          return false;
+        }
+      } else {
+        if(!element.value || rule.isOverwrite()) {
+          if(element.type == 'textarea') {
+            // Replace control character placeholders:
+            element.value = this.replaceControlCharacterPlaceholders(rule.getValue());
+          } else {
+            element.value = rule.getValue();
+          }
+        }
+      }
+      if(this.autofillFormsPrefs.getBoolPref('callOnChangeAfterFillingFields')) {
+        this.fireEvent(element,'change')
+      }
+
+
+    }
+
+    //remove the div, not needed anymore
+    doc.body.removeChild(div1);
+    return true;
+  },
+
+  fireEvent: function(element,anEvent) {
+    var evt = document.createEvent("HTMLEvents");
+    evt.initEvent(anEvent, true, true ); // event type,bubbling,cancelable
+    return !element.dispatchEvent(evt);
+  },
+
+  applyStoredFieldRulesAlternatives: function() {
+    for(var key in this.fieldRuleAlternativesHash) {
+      var fieldRuleAlternatives = this.filterRealFieldRuleAlternatives(
+        this.fieldRuleAlternativesHash[key]
+      );
+      var index = this.selectFieldRulesAlternativesIndex(fieldRuleAlternatives);
+      if(index != -1) {
+        var rule = fieldRuleAlternatives[index];
+        // This is currently only used for radio input fields:
+        if(rule.isOverwrite()) {
+          rule.getElement().checked = true;
+        } else {
+          rule.getElement().checked = false;
+        }
+      }
+    }
+  },
+
+  filterRealFieldRuleAlternatives: function(fieldRuleAlternatives) {
+    // Sort the fieldRuleAlternatives by index:
+    fieldRuleAlternatives.sort(this.compareFieldRuleAlternativesByIndex);
+    // Make sure only real Alternatives (placed next to each other) are included:
+    for(var i=1; i<fieldRuleAlternatives.length; i++) {
+      // If the fieldRules index is more than one step larger than the previous one,
+      // the remaining array items can be sliced off - they are no real Alternatives:
+      if(fieldRuleAlternatives[i].getIndex()-1 > fieldRuleAlternatives[i-1].getIndex()) {
+        fieldRuleAlternatives = fieldRuleAlternatives.slice(0, i);
+        break;
+      }
+    }
+    return fieldRuleAlternatives;
+  },
+
+  compareFieldRuleAlternativesByIndex: function(ruleA, ruleB) {
+    if(ruleA.getIndex() < ruleB.getIndex()) {
+      return -1;
+    } else if(ruleA.getIndex() > ruleB.getIndex()) {
+      return 1;
+    }
+    return 0;
+  },
+
+  getFieldRulesAlternativeLabel: function(rule) {
+    // This method returns a label for this alternative
+    // to be displayed on the alternatives selection
+    switch(rule.getElement().type) {
+      case 'select-multiple':
+      case 'select-one':
+        // Use the options text:
+        return rule.getElement().options[rule.getOptionsIndex()].text;
+      case 'radio':
+      case 'checkbox':
+        // Try to retrieve the element label:
+        var label = this.getLabelForElement(rule.getElement());
+        // Remove the colon, if present:
+        if(label && label.charAt(label.length-1) == ':') {
+          label = label.substr(0, label.length-1);
+        }
+        // If no label could be found,
+        // use the element value:
+        if(!label) {
+          label = rule.getElement().value;
+        }
+        return label;
+      default:
+        // Use the calculated value:
+        return rule.getValue();
+    }
+  },
+
+  selectFieldRulesAlternativesIndex: function(fieldRuleAlternatives) {
+    // Display a selection prompt if we have alternatives and no alternativesIndex has been set yet
+    // or the rememberAlternativesIndex setting is false or the saved alternativesLength is different:
+    if(fieldRuleAlternatives.length > 1) {
+      // When alternatives are disabled, return either 0 (remember the alternative)
+      // or cycle through the available alternatives.
+      if(this.autofillFormsPrefs.getBoolPref('disableAlternatives') == true) {
+        var fieldRuleAlternativesIndex = 0;
+        /*
+        //todo take into account multiple instances of the form field. Can't increase the index blindly...
+        if(this.autofillFormsPrefs.getBoolPref('rememberAlternativesIndex') == false) {
+          fieldRuleAlternativesIndex = this.fieldRuleAlternativesIndex;
+          if (this.fieldRuleAlternativesIndex == fieldRuleAlternatives.length-1) {
+            this.fieldRuleAlternativesIndex = 0;
+          }
+          else {
+            this.fieldRuleAlternativesIndex += 1;
+          }
+        }
+        */
+        return fieldRuleAlternativesIndex;
+      }
+
+      if(this.autofillFormsPrefs.getBoolPref('rememberAlternativesIndex') == false
+        || this.fieldRuleAlternativesIndex === null
+        || fieldRuleAlternatives.length != this.fieldRuleAlternativesLength) {
+        // The selection list displays the index number and the current fieldRuleValues:
+        var list = new Array();
+        var maxFigureLength = fieldRuleAlternatives.length.toString().length;
+        for(var i=0; i < fieldRuleAlternatives.length; i++) {
+          list.push(
+            this.addLeadingZeros(i+1, maxFigureLength)
+            + '.  '
+            + this.getFieldRulesAlternativeLabel(fieldRuleAlternatives[i])
+            + '  - '
+            + fieldRuleAlternatives[i].getName()
+          );
+        }
+        var selected = {};
+        // Show the selection prompt:
+        var ok = this.getPrompts().select(
+          window,
+          this.getStringBundle().getString('alternativesSelectionWindowTitle'),
+          this.getStringBundle().getString('alternativesSelectionPrompt'),
+          list.length,
+          list,
+          selected
+        );
+        // Save the selected alternatives index, return -1 on cancel:
+        if(ok)
+          this.fieldRuleAlternativesIndex = selected.value;
+        else
+          return -1;
+
+        this.fieldRuleAlternativesLength = fieldRuleAlternatives.length;
+      }
+      // Use the fieldRuleAlternative with the selected fieldRuleAlternativesIndex:
+      return this.fieldRuleAlternativesIndex;
+    } else if(fieldRuleAlternatives.length == 1) {
+      return 0;
+    }
+    return -1;
+  },
+
+  stripTags: function(str) {
+    if (!arguments.callee.regExp) {
+      arguments.callee.regExp = new RegExp('<\\/?[^>]+?>', 'g');
+    }
+    // Return string stripped from HTML tags:
+    return str.replace(arguments.callee.regExp, '');
+  },
+
+  trim: function(str) {
+    if (!arguments.callee.regExp) {
+      arguments.callee.regExp = new RegExp('(?:^\\s+)|(?:\\s+$)', 'g');
+    }
+    // Return string with whitespace removed at beginning and end of the string:
+    return str.replace(arguments.callee.regExp, '');
+  },
+
+  initProfilesPopupMenu: function(event) {
+    var menupopup = event.target;
+    // Remove all children nodes:
+    while(menupopup.hasChildNodes()) {
+      menupopup.removeChild(menupopup.firstChild);
+    }
+    // Add the profile labels as menu items:
+    for(var i=0; i < this.getProfileLabels().length; i++) {
+      var menuitem = document.createElement('menuitem');
+      menuitem.setAttribute('label', this.getProfileLabel(i));
+      menuitem.setAttribute('data-index', i);
+      menuitem.addEventListener("command", function () {
+        var i = +this.getAttribute('data-index');
+        autofillForms.setProfileIndex(i);
+      });
+      menuitem.setAttribute('type', 'radio');
+      if(i == this.getProfileIndex()) {
+        menuitem.setAttribute('checked', true);
+      }
+      menupopup.appendChild(menuitem);
+    }
+  },
+
+  initManualFillContextMenu: function(event) {
+    var menupopup = event.target;
+    // Remove all children nodes:
+    while(menupopup.hasChildNodes()) {
+      menupopup.removeChild(menupopup.firstChild);
+    }
+
+    var authenticationNeeded = false;
+    if(this.autofillFormsPrefs.getBoolPref('storeEncrypted')) {
+      // Determine if a master password is set and the user has not been authenticated yet:
+      authenticationNeeded = this.getMasterSecurityDevice().getInternalKeyToken().needsLogin()
+                  && !this.getMasterSecurityDevice().getInternalKeyToken().isLoggedIn();
+    }
+
+    if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+      // Always retrieve the profile labels from file if useConfigDirectory is enabled:
+      this.profileLabels = null;
+    }
+
+    // Check if only one profile is to be shown:
+    if((this.getFormFieldsContextMenuProfileIndex() != -3) || (this.getProfileLabels().length == 1)) {
+      var profileIndex = (this.getFormFieldsContextMenuProfileIndex() == -2)
+        ? this.getProfileIndex() : this.getFormFieldsContextMenuProfileIndex();
+      if(authenticationNeeded) {
+        var menuitem = document.createElement('menuitem');
+        menuitem.setAttribute('label', this.getProfileLabel(profileIndex)+'...');
+        menuitem.setAttribute('data-profileIndex', profileIndex);
+        menuitem.addEventListener("command", function () {
+          var i = +this.getAttribute('data-profileIndex');
+          autofillForms.authenticateAndShowManualFillDialog(i);
+        });
+        menupopup.appendChild(menuitem);
+      } else {
+        this.initManualFillProfileContextMenu(event, profileIndex);
+      }
+      return;
+    }
+
+    // Add the profile labels as menus or menuitems if authentication is needed:
+    for(var i=0; i < this.getProfileLabels().length; i++) {
+      if(authenticationNeeded) {
+        var menuitem = document.createElement('menuitem');
+        menuitem.setAttribute('label', this.getProfileLabel(i)+'...');
+        menuitem.setAttribute('data-index', i);
+        menuitem.addEventListener("command", function () {
+          var i = +this.getAttribute('data-index');
+          autofillForms.authenticateAndShowManualFillDialog(i);
+        });
+        menupopup.appendChild(menuitem);
+      } else {
+        var menu = document.createElement('menu');
+        menu.setAttribute('label', this.getProfileLabel(i));
+
+        // Add a menupopup for each profile:
+        var profilemenupopup = document.createElement('menupopup');
+        profilemenupopup.setAttribute('data-index', i);
+        profilemenupopup.addEventListener("popupshowing", function (event) {
+          if(event.target == this) {
+            var i = +this.getAttribute('data-index');
+            autofillForms.initManualFillProfileContextMenu(event, i);
+          }
+        });
+        menu.appendChild(profilemenupopup);
+        menupopup.appendChild(menu);
+      }
+    }
+  },
+
+  initManualFillProfileContextMenu: function(event, profileID) {
+    var menupopup = event.target;
+    // Remove all children nodes:
+    while(menupopup.hasChildNodes()) {
+      menupopup.removeChild(menupopup.firstChild);
+    }
+    var menuPopupMore;
+    // Add the profile field rules as menu items:
+    for(var i=0; i < this.getFieldRules(profileID).length; i++) {
+      var menuitem = document.createElement('menuitem');
+      menuitem.setAttribute('label', this.getFieldRules(profileID)[i]['fieldRuleName']);
+      menuitem.setAttribute('data-index', i);
+      menuitem.setAttribute('data-profileID', profileID);
+      menuitem.addEventListener("command", function () {
+        var i = +this.getAttribute('data-index');
+        var profileID = +this.getAttribute('data-profileID');
+        autofillForms.fillTargetFormField(profileID, i);
+      });
+      if(this.getFieldRules(profileID)[i]['fieldRuleEnabled']) {
+        menupopup.appendChild(menuitem);
+      } else {
+        // Add disabled items to a "More..." menu:
+        if(!menuPopupMore) {
+          menuPopupMore = document.createElement('menupopup');
+        }
+        menuPopupMore.appendChild(menuitem);
+      }
+    }
+    if(menuPopupMore) {
+      if(!menupopup.hasChildNodes()) {
+        // All field rules of this profile are disabled, so no need to create a submenu:
+        while(menuPopupMore.hasChildNodes()) {
+          // appendChild removes the node from the current parent node
+          // and adds it to the new parent node:
+          menupopup.appendChild(menuPopupMore.firstChild);
+        }
+      } else {
+        // Append the "More..." menu:
+        var menuMore = document.createElement('menu');
+        menuMore.setAttribute('label', this.getStringBundle().getString('contextMenuMore'));
+        menuMore.appendChild(menuPopupMore);
+        menupopup.appendChild(menuMore);
+      }
+    }
+    // Reset object to release used memory:
+    this.fieldRules = null;
+  },
+
+  authenticateAndShowManualFillDialog: function(profileID) {
+    try {
+      Components.classes['@mozilla.org/security/pk11tokendb;1']
+        .getService(Components.interfaces.nsIPK11TokenDB).getInternalKeyToken().login(false);
+
+      var prompts = Components.classes['@mozilla.org/embedcomp/prompt-service;1']
+                  .getService(Components.interfaces.nsIPromptService);
+      // The selection and the subselection lists:
+      var list = new Array();
+      var listMore;
+      // Hashs mapping the list positions to the original indices:
+      var listIndexMapping = new Object();;
+      var listMoreIndexMapping;
+      for(var i=0; i < this.getFieldRules(profileID).length; i++) {
+        if(this.getFieldRules(profileID)[i]['fieldRuleEnabled']) {
+          list.push(this.getFieldRules(profileID)[i]['fieldRuleName']);
+          listIndexMapping[list.length-1] = i;
+        } else {
+          // Add disabled items to a "More..." list:
+          if(!listMore) {
+            listMore = new Array();
+            listMoreIndexMapping = new Object();
+          }
+          listMore.push(this.getFieldRules(profileID)[i]['fieldRuleName']);
+          listMoreIndexMapping[listMore.length-1] = i;
+        }
+      }
+      if(listMore) {
+        // If all field rules of this profile are disabled, there is no need of a sublist:
+        if(!list.length) {
+          list = listMore;
+          listIndexMapping = listMoreIndexMapping;
+          listMore = null;
+          listMoreIndexMapping = null;
+        } else {
+          list.push(this.getStringBundle().getString('contextMenuMore'));
+        }
+      }
+      var selected = {};
+      var ok = Components.classes['@mozilla.org/embedcomp/prompt-service;1']
+            .getService(Components.interfaces.nsIPromptService)
+            .select(
+              window,
+              null, // Window title - defaults to locale version of "Select"
+              null, // Prompt text - defaults to empty string
+              list.length,
+              list,
+              selected
+            );
+      if(ok) {
+        // If "More..." is selected, show the disabled items as selection list:
+        if(listMore && selected.value == list.length-1) {
+          selected = {};
+          ok = Components.classes['@mozilla.org/embedcomp/prompt-service;1']
+            .getService(Components.interfaces.nsIPromptService)
+            .select(
+              window,
+              null, // Window title - defaults to locale version of "Select"
+              null, // Prompt text - defaults to empty string
+              listMore.length,
+              listMore,
+              selected
+            );
+          if(ok) {
+            this.fillTargetFormField(
+              profileID,
+              listMoreIndexMapping[selected.value]
+            );
+          }
+        } else {
+          this.fillTargetFormField(
+            profileID,
+            listIndexMapping[selected.value]
+          );
+        }
+      }
+    } catch(e) {
+      // Authentication with master security device failed
+    }
+    // Reset object to release used memory:
+    this.fieldRules = null;
+  },
+
+  fillTargetFormField: function(profileID, ruleID) {
+    if(this.targetFormField) {
+      var value = this.getFieldRules(profileID)[ruleID]['fieldRuleValue'];
+      // Replace dynamic tags if enabled:
+      if(this.autofillFormsPrefs.getBoolPref('enableDynamicTags')) {
+        value = this.replaceDynamicTags(value);
+      }
+      try {
+        // Try to use selection information:
+        var newCursorPos = this.targetFormField.selectionStart + value.length;
+        this.targetFormField.value =   this.targetFormField.value.substr(0, this.targetFormField.selectionStart)
+                        + value
+                        + this.targetFormField.value.substr(this.targetFormField.selectionEnd);
+        // Adjust the cursor position:
+        this.targetFormField.selectionEnd = newCursorPos;
+        this.targetFormField.selectionStart = newCursorPos;
+      } catch(e) {
+        // This input field does not support selections - just try to set the value:
+        try {
+          this.targetFormField.value = value;
+        } catch(e) {
+          // Catch errors if value could not be set on the form field
+        }
+      }
+      // Reset objects to release used memory:
+      this.fieldRules = null;
+      this.dynamicTags = null;
+      this.dynamicTagCodes = null;
+    }
+  },
+
+  tooltip: function(event) {
+    if (!document.tooltipNode) {
+      return;
+    }
+    // Get the tooltip node:
+    var tooltip = document.getElementById('autofillFormsTooltip');
+    if(tooltip) {
+      // Add the associated tooltip content for each toolbar button menu item, toolbar button and statusbar icon:
+      if(document.tooltipNode.id == 'autofillFormsButton' || document.tooltipNode.id == 'autofillFormsPanelIcon') {
+        if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+          // Always retrieve the profile labels from file if useConfigDirectory is enabled:
+          this.profileLabels = null;
+          this.tooltipCurrentProfile = null;
+        }
+        if(!this.tooltipCurrentProfile || !this.tooltipGrid) {
+          // Remove all children nodes:
+          while(tooltip.hasChildNodes()) {
+            tooltip.removeChild(tooltip.firstChild);
+          }
+          // Add the current profile label:
+          tooltip.appendChild(this.getTooltipCurrentProfile());
+          // Add the tooltip grid with the command labels, mouse buttons and keyboard shortcuts:
+          tooltip.appendChild(this.getTooltipGrid());
+        }
+      } else {
+        // Don't show tooltips for the toolbar button menu items:
+        event.preventDefault();
+      }
+    }
+  },
+
+  getTooltipCurrentProfile: function() {
+    if(!this.tooltipCurrentProfile) {
+      var hbox = document.createElement('hbox');
+      hbox.setAttribute(
+        'id',
+        'autofillFormsTooltipCurrentProfile'
+      );
+      var label = document.createElement('label');
+      label.setAttribute(
+        'value',
+        this.getStringBundle().getString('currentProfileLabel')
+      );
+      label.setAttribute(
+        'id',
+        'autofillFormsTooltipCurrentProfileCaption'
+      );
+      hbox.appendChild(label);
+      label = label.cloneNode(false);
+      label.setAttribute(
+        'value',
+        this.getProfileLabel(this.getProfileIndex())
+      );
+      label.setAttribute(
+        'id',
+        'autofillFormsTooltipCurrentProfileLabel'
+      );
+      hbox.appendChild(label);
+      this.tooltipCurrentProfile = hbox;
+    }
+    return this.tooltipCurrentProfile;
+  },
+
+  getTooltipGrid: function() {
+    if(!this.tooltipGrid) {
+      var commands = new Array();
+      for(var property in this.shortcut) {
+        commands.push(new Array(
+          this.getStringBundle().getString('tooltip'+property.replace(/shortcut/,'')),
+          this.getFormattedMouseButton(this.getMouseButton('mouseS'+property.substr(1))),
+          this.getFormattedShortcut(this.getShortcut(property))
+        ));
+      }
+      var grid = document.createElement('grid');
+      grid.setAttribute(
+        'id',
+        'autofillFormsTooltipGrid'
+      );
+      var columns = document.createElement('columns');
+      var column = document.createElement('column');
+      var rows = document.createElement('rows');
+      var row = document.createElement('row');
+      var label = document.createElement('label');
+      columns.appendChild(column);
+      columns.appendChild(column.cloneNode(false));
+      columns.appendChild(column.cloneNode(false));
+      grid.appendChild(columns);
+      // Create the column headers:
+      label.setAttribute(
+        'class',
+        'autofillFormsTooltipGridHeader'
+      );
+      label.setAttribute(
+        'value',
+        this.getStringBundle().getString('command')
+      );
+      row.appendChild(label);
+      label = label.cloneNode(false);
+      label.setAttribute(
+        'value',
+        this.getStringBundle().getString('mousebutton')
+      );
+      row.appendChild(label);
+      label = label.cloneNode(false);
+      label.setAttribute(
+        'value',
+        this.getStringBundle().getString('keyboardShortcut')
+      );
+      row.appendChild(label);
+      rows.appendChild(row);
+      // Create a row for each command:
+      for(var i=0; i<commands.length; i++) {
+        row = row.cloneNode(false);
+        // Skip if neither mouseButton nor keyboard shortcut is set:
+        if(!commands[i][1] && !commands[i][2]) {
+          continue;
+        }
+        for(var j=0; j<commands[i].length; j++) {
+          label = label.cloneNode(false);
+          label.setAttribute(
+            'value',
+            commands[i][j]
+          );
+          if(j == 0) {
+            label.setAttribute(
+              'class',
+              'autofillFormsTooltipGridCommand'
+            );
+          } else if(j == 1) {
+            label.setAttribute(
+              'class',
+              'autofillFormsTooltipGridMouseButton'
+            );
+          } else {
+            label.setAttribute(
+              'class',
+              'autofillFormsTooltipGridKeyboardShortcut'
+            );
+          }
+          row.appendChild(label);
+        }
+        rows.appendChild(row);
+      }
+      grid.appendChild(rows);
+      this.tooltipGrid = grid;
+    }
+    return this.tooltipGrid;
+  },
+
+  resetAllProfiles: function() {
+    if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+      // Confirmation dialog:
+      if(!this.getPrompts().confirm(
+          null,
+          this.getStringBundle().getString('resetAllProfilesTitle'),
+          this.getStringBundle().getString('resetAllProfilesText')
+        )
+      ) {
+        return;
+      }
+    }
+
+    // Reset the user preferences:
+    if(this.autofillFormsPrefs.prefHasUserValue('useConfigDirectory')) {
+      this.autofillFormsPrefs.clearUserPref('useConfigDirectory');
+    }
+    if(this.autofillFormsPrefs.prefHasUserValue('storeEncrypted')) {
+      this.autofillFormsPrefs.clearUserPref('storeEncrypted');
+    }
+    if(this.autofillFormsPrefs.prefHasUserValue('profileIndex')) {
+      this.autofillFormsPrefs.clearUserPref('profileIndex');
+    }
+    if(this.autofillFormsPrefs.prefHasUserValue('profileLabels')) {
+      this.autofillFormsPrefs.clearUserPref('profileLabels');
+    }
+    if(this.autofillFormsPrefs.prefHasUserValue('profileSiteRules')) {
+      this.autofillFormsPrefs.clearUserPref('profileSiteRules');
+    }
+    if(this.autofillFormsPrefs.prefHasUserValue('fieldRules')) {
+      this.autofillFormsPrefs.clearUserPref('fieldRules');
+    }
+
+    this.profileIndex = null;
+    this.profileLabels = null;
+    this.profileSiteRules = null;
+    this.fieldRules = null;
+
+    // Re-init the profiles lists:
+    this.initProfilesLists();
+    // Re-init the fieldRules tree:
+    this.initTree();
+    // Re-initialize the simple interface:
+    this.initSimpleInterface();
+
+    if(this.tree && this.selection) {
+      try {
+        // Clear out the fieldRules tree selections
+        this.selection.select(-1);
+      } catch(e) {
+        this.log(e);
+      }
+    }
+  },
+
+  initProfilesLists: function(event) {
+    // The profiles tree:
+    this.initProfilesTree();
+
+    // Editable profiles menu list:
+    var profilesMenuList = document.getElementById('profilesMenuList');
+    if(profilesMenuList) {
+      profilesMenuList.removeAllItems();
+      for(var i=0; i < this.getProfileLabels().length; i++) {
+        profilesMenuList.appendItem(
+          this.getProfileLabel(i)
+        );
+      }
+      profilesMenuList.selectedIndex = this.getProfileIndex();
+    }
+    // Simple interface profiles menu list:
+    var simpleInterfaceProfileMenuList = document.getElementById('simpleInterfaceProfileMenuList');
+    if(simpleInterfaceProfileMenuList) {
+      simpleInterfaceProfileMenuList.removeAllItems();
+      for(var i=0; i < this.getProfileLabels().length; i++) {
+        simpleInterfaceProfileMenuList.appendItem(
+          this.getProfileLabel(i)
+        );
+      }
+      simpleInterfaceProfileMenuList.selectedIndex = this.getProfileIndex();
+    }
+    // Global profile selection:
+    var globalProfileMenuList = document.getElementById('globalProfileMenuList');
+    if(globalProfileMenuList) {
+      globalProfileMenuList.removeAllItems();
+      for(var i=0; i < this.getProfileLabels().length; i++) {
+        globalProfileMenuList.appendItem(
+          this.getProfileLabel(i)
+        );
+      }
+      globalProfileMenuList.selectedIndex = this.getGlobalProfileIndex();
+    }
+    // Form fields context menu selection:
+    var contextMenuProfileMenuList = document.getElementById('contextMenuProfileMenuList');
+    if(contextMenuProfileMenuList) {
+      // The first 3 items are "All profiles", "Active profile" and a menuseparator:
+      while(contextMenuProfileMenuList.firstChild.childNodes[3]) {
+        // The more convenient getItemAtIndex does not seem to work with Firefox versions < 3,
+        // so we use DOM methods on the menupopup child node of the menu node instead:
+        contextMenuProfileMenuList.firstChild.removeChild(
+          contextMenuProfileMenuList.firstChild.childNodes[3]
+        );
+      }
+      for(var i=0; i < this.getProfileLabels().length; i++) {
+        contextMenuProfileMenuList.appendItem(
+          this.getProfileLabel(i)
+        );
+      }
+      contextMenuProfileMenuList.selectedIndex
+        = this.getFormFieldsContextMenuProfileIndex()+3;
+    }
+
+    // The profile site rule textbox:
+    this.initProfileSiteRuleTextBox();
+  },
+
+  updateProfilesLists: function() {
+    // The more convenient getItemAtIndex does not seem to work with Firefox versions < 3,
+    // so we use DOM methods on the menupopup child node of the menu nodes instead:
+
+    // Editable profiles menu list:
+    var profilesMenuList = document.getElementById('profilesMenuList');
+    if(profilesMenuList) {
+      profilesMenuList
+        .firstChild.childNodes[this.getProfileIndex()].label
+        = this.getProfileLabel(this.getProfileIndex());
+    }
+    // Simple interface profiles menu list:
+    var simpleInterfaceProfileMenuList = document.getElementById('simpleInterfaceProfileMenuList');
+    if(simpleInterfaceProfileMenuList) {
+      simpleInterfaceProfileMenuList
+        .firstChild.childNodes[this.getProfileIndex()].label
+        = this.getProfileLabel(this.getProfileIndex());
+    }
+    // Global profile selection:
+    var globalProfileMenuList = document.getElementById('globalProfileMenuList');
+    if(globalProfileMenuList) {
+      globalProfileMenuList
+        .firstChild.childNodes[this.getProfileIndex()].label
+        = this.getProfileLabel(this.getProfileIndex());
+    }
+    // Form fields context menu selection:
+    var contextMenuProfileMenuList = document.getElementById('contextMenuProfileMenuList');
+    if(contextMenuProfileMenuList) {
+      // The first 3 items are "All profiles", "Active profile" and a menuseparator:
+      contextMenuProfileMenuList
+        .firstChild.childNodes[this.getProfileIndex()+3].label
+        = this.getProfileLabel(this.getProfileIndex());
+    }
+    // The profiles tree:
+    if(this.profilesTreeBox) {
+      this.profilesTreeBox.invalidateRow(this.getProfileIndex());
+    }
+  },
+
+  getProfileIndex: function() {
+    if(this.profileIndex == null)
+      this.profileIndex = this.autofillFormsPrefs.getIntPref('profileIndex');
+    return this.profileIndex;
+  },
+
+  setProfileIndex: function(index) {
+    if(this.profileIndex == index)
+      return;
+
+    // See method selectedFieldRule() why this has to be set to null:
+    this.lastSelectedIndex = null;
+
+    this.autofillFormsPrefs.setIntPref('profileIndex',parseInt(index));
+    // Update the tree view if present:
+    if(this.tree) {
+      // The settings page doesn't observe preferences changes - set the profileIndex manually:
+      this.profileIndex = index;
+      // Re-init the tree:
+      this.initTree();
+      // Re-initialize the simple interface:
+      this.initSimpleInterface();
+    }
+    // Update the profiles tree selection if present and not already updated:
+    if(this.profilesTree && this.profilesSelection.currentIndex != index) {
+      // Select the current profile:
+      this.profilesSelection.select(index);
+
+      // Ensure row is visible (scrolls if not):
+      this.profilesTreeBox.ensureRowIsVisible(index);
+    }
+    // Editable profiles menu list:
+    var profilesMenuList = document.getElementById('profilesMenuList');
+    if(profilesMenuList) {
+      profilesMenuList.selectedIndex = this.getProfileIndex();
+    }
+    // Simple interface profiles menu list:
+    var simpleInterfaceProfileMenuList = document.getElementById('simpleInterfaceProfileMenuList');
+    if(simpleInterfaceProfileMenuList) {
+      simpleInterfaceProfileMenuList.selectedIndex = this.getProfileIndex();
+    }
+
+    // The profile site rule textbox:
+    this.initProfileSiteRuleTextBox();
+  },
+
+  getGlobalProfileIndex: function() {
+    if(this.globalProfileIndex == null) {
+      this.globalProfileIndex = this.autofillFormsPrefs.getIntPref('globalProfileIndex');
+    }
+    return this.globalProfileIndex;
+  },
+
+  setGlobalProfileIndex: function(index) {
+    if(this.globalProfileIndex == index) {
+      return;
+    }
+    this.autofillFormsPrefs.setIntPref('globalProfileIndex',parseInt(index));
+    // The settings page doesn't observe preferences changes - set the profileIndex manually:
+    this.globalProfileIndex = index;
+  },
+
+  getFormFieldsContextMenuProfileIndex: function() {
+    if(this.formFieldsContextMenuProfileIndex == null) {
+      this.formFieldsContextMenuProfileIndex
+        = this.autofillFormsPrefs.getIntPref('formFieldsContextMenuProfileIndex');
+    }
+    return this.formFieldsContextMenuProfileIndex;
+  },
+
+  setFormFieldsContextMenuProfileIndex: function(index) {
+    if(this.formFieldsContextMenuProfileIndex == index) {
+      return;
+    }
+    this.autofillFormsPrefs.setIntPref('formFieldsContextMenuProfileIndex',parseInt(index));
+    // The settings page doesn't observe preferences changes - set the profileIndex manually:
+    this.formFieldsContextMenuProfileIndex = index;
+  },
+
+  getProfileLabelsFile: function() {
+    var file = this.getConfigDirectory();
+    file.append('profileLabels.txt');
+    if(!file.exists()) {
+      file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
+    }
+    return file;
+  },
+
+  exportProfileLabelsToConfigDirectory: function() {
+    var prefString;
+    // Get the profileLabels string from the preferences:
+    prefString = this.autofillFormsPrefs
+              .getComplexValue('profileLabels',Components.interfaces.nsIPrefLocalizedString)
+              .data;
+    if(prefString) {
+      this.setFileContent(this.getProfileLabelsFile(), prefString);
+    }
+  },
+
+  importProfileLabelsFromConfigDirectory: function() {
+    var prefString;
+    prefString = this.getFileContent(this.getProfileLabelsFile());
+    if(prefString) {
+      // Store the profileLabels as unicode string in the preferences:
+      this.autofillFormsPrefs.setComplexValue(
+        'profileLabels',
+        Components.interfaces.nsISupportsString,
+        this.getUnicodeString(prefString)
+      );
+    }
+  },
+
+  getProfileLabels: function() {
+    if(this.profileLabels == null) {
+      var prefString;
+      if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+        // Get the profileLabels string from the profileLabels file in the configDirectory:
+        prefString = this.getFileContent(this.getProfileLabelsFile());
+      }
+      if(!prefString) {
+        prefString = this.autofillFormsPrefs
+                .getComplexValue('profileLabels',Components.interfaces.nsIPrefLocalizedString)
+                .data;
+      }
+      // The profile labels are stored as a string with tabs as separators:
+      this.profileLabels = prefString.split('\t');
+    }
+    return this.profileLabels;
+  },
+
+  setProfileLabels: function(profileLabels) {
+    // Save the profile labels separated by tabs:
+    var prefString = profileLabels.join('\t');
+    if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+      this.setFileContent(this.getProfileLabelsFile(), prefString);
+    } else {
+      this.autofillFormsPrefs.setComplexValue(
+        'profileLabels',
+        Components.interfaces.nsISupportsString,
+        this.getUnicodeString(prefString)
+      );
+    }
+  },
+
+  getProfileLabel: function(index) {
+    while(this.getProfileLabels().length <= index) {
+      this.getProfileLabels().push(this.getUniqueProfileLabel());
+    }
+    return this.getProfileLabels()[index];
+  },
+
+  setProfileLabel: function(index, label) {
+    while(this.getProfileLabels().length <= index) {
+      this.getProfileLabels().push(this.getUniqueProfileLabel());
+    }
+    this.getProfileLabels()[index] = label;
+    // Save the profileLabels list in the preferences:
+    this.setProfileLabels(this.getProfileLabels());
+  },
+
+  getUniqueProfileLabel: function(profileLabel) {
+    if(!profileLabel) {
+      profileLabel = 'Profile';
+    }
+
+    // Make sure the profile label is unique:
+    if(!this.inArray(this.getProfileLabels(), profileLabel)) {
+      return profileLabel;
+    }
+    var i = profileLabel.lastIndexOf(' ');
+    var n = parseInt(profileLabel.substr(i+2));
+    if(isNaN(n)) {
+      return this.getUniqueProfileLabel(profileLabel+' (2)');
+    }
+    n++;
+    profileLabel = profileLabel.substr(0, i)+' ('+n+')';
+    return this.getUniqueProfileLabel(profileLabel);
+  },
+
+  changeProfileLabel: function(newProfileLabel) {
+    var profilesMenuList = document.getElementById('profilesMenuList');
+    if(profilesMenuList) {
+      // Make sure the new profile label is safe and unique:
+      newProfileLabel = this.getUniqueProfileLabel(this.makeSafe(newProfileLabel));
+      // Update the label of the selected profile:
+      this.setProfileLabel(this.getProfileIndex(), newProfileLabel);
+      // Update the profiles textbox contents:
+      profilesMenuList.inputField.value = newProfileLabel;
+      document.getElementById('profileLabelTextBox').value = newProfileLabel;
+      // Update the profiles lists:
+      this.updateProfilesLists();
+    }
+  },
+
+  initProfileSiteRuleTextBox: function(event) {
+    var profileSiteRuleTextBox = document.getElementById('profileSiteRuleTextBox');
+    if(profileSiteRuleTextBox) {
+      profileSiteRuleTextBox.value = this.getProfileSiteRule(this.getProfileIndex());
+    }
+  },
+
+  changeProfileSiteRule: function(siteRule) {
+    var profileSiteRuleTextBox = document.getElementById('profileSiteRuleTextBox');
+    if(profileSiteRuleTextBox) {
+      // Check the regular expression before updating the profile site rules:
+      try {
+        siteRule = this.getRegExpStr(
+          this.makeSafe(siteRule)
+        );
+        profileSiteRuleTextBox.value = siteRule;
+        document.getElementById('profileSiteRuleTextBox2').value = siteRule;
+
+        var newProfileSiteRules = this.getProfileSiteRules();
+        newProfileSiteRules[this.getProfileIndex()] = siteRule;
+        this.setProfileSiteRules(newProfileSiteRules);
+
+        // Update the profiles tree:
+        if(this.profilesTreeBox) {
+          this.profilesTreeBox.invalidateRow(this.getProfileIndex());
+        }
+      } catch(e) {
+        this.invalidRegExpAlert(e);
+      }
+    }
+  },
+
+  getProfileSiteRulesFile: function() {
+    var file = this.getConfigDirectory();
+    file.append('profileSiteRules.txt');
+    if(!file.exists()) {
+      file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
+    }
+    return file;
+  },
+
+  exportProfileSiteRulesToConfigDirectory: function() {
+    var prefString;
+    // Get the profileSiteRules string from the preferences:
+    prefString = this.autofillFormsPrefs
+              .getComplexValue('profileSiteRules',Components.interfaces.nsISupportsString)
+              .data;
+    if(prefString) {
+      this.setFileContent(this.getProfileSiteRulesFile(), prefString);
+    }
+  },
+
+  importProfileSiteRulesFromConfigDirectory: function() {
+    var prefString;
+    prefString = this.getFileContent(this.getProfileSiteRulesFile());
+    if(prefString) {
+      // Store the profileSiteRules as unicode string in the preferences:
+      this.autofillFormsPrefs.setComplexValue(
+        'profileSiteRules',
+        Components.interfaces.nsISupportsString,
+        this.getUnicodeString(prefString)
+      );
+    }
+  },
+
+  getProfileSiteRules: function() {
+    if(this.profileSiteRules == null) {
+      var prefString;
+      if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+        // Get the profileSiteRules string from the profileSiteRules file in the configDirectory:
+        prefString = this.getFileContent(this.getProfileSiteRulesFile());
+      }
+      if(!prefString) {
+        prefString = this.autofillFormsPrefs
+                .getComplexValue('profileSiteRules',Components.interfaces.nsISupportsString)
+                .data;
+      }
+      // The profile SiteRules are stored as a string with tabs as separators:
+      this.profileSiteRules = prefString.split('\t');
+    }
+    return this.profileSiteRules;
+  },
+
+  setProfileSiteRules: function(profileSiteRules) {
+    // Save the profile SiteRules separated by tabs:
+    var prefString = profileSiteRules.join('\t');
+    if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+      this.setFileContent(this.getProfileSiteRulesFile(), prefString);
+    } else {
+      this.autofillFormsPrefs.setComplexValue(
+        'profileSiteRules',
+        Components.interfaces.nsISupportsString,
+        this.getUnicodeString(prefString)
+      );
+    }
+  },
+
+  getProfileSiteRule: function(index) {
+    while(this.getProfileSiteRules().length <= index) {
+      this.getProfileSiteRules().push('(?:)');
+    }
+    return this.getProfileSiteRules()[index];
+  },
+
+  setProfileSiteRule: function(index, siteRule) {
+    while(this.getProfileSiteRules().length <= index) {
+      this.getProfileSiteRules().push('(?:)');
+    }
+    this.getProfileSiteRules()[index] = siteRule;
+    // Save the profileSiteRules in the preferences:
+    this.setProfileSiteRules(this.getProfileSiteRules());
+  },
+
+  addFormAsProfile: function(event) {
+    if(this.targetFormField && this.targetFormField.form) {
+      var elements = this.targetFormField.form.elements;
+      var doc = this.targetFormField.form.ownerDocument;
+
+      var newProfile = new Array();
+
+      // Go through the form elements:
+      for(var i=0; i<elements.length; i++) {
+        // Only use valid form fields:
+        if(this.isValidFormField(elements[i])) {
+          var value;
+          var overwrite = true;
+
+          // Create the fieldRule (from name, label or id):
+          var fieldRule = this.getFieldRuleForElement(elements[i]);
+
+          switch(elements[i].type) {
+            case 'checkbox':
+              // Add a rule to uncheck the checkbox if it is unchecked:
+              if(!elements[i].checked) {
+                overwrite = false;
+              }
+              value = this.getRegExpStrForValue(elements[i].value);
+              break;
+            case 'radio':
+              // Only add checked radio buttons:
+              if(!elements[i].checked) {
+                continue;
+              }
+              value = this.getRegExpStrForValue(elements[i].value);
+              break;
+            case 'select-one':
+              value = this.getRegExpStrForValue(elements[i].value);
+              break;
+            case 'select-multiple':
+              var fieldRuleLabel = this.makeSafe(this.getFieldRuleNameForElement(elements[i]));
+              // Add all options as fieldRules, set "overwrite" to true if selected:
+              for(var j = 0; j < elements[i].options.length; j++) {
+                newProfile.push(
+                  this.createFieldRule(
+                    fieldRuleLabel+' ('+j+')',
+                    this.getRegExpStrForValue(elements[i].options[j].value),
+                    fieldRule,
+                    '(?:)',
+                    elements[i].options[j].selected,
+                    true
+                  )
+                );
+              }
+              continue;
+            default:
+              value = this.makeSafe(this.replaceControlCharacters(elements[i].value));
+              break;
+          }
+
+          // Add the current element as new rule to the profile list:
+          newProfile.push(
+            this.createFieldRule(
+              this.makeSafe(this.getFieldRuleNameForElement(elements[i])),
+              value,
+              fieldRule,
+              '(?:)',
+              overwrite,
+              true
+            )
+          );
+        }
+      }
+
+      // Initialize the fieldRules:
+      this.getFieldRules();
+
+      // Add the new profile to the fieldRules:
+      this.fieldRules.push(newProfile);
+      // Save the profiles in the preferences:
+      this.setFieldRules();
+
+      // Add a label for default empty profile:
+      if(this.getProfileLabels().length == 0) {
+        this.getProfileLabels().push(this.getUniqueProfileLabel());
+      }
+      // Use the documents hostname as profile label and add it to the profile labels list:
+      this.getProfileLabels().push(this.getUniqueProfileLabel(this.makeSafe(doc.location.host)));
+      // Save the profileLabels list in the preferences:
+      this.setProfileLabels(this.getProfileLabels());
+
+      // Use the protocol and domain of the web form as profile siteRule:
+      this.getProfileSiteRules().push(this.getSiteRuleForURL(doc.location.protocol+'//'+doc.location.host));
+      // Save the profileSiteRules in the preferences:
+      this.setProfileSiteRules(this.getProfileSiteRules());
+
+      // Save the the new profile index as selected profileIndex:
+      this.setProfileIndex(this.getProfileLabels().length-1);
+
+      // Reset the target form field:
+      this.targetFormField = null;
+
+      // Create parameters for the settings page:
+      var params = new Object();
+      params.newProfileFromForm = true;
+
+      // Open up the settings page:
+      this.showDialog('chrome://autofillForms/content/autofillFormsOptions.xul', params);
+    }
+  },
+
+  addProfile: function(newProfileLabel) {
+    // Duplicate the selected profile (do a deep copy):
+    this.fieldRules.push(
+      this.copyFieldRules(this.getFieldRules())
+    );
+    // Save the profiles in the preferences:
+    this.setFieldRules();
+    // Add profile label for default empty profile:
+    if(this.getProfileLabels().length == 0) {
+      this.getProfileLabels().push(this.getUniqueProfileLabel());
+    }
+    // Add the (unique) newProfileLabel to the profileLabels list:
+    this.getProfileLabels().push(this.getUniqueProfileLabel(this.makeSafe(newProfileLabel)));
+    // Save the profileLabels list in the preferences:
+    this.setProfileLabels(this.getProfileLabels());
+    // Add a new empty profileSiteRule:
+    this.getProfileSiteRules().push('(?:)');
+    // Save the profileSiteRules in the preferences:
+    this.setProfileSiteRules(this.getProfileSiteRules());
+    // Save the the new profile index as selected profileIndex:
+    this.setProfileIndex(this.getProfileLabels().length-1);
+    // Update the profiles lists:
+    this.initProfilesLists();
+    // Re-init the fieldRules tree:
+    this.initTree();
+    // Re-initialize the simple interface:
+    this.initSimpleInterface();
+  },
+
+  removeProfile: function(event) {
+    if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+      // Confirmation dialog:
+      if(!this.getPrompts().confirm(
+          null,
+          this.getStringBundle().getString('removeProfileTitle'),
+          this.getStringBundle().getString('removeProfileText')
+        )
+      ) {
+        return;
+      }
+    }
+
+    // Remove the selected profile from the list:
+    this.fieldRules.splice(this.getProfileIndex(),1);
+    // Save the profiles in the preferences:
+    this.setFieldRules();
+    // Remove the selected profile from the profileLabels list:
+    this.getProfileLabels().splice(this.getProfileIndex(),1);
+    // Save the profileLabels list in the preferences:
+    this.setProfileLabels(this.getProfileLabels());
+    // Remove the selected profile's siteRule:
+    this.getProfileSiteRules().splice(this.getProfileIndex(),1);
+    // Save the profileSiteRules in the preferences:
+    this.setProfileSiteRules(this.getProfileSiteRules());
+    // Adjust the profileIndex if the last profile on the list has been deleted:
+    if(this.getProfileIndex()+1 > this.fieldRules.length) {
+      var newIndex = this.fieldRules.length>0 ? this.fieldRules.length-1 : 0;
+      this.setProfileIndex(newIndex);
+    }
+    // Update the profiles lists:
+    this.initProfilesLists();
+    // Re-init the tree:
+    this.initTree();
+    // Re-initialize the simple interface:
+    this.initSimpleInterface();
+  },
+
+  createFieldRule: function(name,value,fieldRule,siteRule,overwrite,enabled) {
+    var rule = new Object();
+    rule['fieldRuleName'] = name;
+    rule['fieldRuleValue'] = value;
+    rule['fieldRuleFieldRule'] = fieldRule;
+    rule['fieldRuleSiteRule'] = siteRule;
+    rule['fieldRuleOverwrite'] = overwrite;
+    rule['fieldRuleEnabled'] = enabled;
+    return rule;
+  },
+
+  getRegExpPasswordLabel: function() {
+    if(!arguments.callee.regExpPass) {
+      arguments.callee.regExpPass = new RegExp(
+                this.autofillFormsPrefs
+                .getComplexValue('regExpPasswordLabel',Components.interfaces.nsIPrefLocalizedString)
+                .data,
+                'i');
+    }
+    return arguments.callee.regExpPass;
+  },
+
+  initTree: function() {
+    // Get the tree:
+    this.tree = document.getElementById('fieldRulesTree');
+
+    if(this.tree) {
+
+      // Implement the TreeView interface:
+      this.treeView = {
+        rowCount: 0,
+        setTree: function(tree){},
+        getImageSrc: function(row,column) {},
+        getProgressMode: function(row,column) {},
+        getCellValue: function(row,column) {
+          var rowObj = this.parent.getFieldRules()[row];
+          if(rowObj) {
+            return rowObj[column.id];
+          }
+        },
+        getCellText: function(row,column){
+          var rowObj = this.parent.getFieldRules()[row];
+          if(rowObj) {
+            if(column.id=='fieldRuleValue' &&
+              this.parent.getRegExpPasswordLabel().test(rowObj['fieldRuleName'])) {
+              // Show passwords as asterisks:
+              return rowObj[column.id].replace(/./g, '*');
+            } else {
+              return rowObj[column.id];
+            }
+          }
+          return '';
+        },
+        isEditable: function(row,column){
+          // Only checkbox columns are editable:
+          if(column.id=='fieldRuleOverwrite' || column.id=='fieldRuleEnabled')
+            return true;
+          else
+            return false;
+        },
+        setCellValue: function(row,column,value){
+          var rowObj = this.parent.getFieldRules()[row];
+          if(rowObj) {
+            rowObj[column.id] = value;
+            // Notify the tree:
+            this.parent.treeBox.invalidateRow(row);
+            // Update the preferences:
+            this.parent.setFieldRules();
+            // Update the simple interface (add/remove enabled/disabled rules):
+            if(column.id=='fieldRuleEnabled') {
+              if(value == 'true') {
+                this.parent.addSimpleInterfaceRow(row);
+              } else {
+                this.parent.removeSimpleInterfaceRow(row);
+              }
+            }
+          }
+        },
+        isSeparator: function(index) {return false;},
+        isSorted: function() {return false;},
+        isContainer: function(index) {return false;},
+        cycleHeader: function(column) {},
+        getRowProperties: function(row,prop){},
+        getColumnProperties: function(column,prop){},
+        getCellProperties: function(row,column,prop){},
+        getParentIndex: function(index) {return -1}
+      };
+      // Set the autofillForms object as parent:
+      this.treeView.parent = this;
+
+      // Set the tree length using the fieldRules list length:
+      this.treeView.rowCount = this.getFieldRules().length;
+
+      // Assign the treeview:
+      this.tree.view = this.treeView;
+
+      // The TreeSelection object:
+      this.selection = this.tree.view.selection;
+
+      // The TreeBox object:
+      this.treeBox = this.tree.treeBoxObject;
+    }
+  },
+
+  sortFieldRules: function(event) {
+    // See method selectedFieldRule() why this has to be set to null:
+    this.lastSelectedIndex = null;
+
+    if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+      // Confirmation dialog:
+      if(!this.getPrompts().confirm(
+          null,
+          this.getStringBundle().getString('sortFieldRulesTitle'),
+          this.getStringBundle().getString('sortFieldRulesText')
+        )
+      ) {
+        return;
+      }
+    }
+
+    // Get the id of the column:
+    var id = event.target.id;
+
+    // Helper function to sort the fieldRules objects:
+    function customSort(a,b) {
+      // This enables comparison of boolean true and false:
+      var x = a[id].toString();
+      var y = b[id].toString();
+
+      if(x > y) return 1;
+      if(x < y) return -1;
+      return 0;
+    }
+
+    // Sort the form field rules using the helper function:
+    this.getFieldRules().sort(customSort);
+
+    // Change sort direction for next click:
+    if(this.ascending) {
+      this.ascending = false;
+    } else {
+      this.getFieldRules().reverse();
+      this.ascending = true;
+    }
+
+    // Notify the tree:
+    this.treeBox.invalidate();
+
+    // Clear out selections
+    this.selection.select(-1);
+
+    // Update the preferences:
+    this.setFieldRules();
+
+    // Re-initialize the simple interface:
+    this.initSimpleInterface();
+  },
+
+  selectedFieldRule: function(event) {
+    if(this.selection.currentIndex == -1) {
+      // Disable buttons:
+      document.getElementById('buttonRemoveFieldRule').setAttribute('disabled', 'true');
+      document.getElementById('buttonMoveUpFieldRule').setAttribute('disabled', 'true');
+      document.getElementById('buttonMoveDownFieldRule').setAttribute('disabled', 'true');
+
+      this.lastSelectedIndex = null;
+    } else if(this.selection.count == 1) {
+      // The onchange event (as well as onblur, etc.) of the textboxes seems to be ignored if a new item is selected,
+      // so we try and apply the field rules of the last element (if changed):
+      if(this.lastSelectedIndex !== null) {
+        this.applyFieldRuleOnIndex(this.lastSelectedIndex);
+      }
+
+      // Update the textboxes with the selected fieldRule:
+      var index = this.selection.currentIndex;
+      document.getElementById('fieldRuleNameTextBox').value = this.getFieldRules()[index]['fieldRuleName'];
+      document.getElementById('fieldRuleValueTextBox').value = this.getFieldRules()[index]['fieldRuleValue'];
+      document.getElementById('fieldRuleFieldRuleTextBox').value = this.getFieldRules()[index]['fieldRuleFieldRule'];
+      document.getElementById('fieldRuleSiteRuleTextBox').value = this.getFieldRules()[index]['fieldRuleSiteRule'];
+
+      // Enable/Disable buttons:
+      document.getElementById('buttonRemoveFieldRule').setAttribute('disabled', 'false');
+      document.getElementById('buttonMoveUpFieldRule').setAttribute(
+        'disabled',
+        (index == 0)
+      );
+      document.getElementById('buttonMoveDownFieldRule').setAttribute(
+        'disabled',
+        (index == this.getFieldRules().length-1)
+      );
+
+      // Save the last selected index and reset it to null for any other action than just a single selection:
+      this.lastSelectedIndex = index;
+    } else if(this.selection.count > 1) {
+      // Enable/Disable buttons:
+      document.getElementById('buttonRemoveFieldRule').setAttribute('disabled', 'false');
+      document.getElementById('buttonMoveUpFieldRule').setAttribute('disabled', 'true');
+      document.getElementById('buttonMoveDownFieldRule').setAttribute('disabled', 'true');
+
+      this.lastSelectedIndex = null;
+    }
+  },
+
+  initProfilesTree: function() {
+    this.profilesTree = document.getElementById('profilesTree');
+    if(this.profilesTree) {
+
+      // Implement the profiles TreeView interface:
+      this.profilesTreeView = {
+        rowCount: 0,
+        setTree: function(tree){},
+        getImageSrc: function(row,column) {},
+        getProgressMode: function(row,column) {},
+        getCellValue: function(row,column) {
+          if(column.id=='profilesTreeColName') {
+            return this.parent.getProfileLabel(row);
+          } else {
+            return this.parent.getProfileSiteRule(row);
+          }
+        },
+        getCellText: function(row,column){
+          if(column.id=='profilesTreeColName') {
+            return this.parent.getProfileLabel(row);
+          } else {
+            return this.parent.getProfileSiteRule(row);
+          }
+        },
+        isEditable: function(row,column){return false;},
+        setCellValue: function(row,column,value){},
+        isSeparator: function(index) {return false;},
+        isSorted: function() {return false;},
+        isContainer: function(index) {return false;},
+        cycleHeader: function(column) {},
+        getRowProperties: function(row,prop){},
+        getColumnProperties: function(column,prop){},
+        getCellProperties: function(row,column,prop){},
+        getParentIndex: function(index) {return -1}
+      };
+      // Set the autofillForms object as parent:
+      this.profilesTreeView.parent = this;
+
+      // Seems like we need to reset these arrays to have a consistens UI:
+      this.profileLabels = null;
+      this.profileSiteRules = null;
+
+      // Set the tree length using the profiles labels list length:
+      this.profilesTreeView.rowCount = this.getProfileLabels().length;
+
+      // Assign the treeview:
+      this.profilesTree.view = this.profilesTreeView;
+
+      // The TreeSelection object:
+      this.profilesSelection = this.profilesTree.view.selection;
+
+      // The TreeBox object:
+      this.profilesTreeBox = this.profilesTree.treeBoxObject;
+
+      // Select the current profile:
+      this.profilesSelection.select(this.getProfileIndex());
+
+      // Ensure row is visible (scrolls if not):
+      this.profilesTreeBox.ensureRowIsVisible(this.getProfileIndex());
+    }
+  },
+
+  selectedProfile: function(event) {
+    var index = this.profilesSelection.currentIndex;
+    if(index != -1) {
+      this.setProfileIndex(index);
+
+      if(index > 0) {
+        document.getElementById('buttonMoveUpProfile').disabled = false;
+      } else {
+        document.getElementById('buttonMoveUpProfile').disabled = true;
+      }
+      if(index+1 < this.getProfileLabels().length) {
+        document.getElementById('buttonMoveDownProfile').disabled = false;
+      } else {
+        document.getElementById('buttonMoveDownProfile').disabled = true;
+      }
+
+      if(document.getElementById('profileLabelTextBox')) {
+        document.getElementById('profileLabelTextBox').value = this.getProfileLabel(this.getProfileIndex());
+      }
+      if(document.getElementById('profileSiteRuleTextBox2')) {
+        document.getElementById('profileSiteRuleTextBox2').value = this.getProfileSiteRule(this.getProfileIndex());
+      }
+    } else {
+      document.getElementById('buttonMoveUpProfile').disabled = true;
+      document.getElementById('buttonMoveDownProfile').disabled = true;
+    }
+  },
+
+  moveUpProfile: function(event) {
+    var tmpProfile = this.getFieldRules(this.getProfileIndex()-1);
+    this.fieldRules[this.getProfileIndex()-1] = this.getFieldRules(this.getProfileIndex());
+    this.fieldRules[this.getProfileIndex()] = tmpProfile;
+    this.setFieldRules();
+
+    var tmpProfileLabel = this.getProfileLabel(this.getProfileIndex()-1);
+    this.getProfileLabels()[this.getProfileIndex()-1] = this.getProfileLabel(this.getProfileIndex());
+    this.getProfileLabels()[this.getProfileIndex()] = tmpProfileLabel;
+    this.setProfileLabels(this.getProfileLabels());
+
+    var tmpProfileSiteRule = this.getProfileSiteRule(this.getProfileIndex()-1);
+    this.getProfileSiteRules()[this.getProfileIndex()-1] = this.getProfileSiteRule(this.getProfileIndex());
+    this.getProfileSiteRules()[this.getProfileIndex()] = tmpProfileSiteRule;
+    this.setProfileSiteRules(this.getProfileSiteRules());
+
+    this.setProfileIndex(this.getProfileIndex()-1);
+
+    this.initProfilesLists();
+  },
+
+  moveDownProfile: function(event) {
+    var tmpProfile = this.getFieldRules(this.getProfileIndex()+1);
+    this.fieldRules[this.getProfileIndex()+1] = this.getFieldRules(this.getProfileIndex());
+    this.fieldRules[this.getProfileIndex()] = tmpProfile;
+    this.setFieldRules();
+
+    var tmpProfileLabel = this.getProfileLabel(this.getProfileIndex()+1);
+    this.getProfileLabels()[this.getProfileIndex()+1] = this.getProfileLabel(this.getProfileIndex());
+    this.getProfileLabels()[this.getProfileIndex()] = tmpProfileLabel;
+    this.setProfileLabels(this.getProfileLabels());
+
+    var tmpProfileSiteRule = this.getProfileSiteRule(this.getProfileIndex()+1);
+    this.getProfileSiteRules()[this.getProfileIndex()+1] = this.getProfileSiteRule(this.getProfileIndex());
+    this.getProfileSiteRules()[this.getProfileIndex()] = tmpProfileSiteRule;
+    this.setProfileSiteRules(this.getProfileSiteRules());
+
+    this.setProfileIndex(this.getProfileIndex()+1);
+
+    this.initProfilesLists();
+  },
+
+  sortProfiles: function(event) {
+    var newSelectedIndex = this.getProfileIndex();
+    var fieldArray = this.getFieldsArray();
+    var oldIndex;
+
+    switch(event.target.id) {
+      case 'profilesTreeColName':
+        //Sort by Profile Label
+        fieldArray.sort(function (a, b) {
+          if (a[1] == b[1]) {
+            return 0;
+          }
+          if (a[1] < b[1]) {
+            return -1;
+          }
+          return 1;
+        });
+        if (!this.profilesAscending) {
+          fieldArray.reverse();
+        }
+        for(var i=0; i<this.getProfileLabels().length; i++) {
+          oldIndex = fieldArray[i][0];
+          if(oldIndex == this.getProfileIndex()) {
+            newSelectedIndex = i;
+          }
+          this.getProfileLabels()[i] = fieldArray[i][1];
+          this.getProfileSiteRules()[i] = fieldArray[i][2];
+          this.fieldRules[i] = fieldArray[i][3];
+        }
+        break;
+
+      case 'profilesTreeColSiteRule':
+        //Sort by Profile Site Rule
+        fieldArray.sort(function (a, b) {
+          if (a[2] == b[2]) {
+            return 0;
+          }
+          if (a[2] < b[2]) {
+            return -1;
+          }
+          return 1;
+        });
+        if (!this.profilesAscending) {
+          fieldArray.reverse();
+        }
+        for(var i=0; i<this.getProfileLabels().length; i++) {
+          oldIndex = fieldArray[i][0];
+          if(oldIndex == this.getProfileIndex()) {
+            newSelectedIndex = i;
+          }
+          this.getProfileLabels()[i] = fieldArray[i][1];
+          this.getProfileSiteRules()[i] = fieldArray[i][2];
+          this.fieldRules[i] = fieldArray[i][3];
+        }
+        break;
+    }
+    // Change sort direction for next click:
+    this.profilesAscending = !this.profilesAscending;
+
+    this.setFieldRules();
+    this.setProfileLabels(this.getProfileLabels());
+    this.setProfileSiteRules(this.getProfileSiteRules());
+
+    this.setProfileIndex(newSelectedIndex);
+
+    this.initProfilesLists();
+  },
+  getFieldsArray: function() {
+    // This creates an array of [i, ProfileLabel, ProfileSiteRule, fieldRules] rows
+    // we can then sort by rows[1] or rows[2] and store the row elements back in
+    // their respective arrays.
+    var row;
+    var fieldArray = new Array();
+    var tmpProfileLabels = this.getProfileLabels().slice(0);
+    var tmpProfileSiteRules = this.getProfileSiteRules().slice(0);
+
+    for(var i=0; i<this.getProfileSiteRules().length; i++) {
+      row = new Array();
+      row.push(i);
+      row.push(tmpProfileLabels[i]);
+      row.push(tmpProfileSiteRules[i]);
+      row.push(this.getFieldRules(i));
+      fieldArray.push(row);
+    }
+    return fieldArray;
+  },
+  profilesTreeHandleKeyPress: function(event) {
+    if(event.keyCode == 46) {
+      this.removeProfile();
+    }
+  },
+
+  invalidRegExpAlert: function(error) {
+    // Invalid regular expression alert:
+    this.getPrompts().alert(
+      null,
+      this.getStringBundle().getString('invalidRegExpTitle'),
+      this.getStringBundle().getString('invalidRegExpText') + "\n\n" + error
+    );
+  },
+
+  makeSafe: function(str) {
+    // Remove all tabs and linefeeds from the given string
+    // (these are used as separators):
+    return str.replace(/\t|\n/g, '');
+  },
+
+  replaceControlCharacters: function(str) {
+    return str.replace(
+      /\n|\t/g,
+      this.replaceControlCharactersCallback
+    );
+  },
+
+  replaceControlCharactersCallback: function(str) {
+    switch(str) {
+      case "\n":
+        return autofillForms.autofillFormsPrefs.getCharPref('placeholderLineBreak');
+      case "\t":
+        return '  ';
+      default:
+        return str;
+    }
+  },
+
+  replaceControlCharacterPlaceholders: function(str) {
+    try {
+      var regExpObj = new RegExp(
+        '('
+        +this.autofillFormsPrefs.getCharPref('placeholderLineBreak')
+        +')|('
+        +this.autofillFormsPrefs.getCharPref('placeholderTab')
+        +')',
+        'g'
+      );
+      return str.replace(
+        regExpObj,
+        this.replaceControlCharacterPlaceholdersCallback
+      );
+    } catch(e) {
+      return str;
+    }
+  },
+
+  replaceControlCharacterPlaceholdersCallback: function(str) {
+    switch(str) {
+      case autofillForms.autofillFormsPrefs.getCharPref('placeholderLineBreak'):
+        return "\n";
+      case autofillForms.autofillFormsPrefs.getCharPref('placeholderTab'):
+        return "\t";
+      default:
+        return str;
+    }
+  },
+
+  applyFieldRuleOnIndex: function(index) {
+    // Check the regular expressions:
+    try {
+      var fieldRule = this.getRegExpStr(
+        this.makeSafe(document.getElementById('fieldRuleFieldRuleTextBox').value)
+      );
+      document.getElementById('fieldRuleFieldRuleTextBox').value = fieldRule;
+
+      var siteRule = this.getRegExpStr(
+        this.makeSafe(document.getElementById('fieldRuleSiteRuleTextBox').value)
+      );
+      document.getElementById('fieldRuleSiteRuleTextBox').value = siteRule;
+    } catch(e) {
+      this.invalidRegExpAlert(e);
+      return;
+    }
+
+    var ruleName = this.makeSafe(document.getElementById('fieldRuleNameTextBox').value);
+    var ruleValue = this.makeSafe(document.getElementById('fieldRuleValueTextBox').value);
+
+    if(  this.getFieldRules()[index] && (
+      this.getFieldRules()[index]['fieldRuleName'] != ruleName ||
+      this.getFieldRules()[index]['fieldRuleValue'] != ruleValue ||
+      this.getFieldRules()[index]['fieldRuleFieldRule'] != fieldRule ||
+      this.getFieldRules()[index]['fieldRuleSiteRule'] != siteRule)) {
+      // Update the formFieldRule on the given index:
+      this.getFieldRules()[index]['fieldRuleName'] = ruleName;
+      this.getFieldRules()[index]['fieldRuleValue'] = ruleValue;
+      this.getFieldRules()[index]['fieldRuleFieldRule'] = fieldRule;
+      this.getFieldRules()[index]['fieldRuleSiteRule'] = siteRule;
+
+      // Notify the tree:
+      this.treeBox.invalidateRow(index);
+
+      // Update the preferences:
+      this.setFieldRules();
+
+      // Update the related row of the simple interface:
+      this.updateSimpleInterfaceRow(index);
+    }
+  },
+
+  applyFieldRule: function(event) {
+    // Only apply changes if one item is selected:
+    if(this.selection.count == 1) {
+      // Update the selected formFieldRule:
+      this.applyFieldRuleOnIndex(this.selection.currentIndex);
+    }
+  },
+
+  addFieldRule: function(event) {
+    // See method selectedFieldRule() why this has to be set to null:
+    this.lastSelectedIndex = null;
+
+    // Check the regular expressions:
+    try {
+      var fieldRuleFieldRuleTextBox = document.getElementById('fieldRuleFieldRuleTextBox');
+      var fieldRule = this.getRegExpStr(
+        this.makeSafe(fieldRuleFieldRuleTextBox.value)
+      );
+      fieldRuleFieldRuleTextBox.value = fieldRule;
+
+      var fieldRuleSiteRuleTextBox = document.getElementById('fieldRuleSiteRuleTextBox');
+      var siteRule = this.getRegExpStr(
+        this.makeSafe(fieldRuleSiteRuleTextBox.value)
+      );
+      fieldRuleSiteRuleTextBox.value = siteRule;
+    } catch(e) {
+      this.invalidRegExpAlert(e);
+      return;
+    }
+
+    var newFieldRule =   this.createFieldRule(
+      this.makeSafe(document.getElementById('fieldRuleNameTextBox').value),
+      this.makeSafe(document.getElementById('fieldRuleValueTextBox').value),
+      fieldRule,
+      siteRule,
+      true,
+      true
+    )
+
+    var newFieldRuleIndex;
+
+    // Add the new formFieldRule right after the selected position or to the start of the list:
+    if(this.selection.currentIndex == -1 || this.selection.currentIndex == this.treeView.rowCount) {
+      this.getFieldRules().unshift(newFieldRule);
+      newFieldRuleIndex = 0;
+    } else {
+      newFieldRuleIndex = this.selection.currentIndex+1;
+      this.getFieldRules().splice(
+        newFieldRuleIndex,
+        0,
+        newFieldRule
+      );
+    }
+
+    // Update the tree count and notify the tree:
+    this.treeView.rowCount++;
+    this.treeBox.rowCountChanged(this.treeView.rowCount, +1);
+    this.treeBox.invalidate();
+
+    // Select the new item:
+    this.selection.select(newFieldRuleIndex);
+
+    // Ensure row is visible (scrolls if not):
+    this.treeBox.ensureRowIsVisible(newFieldRuleIndex);
+
+    // Update the preferences:
+    this.setFieldRules();
+
+    // Re-initialize the simple interface:
+    this.initSimpleInterface();
+  },
+
+  removeFieldRule: function(event) {
+    this.removeSelectedFieldRules();
+  },
+
+  moveUpFieldRule: function(event) {
+    // See method selectedFieldRule() why this has to be set to null:
+    this.lastSelectedIndex = null;
+
+    var index = this.selection.currentIndex;
+
+    // Change place with the next upper item:
+    var sibling = this.getFieldRules()[index-1];
+    this.getFieldRules()[index-1] = this.getFieldRules()[index];
+    this.getFieldRules()[index] = sibling;
+
+    // Keep moved item selected:
+    this.selection.select(index-1);
+
+    // Notify the tree:
+    this.treeBox.invalidate();
+
+    // Ensure row is visible (scrolls if not):
+    this.treeBox.ensureRowIsVisible(index-1);
+
+    // Update the preferences:
+    this.setFieldRules();
+
+    // Update the related rows of the simple interface:
+    this.updateSimpleInterfaceRow(index-1);
+    this.updateSimpleInterfaceRow(index);
+  },
+
+  moveDownFieldRule: function(event) {
+    // See method selectedFieldRule() why this has to be set to null:
+    this.lastSelectedIndex = null;
+
+    var index = this.selection.currentIndex;
+
+    // Change place with the next lower item:
+    var sibling = this.getFieldRules()[index+1];
+    this.getFieldRules()[index+1] = this.getFieldRules()[index];
+    this.getFieldRules()[index] = sibling;
+
+    // Keep moved item selected:
+    this.selection.select(index+1);
+
+    // Notify the tree:
+    this.treeBox.invalidate();
+
+    // Ensure row is visible (scrolls if not):
+    this.treeBox.ensureRowIsVisible(index+1);
+
+    // Update the preferences:
+    this.setFieldRules();
+
+    // Update the related rows of the simple interface:
+    this.updateSimpleInterfaceRow(index+1);
+    this.updateSimpleInterfaceRow(index);
+  },
+
+  removeSelectedFieldRules: function(event) {
+    // See method selectedFieldRule() why this has to be set to null:
+    this.lastSelectedIndex = null;
+
+    if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+      // Confirmation dialog:
+      if(!this.getPrompts().confirm(
+          null,
+          this.getStringBundle().getString('removeFieldRulesTitle'),
+          this.getStringBundle().getString('removeFieldRulesText')
+        )
+      ) {
+        return;
+      }
+    }
+
+    // Start of update batch:
+    this.treeBox.beginUpdateBatch();
+
+    // Helper object to store a range:
+    function Range(start, end) {
+      this.start = start.value;
+      this.end = end.value;
+    }
+
+    // List of ranges:
+    var ranges = new Array();
+
+    // Get the number of ranges:
+    var numRanges = this.selection.getRangeCount();
+
+    // Helper vars to store the range end points:
+    var start = new Object();
+    var end = new Object();
+
+    // We store the list of ranges first, as calling
+    // this.treeBox.rowCountChanged()
+    // seems to invalidate the current selection
+
+    for(var i=0; i < numRanges; i++) {
+      // Get the current range end points:
+      this.selection.getRangeAt(i,start,end);
+      // Store them as a Range object in the ranges list:
+      ranges[i] = new Range(start, end);
+    }
+
+    for(var i=0; i < numRanges; i++) {
+      // Go through the stored ranges:
+      for(var j = ranges[i].start; j <= ranges[i].end; j++) {
+        // Set the selected fieldRules to null:
+        this.getFieldRules()[j] = null;
+      }
+
+      // Calculate the new tree count:
+      var count = ranges[i].end - ranges[i].start + 1;
+
+      // Update the tree count and notify the tree:
+      this.treeView.rowCount -= count;
+      this.treeBox.rowCountChanged(ranges[i].start, -count);
+    }
+
+    // Collapse list by removing all the null entries
+    for (var i=0; i < this.getFieldRules().length; i++) {
+      if (!this.getFieldRules()[i]) {
+        var j = i;
+        while (j < this.getFieldRules().length && !this.getFieldRules()[j])
+          j++;
+        this.getFieldRules().splice(i, j-i);
+      }
+    }
+
+    // Clear out selections
+    this.selection.select(-1);
+
+    // End of update batch:
+    this.treeBox.endUpdateBatch();
+
+    // Update the preferences:
+    this.setFieldRules();
+
+    // Re-initialize the simple interface:
+    this.initSimpleInterface();
+  },
+
+  handleKeyPress: function(event) {
+    if(event.keyCode == 46) {
+      this.removeSelectedFieldRules();
+    } else if(event.ctrlKey && event.which == 97) {
+      if(this.tree && this.selection) {
+        try {
+          // Select all rows:
+          this.selection.selectAll();
+        } catch(e) {
+          this.log(e);
+        }
+      }
+    }
+  },
+
+  getGlobalFieldRules: function() {
+    // Return the fieldRules for the selected global profile if globalProfileIndex is not out of range:
+    if(this.getGlobalProfileIndex() >= 0 && this.getGlobalProfileIndex() < this.getProfileLabels().length) {
+      return this.getFieldRules(this.getGlobalProfileIndex());
+    } else {
+      this.globalProfileIndex = 0;
+      return this.getFieldRules(0);
+    }
+  },
+
+  getFileContent: function(file) {
+    var fileContent = null;
+    try {
+      var fis = Components.classes['@mozilla.org/network/file-input-stream;1']
+            .createInstance(Components.interfaces.nsIFileInputStream);
+      fis.init(file, -1, 0, 0);
+      var is = Components.classes['@mozilla.org/intl/converter-input-stream;1']
+            .createInstance(Components.interfaces.nsIConverterInputStream);
+      is.init(fis, 'UTF-8', 1024, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+      if(is instanceof Components.interfaces.nsIUnicharLineInputStream) {
+        var line = {};
+        var cont;
+        do {
+          cont = is.readLine(line);
+          if(fileContent == null) {
+            fileContent = line.value;
+          } else {
+            fileContent += '\n'+line.value;
+          }
+        } while (cont);
+      }
+      is.close();
+      fis.close();
+    } catch(e) {
+      this.log(e);
+    }
+    return fileContent;
+  },
+
+  setFileContent: function(file, str) {
+    try {
+      var fos = Components.classes['@mozilla.org/network/file-output-stream;1']
+            .createInstance(Components.interfaces.nsIFileOutputStream);
+      fos.init(file, 0x02 | 0x08 | 0x20, 0664, 0);
+      var os = Components.classes['@mozilla.org/intl/converter-output-stream;1']
+            .createInstance(Components.interfaces.nsIConverterOutputStream);
+      os.init(fos, 'UTF-8', 4096, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+      os.writeString(str);
+      os.close();
+      fos.close();
+    } catch(e) {
+      this.log(e);
+    }
+  },
+
+  getFieldRulesFile: function() {
+    var file = this.getConfigDirectory();
+    file.append('fieldRules.txt');
+    if(!file.exists()) {
+      file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
+    }
+    return file;
+  },
+
+  getConfigDirectory: function() {
+    var configDirectory;
+    if(this.autofillFormsPrefs.prefHasUserValue('configDirectory')) {
+      try {
+        configDirectory = this.autofillFormsPrefs.getComplexValue(
+                    'configDirectory',
+                    Components.interfaces.nsILocalFile
+        );
+      } catch(e) {
+        this.autofillFormsPrefs.clearUserPref('configDirectory');
+      }
+    }
+    if(!configDirectory) {
+      configDirectory = this.getDefaultConfigDirectory();
+    }
+    return configDirectory;
+  },
+
+  getDefaultConfigDirectory: function() {
+    // Use a directory "autofillForms at blueimp.net" inside Firefox profile directory as default:
+    var configDirectory = Components.classes['@mozilla.org/file/directory_service;1']
+                .getService(Components.interfaces.nsIProperties)
+                .get('ProfD', Components.interfaces.nsILocalFile);
+    configDirectory.append('autofillForms at blueimp.net');
+    if(!configDirectory.exists()) {
+       configDirectory.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0770);
+    }
+    return configDirectory;
+  },
+
+  setConfigDirectory: function(textBox) {
+    try {
+      // Create a file picker instance:
+      var fp = Components.classes['@mozilla.org/filepicker;1']
+            .createInstance(Components.interfaces.nsIFilePicker);
+
+      // Initialize the file picker window:
+      fp.init(
+        window,
+        this.getStringBundle().getString('selectConfigDirectory'),
+        Components.interfaces.nsIFilePicker.modeGetFolder
+      );
+
+      // Show the file picker window:
+      var rv = fp.show();
+
+      if (rv == Components.interfaces.nsIFilePicker.returnOK) {
+        var newDir = fp.file;
+        if(newDir.path == this.getConfigDirectory().path) {
+          return;
+        }
+        this.moveConfigFiles(newDir);
+        // Save the selected directory in the preferences:
+        this.autofillFormsPrefs.setComplexValue(
+          'configDirectory',
+          Components.interfaces.nsILocalFile, newDir
+        );
+        if(textBox) {
+          // Set the textbox value to the directory path:
+          textBox.value = newDir.path;
+        }
+      }
+    } catch(e) {
+      this.log(e);
+    }
+  },
+
+  resetConfigDirectory: function(textBox) {
+    if(this.autofillFormsPrefs.prefHasUserValue('configDirectory')) {
+      var newDir = this.getDefaultConfigDirectory();
+      this.moveConfigFiles(newDir);
+      this.autofillFormsPrefs.clearUserPref('configDirectory');
+      if(textBox) {
+        // Set the textbox value to an empty string:
+        textBox.value = '';
+      }
+    }
+  },
+
+  openConfigDirectory: function() {
+    var configDirectory = this.getConfigDirectory();
+    if(configDirectory) {
+      try {
+        // Open the config directory in the operating system file manager:
+        configDirectory.reveal();
+      } catch(e) {
+        // reveal method may not be supported on some platforms,
+        // use nsIExternalProtocolService instead:
+        var uri = Components.classes["@mozilla.org/network/io-service;1"]
+          .getService(Components.interfaces.nsIIOService)
+          .newFileURI(configDirectory);
+        var protocolSvc =
+        Components.classes["@mozilla.org/uriloader/external-protocol-service;1"]
+          .getService(Components.interfaces.nsIExternalProtocolService);
+        protocolSvc.loadUrl(uri);
+      }
+    }
+  },
+
+  moveConfigFiles: function(newDir) {
+    if(this.checkConfigDirectoryOverwrite(newDir)) {
+      this.moveFile(this.getFieldRulesFile(), newDir);
+      this.moveFile(this.getDynamicTagsFile(), newDir);
+      this.moveFile(this.getDynamicTagCodesFile(), newDir);
+      this.moveFile(this.getProfileLabelsFile(), newDir);
+      this.moveFile(this.getProfileSiteRulesFile(), newDir);
+      return true;
+    }
+    return false;
+  },
+
+  importFromConfigDirectory: function() {
+    var ok = true;
+    if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+      ok = this.getPrompts().confirm(
+        window,
+        this.getStringBundle().getString('importFromConfigDirectoryTitle'),
+        this.getStringBundle().getString('importFromConfigDirectoryText')
+      );
+    }
+    if(ok) {
+      this.importFieldRulesFromConfigDirectory();
+      this.importDynamicTagsFromConfigDirectory();
+      this.importDynamicTagCodesFromConfigDirectory();
+      this.importProfileLabelsFromConfigDirectory();
+      this.importProfileSiteRulesFromConfigDirectory();
+    }
+  },
+
+  exportToConfigDirectory: function() {
+    if(this.checkConfigDirectoryOverwrite(this.getConfigDirectory())) {
+      this.exportFieldRulesToConfigDirectory();
+      this.exportDynamicTagsToConfigDirectory();
+      this.exportDynamicTagCodesToConfigDirectory();
+      this.exportProfileLabelsToConfigDirectory();
+      this.exportProfileSiteRulesToConfigDirectory();
+      return true;
+    }
+    return false;
+  },
+
+  moveFile: function(file, newDir, newFileName) {
+    try {
+      // The new fileName - uses the current fileName if empty:
+      newFileName = (typeof newFileName == 'string') ? newFileName : null;
+
+      file.moveTo(newDir, newFileName);
+      return true;
+    } catch(e) {
+      this.log(e);
+      return false;
+    }
+  },
+
+  checkConfigDirectoryOverwrite: function(newDir) {
+    var ok = true;
+    if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+      if(newDir.directoryEntries.hasMoreElements()) {
+        ok = this.getPrompts().confirm(
+          window,
+          this.getStringBundle().getString('newConfigDirectoryNotEmptyTitle'),
+          this.getStringBundle().getString('newConfigDirectoryNotEmptyText')
+        );
+      }
+    }
+    return ok;
+  },
+
+  exportFieldRulesToConfigDirectory: function() {
+    var prefString;
+    // Get the fieldRules string from the preferences:
+    prefString = this.autofillFormsPrefs
+              .getComplexValue('fieldRules',Components.interfaces.nsIPrefLocalizedString)
+              .data;
+    if(prefString) {
+      this.setFileContent(this.getFieldRulesFile(), prefString);
+    }
+  },
+
+  importFieldRulesFromConfigDirectory: function() {
+    var prefString;
+    prefString = this.getFileContent(this.getFieldRulesFile());
+    if(prefString) {
+      // Store the fieldRules as unicode string in the preferences:
+      this.autofillFormsPrefs.setComplexValue(
+        'fieldRules',
+        Components.interfaces.nsISupportsString,
+        this.getUnicodeString(prefString)
+      );
+    }
+  },
+
+  getFieldRules: function(profileIndex) {
+    if(this.fieldRules == null) {
+      this.fieldRules = new Array();
+
+      var prefString;
+      if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+        // Get the fieldRules string from the fieldRules file in the configDirectory:
+        prefString = this.getFileContent(this.getFieldRulesFile());
+      }
+      if(!prefString) {
+        // Get the fieldRules string from the preferences:
+        prefString = this.autofillFormsPrefs
+                  .getComplexValue('fieldRules',Components.interfaces.nsIPrefLocalizedString)
+                  .data;
+      }
+
+      // On change of the "storeEncrypted" setting, we must decrypt or may not decrypt
+      // the prefString in opposition to the setting - the "invertedSetting" helper var
+      // helps to identify this situation:
+      var boolTest = this.invertedSetting ? false : true;
+
+      // If the fieldRules are stored encrypted, decrypt the prefString:
+      if(this.autofillFormsPrefs.getBoolPref('storeEncrypted') == boolTest) {
+        try {
+          // nsISecretDecoderRing fails to handle characters above ISO-8859-1 charset
+          // The usage of encodeURI/decodeURI on the fieldRule properties bypasses this problem
+          prefString = this.getCryptoService().decryptString(prefString);
+        } catch(e) {
+          // Decrypting failed - return an empty default profile:
+          this.fieldRules.push(new Array());
+          this.profileIndex = 0;
+          return this.fieldRules[0];
+        }
+      }
+
+      // Get the profiles (separated by \n\n):
+      var profiles = prefString.split('\n\n');
+
+      for(var i=0; i<profiles.length; i++) {
+        // Create an array for each profile:
+        this.fieldRules.push(new Array());
+
+        // Get the fieldRules rows (separated by \n):
+        var rows = profiles[i].split('\n');
+        if(rows[0]) {
+          for(var j=0; j<rows.length; j++) {
+            if(!rows[j])
+              continue;
+
+            // Get the fieldRules column items (separated by \t):
+            var cols = rows[j].split('\t');
+
+            // Create fieldRules objects and save them in the current fieldRules Array:
+            if(cols.length && cols.length == 6) {
+
+              // Decode the fieldRule properties:
+              for(var k=0; k<cols.length; k++) {
+                cols[k] = decodeURI(cols[k]);
+              }
+
+              this.fieldRules[i].push(
+                this.createFieldRule(
+                  cols[0],cols[1],cols[2],cols[3],
+                  (cols[4] != 'false'),
+                  (cols[5] != 'false')
+                )
+              );
+            }
+          }
+        } else
+          this.fieldRules[i] = new Array();
+      }
+    }
+
+    profileIndex = (typeof profileIndex != 'undefined') ? profileIndex : this.getProfileIndex();
+
+    // Return the fieldRules for the selected profile if profileIndex is not out of range:
+    if(profileIndex >= 0 && profileIndex < this.fieldRules.length)
+      return this.fieldRules[profileIndex];
+    else {
+      this.profileIndex = 0;
+      if(this.fieldRules[0] == null)
+        this.fieldRules[0] = new Array();
+      return this.fieldRules[0];
+    }
+  },
+
+  setFieldRules: function() {
+    if(this.fieldRules == null) {
+      // Initialize the field rules:
+      this.getFieldRules();
+    }
+
+    var profiles = '';
+    var rows, cols;
+    for(var i=0; i < this.fieldRules.length; i++) {
+      rows = '';
+      for(var j=0; j<this.fieldRules[i].length; j++) {
+        cols = null;
+        for(var property in this.fieldRules[i][j]) {
+          if(cols == null)
+            cols = '';
+          else
+            cols += '\t';
+          // Encode the fieldRule property before adding it to the string:
+          cols += encodeURI(this.fieldRules[i][j][property]);
+        }
+        if(j!=0)
+          rows += '\n';
+        rows += cols;
+      }
+      if(i!=0)
+        profiles += '\n\n';
+      profiles += rows;
+    }
+
+    // If the fieldRules are to be stored encrypted, encrypt the prefString:
+    if(this.autofillFormsPrefs.getBoolPref('storeEncrypted')) {
+      try {
+        // nsISecretDecoderRing fails to handle characters above ISO-8859-1 charset
+        // The usage of encodeURI/decodeURI on the fieldRule properties bypasses this problem
+        profiles = this.getCryptoService().encryptString(profiles);
+      } catch(e) {
+        // Decrypting failed - return:
+        return;
+      }
+    }
+
+    if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+      this.setFileContent(this.getFieldRulesFile(), profiles);
+    } else {
+      // Store the fieldRules objects as unicode string in the preferences:
+      this.autofillFormsPrefs.setComplexValue(
+        'fieldRules',
+        Components.interfaces.nsISupportsString,
+        this.getUnicodeString(profiles)
+      );
+    }
+  },
+
+  copyFieldRules: function(origin) {
+    var copy = new Array();
+    for(var i=0; i<origin.length; i++) {
+      copy.push(
+        this.createFieldRule(
+          origin[i]['fieldRuleName'],
+          origin[i]['fieldRuleValue'],
+          origin[i]['fieldRuleFieldRule'],
+          origin[i]['fieldRuleSiteRule'],
+          origin[i]['fieldRuleOverwrite'],
+          origin[i]['fieldRuleEnabled']
+        )
+      )
+    }
+    return copy;
+  },
+  importDynamicTagsFromSettings: function() {
+    //Here the tags are added directly
+    var prefString = null;
+
+    prefString = this.autofillFormsPrefs
+              .getComplexValue('dynamicTags',Components.interfaces.nsIPrefLocalizedString)
+              .data;
+    var dynamicTags = prefString.split('\t');
+
+    prefString = this.autofillFormsPrefs
+              .getComplexValue('dynamicTagCodes',Components.interfaces.nsIPrefLocalizedString)
+              .data;
+    var dynamicTagCodes = prefString.split('\t');
+
+    this.importDynamicTags(dynamicTags, dynamicTagCodes);
+    this.setDynamicTags(dynamicTags);
+    this.setDynamicTagCodes(dynamicTagCodes);
+  },
+  importDynamicTagsFromTagEditor: function() {
+    //Here the tags are added to the editor window, can be cancelled if necessary
+    var richlistbox = document.getElementById('tagList');
+    if(richlistbox) {
+      var richlistitems = richlistbox.getElementsByTagName('richlistitem');
+      var textboxes;
+
+      var dynamicTags = new Array();
+      var dynamicTagCodes = new Array();
+
+      // Go through the richlistbox items:
+      for(var i=0; i<richlistitems.length; i++) {
+        textboxes = richlistitems[i].getElementsByTagName('textbox');
+
+        // Add the dynamic tags and their associated tag codes to the lists:
+        if (textboxes[0].value != '' && textboxes[1].value != '') {
+          dynamicTags.push(this.makeSafe(textboxes[0].value));
+          dynamicTagCodes.push(this.makeSafe(textboxes[1].value));
+        }
+      }
+      this.importDynamicTags(dynamicTags, dynamicTagCodes);
+    }
+  },
+  importDynamicTags: function(dynamicTags, dynamicTagCodes) {
+    try {
+      var file = this.filePicker('modeOpen', this.getStringBundle().getString('importDynamicTags'));
+      if(file) {
+        var fis = Components.classes['@mozilla.org/network/file-input-stream;1']
+                .createInstance(Components.interfaces.nsIFileInputStream);
+        fis.init(file, -1, 0, 0);
+
+        var is = Components.classes['@mozilla.org/intl/converter-input-stream;1']
+              .createInstance(Components.interfaces.nsIConverterInputStream);
+        is.init(fis, 'UTF-8', 1024, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+        if (is instanceof Components.interfaces.nsIUnicharLineInputStream) {
+          var line = {};
+          var cont;
+          var firstLine = true;
+          var i;
+
+          do {
+            cont = is.readLine(line);
+
+            // Get the dynamicTags column items (separated by \t) from the file:
+            var cols = line.value.split('\t');
+
+            if (firstLine == true) {
+              // The first row has the following syntax (added in version 0.9.5):
+              // autofillForms at blueimp.net  Version  dynamictags
+              if(cols.length && cols.length != 3)
+                cont = false;
+              else if (cols[0] != 'autofillForms at blueimp.net')
+                cont = false;
+              else if (cols[2] != 'dynamictags')
+                cont = false;
+              firstLine = false;
+            }
+            else if (cols.length && cols.length == 2) {
+              //Check the imported pair isn't already defined or empty.
+              i = dynamicTags.indexOf(cols[0]);
+              if ((i >= 0 && dynamicTagCodes[i] == cols[1])||(cols[0]=='' && cols[1]=='')) {
+                continue;
+              } else {
+                dynamicTags.push(cols[0]);
+                dynamicTagCodes.push(cols[1]);
+                this.tagEditorAdd(cols[0],cols[1])
+              }
+            }
+          } while (cont);
+
+        }
+        is.close();
+        fis.close();
+      }
+    } catch(e) {
+      this.log(e);
+    }
+  },
+  exportDynamicTagsFromSettings: function() {
+    var prefString = null;
+
+    // Write the tags to file analog to storing them in the preferences:
+    prefString = this.autofillFormsPrefs
+              .getComplexValue('dynamicTagCodes',Components.interfaces.nsIPrefLocalizedString)
+              .data;
+    var dynamicTagCodes = prefString.split('\t');
+
+    prefString = this.autofillFormsPrefs
+              .getComplexValue('dynamicTags',Components.interfaces.nsIPrefLocalizedString)
+              .data;
+    var dynamicTags = prefString.split('\t');
+    this.exportDynamicTags(dynamicTags, dynamicTagCodes);
+  },
+  exportDynamicTagsFromTagEditor: function() {
+    var richlistbox = document.getElementById('tagList');
+    if(richlistbox) {
+      var richlistitems = richlistbox.getElementsByTagName('richlistitem');
+      var textboxes;
+
+      var dynamicTags = new Array();
+      var dynamicTagCodes = new Array();
+
+      // Go through the richlistbox items:
+      for(var i=0; i<richlistitems.length; i++) {
+        textboxes = richlistitems[i].getElementsByTagName('textbox');
+
+        // Add the dynamic tags and their associated tag codes to the lists:
+        if (textboxes[0].value != '' && textboxes[1].value != '') {
+          dynamicTags.push(this.makeSafe(textboxes[0].value));
+          dynamicTagCodes.push(this.makeSafe(textboxes[1].value));
+        }
+      }
+      this.exportDynamicTags(dynamicTags, dynamicTagCodes);
+    }
+  },
+  exportDynamicTags: function(dynamicTags, dynamicTagCodes) {
+    try {
+      var file = this.filePicker(
+        'modeSave',
+        this.getStringBundle().getString('exportDynamicTags'),
+        this.getProfileLabel(this.getProfileIndex())+'.txt'
+      );
+      if(file) {
+        var fos = Components.classes['@mozilla.org/network/file-output-stream;1'].
+                    createInstance(Components.interfaces.nsIFileOutputStream);
+        fos.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
+
+        var os = Components.classes['@mozilla.org/intl/converter-output-stream;1']
+              .createInstance(Components.interfaces.nsIConverterOutputStream);
+        os.init(fos, 'UTF-8', 4096, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+
+        var header = 'autofillForms at blueimp.net' + '\t'
+                + this.version + '\t'
+                + 'dynamictags\n';
+        os.writeString(header);
+
+        var cols;
+        for(var i=0; i<dynamicTags.length; i++) {
+          cols = dynamicTags[i]+'\t'+dynamicTagCodes[i];
+          os.writeString('\n' + cols);
+        }
+        os.close();
+        fos.close();
+      }
+    } catch(e) {
+      this.log(e);
+    }
+  },
+  importProfile: function() {
+    try {
+      var file = this.filePicker('modeOpen', this.getStringBundle().getString('importProfile'));
+      if(file) {
+        var fis = Components.classes['@mozilla.org/network/file-input-stream;1']
+                .createInstance(Components.interfaces.nsIFileInputStream);
+        fis.init(file, -1, 0, 0);
+
+        var is = Components.classes['@mozilla.org/intl/converter-input-stream;1']
+              .createInstance(Components.interfaces.nsIConverterInputStream);
+        is.init(fis, 'UTF-8', 1024, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+        if(this.fieldRules == null) {
+          // Initialize the field rules:
+          this.getFieldRules();
+        }
+
+        // Create a new fieldRule profile (index is incremented when a valid header is found):
+        var newProfileLabel = '';
+        var newProfileSiteRule = '(?:)';
+        var newProfileIndex = this.fieldRules.length-1;
+        var validProfile = false;
+
+        if (is instanceof Components.interfaces.nsIUnicharLineInputStream) {
+          var line = {};
+          var cont;
+          do {
+            cont = is.readLine(line);
+
+            // Get the fieldRules column items (separated by \t) from the file:
+            var cols = line.value.split('\t');
+
+            if(cols.length && cols.length < 6 && cols[0] == 'autofillForms at blueimp.net') {
+              // The first row has the following syntax (added SiteRule for version 0.9.1):
+              // autofillForms at blueimp.net  Version  Label  SiteRule
+              // Every time such a row is encountered, a new profile is generated.
+              if(cols.length >= 3) {
+                newProfileLabel = cols[2];
+                // Add profile label for default empty profile:
+                if(this.getProfileLabels().length == 0) {
+                  this.getProfileLabels().push(this.getUniqueProfileLabel());
+                }
+                // Add the newProfileLabel to the profileLabels list (make sure it is unique):
+                this.getProfileLabels().push(this.getUniqueProfileLabel(newProfileLabel));
+              }
+              if(cols.length >= 4) {
+                try {
+                  newProfileSiteRule = this.getRegExpStr(cols[3]);
+                  // Add a new profileSiteRule:
+                  this.getProfileSiteRules().push(newProfileSiteRule);
+                } catch(e) {
+                  // Catch missing or invalid site rule
+                }
+              }
+              // Increment the ProfileIndex
+              newProfileIndex += 1;
+              this.fieldRules.push(new Array());
+              validProfile = true;
+            } else if(cols.length && cols.length == 6 && validProfile == true) {
+              // Create fieldRules objects and save them in the fieldRules Array:
+              this.fieldRules[newProfileIndex].push(
+                this.createFieldRule(
+                  cols[0],cols[1],cols[2],cols[3],
+                  (cols[4] != 'false'),
+                  (cols[5] != 'false')
+                )
+              );
+            }
+
+          } while (cont);
+        }
+
+        // Save the profileLabels list in the preferences:
+        this.setProfileLabels(this.getProfileLabels());
+        // Save the profileSiteRules in the preferences:
+        this.setProfileSiteRules(this.getProfileSiteRules());
+        // Update the profiles lists:
+        this.initProfilesLists();
+
+        // Update the fieldRules:
+        this.setFieldRules();
+
+        is.close();
+        fis.close();
+      }
+    } catch(e) {
+      this.log(e);
+    }
+  },
+  exportProfile: function() {
+    try {
+      var file = this.filePicker(
+        'modeSave',
+        this.getStringBundle().getString('exportProfile'),
+        this.getProfileLabel(this.getProfileIndex())+'.txt'
+      );
+      if(file) {
+        var fos = Components.classes['@mozilla.org/network/file-output-stream;1'].
+                    createInstance(Components.interfaces.nsIFileOutputStream);
+        fos.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
+
+        var os = Components.classes['@mozilla.org/intl/converter-output-stream;1']
+              .createInstance(Components.interfaces.nsIConverterOutputStream);
+        os.init(fos, 'UTF-8', 4096, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+        var profileIndex = this.getProfileIndex();
+        this.writeProfile(os, profileIndex);
+
+        os.close();
+        fos.close();
+      }
+    } catch(e) {
+      this.log(e);
+    }
+  },
+  exportAllProfiles: function() {
+    try {
+      //use the first profile label as the filename
+      var file = this.filePicker(
+        'modeSave',
+        this.getStringBundle().getString('exportProfile'),
+        this.getProfileLabel(0)+'.txt'
+      );
+      if(file) {
+        var fos = Components.classes['@mozilla.org/network/file-output-stream;1'].
+                    createInstance(Components.interfaces.nsIFileOutputStream);
+        fos.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
+
+        var os = Components.classes['@mozilla.org/intl/converter-output-stream;1']
+              .createInstance(Components.interfaces.nsIConverterOutputStream);
+
+        os.init(fos, 'UTF-8', 4096, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+        for(var i=0; i<this.getProfileLabels().length; i++) {
+          this.writeProfile(os, i);
+          os.writeString('\n\n');
+        }
+        os.close();
+        fos.close();
+      }
+    } catch(e) {
+      this.log(e);
+    }
+  },
+  writeProfile: function(os, profileIndex) {
+    try {
+      var header = 'autofillForms at blueimp.net' + '\t'
+            + this.version + '\t'
+            + this.getProfileLabel(profileIndex) + '\t'
+            + this.getProfileSiteRule(profileIndex) + '\n';
+
+
+      os.writeString(header);
+      // Write the rules to file analog to storing them in the preferences:
+      var cols;
+      for(var i=0; i<this.getFieldRules(profileIndex).length; i++) {
+        cols = null;
+        for(var property in this.getFieldRules(profileIndex)[i]) {
+          if(cols == null)
+            cols = '';
+          else
+            cols += '\t';
+          cols += this.getFieldRules(profileIndex)[i][property];
+        }
+        os.writeString('\n' + cols);
+      }
+    } catch(e) {
+      this.log(e);
+    }
+  },
+  filePicker: function(mode, title, fileName) {
+    try {
+      // Create a file picker instance:
+      var fp = Components.classes['@mozilla.org/filepicker;1']
+            .createInstance(Components.interfaces.nsIFilePicker);
+
+      // The filename suggested to the user as a default:
+      if(fileName) {
+        fp.defaultString = fileName;
+      }
+
+      // Initialize the file picker window:
+      fp.init(
+        window,
+        title,
+        Components.interfaces.nsIFilePicker[mode]
+      );
+
+      // Show the file picker window:
+      var rv = fp.show();
+
+      if(rv==Components.interfaces.nsIFilePicker.returnOK || rv==Components.interfaces.nsIFilePicker.returnReplace)
+        return fp.file;
+      else
+        return null;
+    } catch(e) {
+      return null;
+    }
+  },
+
+  getUnicodeString: function(stringData) {
+    // Create an Unicode String:
+    var str = Components.classes['@mozilla.org/supports-string;1']
+          .createInstance(Components.interfaces.nsISupportsString);
+    // Set the String value:
+    str.data = stringData;
+    // Return the Unicode String:
+    return str;
+  },
+
+  getStringBundle: function() {
+    return document.getElementById('autofillFormsStringBundle');
+  },
+
+  getDoc: function(win) {
+    if(win)
+      return win.document;
+    else if(content)
+      return content.document;
+    else
+      return this.getBrowser().contentDocument;
+  },
+
+  getWin: function() {
+    if(content)
+      return content;
+    else
+      return this.getBrowser().contentWindow;
+  },
+
+  getBrowser: function() {
+    try {
+      return gBrowser;
+    } catch(e) {
+      // gBrowser is not available, so make use of the WindowMediator service instead:
+      return this.getWindowMediator().getMostRecentWindow('navigator:browser').getBrowser();
+    }
+  },
+
+  getWindowMediator: function() {
+    return Components.classes['@mozilla.org/appshell/window-mediator;1']
+        .getService(Components.interfaces.nsIWindowMediator);
+  },
+
+  getRegExpStr: function(str) {
+    // Create a RegExp object using the given String:
+    var regExpStr = new RegExp(str).toString();
+    // Return the String representation without the surrounding slashes:
+    return regExpStr.substr(1,regExpStr.length-2);
+  },
+
+  getPrefManager: function() {
+    return Components.classes['@mozilla.org/preferences-service;1']
+        .getService(Components.interfaces.nsIPrefService);
+  },
+
+  getCryptoService: function() {
+    return Components.classes['@mozilla.org/security/sdr;1']
+        .createInstance(Components.interfaces.nsISecretDecoderRing);
+  },
+
+  getPrompts: function() {
+    return Components.classes['@mozilla.org/embedcomp/prompt-service;1']
+        .getService(Components.interfaces.nsIPromptService);
+  },
+
+  recognizeMouseButton: function(event) {
+    var modifiers = new Array();
+
+    // Get the modifiers:
+    if(event.altKey) modifiers.push('alt');
+    if(event.ctrlKey) modifiers.push('control');
+    if(event.metaKey) modifiers.push('meta');
+    if(event.shiftKey) modifiers.push('shift');
+
+    // Return a mouseButtonObj:
+    return this.mouseButtonFactory(modifiers, 'mousebutton'+event.button);
+  },
+
+  mouseButtonFactory: function(modifiers, mouseButton) {
+    if(typeof arguments.callee.mouseButtonObj == 'undefined') {
+      arguments.callee.mouseButtonObj = function(modifiers, mouseButton) {
+        this.modifiers = modifiers ? modifiers : new Array();
+        this.mouseButton = mouseButton;
+        this.toString = function() {
+          if(this.modifiers.length) {
+            return this.modifiers.join('+')+'+'+this.mouseButton;
+          } else {
+            return this.mouseButton;
+          }
+        }
+        this.equals = function(mouseButtonObj) {
+          if(this.mouseButton != mouseButtonObj.mouseButton) {
+            return false;
+          }
+          if(this.modifiers.length != mouseButtonObj.modifiers.length) {
+            return false;
+          }
+          for(var i=0; i<this.modifiers.length; i++) {
+            if(this.modifiers[i] != mouseButtonObj.modifiers[i]) {
+              return false;
+            }
+          }
+          return true;
+        }
+        return this;
+      }
+    }
+    return new arguments.callee.mouseButtonObj(modifiers, mouseButton);
+  },
+
+  getFormattedMouseButton: function(mouseButtonObj) {
+    var formattedMouseButton = '';
+    if(!mouseButtonObj.mouseButton) {
+      return formattedMouseButton;
+    }
+    // Add the modifiers:
+    for(var i=0; i < mouseButtonObj.modifiers.length; i++) {
+      try {
+        formattedMouseButton += this.getStringBundle().getString(mouseButtonObj.modifiers[i])+'+';
+      } catch(e) {
+        this.log(e);
+        // Error in shortcut string, return empty String:
+        return '';
+      }
+    }
+    try {
+      formattedMouseButton += this.getStringBundle().getString(mouseButtonObj.mouseButton);
+    } catch(e) {
+      // No localization for this mouse button, add generic button string :
+      formattedMouseButton += this.getStringBundle().getString('mousebutton');
+      // Add the index of the given mouseButton:
+      formattedMouseButton += ' '+mouseButtonObj.mouseButton.substr('mousebutton'.length);
+    }
+    return formattedMouseButton;
+  },
+
+  applyMouseButton: function(event, id) {
+    // Recognize the mouse button event:
+    var mouseButtonObj = this.recognizeMouseButton(event);
+    if(!mouseButtonObj)
+      return;
+    // Ignore the right mouse button (mousebutton2), as this already invokes the context menu:
+    if(mouseButtonObj.mouseButton == 'mousebutton2') {
+      return;
+    }
+    // Save the new mouse button object:
+    this.setMouseButton(id, mouseButtonObj);
+    // Update the mouse button textbox:
+    if(event.view.document && event.view.document.getElementById(id)) {
+      event.view.document.getElementById(id).value = this.getFormattedMouseButton(mouseButtonObj);
+    }
+  },
+
+  disableMouseButton: function(event, id) {
+    // Disable the mouse button:
+    this.setMouseButton(id, null);
+    // Update the mouse button textbox:
+    if(event.view.document && event.view.document.getElementById(id)) {
+      event.view.document.getElementById(id).value = '';
+    }
+  },
+
+  getMouseButton: function(id) {
+    if(this.mouseButton == null) {
+      // Create a new mouseButton container object:
+      this.mouseButton = new Object();
+    }
+    if(this.mouseButton[id] == null) {
+      var mouseButtonItems = this.autofillFormsPrefs.getCharPref(id).split('+');
+      var mouseButton;
+      if(mouseButtonItems.length == 0) {
+        mouseButton = '';
+      } else {
+        // Remove the last element and save it as mouseButton
+        // the remaining mouseButtonItems are the modifiers:
+        mouseButton = mouseButtonItems.pop();
+      }
+      // Create a new mouseButton object:
+      this.mouseButton[id] = this.mouseButtonFactory(mouseButtonItems, mouseButton);
+    }
+    return this.mouseButton[id];
+  },
+
+  setMouseButton: function(id, mouseButtonObj) {
+    var stringData;
+    if(mouseButtonObj) {
+      stringData = mouseButtonObj.toString();
+    } else {
+      stringData = '';
+    }
+    // Save the mouseButtonObj as Unicode String in the preferences:
+    this.autofillFormsPrefs.setComplexValue(
+      id,
+      Components.interfaces.nsISupportsString,
+      this.getUnicodeString(stringData)
+    );
+  },
+
+  recognizeKeys: function(event) {
+    var modifiers = new Array();
+    var key = '';
+    var keycode = '';
+
+    // Get the modifiers:
+    if(event.altKey) modifiers.push('alt');
+    if(event.ctrlKey) modifiers.push('control');
+    if(event.metaKey) modifiers.push('meta');
+    if(event.shiftKey) modifiers.push('shift');
+
+    // Get the key or keycode:
+    if(event.charCode) {
+      key = String.fromCharCode(event.charCode).toUpperCase();
+    } else {
+      // Get the keycode from the keycodes list:
+      keycode = this.getKeyCodes()[event.keyCode];
+      if(!keycode) {
+        return null;
+      }
+    }
+
+    // Shortcut may be anything, but not 'VK_TAB' alone (without modifiers),
+    // as this button is used to change focus to the 'Apply' button:
+    if(modifiers.length > 0 || keycode != 'VK_TAB') {
+      return this.shortcutFactory(modifiers, key, keycode);
+    }
+    return null;
+  },
+
+  shortcutFactory: function(modifiers, key, keycode) {
+    if(typeof arguments.callee.shortcut == 'undefined') {
+      arguments.callee.shortcut = function(modifiers, key, keycode) {
+        this.modifiers = modifiers ? modifiers : new Array();
+        this.key = key;
+        this.keycode = keycode;
+        this.toString = function() {
+          if(this.modifiers.length) {
+            return this.modifiers.join('+')+'+'+this.key+this.keycode;
+          } else {
+            return this.key+this.keycode;
+          }
+        }
+        this.equals = function(shortcut) {
+          if(this.key != shortcut.key) {
+            return false;
+          }
+          if(this.keycode != shortcut.keycode) {
+            return false;
+          }
+          if(this.modifiers.length != shortcut.modifiers.length) {
+            return false;
+          }
+          for(var i=0; i<this.modifiers.length; i++) {
+            if(this.modifiers[i] != shortcut.modifiers[i]) {
+              return false;
+            }
+          }
+          return true;
+        }
+        return this;
+      }
+    }
+    return new arguments.callee.shortcut(modifiers, key, keycode);
+  },
+
+  getKeyCodes: function() {
+    var keycodes = new Array();
+    // Get the list of keycodes from the KeyEvent object:
+    for(var property in KeyEvent) {
+      keycodes[KeyEvent[property]] = property.replace('DOM_','');
+    }
+    // VK_BACK_SPACE (index 8) must be VK_BACK:
+    keycodes[8] = 'VK_BACK';
+    return keycodes;
+  },
+
+  applyShortcut: function(event, id) {
+    // Recognize the pressed keys:
+    var shortcut = this.recognizeKeys(event)
+    if(!shortcut)
+      return;
+    // Save the new shortcut:
+    this.setShortcut(id, shortcut);
+    // Update the shortcut textbox:
+    if(event.view.document && event.view.document.getElementById(id)) {
+      event.view.document.getElementById(id).value = this.getFormattedShortcut(shortcut);
+    }
+  },
+
+  disableShortcut: function(event, id) {
+    // Disable the shortcut:
+    this.setShortcut(id, null);
+    // Update the shortcut textbox:
+    if(event.view.document && event.view.document.getElementById(id)) {
+      event.view.document.getElementById(id).value = '';
+    }
+  },
+
+  getShortcut: function(id) {
+    if(this.shortcut == null) {
+      // Create a new shortcut container object:
+      this.shortcut = new Object();
+    }
+    if(this.shortcut[id] == null) {
+      var key = null;
+      var keycode = null;
+      var shortcutItems = this.autofillFormsPrefs
+                .getComplexValue(id,Components.interfaces.nsIPrefLocalizedString)
+                .data.split('+');
+      if(shortcutItems.length > 0) {
+        // Remove the last element and save it as key
+        // the remaining shortcutItems are the modifiers:
+        key = shortcutItems.pop();
+        // Check if the key is a keycode:
+        if(key.indexOf('VK') == 0) {
+          keycode  = key;
+          key = null;
+        }
+      }
+      // Create a new shortcut object:
+      this.shortcut[id] = this.shortcutFactory(shortcutItems, key, keycode);
+    }
+    return this.shortcut[id];
+  },
+
+  setShortcut: function(id, shortcut) {
+    var stringData;
+    if(shortcut) {
+      stringData = shortcut.toString();
+    } else {
+      stringData = '';
+    }
+    // Save the shortcut as Unicode String in the preferences:
+    this.autofillFormsPrefs.setComplexValue(
+      id,
+      Components.interfaces.nsISupportsString,
+      this.getUnicodeString(stringData)
+    );
+  },
+
+  updateShortcut: function(id) {
+    if(this.shortcut == null) {
+      this.shortcut = new Object();
+    }
+    // Setting the shortcut object to "null" will update it on the next getShortcut() call:
+    this.shortcut[id] = null;
+
+    // Get the keyboard shortcut elements:
+    var modifiers = this.getShortcut(id).modifiers.join(' ');
+    var key = this.getShortcut(id).key;
+    var keycode = this.getShortcut(id).keycode;
+
+    var domId = 'autofillForms' + id.replace(/shortcut/, 'Shortcut');
+    var command = 'autofillForms' + id.replace(/shortcut/i, '');
+
+    // Remove current key if existing:
+    if(document.getElementById(domId)) {
+      document.getElementById('mainKeyset').removeChild(
+        document.getElementById(domId)
+      );
+    }
+
+    // Check if keyboard shortcut is enabled:
+    if(key || keycode) {
+      // Create a key element:
+      var keyNode = document.createElement('key');
+
+      keyNode.setAttribute('id', domId);
+      keyNode.setAttribute('command', command);
+
+      // Set the key attributes from saved shortcut:
+      keyNode.setAttribute('modifiers', modifiers);
+      if(key) {
+        keyNode.setAttribute('key', key);
+      } else {
+        keyNode.setAttribute('keycode', keycode);
+      }
+
+      // Add the key to the mainKeyset:
+      document.getElementById('mainKeyset').appendChild(keyNode);
+    }
+  },
+
+  getFormattedShortcut: function(shortcut) {
+    var formattedShortcut = '';
+    // Add the modifiers:
+    for(var i=0; i < shortcut.modifiers.length; i++) {
+      try {
+        formattedShortcut += this.getStringBundle().getString(shortcut.modifiers[i]) + '+';
+      } catch(e) {
+        // Error in shortcut string, return empty String;
+        return '';
+      }
+    }
+    if(shortcut.key) {
+      // Add the key:
+      if(shortcut.key == ' ') {
+        formattedShortcut += this.getStringBundle().getString('VK_SPACE');
+      } else {
+        formattedShortcut += shortcut.key;
+      }
+    } else if(shortcut.keycode) {
+      // Add the keycode (instead of the key):
+      try {
+        formattedShortcut += this.getStringBundle().getString(shortcut.keycode);
+      } catch(e) {
+        formattedShortcut += shortcut.keycode.replace('VK_', '');
+      }
+    }
+    return formattedShortcut;
+  },
+
+  replaceDynamicTags: function(fieldRuleValue) {
+    // Replace all dynamic tags with the return values of their associated tag codes:
+    for(var j=0; j<this.getDynamicTags().length; j++) {
+      // Catch if the number of tags doesn't match the number of tag codes or if the tag code is invalid:
+      try {
+        var regExpObj = new RegExp(this.getDynamicTags()[j],'g');
+        // We use eval() here without restrictions - the given tagCode must be trusted:
+        fieldRuleValue = fieldRuleValue.replace(regExpObj, eval(this.getDynamicTagCodes()[j]));
+      } catch(e) {
+        this.log(e);
+      }
+    }
+    return fieldRuleValue;
+  },
+
+  getDynamicTagsFile: function() {
+    var file = this.getConfigDirectory();
+    file.append('dynamicTags.txt');
+    if(!file.exists()) {
+      file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
+    }
+    return file;
+  },
+
+  exportDynamicTagsToConfigDirectory: function() {
+    var prefString;
+    // Get the dynamicTags string from the preferences:
+    prefString = this.autofillFormsPrefs
+              .getComplexValue('dynamicTags',Components.interfaces.nsIPrefLocalizedString)
+              .data;
+    if(prefString) {
+      this.setFileContent(this.getDynamicTagsFile(), prefString);
+    }
+  },
+
+  importDynamicTagsFromConfigDirectory: function() {
+    var prefString;
+    prefString = this.getFileContent(this.getDynamicTagsFile());
+    if(prefString) {
+      // Store the dynamicTags as unicode string in the preferences:
+      this.autofillFormsPrefs.setComplexValue(
+        'dynamicTags',
+        Components.interfaces.nsISupportsString,
+        this.getUnicodeString(prefString)
+      );
+    }
+  },
+
+  getDynamicTags: function() {
+    if(this.dynamicTags == null) {
+      var prefString;
+      if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+        // Get the dynamicTags string from the dynamicTags file in the configDirectory:
+        prefString = this.getFileContent(this.getDynamicTagsFile());
+      }
+      if(!prefString) {
+        prefString = this.autofillFormsPrefs
+                  .getComplexValue('dynamicTags',Components.interfaces.nsIPrefLocalizedString)
+                  .data;
+      }
+      this.dynamicTags = prefString.split('\t');
+    }
+    return this.dynamicTags;
+  },
+
+  setDynamicTags: function(dynamicTags) {
+    // Save the dynamic tags separated by tabs:
+    var prefString = dynamicTags.join('\t');
+    if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+      this.setFileContent(this.getDynamicTagsFile(), prefString);
+    } else {
+      this.autofillFormsPrefs.setComplexValue(
+        'dynamicTags',
+        Components.interfaces.nsISupportsString,
+        this.getUnicodeString(prefString)
+      );
+    }
+  },
+
+  getDynamicTagCodesFile: function() {
+    var file = this.getConfigDirectory();
+    file.append('dynamicTagCodes.txt');
+    if(!file.exists()) {
+      file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
+    }
+    return file;
+  },
+
+  exportDynamicTagCodesToConfigDirectory: function() {
+    var prefString;
+    // Get the dynamicTagCodes string from the preferences:
+    prefString = this.autofillFormsPrefs
+              .getComplexValue('dynamicTagCodes',Components.interfaces.nsIPrefLocalizedString)
+              .data;
+    if(prefString) {
+      this.setFileContent(this.getDynamicTagCodesFile(), prefString);
+    }
+  },
+
+  importDynamicTagCodesFromConfigDirectory: function() {
+    var prefString;
+    prefString = this.getFileContent(this.getDynamicTagCodesFile());
+    if(prefString) {
+      // Store the dynamicTagCodes as unicode string in the preferences:
+      this.autofillFormsPrefs.setComplexValue(
+        'dynamicTagCodes',
+        Components.interfaces.nsISupportsString,
+        this.getUnicodeString(prefString)
+      );
+    }
+  },
+
+  getDynamicTagCodes: function() {
+    if(this.dynamicTagCodes == null) {
+      var prefString;
+      if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+        // Get the dynamicTagCodes string from the dynamicTagCodes file in the configDirectory:
+        prefString = this.getFileContent(this.getDynamicTagCodesFile());
+      }
+      if(!prefString) {
+        prefString = this.autofillFormsPrefs
+                  .getComplexValue('dynamicTagCodes',Components.interfaces.nsIPrefLocalizedString)
+                  .data;
+      }
+      this.dynamicTagCodes = prefString.split('\t');
+    }
+    return this.dynamicTagCodes;
+  },
+
+  setDynamicTagCodes: function(dynamicTagCodes) {
+    // Save the dynamic tag codes separated by tabs:
+    var prefString = dynamicTagCodes.join('\t');
+    if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+      this.setFileContent(this.getDynamicTagCodesFile(), prefString);
+    } else {
+      this.autofillFormsPrefs.setComplexValue(
+      'dynamicTagCodes',
+        Components.interfaces.nsISupportsString,
+        this.getUnicodeString(prefString)
+      );
+    }
+  },
+
+  optionsInitialize: function() {
+    // Save the reference to the Autofill Forms preferences branch:
+    this.autofillFormsPrefs = this.getPrefManager().getBranch('extensions.autofillForms at blueimp.net.');
+
+    // Initialize the profile lists:
+    this.initProfilesLists();
+    // Initialize the fieldRules tree:
+    this.initTree();
+    // Initialize the simple interface:
+    this.initSimpleInterface();
+
+    // Sort is to be ascending if clicked first:
+    this.ascending = true;
+    this.profilesAscending = true;
+
+    var configDirectoryTextbox = document.getElementById('configDirectoryTextBox');
+    if(configDirectoryTextbox && this.autofillFormsPrefs.prefHasUserValue('configDirectory')) {
+      var configDirectory = this.getConfigDirectory();
+      if(configDirectory) {
+        configDirectoryTextbox.value = configDirectory.path;
+      }
+    }
+
+    // Initialize the keyboard shortcut objects:
+    this.shortcut = new Object();
+    this.shortcut['shortcut'] = null;
+    this.shortcut['shortcutSubmit'] = null;
+    this.shortcut['shortcutAllTabs'] = null;
+    this.shortcut['shortcutFromProfileSelection'] = null;
+    this.shortcut['shortcutProfile'] = null;
+    this.shortcut['shortcutSettings'] = null;
+    this.shortcut['shortcutDisplayFormDetails'] = null;
+
+    // Display the shortcut combinations:
+    for(var property in this.shortcut) {
+      if(document.getElementById(property)) {
+        document.getElementById(property).value = this.getFormattedShortcut(this.getShortcut(property));
+      }
+    }
+
+    // Initialize the mouse button objects:
+    this.mouseButton = new Object();
+    this.mouseButton['mouseShortcut'] = null;
+    this.mouseButton['mouseShortcutSubmit'] = null;
+    this.mouseButton['mouseShortcutAllTabs'] = null;
+    this.mouseButton['mouseShortcutFromProfileSelection'] = null;
+    this.mouseButton['mouseShortcutProfile'] = null;
+    this.mouseButton['mouseShortcutSettings'] = null;
+    this.mouseButton['mouseShortcutDisplayFormDetails'] = null;
+
+    // Display the mouse button combinations:
+    for(var property in this.mouseButton) {
+      if(document.getElementById(property)) {
+        document.getElementById(property).value = this.getFormattedMouseButton(this.getMouseButton(property));
+      }
+    }
+
+    // Parse the window params (e.g. initializing the target form field values):
+    this.parseOptionsWindowParams();
+  },
+  
+  initSimpleInterface: function() {
+    var rows = document.getElementById('simpleInterfaceRows');
+    if(rows) {
+      while(rows.hasChildNodes()) {
+        rows.removeChild(rows.firstChild);
+      }
+      for(var i=0; i<this.getFieldRules().length; i++) {
+        // Only show enabled fieldRules:
+        if(!this.getFieldRules()[i]['fieldRuleEnabled']) {
+          continue;
+        }
+        rows.appendChild(
+          this.getSimpleInterfaceRow(
+            i,
+            this.getFieldRules()[i]['fieldRuleName'],
+            this.getFieldRules()[i]['fieldRuleValue']
+          )
+        );
+      }
+    }
+  },
+
+  addSimpleInterfaceRow: function(index) {
+    var row = this.getSimpleInterfaceRow(
+            index,
+            this.getFieldRules()[index]['fieldRuleName'],
+            this.getFieldRules()[index]['fieldRuleValue']
+          )
+    var rows = document.getElementById('simpleInterfaceRows');
+    if(rows) {
+      var nextSibling;
+      if(rows.childNodes) {
+        for(var i=index+1; i<rows.childNodes.length; i++) {
+          nextSibling = document.getElementById('simpleInterfaceRow_'+i);
+          if(nextSibling) {
+            rows.insertBefore(row, nextSibling);
+            break;
+          }
+        }
+      }
+      if(!nextSibling) {
+        rows.appendChild(row);
+      }
+    }
+  },
+
+  removeSimpleInterfaceRow: function(index) {
+    var row = document.getElementById('simpleInterfaceRow_'+index);
+    if(row) {
+      row.parentNode.removeChild(row);
+    }
+  },
+
+  getSimpleInterfaceRow: function(index, name, value) {
+    if(!arguments.callee.row) {
+      arguments.callee.row = document.createElement('row');
+      arguments.callee.row.setAttribute('align', 'center');
+      var label = document.createElement('label');
+      var textbox = document.createElement('textbox');
+      textbox.setAttribute('newlines', 'pasteintact');
+      arguments.callee.row.appendChild(label);
+      arguments.callee.row.appendChild(textbox);
+    }
+    var row = arguments.callee.row.cloneNode(true);
+    row.setAttribute('id', 'simpleInterfaceRow_'+index);
+    row.firstChild.setAttribute('value', name+':');
+    row.firstChild.setAttribute('id', 'simpleInterfaceLabel_'+index);
+    row.firstChild.setAttribute('control', 'simpleInterfaceTextbox_'+index);
+    row.lastChild.setAttribute('id', 'simpleInterfaceTextbox_'+index);
+    row.lastChild.setAttribute('value', value);
+    row.lastChild.addEventListener('change', function (){
+      autofillForms.applySimpleInterfaceValue(this);
+    }, false);
+    row.lastChild.addEventListener('input', function () {
+      this.value = autofillForms.replaceControlCharacters(this.value);
+    }, false);
+    
+    // Is textbox a password field?
+    if(this.getRegExpPasswordLabel().test(name)) {
+      row.lastChild.setAttribute('type', 'password');
+    }
+    return row;
+  },
+
+  applySimpleInterfaceValue: function(textBox) {
+    // See method selectedFieldRule() why this has to be set to null:
+    this.lastSelectedIndex = null;
+
+    var index = parseInt(textBox.getAttribute('id').split('_')[1]);
+    this.getFieldRules()[index]['fieldRuleValue'] = this.makeSafe(textBox.value);
+
+    // Notify the tree (of the advanced interface):
+    try {
+      this.treeBox.invalidateRow(index);
+    } catch(e) {
+    }
+
+    // Update the preferences:
+    this.setFieldRules();
+  },
+
+  updateSimpleInterfaceRow: function(index) {
+    var row = document.getElementById('simpleInterfaceRow_'+index);
+    if(row) {
+      row.firstChild.value = this.getFieldRules()[index]['fieldRuleName']+':';
+      row.lastChild.value = this.getFieldRules()[index]['fieldRuleValue'];
+      // Is textbox a password field?
+      if(this.getRegExpPasswordLabel().test(this.getFieldRules()[index]['fieldRuleName'])) {
+        row.lastChild.setAttribute('type', 'password');
+      } else {
+        row.lastChild.removeAttribute('type');
+      }
+    }
+  },
+
+  getFieldRuleNameForElement: function(element) {
+    // Use the form field label as name if available:
+    var labelValue = this.getLabelForElement(element);
+    // Remove the colon, if present:
+    if(labelValue && labelValue.charAt(labelValue.length-1) == ':') {
+      labelValue = labelValue.substr(0, labelValue.length-1);
+    }
+    // If no label could be found, use the name or the id with the first character in upper case:
+    if(!labelValue) {
+      labelValue = element.name;
+      if(!labelValue) {
+        labelValue = element.id;
+      }
+      if(labelValue) {
+        labelValue = labelValue.charAt(0).toUpperCase() + labelValue.substr(1);
+      }
+    }
+    return labelValue;
+  },
+
+  getRegExpStrForValue: function(value) {
+    try {
+      // Remove unsave characters, escape regexp characters and return the regexp string:
+      return this.getRegExpStr('(?:^'+this.escapeRegExp(this.makeSafe(value))+'$)');
+    } catch(e) {
+      // If an error occurs, return the safe value string.
+      // If using it as regular expression fails a simple string comparison is used:
+      return this.makeSafe(value);
+    }
+  },
+
+  getFieldRuleForElement: function(element) {
+    var name = element.name;
+    // If no name is available use the label as fallback:
+    if(!name) {
+      name = this.getLabelForElement(element);
+    }
+    // If no name and no label is available use the id as fallback:
+    if(!name) {
+      name = element.id;
+    }
+    try {
+      // Remove unsave characters, escape regexp characters and return the regexp string:
+      return this.getRegExpStr('(?:^'+this.escapeRegExp(this.makeSafe(name))+'$)');
+    } catch(e) {
+      // If an error occurs, return an always matching regexp string:
+      return '(?:)';
+    }
+  },
+
+  getSiteRuleForURL: function(url) {
+    try {
+      // Remove unsave characters, escape regexp characters and return the regexp string:
+      return this.getRegExpStr('(?:^'+this.escapeRegExp(this.makeSafe(url))+')');
+    } catch(e) {
+      // If an error occurs, return an always matching regexp string:
+      return '(?:)';
+    }
+  },
+
+  parseOptionsWindowParams: function() {
+    // Check the windows arguments:
+    if(window.arguments && window.arguments[0]) {
+      if(window.arguments[0].targetFormField) {
+        var formFieldObject = window.arguments[0].targetFormField;
+
+        var value;
+        switch(formFieldObject.type) {
+          case 'checkbox':
+          case 'radio':
+          case 'select-one':
+          case 'select-multiple':
+            value = this.getRegExpStrForValue(formFieldObject.value);
+            break;
+          default:
+            value = this.replaceControlCharacters(formFieldObject.value);
+            break;
+        }
+
+        var location = this.getDoc().location;
+
+        // Reset the targetFormField of the autofillForms object referenced by window.arguments[0]:
+        window.arguments[0].targetFormField = null;
+
+        // Set the textbox values using the form field properties and the current document location:
+        document.getElementById('fieldRuleNameTextBox').value
+          = this.getFieldRuleNameForElement(formFieldObject)
+          + (location.hostname ? ' - ' + location.hostname : '');
+        document.getElementById('fieldRuleValueTextBox').value = value;
+        document.getElementById('fieldRuleFieldRuleTextBox').value
+          = this.getFieldRuleForElement(formFieldObject);
+        document.getElementById('fieldRuleSiteRuleTextBox').value
+          = this.getSiteRuleForURL(location.protocol + '//' + location.host);
+
+        // Make sure the main pane is selected:
+        document.getElementById('autofillFormsPrefs').showPane(
+          document.getElementById('autofillFormsPrefPaneMain')
+        );
+
+        // Set the focus to the name field:
+        document.getElementById('fieldRuleNameTextBox').focus();
+      } else if(window.arguments[0].newProfileFromForm) {
+        // Make sure the main pane is selected:
+        document.getElementById('autofillFormsPrefs').showPane(
+          document.getElementById('autofillFormsPrefPaneMain')
+        );
+      }
+    }
+  },
+
+  optionsFinalize: function() {
+  },
+
+  showProfileSwitcher: function() {
+    if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
+      // Always retrieve the profile labels from file if useConfigDirectory is enabled:
+      this.profileLabels = null;
+    }
+    // The nsIPromptService select() method doesn't offer to set a preselection,
+    // so we switch the current profile label with the first item (which is selected by default):
+    var list;
+    var currentIndex = this.getProfileIndex();
+    if(currentIndex != 0) {
+      // Copy the profilLabels array (so we don't change the original):
+      list = new Array().concat(this.getProfileLabels());
+      // Switch the current profile label with the first item:
+      var tmp = list[0];
+      list[0] = list[currentIndex];
+      list[currentIndex] = tmp;
+    } else {
+      // Set the list to the profilLabels reference if it is not to be changed:
+      list = this.getProfileLabels();
+    }
+    var selected = {};
+    // Show the selection prompt:
+    var ok = this.getPrompts().select(
+      window,
+      this.getStringBundle().getString('profileSelectionWindowTitle'),
+      this.getStringBundle().getString('profileSelectionPrompt'),
+      list.length,
+      list,
+      selected
+    );
+    if(ok) {
+      // If nothing changed, return:
+      if(selected.value == 0)
+        return;
+      // If the currentIndex has been selected and is not 0, it is in fact the index 0:
+      if(currentIndex != 0 && selected.value == currentIndex)
+        selected.value = 0;
+      // Set the profile index to the selected one:
+      this.setProfileIndex(selected.value)
+    }
+  },
+
+  showDialog: function(url, params) {
+    if (this.currentDialogs == null) {
+      this.currentDialogs = new Object();
+    }
+
+    // Is the window already
+    var win = this.currentDialogs[url];
+    if (win == null || win.closed)
+    {
+      var paramObject = params ? params : this;
+      win = window.openDialog(
+        url,
+        '',
+        'chrome=yes,resizable=yes,toolbar=yes,centerscreen=yes,modal=no,dependent=no,dialog=no',
+        paramObject
+      );
+      
+      this.currentDialogs[url] = win;
+      return win;
+    } else {
+      win.focus();
+    }
+  },
+
+  inArray: function(array, item) {
+    var i = array.length;
+    while(i--)
+      if(array[i] === item)
+        return true;
+    return false;
+  },
+
+  displayFormDetails: function() {
+    this.searchAndDisplayFormDetails(this.getWin());
+  },
+
+  searchAndDisplayFormDetails: function(win) {
+    win = win ? win : this.getWin();
+
+    var doc = this.getDoc(win);
+
+    // Check if any web forms are available on the current window:
+    if(doc && doc.forms && doc.forms.length > 0) {
+
+       // Go through the forms:
+       for(var i = 0; i < doc.forms.length; i++) {
+
+        // The form elements list:
+        var elements = doc.forms[i].elements;
+
+        // Go through the form elements:
+        for(var j = 0; j < elements.length; j++) {
+          this.displayFormElementDetails(elements[j], j, i, doc);
+        }
+      }
+    }
+
+    // Recursive call for all subframes:
+    for(var f=0; f < win.frames.length; f++) {
+      this.searchAndDisplayFormDetails(win.frames[f]);
+    }
+  },
+
+  isValidFormField: function(element) {
+    // ignore disabled (and return false) only if 'ignore disabled fields' is ticked
+    if(element.disabled && this.autofillFormsPrefs.getBoolPref('ignoreDisabledFields')) {
+      return false;
+    }
+    if(!arguments.callee.regExpFormFieldType) {
+      arguments.callee.regExpFormFieldType = new RegExp(
+        this.autofillFormsPrefs.getCharPref('regExpFormFieldTypes')
+      );
+    }
+    return arguments.callee.regExpFormFieldType.test(element.type);
+  },
+
+  displayFormElementDetails: function(element, elementNumber, formNumber, doc) {
+    // Create a unique id for the form element:
+    var id = 'autofillForms-f' + formNumber + '-e' + elementNumber;
+
+    // Remove the form details node if already present
+    // (nodeType 1 is an element node):
+    if(element.nextSibling && element.nextSibling.nodeType == 1 && element.nextSibling.getAttribute('id') == id) {
+      element.parentNode.removeChild(element.nextSibling);
+      return;
+    }
+
+    // Only display valid form fields:
+    if(this.isValidFormField(element)) {
+      // Create a "span" node with element details:
+      var text;
+      // Display the element name if available, else the element id if available, else an empty name:
+      if(element.name || !element.id) {
+        text = 'name="' + element.name;
+      } else {
+        text = 'id="' + element.id;
+      }
+      // Display the element value:
+      text += '" value="' +  element.value + '"';
+      var span = doc.createElement('span');
+      span.setAttribute('id', id);
+      span.setAttribute('style', this.autofillFormsPrefs.getCharPref('formDetailsStyle'));
+      span.setAttribute('title', text);
+      span.appendChild(doc.createTextNode(text));
+
+      // Insert the form details node after the element:
+      if(element.nextSibling)
+        element.parentNode.insertBefore(span, element.nextSibling);
+      else
+        element.parentNode.appendChild(span);
+    }
+  },
+
+  ruleEditorInitialize: function() {
+    // Save the reference to the Autofill Forms preferences branch:
+    this.autofillFormsPrefs = this.getPrefManager().getBranch('extensions.autofillForms at blueimp.net.');
+
+    if(window.arguments && window.arguments[0] && window.arguments[0].attributes) {
+      this.currentRuleField = window.arguments[0];
+    }
+
+    // Initialize the ruleElementTypes:
+    this.ruleElementTypes = new Array();
+    this.ruleElementTypes.push('contains');
+    this.ruleElementTypes.push('beginsWith');
+    this.ruleElementTypes.push('endsWith');
+    this.ruleElementTypes.push('equals');
+
+    // If the rule editor is used to edit the site rule, add two predefined protocol rules:
+    if(this.currentRuleField && this.currentRuleField.id && this.currentRuleField.id.indexOf('SiteRule') != -1) {
+      this.ruleEditorAdd('beginsWith', 'http:\/\/');
+      this.ruleEditorAdd('beginsWith', 'https:\/\/');
+    } else {
+      this.ruleEditorAdd();
+    }
+  },
+
+  ruleEditorSave: function() {
+    if(document.getElementById('ruleElementsList')) {
+      var str = '';
+      var richlistbox = document.getElementById('ruleElementsList');
+      var richlistitems = richlistbox.getElementsByTagName('richlistitem');
+      var menulists,textboxes;
+
+      // Go through the richlistbox items:
+      for(var i=0; i<richlistitems.length; i++) {
+        // Link the conditions as disjunctions (OR-Relations);
+        if(str.length != 0)
+          str += '|';
+        menulists = richlistitems[i].getElementsByTagName('menulist');
+        textboxes = richlistitems[i].getElementsByTagName('textbox');
+
+        // Add the current condition to the string:
+        switch(menulists[0].selectedItem.value) {
+          case 'contains':
+            str += '(?:' + textboxes[0].value + ')';
+            break;
+          case 'beginsWith':
+            str += '(?:^' + textboxes[0].value + ')';
+            break;
+          case 'endsWith':
+            str += '(?:' + textboxes[0].value + '$)';
+            break;
+          case 'equals':
+            str += '(?:^' + textboxes[0].value + '$)';
+            break;
+        }
+      }
+      if(this.currentRuleField) {
+        // Set the current field value to the created string:
+        this.currentRuleField.value = str;
+        // Call the onchange handler:
+        if(this.currentRuleField.onchange) {
+          this.currentRuleField.onchange();
+        }
+        // Call the focus handler:
+        if(this.currentRuleField.focus) {
+          this.currentRuleField.focus();
+        }
+      }
+    }
+    return true;
+  },
+
+  ruleEditorAdd: function(type, ruleElement) {
+    if(document.getElementById('ruleElementsList')) {
+      var richlistbox = document.getElementById('ruleElementsList');
+
+      var richlistitem,menulist,menupopup,menuitem,textbox,label;
+
+      richlistitem = document.createElement('richlistitem');
+
+      // Create the condition type menu:
+      menulist = document.createElement('menulist');
+      menupopup = document.createElement('menupopup');
+
+      var selectedIndex = 0;
+
+      // Create the menu of ruleElementTypes:
+      for(var i=0; i<this.ruleElementTypes.length; i++) {
+        menuitem = document.createElement('menuitem');
+        menuitem.setAttribute(
+          'value',
+          this.ruleElementTypes[i]
+        );
+        menuitem.setAttribute(
+          'label',
+          this.getStringBundle().getString(this.ruleElementTypes[i] + 'RuleType')
+        );
+        menupopup.appendChild(menuitem);
+
+        // Set the selectedIndex:
+        if(type != null && type == this.ruleElementTypes[i])
+          selectedIndex = i;
+      }
+
+      menulist.appendChild(menupopup);
+      richlistitem.appendChild(menulist);
+
+      // Create the textbox:
+      textbox = document.createElement('textbox');
+      if(ruleElement != null)
+        textbox.setAttribute('value',ruleElement);
+      textbox.setAttribute('flex','1');
+      richlistitem.appendChild(textbox);
+
+      richlistbox.appendChild(richlistitem);
+
+      // Select the menuitem:
+      menulist.selectedIndex = selectedIndex;
+    }
+  },
+
+  ruleEditorRemove: function(index) {
+    var ruleElementsList = document.getElementById('ruleElementsList');
+    if(ruleElementsList) {
+      if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+        // Confirmation dialog:
+        if(!this.getPrompts().confirm(
+            null,
+            this.getStringBundle().getString('removeRuleConditionTitle'),
+            this.getStringBundle().getString('removeRuleConditionText')
+          )
+        ) {
+          return;
+        }
+      }
+
+      var richlistbox = ruleElementsList;
+      if(index)
+        richlistbox.selectedIndex = index;
+      if(richlistbox.selectedItem && richlistbox.selectedIndex != -1)
+        richlistbox.removeChild(richlistbox.selectedItem);
+    }
+  },
+
+  ruleEditorIsTextBoxFocused: function() {
+    return this.ruleEditorTextBoxFocused;
+  },
+
+  ruleEditorFocus: function() {
+    var focusedElement = document.commandDispatcher.focusedElement;
+
+    // Monitor if a textbox is focused:
+    if(!this.ruleEditorTextBoxFocused && focusedElement && focusedElement.tagName == 'html:input') {
+      this.ruleEditorTextBoxFocused = true;
+    } else if(this.ruleEditorTextBoxFocused && focusedElement && focusedElement.tagName == 'richlistbox') {
+      this.ruleEditorTextBoxFocused = false;
+    }
+  },
+
+  ruleEditorHandleKeyPress: function(event) {
+    // Only remove a dynamic tag on delete key press if no textbox is focused:
+    if(event.keyCode == 46 && !this.ruleEditorIsTextBoxFocused()) {
+      this.ruleEditorRemove();
+    }
+  },
+
+  ruleEditorFinalize: function() {
+    this.currentRuleField = null;
+  },
+
+  tagEditorInitialize: function() {
+    // Save the reference to the Autofill Forms preferences branch:
+    this.autofillFormsPrefs = this.getPrefManager().getBranch('extensions.autofillForms at blueimp.net.');
+
+    // Add existing tags to the list:
+    for(var i=0; i<this.getDynamicTags().length; i++) {
+      // Catch if the number of tags doesn't match the number of tag codes:
+      try {
+        this.tagEditorAdd(this.getDynamicTags()[i],this.getDynamicTagCodes()[i])
+      } catch(e) {
+        this.log(e);
+      }
+    }
+  },
+
+  tagEditorSave: function() {
+    var richlistbox = document.getElementById('tagList');
+    if(richlistbox) {
+      var richlistitems = richlistbox.getElementsByTagName('richlistitem');
+      var textboxes;
+
+      var dynamicTags = new Array();
+      var dynamicTagCodes = new Array();
+
+      // Go through the richlistbox items:
+      for(var i=0; i<richlistitems.length; i++) {
+        textboxes = richlistitems[i].getElementsByTagName('textbox');
+
+        // Add the dynamic tags and their associated tag codes to the lists:
+        if (textboxes[0].value != '' && textboxes[1].value != '') {
+          dynamicTags.push(this.makeSafe(textboxes[0].value));
+          dynamicTagCodes.push(this.makeSafe(textboxes[1].value));
+        }
+      }
+      // Save the lists in the preferences:
+      this.setDynamicTags(dynamicTags);
+      this.setDynamicTagCodes(dynamicTagCodes);
+    }
+    return true;
+  },
+
+  tagEditorAdd: function(tag, tagCode) {
+    var richlistbox = document.getElementById('tagList');
+    if(richlistbox) {
+      var richlistitem,textbox;
+
+      richlistitem = document.createElement('richlistitem');
+
+      // Create the tag textbox:
+      textbox = document.createElement('textbox');
+      textbox.setAttribute('class','tag');
+      if(tag != null)
+        textbox.setAttribute('value',tag);
+      richlistitem.appendChild(textbox);
+
+      // Create the tagCode textbox:
+      textbox = document.createElement('textbox');
+      textbox.setAttribute('class','tagCode');
+      textbox.setAttribute('flex','1');
+      if(tagCode != null)
+        textbox.setAttribute('value',tagCode);
+      richlistitem.appendChild(textbox);
+
+      richlistbox.appendChild(richlistitem);
+    }
+  },
+
+  tagEditorRemove: function(index) {
+    var richlistbox = document.getElementById('tagList');
+    if(richlistbox) {
+      if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
+        // Confirmation dialog:
+        if(!this.getPrompts().confirm(
+            null,
+            this.getStringBundle().getString('removeDynamicTagTitle'),
+            this.getStringBundle().getString('removeDynamicTagText')
+          )
+        ) {
+          return;
+        }
+      }
+      if(index)
+        richlistbox.selectedIndex = index;
+      if(richlistbox.selectedItem && richlistbox.selectedIndex != -1)
+      {
+        richlistbox.removeChild(richlistbox.selectedItem);
+      }
+    }
+  },
+
+  tagEditorValidate: function(index) {
+    var richlistbox = document.getElementById('tagList');
+    if(richlistbox) {
+      if(index)
+        richlistbox.selectedIndex = index;
+      if(richlistbox.selectedItem) {
+        var tagCode = richlistbox.selectedItem.lastChild.value;
+        var validationResultTextBox = document.getElementById('validationResultTextBox');
+        try {
+          validationResultTextBox.removeAttribute('style');
+          // We use eval() here without restrictions - the given tagCode must be trusted:
+          validationResultTextBox.value = eval(tagCode);
+        } catch(e) {
+          validationResultTextBox.setAttribute('style', 'color:red;');
+          validationResultTextBox.value = e;
+        }
+      }
+    }
+  },
+
+  tagEditorIsTextBoxFocused: function() {
+    return this.tagEditorTextBoxFocused;
+  },
+
+  tagEditorFocus: function() {
+    var focusedElement = document.commandDispatcher.focusedElement;
+
+    // Monitor if a textbox is focused:
+    if(!this.tagEditorTextBoxFocused && focusedElement && focusedElement.tagName == 'html:input') {
+      this.tagEditorTextBoxFocused = true;
+    } else if(this.tagEditorTextBoxFocused && focusedElement && focusedElement.tagName == 'richlistbox') {
+      this.tagEditorTextBoxFocused = false;
+    }
+  },
+
+  tagEditorHandleKeyPress: function(event) {
+    // Only remove a dynamic tag on delete key press if no textbox is focused:
+    if(event.keyCode == 46 && !this.tagEditorIsTextBoxFocused()) {
+      this.tagEditorRemove();
+    }
+  },
+
+  tagEditorFinalize: function() {
+  },
+
+  openHelp: function(topic) {
+    if(!topic) {
+      topic = '';
+    }
+    var url = this.autofillFormsPrefs.getCharPref('helpURL').replace(/\[TOPIC\]$/, topic);
+    this.openNewTab(url, true);
+  },
+
+  openNewTab: function(url, focus) {
+    var helpTab = this.getBrowser().addTab(url);
+    if(focus) {
+      this.getBrowser().selectedTab = helpTab;
+      this.getWindowMediator().getMostRecentWindow('navigator:browser').focus();
+    }
+  },
+
+  addLeadingZeros: function(number, length) {
+    number = number.toString();
+    while(number.length < length) {
+      number = '0'+number;
+    }
+    return number;
+  },
+
+  escapeRegExp: function(str) {
+    if (!arguments.callee.regExp) {
+      var specials = new Array(
+        '^', '$', '*', '+', '?', '.', '|', '/',
+        '(', ')', '[', ']', '{', '}', '\\'
+      );
+      arguments.callee.regExp = new RegExp(
+        '(\\' + specials.join('|\\') + ')', 'g'
+      );
+    }
+    return str.replace(arguments.callee.regExp, '\\$1');
+  },
+
+  getClipboardText: function() {
+    var clipboardText = null;
+    var clip  = Components.classes['@mozilla.org/widget/clipboard;1']
+            .getService(Components.interfaces.nsIClipboard);
+    if(!clip) {
+      return null;
+    }
+
+    var trans = Components.classes['@mozilla.org/widget/transferable;1']
+            .createInstance(Components.interfaces.nsITransferable);
+    if(!trans) {
+      return null;
+    }
+
+    trans.addDataFlavor('text/unicode');
+
+    clip.getData(trans, clip.kGlobalClipboard);
+
+    var str     = new Object();
+    var strLength = new Object();
+
+    trans.getTransferData('text/unicode', str, strLength);
+
+    if(str) {
+      str = str.value.QueryInterface(Components.interfaces.nsISupportsString);
+    }
+    if(str) {
+      clipboardText = str.data.substring(0, strLength.value / 2);
+    }
+
+    return clipboardText
+  },
+
+  getMasterSecurityDevice: function() {
+    return Components.classes['@mozilla.org/security/pk11tokendb;1']
+        .getService(Components.interfaces.nsIPK11TokenDB);
+  },
+
+  log: function(aMessage, aSourceName, aSourceLine, aLineNumber, aColumnNumber, aFlags, aCategory) {
+    var consoleService = Components.classes['@mozilla.org/consoleservice;1']
+      .getService(Components.interfaces.nsIConsoleService);
+    if(aSourceName != 'undefined') {
+      var scriptError = Components.classes["@mozilla.org/scripterror;1"]
+        .createInstance(Components.interfaces.nsIScriptError);
+      scriptError.init(
+        aMessage,
+        aSourceName,
+        aSourceLine,
+        aLineNumber,
+        aColumnNumber,
+        aFlags,
+        aCategory
+      );
+      consoleService.logMessage(scriptError);
+    } else {
+      consoleService.logStringMessage(aMessage);
+    }
+  },
+
+  finalizeToolbarButtonStatus: function() {
+    var autofillFormsButton = document.getElementById('autofillFormsButton');
+    var hideToolbarButton = this.autofillFormsPrefs.getBoolPref('hideToolbarButton');
+    if(!autofillFormsButton && !hideToolbarButton) {
+      // If the toolbar button icon has been removed from the toolbar by drag&drop
+      // enable the hideToolbarButton setting:
+      this.autofillFormsPrefs.setBoolPref('hideToolbarButton', true);
+    } else if(autofillFormsButton && !autofillFormsButton.getAttribute('hidden')) {
+      // If the toolbar button icon has been added to the toolbar by drag&drop
+      // disable the hideToolbarButton setting:
+      this.autofillFormsPrefs.setBoolPref('hideToolbarButton', false);
+    }
+  },
+
+  finalize: function() {
+    this.finalizeToolbarButtonStatus();
+
+    // Remove the content area context menu listener:
+    var contentAreaContextMenu = document.getElementById('contentAreaContextMenu');
+    if(contentAreaContextMenu) {
+      contentAreaContextMenu.removeEventListener(
+        'popupshowing',
+        this.contentAreaContextMenuEventListener,
+        false
+      );
+    }
+
+    // Remove the preferences Observer:
+    this.autofillFormsPrefs.removeObserver('', this);
+  }
+
+}
diff --git a/src/chrome/content/autofillFormsOptions.js b/chrome/content/autofillFormsOptions.js
similarity index 100%
rename from src/chrome/content/autofillFormsOptions.js
rename to chrome/content/autofillFormsOptions.js
diff --git a/src/chrome/content/autofillFormsOptions.xul b/chrome/content/autofillFormsOptions.xul
similarity index 92%
rename from src/chrome/content/autofillFormsOptions.xul
rename to chrome/content/autofillFormsOptions.xul
index 9645d36..89ea3df 100644
--- a/src/chrome/content/autofillFormsOptions.xul
+++ b/chrome/content/autofillFormsOptions.xul
@@ -13,15 +13,14 @@
 	<prefpane
 		id="autofillFormsPrefPaneSimple"
 		label="&prefpanesimplelabel;"
-		flex="0"
-		helpTopic="Simple Editor"
-		style="overflow:auto;max-height:450px;">
+		flex="1"
+		helpTopic="Simple Editor">
 		<preferences>
 		</preferences>
 		<vbox flex="1">
 			<hbox align="center">
 				<menulist id="simpleInterfaceProfileMenuList" oncommand="autofillForms.setProfileIndex(this.selectedIndex);"/>
-				<spacer flex="0"/>
+				<spacer flex="1"/>
 			</hbox>
 			<separator class="thin"/>
 			<vbox flex="1" id="simpleInterfaceRowsContainer" style="overflow:auto;max-height:450px;">
@@ -38,49 +37,48 @@
 	<prefpane
 		id="autofillFormsPrefPaneProfiles"
 		label="&prefpaneprofileslabel;"
-		flex="0"
-		helpTopic="Profiles"
-		style="overflow:auto;min-height:475px;">
+		flex="1"
+		helpTopic="Profiles">
 		<preferences>
 			<preference id="autoSelectBestProfile" 	name="extensions.autofillForms at blueimp.net.autoSelectBestProfile" 		type="bool"/>
 			<preference id="enableGlobalProfile" 	name="extensions.autofillForms at blueimp.net.enableGlobalProfile" 		type="bool"/>
 		</preferences>
-		<tabbox flex="0">
+		<tabbox flex="1">
 			<tabs>
 				<tab label="&prefpaneprofileslabel;"/>
 				<tab label="&prefpaneadvancedlabel;"/>
 			</tabs>
-			<tabpanels flex="0">
-				<vbox flex="0">
-					<grid flex="0">
+			<tabpanels flex="1">
+				<vbox flex="1">
+					<grid flex="1">
 						<rows>
-							<row align="center" flex="0"/>
+							<row align="center" flex="1"/>
 							<separator class="thin"/>
 							<row align="center"/>
 						</rows>
 						<columns>
-							<column flex="0">
-								<tree id="profilesTree" seltype="single" flex="0" enableColumnDrag="true" onkeypress="autofillForms.profilesTreeHandleKeyPress(event)" onselect="autofillForms.selectedProfile(event);">
+							<column flex="1">
+								<tree id="profilesTree" seltype="single" flex="1" enableColumnDrag="true" onkeypress="autofillForms.profilesTreeHandleKeyPress(event)" onselect="autofillForms.selectedProfile(event);">
 									<treecols>
-										<treecol id="profilesTreeColName" label="&profilename.label;" flex="0" persist="width ordinal hidden" onclick="autofillForms.sortProfiles(event);"/>
+										<treecol id="profilesTreeColName" label="&profilename.label;" flex="1" persist="width ordinal hidden" onclick="autofillForms.sortProfiles(event);"/>
 										<splitter class="tree-splitter"/>
-										<treecol id="profilesTreeColSiteRule" label="&profilesiterule.label;" flex="0" persist="width ordinal hidden" hidden="true" onclick="autofillForms.sortProfiles(event);"/>
+										<treecol id="profilesTreeColSiteRule" label="&profilesiterule.label;" flex="1" persist="width ordinal hidden" hidden="false" onclick="autofillForms.sortProfiles(event);"/>
 									</treecols>
 									<treechildren id="profilesTreeChildren" />
 								</tree>
 								<grid>
 									<columns>
 										<column/>
-										<column flex="0"/>
+										<column flex="1"/>
 									</columns>
 									<rows>
 										<row align="center">
 											<label value="&profilename.label;:"/>
-											<textbox id="profileLabelTextBox" flex="0"/>
+											<textbox id="profileLabelTextBox" flex="1"/>
 										</row>
 										<row align="center">
 											<label value="&profilesiterule.label;:"/>
-											<textbox id="profileSiteRuleTextBox2" flex="0" onchange="autofillForms.changeProfileSiteRule(this.value);"/>
+											<textbox id="profileSiteRuleTextBox2" flex="1" onchange="autofillForms.changeProfileSiteRule(this.value);"/>
 										</row>
 									</rows>
 								</grid>
@@ -108,22 +106,22 @@
 							<button label="&profileimportbutton.label;" oncommand="autofillForms.importProfile();"/>
 							<button label="&profileexportallbutton.label;" oncommand="autofillForms.exportAllProfiles();"/>
 							<button label="&profileexportbutton.label;" oncommand="autofillForms.exportProfile();"/>
-							<spacer flex="0"/>
+							<spacer flex="1"/>
 						</hbox>
 					</groupbox>
 				</vbox>
-				<vbox flex="0" style="">
+				<vbox flex="1" style="">
 					<checkbox label="&autoselectbestprofile.label;" preference="autoSelectBestProfile"/>
 					<separator class="thin"/>
 					<hbox align="center">
 						<checkbox label="&enableglobalprofile.label;" preference="enableGlobalProfile"/>
-						<spacer flex="0"/>
+						<spacer flex="1"/>
 						<menulist id="globalProfileMenuList" oncommand="autofillForms.setGlobalProfileIndex(this.selectedIndex);"/>
 					</hbox>
 					<separator class="thin"/>
 					<hbox align="center">
 						<label control="contextMenuProfileMenuList" value="&formfieldscontextmenu.label;"/>
-						<spacer flex="0"/>
+						<spacer flex="1"/>
 						<menulist id="contextMenuProfileMenuList" oncommand="autofillForms.setFormFieldsContextMenuProfileIndex(this.selectedIndex-3);">
 							<menupopup>
 								<menuitem label="&formfieldscontextmenuitemallprofiles.label;"/>
@@ -135,28 +133,25 @@
 				</vbox>
 			</tabpanels>
 		</tabbox>
-		<vbox style="height:550px;width:1px;">
-		</vbox>
 	</prefpane>
 	<prefpane
 		id="autofillFormsPrefPaneMain"
 		label="&prefpanemainlabel;"
-		flex="0"
-		helpTopic="Advanced Editor"
-		style="overflow:auto;min-height:475px;">
+		flex="1"
+		helpTopic="Advanced Editor">
 		<preferences>
 		</preferences>
-		<vbox flex="0" id="autofillFormsPrefPaneMainBox" style="">
+		<vbox flex="1" id="autofillFormsPrefPaneMainBox" style="">
 			<grid>
 				<columns>
 					<column/>
-					<column flex="0"/>
+					<column flex="1"/>
 				</columns>
 				<rows>
 					<row align="center">
 						<label value="&profile.label;"/>
 						<hbox align="center">
-						<menulist id="profilesMenuList" editable="true" flex="0" oncommand="autofillForms.setProfileIndex(this.selectedIndex);"/>
+						<menulist id="profilesMenuList" editable="true" flex="1" oncommand="autofillForms.setProfileIndex(this.selectedIndex);"/>
 							<button id="buttonApplyProfile" label="&apply.label;" oncommand="autofillForms.changeProfileLabel(document.getElementById('profilesMenuList').inputField.value);"/>
 							<button id="buttonAddProfile" label="&add.label;" oncommand="autofillForms.addProfile(document.getElementById('profilesMenuList').inputField.value);"/>
 							<button id="buttonRemoveProfile" label="&remove.label;" oncommand="autofillForms.removeProfile(event);"/>
@@ -165,16 +160,16 @@
 					<row align="center">
 						<label value="&profilesiterule.label;:"/>
 						<hbox align="center">
-							<textbox id="profileSiteRuleTextBox" flex="0" onchange="autofillForms.changeProfileSiteRule(this.value);"/>
+							<textbox id="profileSiteRuleTextBox" flex="1" onchange="autofillForms.changeProfileSiteRule(this.value);"/>
 							<button label="&ruleeditorbutton.label;" oncommand="autofillForms.showDialog('chrome://autofillForms/content/autofillFormsRuleEditor.xul', document.getElementById('profileSiteRuleTextBox'));"/>
 						</hbox>
 					</row>
 				</rows>
 			</grid>
 			<separator class="thin"/>
-			<tree id="fieldRulesTree" seltype="multiple" flex="0" editable="true" enableColumnDrag="true" onkeypress="autofillForms.handleKeyPress(event)" onselect="autofillForms.selectedFieldRule(event);">
+			<tree id="fieldRulesTree" seltype="multiple" flex="1" editable="true" enableColumnDrag="true" onkeypress="autofillForms.handleKeyPress(event)" onselect="autofillForms.selectedFieldRule(event);">
 				<treecols>
-					<treecol id="fieldRuleName" label="&fieldrulename.label;" flex="0" persist="width ordinal hidden" onclick="autofillForms.sortFieldRules(event);"/>
+					<treecol id="fieldRuleName" label="&fieldrulename.label;" flex="1" persist="width ordinal hidden" onclick="autofillForms.sortFieldRules(event);"/>
 					<splitter class="tree-splitter"/>
 					<treecol id="fieldRuleValue" label="&fieldrulevalue.label;" flex="2" persist="width ordinal hidden" onclick="autofillForms.sortFieldRules(event);"/>
 					<splitter class="tree-splitter"/>
@@ -192,7 +187,7 @@
 			<grid>
 				<columns>
 					<column/>
-					<column flex="0"/>
+					<column flex="1"/>
 					<column/>
 				</columns>
 				<rows>
@@ -227,15 +222,12 @@
 				</rows>
 			</grid>
 		</vbox>
-		<vbox style="height:550px;width:1px;">
-		</vbox>
 	</prefpane>
 	<prefpane
 		id="autofillFormsPrefPaneAdvanced"
 		label="&prefpaneadvancedlabel;"
-		flex="0"
-		helpTopic="Settings"
-		style="overflow:auto;min-height:475px;">
+		flex="1"
+		helpTopic="Settings">
 		<preferences>
 			<preference id="storeEncrypted" 				name="extensions.autofillForms at blueimp.net.storeEncrypted" 					type="bool"/>
 			<preference id="enableDynamicTags" 				name="extensions.autofillForms at blueimp.net.enableDynamicTags" 				type="bool"/>
@@ -253,24 +245,24 @@
 			<preference id="placeholderTab" 				name="extensions.autofillForms at blueimp.net.placeholderTab" 					type="unichar"/>
 			<preference id="useConfigDirectory" 			name="extensions.autofillForms at blueimp.net.useConfigDirectory" 				type="bool"/>
 		</preferences>
-		<tabbox flex="0">
+		<tabbox flex="1">
 			<tabs>
 				<tab label="&prefpanemainlabel;"/>
 				<tab label="&prefpaneadvancedlabel;"/>
 			</tabs>
-			<tabpanels flex="0">
-				<vbox flex="0">
+			<tabpanels flex="1">
+				<vbox flex="1">
 					<groupbox>
 						<caption label="&securitycaption.label;"/>
 						<checkbox label="&storeencrypted.label;" preference="storeEncrypted"/>
 					</groupbox>
 					<separator class="thin"/>
-					<groupbox flex="0">
+					<groupbox flex="1">
 						<caption label="&miscellaneous.label;"/>
-					<vbox  flex="0" style="overflow:auto;">
+					<vbox  flex="1" style="overflow:auto;">
 						<hbox align="center">
 							<checkbox label="&tagsenable.label;" preference="enableDynamicTags"/>
-							<spacer flex="0"/>
+							<spacer flex="1"/>
 							<button id="buttonEditTags" label="&tagsedit.label;" oncommand="autofillForms.showDialog('chrome://autofillForms/content/autofillFormsTagEditor.xul', null);"/>
 						</hbox>
 						<checkbox label="&ignoredisabledrulesonautofill.label;" preference="ignoreDisabledRulesOnAutofill"/>
@@ -283,17 +275,17 @@
 						<checkbox label="&callonchangeafterfillingfields.label;" preference="callOnChangeAfterFillingFields"/>
 						<hbox align="center">
 							<checkbox label="&matchagainstpositions.label;" preference="matchAgainstPositions"/>
-							<spacer flex="0"/>
+							<spacer flex="1"/>
 							<textbox id="positionsIdentifierTextbox" preference="positionsIdentifier" class="placeholderTextbox"/>
 						</hbox>
 						<hbox align="center">
 							<label control="placeholderLineBreakTextbox" value="&placeholderlinebreak.label;"/>
-							<spacer flex="0"/>
+							<spacer flex="1"/>
 							<textbox id="placeholderLineBreakTextbox" preference="placeholderLineBreak" class="placeholderTextbox"/>
 						</hbox>
 						<hbox align="center">
 							<label control="placeholderTabTextbox" value="&placeholdertab.label;"/>
-							<spacer flex="0"/>
+							<spacer flex="1"/>
 							<textbox id="placeholderTabTextbox" preference="placeholderTab" class="placeholderTextbox"/>
 						</hbox>
 				</vbox>
@@ -304,36 +296,33 @@
 						<hbox>
 							<button label="&tagimportbutton.label;" oncommand="autofillForms.importDynamicTagsFromSettings();"/>
 							<button label="&tagexportbutton.label;" oncommand="autofillForms.exportDynamicTagsFromSettings();"/>
-							<spacer flex="0"/>
+							<spacer flex="1"/>
 						</hbox>
 					</groupbox>
 				</vbox>
-				<vbox flex="0">
+				<vbox flex="1">
 					<groupbox>
 						<caption label="&storagelocationcaption.label;"/>
 						<checkbox label="&useconfigdirectory.label;" preference="useConfigDirectory"/>
 						<hbox>
-							<textbox id="configDirectoryTextBox" readonly="true" flex="0" />
+							<textbox id="configDirectoryTextBox" readonly="true" flex="1" />
 							<button	label="&browsedir.label;" icon="open" oncommand="autofillForms.setConfigDirectory(document.getElementById('configDirectoryTextBox'));"/>
 							<button	label="&resetdir.label;" icon="clear" oncommand="autofillForms.resetConfigDirectory(document.getElementById('configDirectoryTextBox'));"/>
 						</hbox>
 						<hbox>
 							<button	label="&opendir.label;" icon="open" oncommand="autofillForms.openConfigDirectory();"/>
-							<spacer flex="0"/>
+							<spacer flex="1"/>
 						</hbox>
 					</groupbox>
 				</vbox>
 			</tabpanels>
 		</tabbox>
-		<vbox style="height:550px;width:1px;">
-		</vbox>
 	</prefpane>
 	<prefpane
 		id="autofillFormsPrefPaneGUI"
 		label="&prefpaneguilabel;"
-		flex="0"
-		helpTopic="Interface"
-		style="overflow:auto;min-height:475px;">
+		flex="1"
+		helpTopic="Interface">
 		<preferences>
 			<preference id="hideStatusbarIcon" 			name="extensions.autofillForms at blueimp.net.hideStatusbarIcon" 			type="bool"/>
 			<preference id="hideContextMenuItem" 		name="extensions.autofillForms at blueimp.net.hideContextMenuItem" 		type="bool"/>
@@ -345,14 +334,14 @@
 			<preference id="highlightStyleNoMatch" 		name="extensions.autofillForms at blueimp.net.highlightStyleNoMatch" 		type="unichar"/>
 			<preference id="formDetailsStyle" 			name="extensions.autofillForms at blueimp.net.formDetailsStyle" 			type="unichar"/>
 		</preferences>
-		<tabbox flex="0">
+		<tabbox flex="1">
 			<tabs>
 				<tab label="&viewcaption.label;"/>
 				<tab label="&shortcutscaption.label;"/>
 				<tab label="&mousebuttonscaption.label;"/>
 			</tabs>
-			<tabpanels flex="0">
-				<vbox flex="0" style="">
+			<tabpanels flex="1">
+				<vbox flex="1" style="">
 					<checkbox label="&hidetoolbarbutton.label;" preference="hideToolbarButton"/>
 					<checkbox label="&hidetoolbarbuttonmenu.label;" preference="hideToolbarButtonMenu"/>
 					<checkbox label="&hidestatusbaricon.label;" preference="hideStatusbarIcon"/>
@@ -363,7 +352,7 @@
 					<grid>
 						<columns>
 							<column/>
-							<column flex="0" minwidth="200"/>
+							<column flex="1" minwidth="200"/>
 						</columns>
 						<rows>
 							<row align="center">
@@ -381,11 +370,11 @@
 						</rows>
 					</grid>
 				</vbox>
-				<vbox flex="0" style="">
+				<vbox flex="1" style="">
 					<grid>
 						<columns>
 							<column class="shortCutsLabelColumn"/>
-							<column class="shortCutsKeyColumn" flex="0"/>
+							<column class="shortCutsKeyColumn" flex="1"/>
 							<column/>
 						</columns>
 						<rows>
@@ -485,11 +474,11 @@
 					<separator class="thin"/>
 					<description class="shortcutInfo">&shortcutinfo.label;</description>
 				</vbox>
-				<vbox flex="0" style="">
+				<vbox flex="1" style="">
 					<grid>
 						<columns>
 							<column class="shortCutsLabelColumn"/>
-							<column class="shortCutsKeyColumn" flex="0"/>
+							<column class="shortCutsKeyColumn" flex="1"/>
 							<column/>
 							<column/>
 						</columns>
@@ -613,8 +602,6 @@
 				</vbox>
 			</tabpanels>	
 		</tabbox>
-		<vbox style="height:550px;width:1px;">
-		</vbox>
 	</prefpane>
 	<script
 		type="application/x-javascript"
diff --git a/src/chrome/content/autofillFormsOverlay.js b/chrome/content/autofillFormsOverlay.js
similarity index 100%
rename from src/chrome/content/autofillFormsOverlay.js
rename to chrome/content/autofillFormsOverlay.js
diff --git a/src/chrome/content/autofillFormsOverlay.xul b/chrome/content/autofillFormsOverlay.xul
similarity index 100%
rename from src/chrome/content/autofillFormsOverlay.xul
rename to chrome/content/autofillFormsOverlay.xul
diff --git a/src/chrome/content/autofillFormsRuleEditor.js b/chrome/content/autofillFormsRuleEditor.js
similarity index 100%
rename from src/chrome/content/autofillFormsRuleEditor.js
rename to chrome/content/autofillFormsRuleEditor.js
diff --git a/src/chrome/content/autofillFormsRuleEditor.xul b/chrome/content/autofillFormsRuleEditor.xul
similarity index 100%
rename from src/chrome/content/autofillFormsRuleEditor.xul
rename to chrome/content/autofillFormsRuleEditor.xul
diff --git a/src/chrome/content/autofillFormsTagEditor.js b/chrome/content/autofillFormsTagEditor.js
similarity index 100%
rename from src/chrome/content/autofillFormsTagEditor.js
rename to chrome/content/autofillFormsTagEditor.js
diff --git a/src/chrome/content/autofillFormsTagEditor.xul b/chrome/content/autofillFormsTagEditor.xul
similarity index 100%
rename from src/chrome/content/autofillFormsTagEditor.xul
rename to chrome/content/autofillFormsTagEditor.xul
diff --git a/src/chrome/locale/cs-CZ/autofillForms.dtd b/chrome/locale/cs-CZ/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/cs-CZ/autofillForms.dtd
rename to chrome/locale/cs-CZ/autofillForms.dtd
diff --git a/src/chrome/locale/cs-CZ/autofillForms.properties b/chrome/locale/cs-CZ/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/cs-CZ/autofillForms.properties
rename to chrome/locale/cs-CZ/autofillForms.properties
diff --git a/src/chrome/locale/de-DE/autofillForms.dtd b/chrome/locale/de-DE/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/de-DE/autofillForms.dtd
rename to chrome/locale/de-DE/autofillForms.dtd
diff --git a/src/chrome/locale/de-DE/autofillForms.properties b/chrome/locale/de-DE/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/de-DE/autofillForms.properties
rename to chrome/locale/de-DE/autofillForms.properties
diff --git a/src/chrome/locale/el-GR/autofillForms.dtd b/chrome/locale/el-GR/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/el-GR/autofillForms.dtd
rename to chrome/locale/el-GR/autofillForms.dtd
diff --git a/src/chrome/locale/el-GR/autofillForms.properties b/chrome/locale/el-GR/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/el-GR/autofillForms.properties
rename to chrome/locale/el-GR/autofillForms.properties
diff --git a/src/chrome/locale/en-US/autofillForms.dtd b/chrome/locale/en-US/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/en-US/autofillForms.dtd
rename to chrome/locale/en-US/autofillForms.dtd
diff --git a/src/chrome/locale/en-US/autofillForms.properties b/chrome/locale/en-US/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/en-US/autofillForms.properties
rename to chrome/locale/en-US/autofillForms.properties
diff --git a/src/chrome/locale/es-ES/autofillForms.dtd b/chrome/locale/es-ES/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/es-ES/autofillForms.dtd
rename to chrome/locale/es-ES/autofillForms.dtd
diff --git a/src/chrome/locale/es-ES/autofillForms.properties b/chrome/locale/es-ES/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/es-ES/autofillForms.properties
rename to chrome/locale/es-ES/autofillForms.properties
diff --git a/src/chrome/locale/fi-FI/autofillForms.dtd b/chrome/locale/fi-FI/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/fi-FI/autofillForms.dtd
rename to chrome/locale/fi-FI/autofillForms.dtd
diff --git a/src/chrome/locale/fi-FI/autofillForms.properties b/chrome/locale/fi-FI/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/fi-FI/autofillForms.properties
rename to chrome/locale/fi-FI/autofillForms.properties
diff --git a/src/chrome/locale/fr-FR/autofillForms.dtd b/chrome/locale/fr-FR/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/fr-FR/autofillForms.dtd
rename to chrome/locale/fr-FR/autofillForms.dtd
diff --git a/src/chrome/locale/fr-FR/autofillForms.properties b/chrome/locale/fr-FR/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/fr-FR/autofillForms.properties
rename to chrome/locale/fr-FR/autofillForms.properties
diff --git a/src/chrome/locale/he-IL/autofillForms.dtd b/chrome/locale/he-IL/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/he-IL/autofillForms.dtd
rename to chrome/locale/he-IL/autofillForms.dtd
diff --git a/src/chrome/locale/he-IL/autofillForms.properties b/chrome/locale/he-IL/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/he-IL/autofillForms.properties
rename to chrome/locale/he-IL/autofillForms.properties
diff --git a/src/chrome/locale/hr-HR/autofillForms.dtd b/chrome/locale/hr-HR/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/hr-HR/autofillForms.dtd
rename to chrome/locale/hr-HR/autofillForms.dtd
diff --git a/src/chrome/locale/hr-HR/autofillForms.properties b/chrome/locale/hr-HR/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/hr-HR/autofillForms.properties
rename to chrome/locale/hr-HR/autofillForms.properties
diff --git a/src/chrome/locale/hu-HU/autofillForms.dtd b/chrome/locale/hu-HU/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/hu-HU/autofillForms.dtd
rename to chrome/locale/hu-HU/autofillForms.dtd
diff --git a/src/chrome/locale/hu-HU/autofillForms.properties b/chrome/locale/hu-HU/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/hu-HU/autofillForms.properties
rename to chrome/locale/hu-HU/autofillForms.properties
diff --git a/src/chrome/locale/it-IT/autofillForms.dtd b/chrome/locale/it-IT/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/it-IT/autofillForms.dtd
rename to chrome/locale/it-IT/autofillForms.dtd
diff --git a/src/chrome/locale/it-IT/autofillForms.properties b/chrome/locale/it-IT/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/it-IT/autofillForms.properties
rename to chrome/locale/it-IT/autofillForms.properties
diff --git a/src/chrome/locale/nl-NL/autofillForms.dtd b/chrome/locale/nl-NL/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/nl-NL/autofillForms.dtd
rename to chrome/locale/nl-NL/autofillForms.dtd
diff --git a/src/chrome/locale/nl-NL/autofillForms.properties b/chrome/locale/nl-NL/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/nl-NL/autofillForms.properties
rename to chrome/locale/nl-NL/autofillForms.properties
diff --git a/src/chrome/locale/pl-PL/autofillForms.dtd b/chrome/locale/pl-PL/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/pl-PL/autofillForms.dtd
rename to chrome/locale/pl-PL/autofillForms.dtd
diff --git a/src/chrome/locale/pl-PL/autofillForms.properties b/chrome/locale/pl-PL/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/pl-PL/autofillForms.properties
rename to chrome/locale/pl-PL/autofillForms.properties
diff --git a/src/chrome/locale/pt-BR/autofillForms.dtd b/chrome/locale/pt-BR/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/pt-BR/autofillForms.dtd
rename to chrome/locale/pt-BR/autofillForms.dtd
diff --git a/src/chrome/locale/pt-BR/autofillForms.properties b/chrome/locale/pt-BR/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/pt-BR/autofillForms.properties
rename to chrome/locale/pt-BR/autofillForms.properties
diff --git a/src/chrome/locale/ro-RO/autofillForms.dtd b/chrome/locale/ro-RO/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/ro-RO/autofillForms.dtd
rename to chrome/locale/ro-RO/autofillForms.dtd
diff --git a/src/chrome/locale/ro-RO/autofillForms.properties b/chrome/locale/ro-RO/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/ro-RO/autofillForms.properties
rename to chrome/locale/ro-RO/autofillForms.properties
diff --git a/src/chrome/locale/ru-RU/autofillForms.dtd b/chrome/locale/ru-RU/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/ru-RU/autofillForms.dtd
rename to chrome/locale/ru-RU/autofillForms.dtd
diff --git a/src/chrome/locale/ru-RU/autofillForms.properties b/chrome/locale/ru-RU/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/ru-RU/autofillForms.properties
rename to chrome/locale/ru-RU/autofillForms.properties
diff --git a/src/chrome/locale/sk-SK/autofillForms.dtd b/chrome/locale/sk-SK/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/sk-SK/autofillForms.dtd
rename to chrome/locale/sk-SK/autofillForms.dtd
diff --git a/src/chrome/locale/sk-SK/autofillForms.properties b/chrome/locale/sk-SK/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/sk-SK/autofillForms.properties
rename to chrome/locale/sk-SK/autofillForms.properties
diff --git a/src/chrome/locale/sv-SE/autofillForms.dtd b/chrome/locale/sv-SE/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/sv-SE/autofillForms.dtd
rename to chrome/locale/sv-SE/autofillForms.dtd
diff --git a/src/chrome/locale/sv-SE/autofillForms.properties b/chrome/locale/sv-SE/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/sv-SE/autofillForms.properties
rename to chrome/locale/sv-SE/autofillForms.properties
diff --git a/src/chrome/locale/tr-TR/autofillForms.dtd b/chrome/locale/tr-TR/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/tr-TR/autofillForms.dtd
rename to chrome/locale/tr-TR/autofillForms.dtd
diff --git a/src/chrome/locale/tr-TR/autofillForms.properties b/chrome/locale/tr-TR/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/tr-TR/autofillForms.properties
rename to chrome/locale/tr-TR/autofillForms.properties
diff --git a/src/chrome/locale/zh-CN/autofillForms.dtd b/chrome/locale/zh-CN/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/zh-CN/autofillForms.dtd
rename to chrome/locale/zh-CN/autofillForms.dtd
diff --git a/src/chrome/locale/zh-CN/autofillForms.properties b/chrome/locale/zh-CN/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/zh-CN/autofillForms.properties
rename to chrome/locale/zh-CN/autofillForms.properties
diff --git a/src/chrome/locale/zh-TW/autofillForms.dtd b/chrome/locale/zh-TW/autofillForms.dtd
similarity index 100%
rename from src/chrome/locale/zh-TW/autofillForms.dtd
rename to chrome/locale/zh-TW/autofillForms.dtd
diff --git a/src/chrome/locale/zh-TW/autofillForms.properties b/chrome/locale/zh-TW/autofillForms.properties
similarity index 100%
rename from src/chrome/locale/zh-TW/autofillForms.properties
rename to chrome/locale/zh-TW/autofillForms.properties
diff --git a/src/chrome/skin/arrows.png b/chrome/skin/arrows.png
similarity index 100%
rename from src/chrome/skin/arrows.png
rename to chrome/skin/arrows.png
diff --git a/chrome/skin/autofillForms.css b/chrome/skin/autofillForms.css
new file mode 100644
index 0000000..5d4678d
--- /dev/null
+++ b/chrome/skin/autofillForms.css
@@ -0,0 +1,59 @@
+#autofillFormsButton,
+.autofillFormsButton {
+  list-style-image: url("pencil.png");
+}
+toolbar[iconsize="small"] #autofillFormsButton,
+toolbar[iconsize="small"] .autofillFormsButton,
+.autofillFormsIcon {
+  list-style-image: url("pencil-small.png");
+}
+#autofillFormsButton[cui-areatype="menu-panel"],
+toolbarpaletteitem[place="palette"] > #autofillFormsButton {
+  list-style-image: url("pencil-big.png");
+}
+/** Retina Display **/
+ at media (min-resolution: 2dppx) {
+  toolbar[iconsize="small"] #autofillFormsButton,
+  toolbar[iconsize="small"] .autofillFormsButton,
+  .autofillFormsIcon {
+    list-style-image: url("pencil-big.png");
+  }
+}
+
+
+.autofillFormsProfileIcon {
+  list-style-image: url("profile-small.png");
+}
+.autofillFormsSettingsIcon {
+  list-style-image: url("settings-small.png");
+}
+.autofillFormsHelpIcon {
+  list-style-image: url("help-small.png");
+}
+
+statusbarpanel.autofillFormsIcon {
+  cursor: pointer;
+}
+
+#autofillFormsTooltipCurrentProfile {
+  margin-bottom:10px;
+}
+#autofillFormsTooltipCurrentProfileCaption {
+}
+#autofillFormsTooltipCurrentProfileLabel {
+  font-weight: bold;
+}
+#autofillFormsTooltipGrid {
+}
+.autofillFormsTooltipGridHeader {
+  font-weight:bold;
+  margin-bottom:5px;
+}
+.autofillFormsTooltipGridCommand {
+}
+.autofillFormsTooltipGridMouseButton {
+  font-style:italic;
+}
+.autofillFormsTooltipGridKeyboardShortcut {
+  font-family:monospace;
+}
diff --git a/src/chrome/skin/autofillFormsMac.css b/chrome/skin/autofillFormsMac.css
similarity index 100%
rename from src/chrome/skin/autofillFormsMac.css
rename to chrome/skin/autofillFormsMac.css
diff --git a/src/chrome/skin/autofillFormsOptions.css b/chrome/skin/autofillFormsOptions.css
similarity index 100%
rename from src/chrome/skin/autofillFormsOptions.css
rename to chrome/skin/autofillFormsOptions.css
diff --git a/src/chrome/skin/autofillFormsOptions1.5.css b/chrome/skin/autofillFormsOptions1.5.css
similarity index 100%
rename from src/chrome/skin/autofillFormsOptions1.5.css
rename to chrome/skin/autofillFormsOptions1.5.css
diff --git a/src/chrome/skin/autofillFormsOptions2.css b/chrome/skin/autofillFormsOptions2.css
similarity index 100%
rename from src/chrome/skin/autofillFormsOptions2.css
rename to chrome/skin/autofillFormsOptions2.css
diff --git a/src/chrome/skin/autofillFormsRuleEditor.css b/chrome/skin/autofillFormsRuleEditor.css
similarity index 100%
rename from src/chrome/skin/autofillFormsRuleEditor.css
rename to chrome/skin/autofillFormsRuleEditor.css
diff --git a/src/chrome/skin/autofillFormsTagEditor.css b/chrome/skin/autofillFormsTagEditor.css
similarity index 100%
rename from src/chrome/skin/autofillFormsTagEditor.css
rename to chrome/skin/autofillFormsTagEditor.css
diff --git a/src/chrome/skin/help-small.png b/chrome/skin/help-small.png
similarity index 100%
rename from src/chrome/skin/help-small.png
rename to chrome/skin/help-small.png
diff --git a/src/chrome/skin/icon.png b/chrome/skin/icon.png
similarity index 100%
copy from src/chrome/skin/icon.png
copy to chrome/skin/icon.png
diff --git a/src/chrome/skin/pencil-active-mac.png b/chrome/skin/pencil-active-mac.png
similarity index 100%
rename from src/chrome/skin/pencil-active-mac.png
rename to chrome/skin/pencil-active-mac.png
diff --git a/src/chrome/skin/icon.png b/chrome/skin/pencil-big.png
similarity index 100%
rename from src/chrome/skin/icon.png
rename to chrome/skin/pencil-big.png
diff --git a/src/chrome/skin/pencil-mac.png b/chrome/skin/pencil-mac.png
similarity index 100%
rename from src/chrome/skin/pencil-mac.png
rename to chrome/skin/pencil-mac.png
diff --git a/src/chrome/skin/pencil-small.png b/chrome/skin/pencil-small.png
similarity index 100%
rename from src/chrome/skin/pencil-small.png
rename to chrome/skin/pencil-small.png
diff --git a/src/chrome/skin/pencil.png b/chrome/skin/pencil.png
similarity index 100%
rename from src/chrome/skin/pencil.png
rename to chrome/skin/pencil.png
diff --git a/src/chrome/skin/profile-small.png b/chrome/skin/profile-small.png
similarity index 100%
rename from src/chrome/skin/profile-small.png
rename to chrome/skin/profile-small.png
diff --git a/src/chrome/skin/settings-small.png b/chrome/skin/settings-small.png
similarity index 100%
rename from src/chrome/skin/settings-small.png
rename to chrome/skin/settings-small.png
diff --git a/src/defaults/preferences/autofillForms.js b/defaults/preferences/autofillForms.js
similarity index 95%
rename from src/defaults/preferences/autofillForms.js
rename to defaults/preferences/autofillForms.js
index 853dd37..0cb3211 100644
--- a/src/defaults/preferences/autofillForms.js
+++ b/defaults/preferences/autofillForms.js
@@ -18,7 +18,7 @@ pref('extensions.autofillForms at blueimp.net.profileLabels', 'chrome://autofillFor
 pref('extensions.autofillForms at blueimp.net.dynamicTags', 'chrome://autofillForms/locale/autofillForms.properties');
 pref('extensions.autofillForms at blueimp.net.dynamicTagCodes', 'chrome://autofillForms/locale/autofillForms.properties');
 pref('extensions.autofillForms at blueimp.net.regExpPasswordLabel', 'chrome://autofillForms/locale/autofillForms.properties');
-pref('extensions.autofillForms at blueimp.net.regExpFormFieldTypes', '^(?:(?:text(?:area)?)|(?:select-(?:(?:one)|(?:multiple)))|(?:checkbox)|(?:radio)|(?:password)|(?:file))$');
+pref('extensions.autofillForms at blueimp.net.regExpFormFieldTypes', '^(?:(?:text(?:area)?)|(?:select-(?:(?:one)|(?:multiple)))|(?:checkbox)|(?:radio)|(?:email)|(?:url)|(?:password)|(?:file))$');
 pref('extensions.autofillForms at blueimp.net.enableDynamicTags', false);
 pref('extensions.autofillForms at blueimp.net.profileIndex', 0);
 pref('extensions.autofillForms at blueimp.net.storeEncrypted', false);
@@ -50,6 +50,6 @@ pref('extensions.autofillForms at blueimp.net.configDirectory', '');
 pref('extensions.autofillForms at blueimp.net.useConfigDirectory', false);
 pref('extensions.autofillForms at blueimp.net.profileSiteRules', '(?:)');
 pref('extensions.autofillForms at blueimp.net.autoSelectBestProfile', true);
-pref('extensions.autofillForms at blueimp.net.helpURL', 'https://www.abine.com/support.php');
+pref('extensions.autofillForms at blueimp.net.helpURL', 'http://firefox.add0n.com/autofill-forms.html');
 pref("extensions.autofillForms at blueimp.net.just_installed", true);
-pref("extensions.autofillForms at blueimp.net.post_install_url", "https://www.abine.com/oldpostinstall.php?addon=autofillForms");
+pref("extensions.autofillForms at blueimp.net.post_install_url", "http://firefox.add0n.com/autofill-forms.html");
diff --git a/install.rdf b/install.rdf
new file mode 100644
index 0000000..21716d0
--- /dev/null
+++ b/install.rdf
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>autofillForms at blueimp.net</em:id>
+    <em:name>Autofill Forms</em:name>
+    <em:creator>Sebastian Tschan</em:creator>
+    <em:contributor>Sarah Avilov</em:contributor>
+    <em:description>Fill out web forms automatically</em:description>
+    <em:iconURL>chrome://autofillForms/skin/icon.png</em:iconURL>
+    <em:optionsURL>chrome://autofillForms/content/autofillFormsOptions.xul</em:optionsURL>
+    <em:homepageURL>http://firefox.add0n.com/autofill-forms.html</em:homepageURL>
+    <em:version>1.0.2</em:version>
+    <em:type>2</em:type>
+    <em:targetApplication>
+      <Description>
+        <!-- Firefox -->
+        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+        <em:minVersion>17.0</em:minVersion>
+        <em:maxVersion>35.0</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <em:targetApplication>
+      <Description>
+        <!-- Midbrowser -->
+        <em:id>{aa5ca914-c309-495d-91cf-3141bbb04115}</em:id>
+        <em:minVersion>0.2</em:minVersion>
+        <em:maxVersion>2.0.0.6</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <em:translator>PetrTwo (Czech)</em:translator>
+    <em:translator>Oliver Roth (German)</em:translator>
+    <em:translator>Koumen (Greek)</em:translator>
+    <em:translator>jesuspportillo (Spanish)</em:translator>
+    <em:translator>Unknown (Finnish)</em:translator>
+    <em:translator>myahoo (French)</em:translator>
+    <em:translator>YuvalSht (Hebrew)</em:translator>
+    <em:translator>Mikes Kaszmán István (Hungarian)</em:translator>
+    <em:translator>Underpass (Italian)</em:translator>
+    <em:translator>gonzalopirobutirro (Italian)</em:translator>
+    <em:translator>Godai71 (Italian)</em:translator>
+    <em:translator>markh (Dutch)</em:translator>
+    <em:translator>teo (Polish)</em:translator>
+    <em:translator>Alberto Eidh (Portuguese - Brazilian)</em:translator>
+    <em:translator>x10firefox (Romanian)</em:translator>
+    <em:translator>Unknown (Russian)</em:translator>
+    <em:translator>Umut (Swedish)</em:translator>
+    <em:translator>ch0ze (Slovak)</em:translator>
+    <em:translator>KenanBalamir (Turkish)</em:translator>
+    <em:translator>simophin (Chinese - Simplified)</em:translator>
+    <em:translator>Lu Ming-Tse (呂明澤) (Chinese - Traditional)</em:translator>
+  </Description>
+</RDF>
diff --git a/src/build.xml b/src/build.xml
deleted file mode 100644
index 9ee9f23..0000000
--- a/src/build.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" ?>
-
-<project name="Autofill Forms" default="xpi">
-	<property name="version.number" value="0.9.8.1" />
-	<property name="jar.name" value="autofillforms" />
-	<property name="xpi.name" value="autofill_forms-${version.number}-fx" />
-	<property name="src.dir" value="." />
-	<property name="chrome.dir" value="chrome" />
-	<property name="dist.dir" value="../downloads" />
-
-	<condition property="jar.present">
-		<and>
-			<available file="${chrome.dir}/${jar.name}.jar" type="file" />
-		</and>
-	</condition>
-
-	<condition property="xpi.present">
-		<and>
-			<available file="${dist.dir}/${xpi.name}.xpi" type="file" />
-		</and>
-	</condition>
-	
-	<target name="jar">
-		<zip destfile="${chrome.dir}/${jar.name}.jar" level="9">
-			<fileset dir="${chrome.dir}">
-				<include name="content/**" />
-				<include name="locale/**" />
-				<include name="skin/**" />
-				<exclude name="**/.*" />
-				<exclude name="**/CVS/**" />
-			</fileset>
-		</zip>
-	</target>
-	
-	<target name="xpi" depends="jar">
-		<copy file="${src.dir}/chrome.manifest.jar.txt" tofile="${src.dir}/chrome.manifest" overwrite="true" />
-		<mkdir dir="${dist.dir}" />
-		<zip destfile="${dist.dir}/${xpi.name}.xpi" level="9">
-			<zipfileset file="${chrome.dir}/${jar.name}.jar" prefix="chrome"/>
-			<fileset dir="${src.dir}">
-				<include name="chrome.manifest" />
-				<include name="install.rdf" />
-				<include name="defaults/**" />
-				<exclude name="**/.*" />
-				<exclude name="**/CVS/**" />
-			</fileset>
-		</zip>
-		<copy file="${src.dir}/chrome.manifest.extracted.txt" tofile="${src.dir}/chrome.manifest" overwrite="true" />
-	</target>
-
-	<target name="clean.jar" if="jar.present">
-		<delete file="${chrome.dir}/${jar.name}.jar" failonerror="false" />
-	</target>
-
-	<target name="clean.xpi" if="xpi.present">
-		<delete file="${dist.dir}/${xpi.name}.xpi" failonerror="false" />
-	</target>
-
-</project>
diff --git a/src/chrome.manifest.extracted.txt b/src/chrome.manifest.extracted.txt
deleted file mode 100644
index c254d33..0000000
--- a/src/chrome.manifest.extracted.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-content		autofillforms						chrome/content/
-locale		autofillforms 		cs-CZ			chrome/locale/cs-CZ/
-locale		autofillforms 		de-DE			chrome/locale/de-DE/
-locale		autofillforms 		el-GR			chrome/locale/el-GR/
-locale		autofillforms 		en-US			chrome/locale/en-US/
-locale		autofillforms 		es-ES			chrome/locale/es-ES/
-locale		autofillforms 		fr-FR			chrome/locale/fr-FR/
-locale		autofillforms 		fi-FI			chrome/locale/fi-FI/
-locale		autofillforms 		he-IL			chrome/locale/he-IL/
-locale		autofillforms 		hr-HR			chrome/locale/hr-HR/
-locale		autofillforms 		hu-HU			chrome/locale/hu-HU/
-locale		autofillforms 		it-IT			chrome/locale/it-IT/
-locale		autofillforms 		nl-NL			chrome/locale/nl-NL/
-locale		autofillforms 		pl-PL			chrome/locale/pl-PL/
-locale		autofillforms 		pt-BR			chrome/locale/pt-BR/
-locale		autofillforms 		ro-RO			chrome/locale/ro-RO/
-locale		autofillforms 		ru-RU			chrome/locale/ru-RU/
-locale		autofillforms 		sk-SK			chrome/locale/sk-SK/
-locale		autofillforms 		sv-SE			chrome/locale/sv-SE/
-locale		autofillforms 		tr-TR			chrome/locale/tr-TR/
-locale		autofillforms 		zh-CN			chrome/locale/zh-CN/
-locale		autofillforms 		zh-TW			chrome/locale/zh-TW/
-skin 		autofillforms		classic/1.0		chrome/skin/
-overlay		chrome://browser/content/browser.xul						chrome://autofillforms/content/autofillFormsOverlay.xul
-style		chrome://global/content/customizeToolbar.xul				chrome://autofillforms/skin/autofillForms.css
-style		chrome://autofillforms/content/autofillFormsOptions.xul		chrome://autofillforms/skin/autofillFormsOptions2.css		appversion<3.0
-style		chrome://autofillforms/content/autofillFormsOptions.xul		chrome://autofillforms/skin/autofillFormsOptions1.5.css		appversion<2.0
-style		chrome://browser/content/browser.xul						chrome://autofillforms/skin/autofillFormsMac.css			appversion>=3.0 os=Darwin
-style		chrome://global/content/customizeToolbar.xul				chrome://autofillforms/skin/autofillFormsMac.css			appversion>=3.0 os=Darwin
\ No newline at end of file
diff --git a/src/chrome.manifest.jar.txt b/src/chrome.manifest.jar.txt
deleted file mode 100644
index c6c22ca..0000000
--- a/src/chrome.manifest.jar.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-content		autofillforms						jar:chrome/autofillforms.jar!/content/
-locale		autofillforms 		cs-CZ			jar:chrome/autofillforms.jar!/locale/cs-CZ/
-locale		autofillforms 		de-DE			jar:chrome/autofillforms.jar!/locale/de-DE/
-locale		autofillforms 		el-GR			jar:chrome/autofillforms.jar!/locale/el-GR/
-locale		autofillforms 		en-US			jar:chrome/autofillforms.jar!/locale/en-US/
-locale		autofillforms 		es-ES			jar:chrome/autofillforms.jar!/locale/es-ES/
-locale		autofillforms 		fr-FR			jar:chrome/autofillforms.jar!/locale/fr-FR/
-locale		autofillforms 		fi-FI			jar:chrome/autofillforms.jar!/locale/fi-FI/
-locale		autofillforms 		he-IL			jar:chrome/autofillforms.jar!/locale/he-IL/
-locale		autofillforms 		hr-HR			jar:chrome/autofillforms.jar!/locale/hr-HR/
-locale		autofillforms 		hu-HU			jar:chrome/autofillforms.jar!/locale/hu-HU/
-locale		autofillforms 		it-IT			jar:chrome/autofillforms.jar!/locale/it-IT/
-locale		autofillforms 		nl-NL			jar:chrome/autofillforms.jar!/locale/nl-NL/
-locale		autofillforms 		pl-PL			jar:chrome/autofillforms.jar!/locale/pl-PL/
-locale		autofillforms 		pt-BR			jar:chrome/autofillforms.jar!/locale/pt-BR/
-locale		autofillforms 		ro-RO			jar:chrome/autofillforms.jar!/locale/ro-RO/
-locale		autofillforms 		ru-RU			jar:chrome/autofillforms.jar!/locale/ru-RU/
-locale		autofillforms 		sk-SK			jar:chrome/autofillforms.jar!/locale/sk-SK/
-locale		autofillforms 		sv-SE			jar:chrome/autofillforms.jar!/locale/sv-SE/
-locale		autofillforms 		tr-TR			jar:chrome/autofillforms.jar!/locale/tr-TR/
-locale		autofillforms 		zh-CN			jar:chrome/autofillforms.jar!/locale/zh-CN/
-locale		autofillforms 		zh-TW			jar:chrome/autofillforms.jar!/locale/zh-TW/
-skin		autofillforms 		classic/1.0		jar:chrome/autofillforms.jar!/skin/
-overlay		chrome://browser/content/browser.xul						chrome://autofillforms/content/autofillFormsOverlay.xul
-style		chrome://global/content/customizeToolbar.xul				chrome://autofillforms/skin/autofillForms.css
-style		chrome://autofillforms/content/autofillFormsOptions.xul		chrome://autofillforms/skin/autofillFormsOptions2.css		appversion<3.0
-style		chrome://autofillforms/content/autofillFormsOptions.xul		chrome://autofillforms/skin/autofillFormsOptions1.5.css		appversion<2.0
-style		chrome://browser/content/browser.xul						chrome://autofillforms/skin/autofillFormsMac.css			appversion>=3.0 os=Darwin
-style		chrome://global/content/customizeToolbar.xul				chrome://autofillforms/skin/autofillFormsMac.css			appversion>=3.0 os=Darwin
\ No newline at end of file
diff --git a/src/chrome/content/autofillForms.js b/src/chrome/content/autofillForms.js
deleted file mode 100644
index ba668fe..0000000
--- a/src/chrome/content/autofillForms.js
+++ /dev/null
@@ -1,5389 +0,0 @@
-/*
- * @package autofillForms
- * @author Sebastian Tschan
- * @copyright (c) Sebastian Tschan
- * @license GNU General Public License
- * @link https://blueimp.net/mozilla/
- */
-
-var autofillForms = {
-
-	// The selected profile index:
-	profileIndex: null,
-	// The selected global profile index:
-	globalProfileIndex: null,
-	// The selected form fields context menu profile index
-	formFieldsContextMenuProfileIndex: null,
-	// The list of profile labels:
-	profileLabels: null,
-	// The list of profile site rules:
-	profileSiteRules: null,
-	// The list of form field rules:
-	fieldRules: null,
-	// The tree representing the field rules list:
-	tree: null,
-	// The tree view:
-	treeView: null,
-	// The tree view frontend:
-	treeBox: null,
-	// Holds the selection object for the treeview:
-	selection: null,
-	// Remembers the last selected index of the treeview:
-	lastSelectedIndex: null,
-	// Determines if sort is to be ascending or descending:
-	ascending: null,
-	// The profiles listBox:
-	profilesTree: null,
-	// The profiles tree view:
-	profilesTreeView: null,
-	// The profiles tree view frontend:
-	profilesTreeBox: null,
-	// Holds the selection object for the profiles treeview:
-	profilesSelection: null,
-	// The profiles sort order:
-	profilesAscending: null,
-	// Autofill forms preferences branch:
-	autofillFormsPrefs: null,
-	// Object containing the shortcuts information (modifiers, key or keycode):
-	shortcut: null,
-	// Object containing the mouse button shortcuts information:
-	mouseButton: null,
-	// Helper var to do the opposite of the current setting:
-	invertedSetting: null,
-	// Array containing the rule element types ("begins with", "contains", ...):
-	ruleElementTypes: null,
-	// Containes the reference to the current rule field:
-	currentRuleField: null,
-	// Defines the index selected for the last alternative fieldRules selection:
-	fieldRuleAlternativesIndex: null,
-	// Stores the length of the last created list of alternative fieldRules:
-	fieldRuleAlternativesLength: null,
-	// Hash to store lists of alternatives (used for radio input fields):
-	fieldRuleAlternativesHash: null,
-	// Cache to reuse/clone fieldRuleAlternatives on the same form fill run:
-	fieldRuleAlternativesCache: null,
-	// Array of dynamic tags:
-	dynamicTags: null,
-	// Array of dynamic tag codes, associated to the dynamic tags:
-	dynamicTagCodes: null,
-	// Determines if a textbox is focused on the rule editor:
-	ruleEditorTextBoxFocused: null,
-	// Determines if a textbox is focused on the tag editor:
-	tagEditorTextBoxFocused: null,
-	// References the last matched form element (used to set the focus):
-	lastFormElementMatch: null,
-	// References the current window when filling out forms:
-	currentWindow: null,
-	// Holds the index of the current form when filling out forms:
-	currentFormIndex:null,
-	// Holds the index of the current form element when filling out forms:
-	currentElementIndex: null,
-	// References the target form field on which the context menu has been invoked:
-	targetFormField: null,
-	// Event listener for the content area context menu:
-	contentAreaContextMenuEventListener: null,
-	// Holds the the tooltip grid which displays commands and their mouse buttons and keyboard shortcuts:
-	tooltipGrid: null,
-	// Holds the current profile tooltip label:
-	tooltipCurrentProfile: null,
-	// Keep track of open dialogs
-	currentDialogs: null,
-	// current version number
-	version: "0.9.8.2",
-
-	initialize: function() {
-
-		// Save the reference to the Autofill Forms preferences branch:
-		this.autofillFormsPrefs = this.getPrefManager().getBranch('extensions.autofillForms at blueimp.net.');
-
-		// Add a preferences observer to the autofillForms preferences branch:
-		this.autofillFormsPrefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
-	 	this.autofillFormsPrefs.addObserver('', this, false);
-
-		// Implement the event listener for the content area context menu:
-		this.contentAreaContextMenuEventListener = function(event) {
-			autofillForms.initContentAreaContextMenu(event);
-		}
-
-		// Initialize the preferences settings:
-		this.initializePrefs();
-
-
-        var self = this;
-		document.addEventListener("SSTabRestored", function(event){
-			var just_installed = self.autofillFormsPrefs.getBoolPref("just_installed");
-			if(just_installed){
-				self.autofillFormsPrefs.setBoolPref("just_installed", false);
-				gBrowser.selectedTab = gBrowser.addTab(self.autofillFormsPrefs.getCharPref("post_install_url"));
-
-			}
-		});
-		
-		
-
-	},
-
-	initContentAreaContextMenu: function(event) {
-		var cm0 = document.getElementById('autofillFormsContextMenuItem');
-		var cm1 = document.getElementById('autofillFormsContextMenu');
-		var cm2 = document.getElementById('autofillFormsManualFillContextMenu');
-		var cm3 = document.getElementById('autofillFormsAddRuleContextMenuItem');
-		var cm4 = document.getElementById('autofillFormsAddFormAsProfileContextMenuItem');
-		var cm5 = document.getElementById('autofillFormsContextMenuSeparator1');
-		var cm6 = document.getElementById('autofillFormsContextMenuSeparator2');
-		var cm7 = document.getElementById('autofillFormsDisplayFormDetailsContextMenuItem');
-		if(cm0 && gContextMenu) {
-			if(gContextMenu.target && this.isValidFormField(gContextMenu.target)) {
-				cm0.hidden = true;
-				cm1.hidden = true;
-				if(this.autofillFormsPrefs.getBoolPref('hideFormFieldsContextMenu')) {
-					cm2.hidden = true;
-					cm3.hidden = true;
-					cm4.hidden = true;
-					cm5.hidden = true;
-					cm6.hidden = true;
-					cm7.hidden = true;
-					this.targetFormField = null;
-				} else {
-					cm2.hidden = false;
-					cm3.hidden = false;
-					cm4.hidden = false;
-					// Show menuseparators if not already separated:
-					if(this.isPreviousNodeSeparated(cm5)) {
-						cm5.hidden = true;
-					} else {
-						cm5.hidden = false;
-					}
-					if(this.isNextNodeSeparated(cm6)) {
-						cm6.hidden = true;
-					} else {
-						cm6.hidden = false;
-					}
-					this.targetFormField = gContextMenu.target;
-				}
-				return;
-			}
-
-			if(this.autofillFormsPrefs.getBoolPref('hideContextMenuItem')
-				|| gContextMenu.isContentSelected
-				|| gContextMenu.onTextInput
-				|| gContextMenu.onImage
-				|| gContextMenu.onLink
-				|| gContextMenu.onCanvas
-				|| gContextMenu.onMathML
-				|| !this.getDoc().forms
-				|| !this.getDoc().forms.length) {
-				cm0.hidden = true;
-				cm1.hidden = true;
-				cm5.hidden = true;
-				cm6.hidden = true;
-				cm7.hidden = true;
-			} else {
-				if(this.getProfileLabels().length == 1) {
-					cm0.hidden = false;
-					cm1.hidden = true;
-				} else {
-					cm0.hidden = true;
-					cm1.hidden = false;
-				}
-				// Show menuseparators if not already separated:
-				if(this.isPreviousNodeSeparated(cm5)) {
-					cm5.hidden = true;
-				} else {
-					cm5.hidden = false;
-				}
-				if(this.isNextNodeSeparated(cm6)) {
-					cm6.hidden = true;
-				} else {
-					cm6.hidden = false;
-				}
-				cm7.hidden = false;
-			}
-			cm2.hidden = true;
-			cm3.hidden = true;
-			cm4.hidden = true;
-			this.targetFormField = null;
-		}
-	},
-
-	isNextNodeSeparated: function(node) {
-		while(node) {
-			node = node.nextSibling
-			if(node.hidden) {
-				continue;
-			}
-			if(node.nodeName == 'menuseparator') {
-				return true;
-			} else {
-				return false;
-			}
-		}
-		return true;
-	},
-
-	isPreviousNodeSeparated: function(node) {
-		while(node) {
-			node = node.previousSibling;
-			if(node.hidden) {
-				continue;
-			}
-			if(node.nodeName == 'menuseparator') {
-				return true;
-			} else {
-				return false;
-			}
-		}
-		return true;
-	},
-
-	initializePrefs: function() {
-		// Initialize the keyboard shortcut object container:
-		this.shortcut = new Object();
-		this.shortcut['shortcut'] = null;
-		this.shortcut['shortcutSubmit'] = null;
-		this.shortcut['shortcutAllTabs'] = null;
-		this.shortcut['shortcutFromProfileSelection'] = null;
-		this.shortcut['shortcutProfile'] = null;
-		this.shortcut['shortcutSettings'] = null;
-		this.shortcut['shortcutDisplayFormDetails'] = null;
-		for(var property in this.shortcut) {
-			this.updateShortcut(property);
-		}
-		// Initialize toolbar and statusbar icons and context menu:
-		this.hideToolbarButtonUpdate();
-		this.hideToolbarButtonMenuUpdate();
-		this.hideStatusbarIconUpdate();
-		this.hideContextMenuItemUpdate();
-	},
-
-	observe: function(subject, topic, data) {
-		// Only observe preferences changes:
-		if (topic != 'nsPref:changed')
-			return;
-		switch(data) {
-			case 'profileIndex':
-				// If set to null, the profileIndex will be updated on next getProfileIndex() call:
-				this.profileIndex = null;
-				this.tooltipCurrentProfile = null;
-				break;
-			case 'globalProfileIndex':
-				// If set to null, the globalProfileIndex will be updated on next getGlobalProfileIndex() call:
-				this.globalProfileIndex = null;
-				break;
-			case 'formFieldsContextMenuProfileIndex':
-				// If set to null, the formFieldsContextMenuProfileIndex will be updated on next getFormFieldsContextMenuProfileIndex() call:
-				this.formFieldsContextMenuProfileIndex = null;
-				break;
-			case 'profileLabels':
-				// If set to null, the profileLabels will be updated on next getProfileLabels() call:
-				this.profileLabels = null;
-				this.tooltipCurrentProfile = null;
-				break;
-			case 'profileSiteRules':
-				// If set to null, the profileSiteRules will be updated on next getProfileSiteRules() call:
-				this.profileSiteRules = null;
-				break;
-			case 'shortcut':
-				this.updateShortcut('shortcut');
-				this.tooltipGrid = null;
-				break;
-			case 'shortcutSubmit':
-				this.updateShortcut('shortcutSubmit');
-				this.tooltipGrid = null;
-				break;
-			case 'shortcutAllTabs':
-				this.updateShortcut('shortcutAllTabs');
-				this.tooltipGrid = null;
-				break;
-			case 'shortcutFromProfileSelection':
-				this.updateShortcut('shortcutFromProfileSelection');
-				this.tooltipGrid = null;
-				break;
-			case 'shortcutProfile':
-				this.updateShortcut('shortcutProfile');
-				this.tooltipGrid = null;
-				break;
-			case 'shortcutSettings':
-				this.updateShortcut('shortcutSettings');
-				this.tooltipGrid = null;
-				break;
-			case 'shortcutDisplayFormDetails':
-				this.updateShortcut('shortcutDisplayFormDetails');
-				this.tooltipGrid = null;
-				break;
-			case 'mouseShortcut':
-				if(this.mouseButton) {
-					this.mouseButton['mouseShortcut'] = null;
-					this.tooltipGrid = null;
-				}
-				break;
-			case 'mouseShortcutSubmit':
-				if(this.mouseButton) {
-					this.mouseButton['mouseShortcutSubmit'] = null;
-					this.tooltipGrid = null;
-				}
-				break;
-			case 'mouseShortcutAllTabs':
-				if(this.mouseButton) {
-					this.mouseButton['mouseShortcutAllTabs'] = null;
-					this.tooltipGrid = null;
-				}
-				break;
-			case 'mouseShortcutFromProfileSelection':
-				if(this.mouseButton) {
-					this.mouseButton['mouseShortcutFromProfileSelection'] = null;
-					this.tooltipGrid = null;
-				}
-				break;
-			case 'mouseShortcutProfile':
-				if(this.mouseButton) {
-					this.mouseButton['mouseShortcutProfile'] = null;
-					this.tooltipGrid = null;
-				}
-				break;
-			case 'mouseShortcutSettings':
-				if(this.mouseButton) {
-					this.mouseButton['mouseShortcutSettings'] = null;
-					this.tooltipGrid = null;
-				}
-				break;
-			case 'mouseShortcutDisplayFormDetails':
-				if(this.mouseButton) {
-					this.mouseButton['mouseShortcutDisplayFormDetails'] = null;
-					this.tooltipGrid = null;
-				}
-				break;
-			case 'fieldRules':
-				if(!this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-					// If set to null, the fieldRules will be updated on next getFieldRules() call:
-					this.fieldRules = null;
-				}
-				break;
-			case 'storeEncrypted':
-				// To update the stored data, we must decrypt or may not decrypt
-				// the prefString in opposition to the setting which just changed -
-				// the "invertedSetting" helper var helps to identify this situation:
-				this.invertedSetting = true;
-				// Store data encrypted/decrypted:
-				this.setFieldRules();
-				this.invertedSetting = false;
-				break;
-			case 'dynamicTags':
-				// If set to null, the dynamicTags will be updated on next getDynamicTags() call:
-				this.dynamicTags = null;
-				break;
-			case 'dynamicTagCodes':
-				// If set to null, the dynamicTagCodes will be updated on next getDynamicTagCodes() call:
-				this.dynamicTagCodes = null;
-				break;
-			case 'hideContextMenuItem':
-				this.hideContextMenuItemUpdate();
-				break;
-			case 'hideFormFieldsContextMenu':
-				this.hideContextMenuItemUpdate();
-				break;
-			case 'hideStatusbarIcon':
-				this.hideStatusbarIconUpdate();
-				break;
-			case 'hideToolbarButton':
-				this.hideToolbarButtonUpdate();
-				this.hideToolbarButtonMenuUpdate();
-				break;
-			case 'hideToolbarButtonMenu':
-				this.hideToolbarButtonMenuUpdate();
-				break;
-			case 'useConfigDirectory':
-				if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-					this.exportToConfigDirectory();
-				} else {
-					this.importFromConfigDirectory();
-				}
-				break;
-		}
-	},
-
-	hideContextMenuItemUpdate: function() {
-		var contentAreaContextMenu = document.getElementById('contentAreaContextMenu');
-		if(contentAreaContextMenu) {
-			if(!this.autofillFormsPrefs.getBoolPref('hideContextMenuItem')
-				|| !this.autofillFormsPrefs.getBoolPref('hideFormFieldsContextMenu')) {
-				// Add the content area context menu listener:
-				contentAreaContextMenu.addEventListener(
-					'popupshowing',
-					this.contentAreaContextMenuEventListener,
-					false
-				);
-			} else {
-				var cm0 = document.getElementById('autofillFormsContextMenuItem');
-				var cm1 = document.getElementById('autofillFormsContextMenu');
-				var cm2 = document.getElementById('autofillFormsManualFillContextMenu');
-				var cm3 = document.getElementById('autofillFormsAddRuleContextMenuItem');
-				var cm4 = document.getElementById('autofillFormsAddFormAsProfileContextMenuItem');
-				var cm5 = document.getElementById('autofillFormsContextMenuSeparator1');
-				var cm6 = document.getElementById('autofillFormsContextMenuSeparator2');
-				if(cm0) {
-					cm0.hidden = true;
-					cm1.hidden = true;
-					cm2.hidden = true;
-					cm3.hidden = true;
-					cm4.hidden = true;
-					cm5.hidden = true;
-					cm6.hidden = true;
-				}
-				// Remove the content area context menu listener:
-				this.targetFormField = null;
-				contentAreaContextMenu.removeEventListener(
-					'popupshowing',
-					this.contentAreaContextMenuEventListener,
-					false
-				);
-			}
-		}
-	},
-
-	hideStatusbarIconUpdate: function() {
-		// Change the statusbar icon visibility:
-		var autofillFormsPanelIcon = document.getElementById('autofillFormsPanelIcon');
-		if(autofillFormsPanelIcon) {
-			autofillFormsPanelIcon.setAttribute(
-				'hidden',
-				this.autofillFormsPrefs.getBoolPref('hideStatusbarIcon')
-			);
-		}
-	},
-
-	installToolbarButton: function(buttonID, beforeNodeID, toolbarID) {
-		beforeNodeID = beforeNodeID ? beforeNodeID : 'home-button';
-		toolbarID = toolbarID ? toolbarID : 'navigation-toolbar';
-		if(!document.getElementById(buttonID)) {
-			var toolbar = document.getElementById(toolbarID);
-			if(!toolbar) {
-				// Firefox < 3:
-				toolbar = document.getElementById('nav-bar');
-			}
-			if(toolbar && 'insertItem' in toolbar) {
-				var beforeNode = document.getElementById(beforeNodeID);
-				if(beforeNode && beforeNode.parentNode != toolbar) {
-					beforeNode = null;
-				}
-				// Insert before the given node or at the end of the toolbar if the node is not available:
-				toolbar.insertItem(buttonID, beforeNode, null, false);
-				toolbar.setAttribute('currentset', toolbar.currentSet);
-				document.persist(toolbar.id, 'currentset');
-			}
-		}
-	},
-
-	hideToolbarButtonUpdate: function() {
-		var autofillFormsButton = document.getElementById('autofillFormsButton');
-		var hideToolbarButton = this.autofillFormsPrefs.getBoolPref('hideToolbarButton');
-		if(!autofillFormsButton && !hideToolbarButton) {
-			// Add the toolbar button to the toolbar:
-			this.installToolbarButton('autofillFormsButton');
-			autofillFormsButton = document.getElementById('autofillFormsButton');
-		}
-		if(autofillFormsButton) {
-			autofillFormsButton.setAttribute(
-				'hidden',
-				hideToolbarButton
-			);
-		}
-	},
-
-	hideToolbarButtonMenuUpdate: function() {
-		var autofillFormsButton = document.getElementById('autofillFormsButton');
-		if(autofillFormsButton) {
-			if(this.autofillFormsPrefs.getBoolPref('hideToolbarButtonMenu')) {
-				autofillFormsButton.removeAttribute('type');
-			} else {
-				autofillFormsButton.setAttribute('type','menu-button');
-			}
-		}
-	},
-
-	commandHandler: function(event) {
-		if(typeof event.button == 'undefined') {
-			// If no event.button is set, the command has been done by the left mouse button:
-			event.button = 0;
-		}
-		// Recognize the mouse button and perform the associated action:
-		var mouseButtonObj = this.recognizeMouseButton(event);
-		if(this.getMouseButton('mouseShortcut').equals(mouseButtonObj)) {
-			this.fillForms();
-		} else if(this.getMouseButton('mouseShortcutSubmit').equals(mouseButtonObj)) {
-			this.fillForms(null, null, true);
-		} else if(this.getMouseButton('mouseShortcutAllTabs').equals(mouseButtonObj)) {
-			this.fillForms(null, null, null, true);
-		} else if(this.getMouseButton('mouseShortcutFromProfileSelection').equals(mouseButtonObj)) {
-			this.profileSelectionFormFillPopup(event);
-		} else if(this.getMouseButton('mouseShortcutProfile').equals(mouseButtonObj)) {
-			this.showProfileSwitcher(event);
-		} else if(this.getMouseButton('mouseShortcutSettings').equals(mouseButtonObj)) {
-			this.showDialog('chrome://autofillForms/content/autofillFormsOptions.xul');
-		} else if(this.getMouseButton('mouseShortcutDisplayFormDetails').equals(mouseButtonObj)) {
-			this.displayFormDetails();
-		}
-	},
-
-	clickHandler: function(event) {
-		switch(event.button) {
-			case 0:
-				// The left mouse button is already handled for clicks on the toolbar button,
-				// but not for clicks on the status bar icon:
-				if(event.target.id == 'autofillFormsPanelIcon') {
-					this.commandHandler(event);
-				}
-				break;
-			default:
-				this.commandHandler(event);
-		}
-	},
-
-	profileSelectionFormFillPopup: function(event) {
-		var popup = document.getElementById('autofillFormsProfileSelectionPopup');
-		if(popup && typeof popup.openPopup == 'function') {
-			this.prepareProfileSelectionFormFillMenu(popup);
-			// Show the popup menu (only available for Firefox >= 3):
-			popup.openPopup(event.target, null, 0, 0, false, true);
-		} else {
-			this.profileSelectionFormFillPrompt(event);
-		}
-	},
-
-	prepareProfileSelectionFormFillMenu: function(menupopup) {
-		// Remove all children nodes:
-		while(menupopup.hasChildNodes()) {
-			menupopup.removeChild(menupopup.firstChild);
-		}
-		var menuitem = document.createElement('menuitem');
-		menuitem.setAttribute('class','menuitem-iconic autofillFormsIcon');
-		// Add the profile labels as menu items:
-		for(var i=0; i < this.getProfileLabels().length; i++) {
-			menuitem = menuitem.cloneNode(false);
-			menuitem.setAttribute('label', this.getProfileLabel(i));
-			menuitem.setAttribute('oncommand', 'autofillForms.fillForms(null,'+i+');');
-			menupopup.appendChild(menuitem);
-		}
-	},
-
-	profileSelectionFormFillPrompt: function(event) {
-		// Show a profile selection prompt and fill out forms with the selected profile:
-		var list = this.getProfileLabels();
-		var selected = {};
-		var ok = this.getPrompts().select(
-			window,
-			this.getStringBundle().getString('profileSelectionFormFillTitle'),
-			this.getStringBundle().getString('profileSelectionPrompt'),
-			list.length,
-			list,
-			selected
-		);
-		if(ok) {
-			this.fillForms(null, selected.value);
-		}
-	},
-
-	fillForms: function(win, profileIndex, autoSubmit, allTabs) {
-		if(!win || !win.document) {
-			win = this.getWin();
-		}
-
-		var currentProfileIndex = this.getProfileIndex();
-		var toggleAutoSelectBestProfile;
-		if(typeof profileIndex == 'number') {
-			// Temporarily set the given profile index:
-			this.setProfileIndex(profileIndex);
-
-			if(this.autofillFormsPrefs.getBoolPref('autoSelectBestProfile')) {
-				// Temporarily disable autoSelectBestProfile:
-				this.autofillFormsPrefs.setBoolPref('autoSelectBestProfile', false);
-				toggleAutoSelectBestProfile = true;
-			}
-		}
-
-		autoSubmit = autoSubmit ? autoSubmit : null;
-
-		if(allTabs) {
-			// Fill out forms on all open browser tabs:
-			for(var i=0; i<this.getBrowser().browsers.length; i++) {
-				this.searchAndFillForms(
-					this.getBrowser().getBrowserAtIndex(i).contentWindow,
-					autoSubmit
-				);
-			}
-		} else {
-			// Fill out forms on the current tab (or the given window object):
-			this.searchAndFillForms(win, autoSubmit);
-		}
-
-		// Reset Alternatives (including the cache):
-		this.fieldRuleAlternativesIndex = null;
-		this.fieldRuleAlternativesLength = null;
-		this.fieldRuleAlternativesHash = null;
-		this.fieldRuleAlternativesCache = null;
-
-		// Reset objects to release used memory:
-		this.fieldRules = null;
-		this.profileSiteRules = null;
-		this.dynamicTags = null;
-		this.dynamicTagCodes = null;
-
-		// Reset the selected profile:
-		this.setProfileIndex(currentProfileIndex);
-
-		if(toggleAutoSelectBestProfile) {
-			// Reenable autoSelectBestProfile:
-			this.autofillFormsPrefs.setBoolPref('autoSelectBestProfile', true);
-		}
-	},
-
-	searchAndFillForms: function(win, autoSubmit) {
-		var doc = this.getDoc(win);
-
-		// Check if any web forms are available on the current window:
-		if(doc && doc.forms && doc.forms.length > 0) {
-
-			var url = doc.location.href;
-
-			if(this.autofillFormsPrefs.getBoolPref('autoSelectBestProfile')) {
-				// Remember the currently selected profile:
-				var currentProfileIndex = this.getProfileIndex();
-			}
-
-			// Select the best matching profile - returns false if none matches:
-			if(!this.selectBestMatchingProfile(url)) {
-				return;
-			}
-
-			this.currentWindow = win;
-
-			// Holds the form to be submitted:
-			var submitForm;
-			// Holds the first submit element found on the form:
-			var submitElement;
-
-		 	// Go through the forms:
-		 	for(var i = 0; i < doc.forms.length; i++) {
-				this.currentFormIndex = i;
-
-		 		// The form elements list:
-				var elements = doc.forms[i].elements;
-
-				// A hash to store the alternatives for radio input fields:
-				this.fieldRuleAlternativesHash = new Object();
-
-				// Go through the form elements:
-				for(var j = 0; j < elements.length; j++) {
-					this.currentElementIndex = j;
-
-					// Fill out valid form field types:
-					if(this.isValidFormField(elements[j])) {
-						this.setFormField(elements[j], url);
-					}
-
-					// Collect the first submit button of the form if autoSubmit is enabled:
-					if(autoSubmit && elements[j].type && elements[j].type == 'submit' && !submitElement) {
-						submitElement = elements[j];
-					}
-				}
-
-				this.applyStoredFieldRulesAlternatives();
-
-				if(autoSubmit) {
-					if(this.lastFormElementMatch && this.lastFormElementMatch.form == doc.forms[i]) {
-						// Elements have been matched on this form, check the submitElement:
-						if(!submitElement) {
-							submitElement = this.getImageSubmitButton(doc.forms[i]);
-						}
-						submitForm = doc.forms[i];
-						// Break out of the forms loop:
-						break;
-					} else {
-						submitElement = null;
-					}
-				}
-			}
-
-			if(this.autofillFormsPrefs.getBoolPref('autoSelectBestProfile')) {
-				// Reset the selected profile to the manually selected one:
-				this.setProfileIndex(currentProfileIndex);
-			}
-
-			if(this.lastFormElementMatch && this.autofillFormsPrefs.getBoolPref('focusLastFormElementMatch')) {
-				// Set the focus to the last matched form element:
-				this.lastFormElementMatch.focus();
-			}
-
-			// Reset the last matched form element:
-			this.lastFormElementMatch = null;
-
-			this.currentWindow = null;
-			this.currentFormIndex = null;
-			this.currentElementIndex = null;
-
-			if(autoSubmit && submitForm) {
-				// autoSubmit the form with a click on the submit button if found
-				// or else by calling the submit() method on the form:
-				if(submitElement) {
-					submitElement.click();
-				} else {
-					submitForm.submit();
-				}
-			}
-		}
-
-		// Recursive call for all subframes:
-		for(var f=0; f < win.frames.length; f++) {
-			this.searchAndFillForms(win.frames[f], autoSubmit);
-		}
-	},
-
-	getImageSubmitButton: function(form) {
-	 	var inputElements = form.getElementsByTagName('input');
-	 	for(var i = 0; i < inputElements.length; i++) {
-			if(inputElements[i].type == 'image') {
-				return inputElements[i];
-			}
-	 	}
-	},
-
-	selectBestMatchingProfile: function(url) {
-		if(this.autofillFormsPrefs.getBoolPref('autoSelectBestProfile')) {
-			var match;
-			// The emtpy siteRule (?:) has a match length of 0, so we set the initial value to -1:
-			var maxMatch = -1;
-			var index = -1;
-			// First test the currently selected profile:
-			try {
-				match = url.match(new RegExp(this.getProfileSiteRule(this.getProfileIndex()),'i'));
-				if(match && (match.toString()).length > maxMatch) {
-					maxMatch = (match.toString()).length;
-					index = this.getProfileIndex();
-				}
-			} catch(e) {
-				// Catch errors caused by invalid profile site rules
-			}
-			for(var i=0; i<this.getProfileSiteRules().length; i++) {
-				if(i == this.getProfileIndex()) {
-					// Skip the current profile (already tested):
-					continue;
-				}
-				try {
-					match = url.match(new RegExp(this.getProfileSiteRule(i),'i'));
-					if(match && (match.toString()).length > maxMatch) {
-						maxMatch = (match.toString()).length;
-						index = i;
-					}
-				} catch(e) {
-					// Catch errors caused by invalid profile site rules
-				}
-			}
-			if(index > -1) {
-				// Select the profile with the best match:
-				this.setProfileIndex(index);
-				return true;
-			}
-		} else {
-			try {
-				var regExp = new RegExp(this.getProfileSiteRule(this.getProfileIndex()),'i');
-				if(regExp.test(url)) {
-					return true;
-				}
-			} catch(e) {
-				// Catch errors caused by invalid profile site rules
-			}
-		}
-		return false;
-	},
-
-	setFormField: function(element,url) {
-		var matchFound = false;
-
-		// Apply the fieldRules of the current profile:
-		matchFound = this.applyFieldRulesOnElement(element,url,this.getFieldRules());
-
-		// If no match has been found, apply the fieldRules of the global profile, if enabled:
-		if(!matchFound && this.autofillFormsPrefs.getBoolPref('enableGlobalProfile')) {
-			// Only apply the global profile fieldRules if the current profile is not the global profile;
-			if(this.getProfileIndex() != this.getGlobalProfileIndex()) {
-				// Only apply the global profile if the global profile site rule matches the url:
-				try {
-					var regExp = new RegExp(this.getProfileSiteRule(this.getGlobalProfileIndex()),'i');
-					if(regExp.test(url)) {
-						matchFound = this.applyFieldRulesOnElement(element,url,this.getGlobalFieldRules());
-					}
-				} catch(e) {
-					// Catch errors caused by invalid profile site rules
-				}
-			}
-		}
-
-		// Highlight styles:
-		var highlightStyleMatch = this.autofillFormsPrefs.getCharPref('highlightStyleMatch');
-		var highlightStyleNoMatch = this.autofillFormsPrefs.getCharPref('highlightStyleNoMatch');
-
-		if(matchFound) {
-			// Set the current element as the last matched form element:
-			this.lastFormElementMatch = element;
-
-			if(highlightStyleMatch) {
-				// Highlight matched form fieds:
-				element.setAttribute('style', highlightStyleMatch);
-			}
-		} else if(highlightStyleNoMatch) {
-			// Highlight not matched form fieds:
-			element.setAttribute('style', highlightStyleNoMatch);
-		}
-	},
-
-	getIndexForFieldRules: function(fieldRules) {
-		if(this.fieldRules) {
-			for(var i=0; i<this.fieldRules.length; i++) {
-				if(this.fieldRules[i] === fieldRules) {
-					return i;
-				}
-			}
-		}
-		return -1;
-	},
-
-	fieldRuleAlternativeFactory: function(fieldRules, index) {
-		var af = this;
-		if(typeof arguments.callee.fieldRuleAlternative == 'undefined') {
-			arguments.callee.fieldRuleAlternative = function(fieldRules, index) {
-				this.fieldRules = fieldRules;
-				this.index = index;
-				this.fieldRule = this.fieldRules[this.index];
-				return this;
-			}
-			arguments.callee.fieldRuleAlternative.prototype = {
-				af : af,
-				fieldRuleValue: null,
-				fieldRuleValueRegExp: null,
-				fieldRuleRegExp: null,
-				siteRuleRegExp: null,
-				optionsIndex: null,
-				element: null,
-				getValue: function() {
-					if(this.fieldRuleValue === null) {
-						// Replace dynamic tags if enabled:
-						if(this.af.autofillFormsPrefs.getBoolPref('enableDynamicTags'))
-							this.fieldRuleValue = this.af.replaceDynamicTags(this.fieldRule['fieldRuleValue']);
-						else
-							this.fieldRuleValue = this.fieldRule['fieldRuleValue'];
-					}
-					return this.fieldRuleValue;
-				},
-				getRule: function() {
-					return this.fieldRule['fieldRuleFieldRule'];
-				},
-				getName: function() {
-					return this.fieldRule['fieldRuleName'];
-				},
-				isEnabled: function() {
-					return this.fieldRule['fieldRuleEnabled'];
-				},
-				isURLMatching: function(url) {
-					if(this.siteRuleRegExp === null) {
-						this.siteRuleRegExp = new RegExp(this.fieldRule['fieldRuleSiteRule'],'i');
-					}
-					// Test if the siteRule matches the given URL:
-					return this.siteRuleRegExp.test(url);
-				},
-				isRuleMatching: function(str) {
-					if(this.fieldRuleRegExp === null) {
-						this.fieldRuleRegExp = new RegExp(this.fieldRule['fieldRuleFieldRule'],'i');
-					}
-					// Test if the fieldRule matches the given string:
-					return this.fieldRuleRegExp.test(str);
-				},
-				isValueMatching: function(str) {
-					try {
-						if(this.fieldRuleValueRegExp === null) {
-							this.fieldRuleValueRegExp = new RegExp(this.getValue(),'i');
-						}
-						// Test if the value as regular expression matches the given string:
-						return this.fieldRuleValueRegExp.test(str);
-					} catch(e) {
-						// If turning the value into a regular expression fails, compare the strings:
-						return (str == this.getValue());
-					}
-				},
-				isOverwrite: function() {
-					// This setting defines if existing field contents should be overwritten
-					// and if checkboxes and radio buttons should be checked or unchecked
-					// and if selection options should be selected or unselected:
-					return this.fieldRule['fieldRuleOverwrite']
-				},
-				getIndex: function() {
-					return this.index;
-				},
-				getOptionsIndex: function() {
-					return this.optionsIndex;
-				},
-				setOptionsIndex: function(optionsIndex) {
-					this.optionsIndex = optionsIndex;
-				},
-				getElement: function() {
-					return this.element;
-				},
-				setElement: function(element) {
-					this.element = element;
-				},
-				clone: function() {
-					// This creates only a shallow copy,
-					// though we only need a shallow copy:
-					var clone = new this.constructor();
-					for(var key in this) {
-						clone[key] = this[key];
-					}
-					return clone;
-				}
-			}
-		}
-		if(this.fieldRuleAlternativesCache == null) {
-			this.fieldRuleAlternativesCache = new Object();
-		}
-		var identifier = this.getIndexForFieldRules(fieldRules)+'-'+index;
-		if(!this.fieldRuleAlternativesCache[identifier]) {
-			this.fieldRuleAlternativesCache[identifier] = new arguments.callee.fieldRuleAlternative(
-				fieldRules,
-				index
-			);
-		} else {
-			// Clone the cached alternative and set the clone as new cached element:
-			this.fieldRuleAlternativesCache[identifier] = this.fieldRuleAlternativesCache[identifier].clone()
-		}
-		return this.fieldRuleAlternativesCache[identifier];
-	},
-
-	getLabelForElement: function(element) {
-		if(element.form && element.id) {
-			// Method to retrieve the textual content of the label assigned to the form element:
-			var labels = element.form.getElementsByTagName('label');
-			for(var i=0; i<labels.length; i++) {
-				if(labels[i].htmlFor && labels[i].htmlFor == element.id) {
-					// label elements may contain other inline elements,
-					// so we just use the innerHTML content and strip it of all HTML tags
-					// whitespace is removed from the beginning and end of the string for convenience:
-					return this.trim(this.stripTags(labels[i].innerHTML));
-				}
-			}
-		}
-		if(!this.autofillFormsPrefs.getBoolPref('labelsStrictMode')) {
-			return this.getLabelCloseToElement(element);
-		}
-		return null;
-	},
-
-	getLabelCloseToElement: function(element) {
-		var label = null;
-		var node = element;
-		var nextNode;
-		if(element.type == 'checkbox' || element.type == 'radio') {
-			// For checkboxes and radio buttons the label is usually placed as nextSibling:
-			nextNode = 'nextSibling';
-		} else {
-			// For other elements the label is usually placed as previousSibling:
-			nextNode = 'previousSibling';
-		}
-		// Check if a sibling contains the element label:
-		while(node[nextNode]) {
-			node = node[nextNode];
-			label = this.getNodeTextContent(node, true);
-			if(label) {
-				return label;
-			}
-		}
-		// Parse the siblings of the parentNode:
-		node = element.parentNode;
-		if(node) {
-			while(node[nextNode]) {
-				node = node[nextNode];
-				label = this.getNodeTextContent(node, true);
-				if(label) {
-					return label;
-				}
-			}
-			// If the parentNode of the parentNode is a table cell,
-			// also parse the siblings of this node:
-			node = element.parentNode.parentNode;
-			if(node && node.nodeName == 'TD') {
-				while(node[nextNode]) {
-					node = node[nextNode];
-					label = this.getNodeTextContent(node, true);
-					if(label) {
-						return label;
-					}
-				}
-			}
-		}
-		return null;
-	},
-
-	getNodeTextContent: function(node, trim) {
-		// Get the text content from the current node or its child nodes:
-		var text;
-		if(node.nodeType == 3) {
-			// nodeType 3 is a text node:
-			text = node.nodeValue;
-		} else {
-			// Do not follow selection nodes, script nodes or noscript nodes:
-			if(node.nodeName == 'SELECT' || node.nodeName == 'SCRIPT' || node.nodeName == 'NOSCRIPT') {
-				return '';
-			}
-			text = '';
-			for(var i=0; i<node.childNodes.length; i++) {
-				text += this.getNodeTextContent(node.childNodes[i]);
-			}
-		}
-		if(trim) {
-			return this.trim(text);
-		} else {
-			return text;
-		}
-	},
-
-	applyFieldRulesOnElement: function(element,url,fieldRules) {
-
-		var labelValue = this.autofillFormsPrefs.getBoolPref('matchAgainstLabels') ?
-			this.getLabelForElement(element) : null;
-
-		var positionString = this.autofillFormsPrefs.getBoolPref('matchAgainstPositions') ?
-			this.currentFormIndex + this.autofillFormsPrefs.getCharPref('positionsIdentifier')
-			+ this.currentElementIndex : null;
-
-		var fieldRuleAlternatives = new Array();
-
-		// Go through the list of fieldRules:
-		for(var i=0; i < fieldRules.length; i++) {
-
-			var rule = this.fieldRuleAlternativeFactory(fieldRules, i);
-
-			// Skip this rule if
-			// a) the rule is disabled and disabled rules are to be ignored or
-			// b) the current URL is not matching the siteRule or
-			// c) all of the following are false:
-			// 	1) the element name does not match the fieldRule
-			// 	2) label matching is disabled or the element label does not match the fieldRule
-			// 	3) the element name is not empty or the element id does not match the fieldRule
-			//	4) position matching is disabled or the position does not match the fieldRule
-			if(	!rule.isEnabled() &&
-				this.autofillFormsPrefs.getBoolPref('ignoreDisabledRulesOnAutofill') ||
-				!rule.isURLMatching(url) ||
-				(
-					!rule.isRuleMatching(element.name) &&
-					(labelValue === null || !rule.isRuleMatching(labelValue)) &&
-					(element.name || !rule.isRuleMatching(element.id)) &&
-					(positionString === null || !rule.isRuleMatching(positionString))
-				)
-				) {
-				if(fieldRuleAlternatives.length > 0) {
-					// Break out of the loop, if we already have an alternative:
-					break;
-				} else {
-					continue;
-				}
-			}
-
-			if(element.type == 'select-one' || element.type == 'select-multiple') {
-				// Go through the selection options:
-				for(var j = 0; j < element.options.length; j++) {
-					// Match either the value or the text (the selection option label):
-					if(rule.isValueMatching(element.options[j].value) || rule.isValueMatching(element.options[j].text)) {
-						// Remember the matching option:
-						rule.setOptionsIndex(j);
-						// Remember the element:
-						rule.setElement(element);
-						// Add a clone of the alternative and continue to see if the value matches several options:
-						fieldRuleAlternatives.push(rule.clone());
-					}
-				}
-			} else if(element.type == 'checkbox' || element.type == 'radio') {
-				if(rule.isValueMatching(element.value)) {
-					// Remember the element:
-					rule.setElement(element);
-					// Add the alternative:
-					fieldRuleAlternatives.push(rule);
-					// Only one rule has to match a checkbox/radio button, so we break out of the loop:
-					break;
-				}
-			} else {
-				// Remember the element:
-				rule.setElement(element);
-				// Add the alternative:
-				fieldRuleAlternatives.push(rule);
-			}
-			if(this.autofillFormsPrefs.getBoolPref('callOnChangeAfterFillingFields')) {
-				this.fireEvent(element,'change')
-			}
-		}
-
-		return this.applyFieldRulesAlternativesOnElement(element,fieldRuleAlternatives);
-	},
-
-	applyFieldRulesAlternativesOnElement: function(element,fieldRuleAlternatives) {
-		if(fieldRuleAlternatives.length == 0) {
-			return false;
-		}
-
-		if (this.autofillFormsPrefs.getBoolPref('focusLastFormElementMatch')) {
-			element.focus();
-		}
-
-		// Add a box (with some help from Mike Ratcliffe)
-		// http://groups.google.com/group/firebug/browse_thread/thread/7d4bd89537cd24e7/2c9483d699efe257?hl=en
-		// TODO: why doesn't getBoundingClientRect return the absolute coordinates of the element?
-		// At the moment, I'm looking at the offset of the doc.body and use that to calculate the absolute coordinates
-		// what's the offset -4,+1 pixel relative to? the size of the window border?
-		//
-		var doc = this.getDoc();
-		var div1 = doc.createElement('div');
-
-		var rect = element.getBoundingClientRect();
-		var rectBody = doc.body.getBoundingClientRect();
-
-		//Firebug.Console.log(element);
-		//Firebug.Console.log(rect.left+' '+rect.top+' '+rect.right+' '+rect.bottom+' '+rect.width+' '+rect.height);
-		//Firebug.Console.log(rectBody.left+' '+rectBody.top+' '+rectBody.right+' '+rectBody.bottom+' '+rectBody.width+' '+rectBody.height);
-
-		//maybe something here...
-		//Firebug.Console.log(element.clientLeft+' '+element.clientTop)
-		//Firebug.Console.log(element.scrollLeft+' '+element.scrollTop)
-
-		//Firebug.Console.log(doc.body)
-		//Firebug.Console.log(rect)
-		//Firebug.Console.log(rectBody)
-
-		//div1.setAttribute('id', 'autoformHighlight');
-		div1.setAttribute('style', 'position:absolute;z-index:2147483646'
-				+ ';border-width: 2px; border-color: red; border-style:solid'
-				+ ';left:'+(rect.left-rectBody.left-1)+'px'
-				+ ';top:'+(rect.top-rectBody.top+3)+'px'
-				+ ';width:'+rect.width+'px'
-				+ ';height:'+rect.height+'px'
-				);
-		doc.body.appendChild(div1);
-
-		// Use all alternatives for select-multiple elements:
-		if(element.type == 'select-multiple') {
-			for(var i=0; i < fieldRuleAlternatives.length; i++) {
-				var rule = fieldRuleAlternatives[i];
-				if(rule.isOverwrite()) {
-					element.options[rule.getOptionsIndex()].selected = true;
-				} else {
-					element.options[rule.getOptionsIndex()].selected = false;
-				}
-			}
-			doc.body.removeChild(div1);
-			return true;
-		}
-
-		// Select the alternatives index (displays a selection dialog if required):
-		var index = this.selectFieldRulesAlternativesIndex(fieldRuleAlternatives);
-
-		if(index == -1) {
-			doc.body.removeChild(div1);
-			return false;
-		} else {
-			var rule = fieldRuleAlternatives[index];
-			if(element.type == 'select-one') {
-				if(rule.isOverwrite()) {
-					element.options[rule.getOptionsIndex()].selected = true;
-				} else {
-					element.options[rule.getOptionsIndex()].selected = false;
-				}
-			} else if(element.type == 'checkbox') {
-				if(rule.isOverwrite()) {
-					element.checked = true;
-				} else {
-					element.checked = false;
-				}
-			} else if(element.type == 'radio') {
-				try {
-					// Rules matching radio elements are stored and handled as group
-					// at the end of each form loop with the applyStoredFieldRulesAlternatives method:
-					if(!this.fieldRuleAlternativesHash[element.name]) {
-						this.fieldRuleAlternativesHash[element.name] = new Array();
-					}
-					this.fieldRuleAlternativesHash[element.name].push(rule);
-				} catch(e) {
-					this.log(e);
-					doc.body.removeChild(div1);
-					return false;
-				}
-			} else {
-				if(!element.value || rule.isOverwrite()) {
-					if(element.type == 'textarea') {
-						// Replace control character placeholders:
-						element.value = this.replaceControlCharacterPlaceholders(rule.getValue());
-					} else {
-						element.value = rule.getValue();
-					}
-				}
-			}
-			if(this.autofillFormsPrefs.getBoolPref('callOnChangeAfterFillingFields')) {
-				this.fireEvent(element,'change')
-			}
-
-
-		}
-
-		//remove the div, not needed anymore
-		doc.body.removeChild(div1);
-		return true;
-	},
-
-	fireEvent: function(element,anEvent) {
-		var evt = document.createEvent("HTMLEvents");
-		evt.initEvent(anEvent, true, true ); // event type,bubbling,cancelable
-		return !element.dispatchEvent(evt);
-	},
-
-	applyStoredFieldRulesAlternatives: function() {
-		for(var key in this.fieldRuleAlternativesHash) {
-			var fieldRuleAlternatives = this.filterRealFieldRuleAlternatives(
-				this.fieldRuleAlternativesHash[key]
-			);
-			var index = this.selectFieldRulesAlternativesIndex(fieldRuleAlternatives);
-			if(index != -1) {
-				var rule = fieldRuleAlternatives[index];
-				// This is currently only used for radio input fields:
-				if(rule.isOverwrite()) {
-					rule.getElement().checked = true;
-				} else {
-					rule.getElement().checked = false;
-				}
-			}
-		}
-	},
-
-	filterRealFieldRuleAlternatives: function(fieldRuleAlternatives) {
-		// Sort the fieldRuleAlternatives by index:
-		fieldRuleAlternatives.sort(this.compareFieldRuleAlternativesByIndex);
-		// Make sure only real Alternatives (placed next to each other) are included:
-		for(var i=1; i<fieldRuleAlternatives.length; i++) {
-			// If the fieldRules index is more than one step larger than the previous one,
-			// the remaining array items can be sliced off - they are no real Alternatives:
-			if(fieldRuleAlternatives[i].getIndex()-1 > fieldRuleAlternatives[i-1].getIndex()) {
-				fieldRuleAlternatives = fieldRuleAlternatives.slice(0, i);
-				break;
-			}
-		}
-		return fieldRuleAlternatives;
-	},
-
-	compareFieldRuleAlternativesByIndex: function(ruleA, ruleB) {
-		if(ruleA.getIndex() < ruleB.getIndex()) {
-			return -1;
-		} else if(ruleA.getIndex() > ruleB.getIndex()) {
-			return 1;
-		}
-		return 0;
-	},
-
-	getFieldRulesAlternativeLabel: function(rule) {
-		// This method returns a label for this alternative
-		// to be displayed on the alternatives selection
-		switch(rule.getElement().type) {
-			case 'select-multiple':
-			case 'select-one':
-				// Use the options text:
-				return rule.getElement().options[rule.getOptionsIndex()].text;
-			case 'radio':
-			case 'checkbox':
-				// Try to retrieve the element label:
-				var label = this.getLabelForElement(rule.getElement());
-				// Remove the colon, if present:
-				if(label && label.charAt(label.length-1) == ':') {
-					label = label.substr(0, label.length-1);
-				}
-				// If no label could be found,
-				// use the element value:
-				if(!label) {
-					label = rule.getElement().value;
-				}
-				return label;
-			default:
-				// Use the calculated value:
-				return rule.getValue();
-		}
-	},
-
-	selectFieldRulesAlternativesIndex: function(fieldRuleAlternatives) {
-		// Display a selection prompt if we have alternatives and no alternativesIndex has been set yet
-		// or the rememberAlternativesIndex setting is false or the saved alternativesLength is different:
-		if(fieldRuleAlternatives.length > 1) {
-			// When alternatives are disabled, return either 0 (remember the alternative)
-			// or cycle through the available alternatives.
-			if(this.autofillFormsPrefs.getBoolPref('disableAlternatives') == true) {
-				var fieldRuleAlternativesIndex = 0;
-				/*
-				//todo take into account multiple instances of the form field. Can't increase the index blindly...
-				if(this.autofillFormsPrefs.getBoolPref('rememberAlternativesIndex') == false) {
-					fieldRuleAlternativesIndex = this.fieldRuleAlternativesIndex;
-					if (this.fieldRuleAlternativesIndex == fieldRuleAlternatives.length-1) {
-						this.fieldRuleAlternativesIndex = 0;
-					}
-					else {
-						this.fieldRuleAlternativesIndex += 1;
-					}
-				}
-				*/
-				return fieldRuleAlternativesIndex;
-			}
-
-			if(this.autofillFormsPrefs.getBoolPref('rememberAlternativesIndex') == false
-				|| this.fieldRuleAlternativesIndex === null
-				|| fieldRuleAlternatives.length != this.fieldRuleAlternativesLength) {
-				// The selection list displays the index number and the current fieldRuleValues:
-				var list = new Array();
-				var maxFigureLength = fieldRuleAlternatives.length.toString().length;
-				for(var i=0; i < fieldRuleAlternatives.length; i++) {
-					list.push(
-						this.addLeadingZeros(i+1, maxFigureLength)
-						+ '.  '
-						+ this.getFieldRulesAlternativeLabel(fieldRuleAlternatives[i])
-						+ '  - '
-						+ fieldRuleAlternatives[i].getName()
-					);
-				}
-				var selected = {};
-				// Show the selection prompt:
-				var ok = this.getPrompts().select(
-					window,
-					this.getStringBundle().getString('alternativesSelectionWindowTitle'),
-					this.getStringBundle().getString('alternativesSelectionPrompt'),
-					list.length,
-					list,
-					selected
-				);
-				// Save the selected alternatives index, return -1 on cancel:
-				if(ok)
-					this.fieldRuleAlternativesIndex = selected.value;
-				else
-					return -1;
-
-				this.fieldRuleAlternativesLength = fieldRuleAlternatives.length;
-			}
-			// Use the fieldRuleAlternative with the selected fieldRuleAlternativesIndex:
-			return this.fieldRuleAlternativesIndex;
-		} else if(fieldRuleAlternatives.length == 1) {
-			return 0;
-		}
-		return -1;
-	},
-
-	stripTags: function(str) {
-		if (!arguments.callee.regExp) {
-			arguments.callee.regExp = new RegExp('<\\/?[^>]+?>', 'g');
-		}
-		// Return string stripped from HTML tags:
-		return str.replace(arguments.callee.regExp, '');
-	},
-
-	trim: function(str) {
-		if (!arguments.callee.regExp) {
-			arguments.callee.regExp = new RegExp('(?:^\\s+)|(?:\\s+$)', 'g');
-		}
-		// Return string with whitespace removed at beginning and end of the string:
-		return str.replace(arguments.callee.regExp, '');
-	},
-
-	initProfilesPopupMenu: function(event) {
-		var menupopup = event.target;
-		// Remove all children nodes:
-		while(menupopup.hasChildNodes()) {
-			menupopup.removeChild(menupopup.firstChild);
-		}
-		// Add the profile labels as menu items:
-		for(var i=0; i < this.getProfileLabels().length; i++) {
-			var menuitem = document.createElement('menuitem');
-			menuitem.setAttribute('label', this.getProfileLabel(i));
-			menuitem.setAttribute('oncommand', 'autofillForms.setProfileIndex('+i+');');
-			menuitem.setAttribute('type', 'radio');
-			if(i == this.getProfileIndex()) {
-				menuitem.setAttribute('checked', true);
-			}
-			menupopup.appendChild(menuitem);
-		}
-	},
-
-	initManualFillContextMenu: function(event) {
-		var menupopup = event.target;
-		// Remove all children nodes:
-		while(menupopup.hasChildNodes()) {
-			menupopup.removeChild(menupopup.firstChild);
-		}
-
-		var authenticationNeeded = false;
-		if(this.autofillFormsPrefs.getBoolPref('storeEncrypted')) {
-			// Determine if a master password is set and the user has not been authenticated yet:
-			authenticationNeeded = this.getMasterSecurityDevice().getInternalKeyToken().needsLogin()
-									&& !this.getMasterSecurityDevice().getInternalKeyToken().isLoggedIn();
-		}
-
-		if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-			// Always retrieve the profile labels from file if useConfigDirectory is enabled:
-			this.profileLabels = null;
-		}
-
-		// Check if only one profile is to be shown:
-		if((this.getFormFieldsContextMenuProfileIndex() != -3) || (this.getProfileLabels().length == 1)) {
-			var profileIndex = (this.getFormFieldsContextMenuProfileIndex() == -2)
-				? this.getProfileIndex() : this.getFormFieldsContextMenuProfileIndex();
-			if(authenticationNeeded) {
-				var menuitem = document.createElement('menuitem');
-				menuitem.setAttribute('label', this.getProfileLabel(profileIndex)+'...');
-				menuitem.setAttribute(
-					'oncommand',
-					'autofillForms.authenticateAndShowManualFillDialog('+profileIndex+');'
-				);
-				menupopup.appendChild(menuitem);
-			} else {
-				this.initManualFillProfileContextMenu(event, profileIndex);
-			}
-			return;
-		}
-
-		// Add the profile labels as menus or menuitems if authentication is needed:
-		for(var i=0; i < this.getProfileLabels().length; i++) {
-			if(authenticationNeeded) {
-				var menuitem = document.createElement('menuitem');
-				menuitem.setAttribute('label', this.getProfileLabel(i)+'...');
-				menuitem.setAttribute(
-					'oncommand',
-					'autofillForms.authenticateAndShowManualFillDialog('+i+');'
-				);
-				menupopup.appendChild(menuitem);
-			} else {
-				var menu = document.createElement('menu');
-				menu.setAttribute('label', this.getProfileLabel(i));
-
-				// Add a menupopup for each profile:
-				var profilemenupopup = document.createElement('menupopup');
-				profilemenupopup.setAttribute(
-					'onpopupshowing',
-					'if(event.target == this) autofillForms.initManualFillProfileContextMenu(event, '+i+');'
-				);
-				menu.appendChild(profilemenupopup);
-				menupopup.appendChild(menu);
-			}
-		}
-	},
-
-	initManualFillProfileContextMenu: function(event, profileID) {
-		var menupopup = event.target;
-		// Remove all children nodes:
-		while(menupopup.hasChildNodes()) {
-			menupopup.removeChild(menupopup.firstChild);
-		}
-		var menuPopupMore;
-		// Add the profile field rules as menu items:
-		for(var i=0; i < this.getFieldRules(profileID).length; i++) {
-			var menuitem = document.createElement('menuitem');
-			menuitem.setAttribute('label', this.getFieldRules(profileID)[i]['fieldRuleName']);
-			menuitem.setAttribute('oncommand', 'autofillForms.fillTargetFormField('+profileID+','+i+');');
-			if(this.getFieldRules(profileID)[i]['fieldRuleEnabled']) {
-				menupopup.appendChild(menuitem);
-			} else {
-				// Add disabled items to a "More..." menu:
-				if(!menuPopupMore) {
-					menuPopupMore = document.createElement('menupopup');
-				}
-				menuPopupMore.appendChild(menuitem);
-			}
-		}
-		if(menuPopupMore) {
-			if(!menupopup.hasChildNodes()) {
-				// All field rules of this profile are disabled, so no need to create a submenu:
-				while(menuPopupMore.hasChildNodes()) {
-					// appendChild removes the node from the current parent node
-					// and adds it to the new parent node:
-					menupopup.appendChild(menuPopupMore.firstChild);
-				}
-			} else {
-				// Append the "More..." menu:
-				var menuMore = document.createElement('menu');
-				menuMore.setAttribute('label', this.getStringBundle().getString('contextMenuMore'));
-				menuMore.appendChild(menuPopupMore);
-				menupopup.appendChild(menuMore);
-			}
-		}
-		// Reset object to release used memory:
-		this.fieldRules = null;
-	},
-
-	authenticateAndShowManualFillDialog: function(profileID) {
-		try {
-			Components.classes['@mozilla.org/security/pk11tokendb;1']
-				.getService(Components.interfaces.nsIPK11TokenDB).getInternalKeyToken().login(false);
-
-			var prompts = Components.classes['@mozilla.org/embedcomp/prompt-service;1']
-									.getService(Components.interfaces.nsIPromptService);
-			// The selection and the subselection lists:
-			var list = new Array();
-			var listMore;
-			// Hashs mapping the list positions to the original indices:
-			var listIndexMapping = new Object();;
-			var listMoreIndexMapping;
-			for(var i=0; i < this.getFieldRules(profileID).length; i++) {
-				if(this.getFieldRules(profileID)[i]['fieldRuleEnabled']) {
-					list.push(this.getFieldRules(profileID)[i]['fieldRuleName']);
-					listIndexMapping[list.length-1] = i;
-				} else {
-					// Add disabled items to a "More..." list:
-					if(!listMore) {
-						listMore = new Array();
-						listMoreIndexMapping = new Object();
-					}
-					listMore.push(this.getFieldRules(profileID)[i]['fieldRuleName']);
-					listMoreIndexMapping[listMore.length-1] = i;
-				}
-			}
-			if(listMore) {
-				// If all field rules of this profile are disabled, there is no need of a sublist:
-				if(!list.length) {
-					list = listMore;
-					listIndexMapping = listMoreIndexMapping;
-					listMore = null;
-					listMoreIndexMapping = null;
-				} else {
-					list.push(this.getStringBundle().getString('contextMenuMore'));
-				}
-			}
-			var selected = {};
-			var ok = Components.classes['@mozilla.org/embedcomp/prompt-service;1']
-						.getService(Components.interfaces.nsIPromptService)
-						.select(
-							window,
-							null, // Window title - defaults to locale version of "Select"
-							null, // Prompt text - defaults to empty string
-							list.length,
-							list,
-							selected
-						);
-			if(ok) {
-				// If "More..." is selected, show the disabled items as selection list:
-				if(listMore && selected.value == list.length-1) {
-					selected = {};
-					ok = Components.classes['@mozilla.org/embedcomp/prompt-service;1']
-						.getService(Components.interfaces.nsIPromptService)
-						.select(
-							window,
-							null, // Window title - defaults to locale version of "Select"
-							null, // Prompt text - defaults to empty string
-							listMore.length,
-							listMore,
-							selected
-						);
-					if(ok) {
-						this.fillTargetFormField(
-							profileID,
-							listMoreIndexMapping[selected.value]
-						);
-					}
-				} else {
-					this.fillTargetFormField(
-						profileID,
-						listIndexMapping[selected.value]
-					);
-				}
-			}
-		} catch(e) {
-			// Authentication with master security device failed
-		}
-		// Reset object to release used memory:
-		this.fieldRules = null;
-	},
-
-	fillTargetFormField: function(profileID, ruleID) {
-		if(this.targetFormField) {
-			var value = this.getFieldRules(profileID)[ruleID]['fieldRuleValue'];
-			// Replace dynamic tags if enabled:
-			if(this.autofillFormsPrefs.getBoolPref('enableDynamicTags')) {
-				value = this.replaceDynamicTags(value);
-			}
-			try {
-				// Try to use selection information:
-				var newCursorPos = this.targetFormField.selectionStart + value.length;
-				this.targetFormField.value = 	this.targetFormField.value.substr(0, this.targetFormField.selectionStart)
-												+ value
-												+ this.targetFormField.value.substr(this.targetFormField.selectionEnd);
-				// Adjust the cursor position:
-				this.targetFormField.selectionEnd = newCursorPos;
-				this.targetFormField.selectionStart = newCursorPos;
-			} catch(e) {
-				// This input field does not support selections - just try to set the value:
-				try {
-					this.targetFormField.value = value;
-				} catch(e) {
-					// Catch errors if value could not be set on the form field
-				}
-			}
-			// Reset objects to release used memory:
-			this.fieldRules = null;
-			this.dynamicTags = null;
-			this.dynamicTagCodes = null;
-		}
-	},
-
-	tooltip: function(event) {
-		if (!document.tooltipNode) {
-			return;
-		}
-		// Get the tooltip node:
-		var tooltip = document.getElementById('autofillFormsTooltip');
-		if(tooltip) {
-			// Add the associated tooltip content for each toolbar button menu item, toolbar button and statusbar icon:
-			if(document.tooltipNode.id == 'autofillFormsButton' || document.tooltipNode.id == 'autofillFormsPanelIcon') {
-				if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-					// Always retrieve the profile labels from file if useConfigDirectory is enabled:
-					this.profileLabels = null;
-					this.tooltipCurrentProfile = null;
-				}
-				if(!this.tooltipCurrentProfile || !this.tooltipGrid) {
-					// Remove all children nodes:
-					while(tooltip.hasChildNodes()) {
-						tooltip.removeChild(tooltip.firstChild);
-					}
-					// Add the current profile label:
-					tooltip.appendChild(this.getTooltipCurrentProfile());
-					// Add the tooltip grid with the command labels, mouse buttons and keyboard shortcuts:
-					tooltip.appendChild(this.getTooltipGrid());
-				}
-			} else {
-				// Don't show tooltips for the toolbar button menu items:
-				event.preventDefault();
-			}
-		}
-	},
-
-	getTooltipCurrentProfile: function() {
-		if(!this.tooltipCurrentProfile) {
-			var hbox = document.createElement('hbox');
-			hbox.setAttribute(
-				'id',
-				'autofillFormsTooltipCurrentProfile'
-			);
-			var label = document.createElement('label');
-			label.setAttribute(
-				'value',
-				this.getStringBundle().getString('currentProfileLabel')
-			);
-			label.setAttribute(
-				'id',
-				'autofillFormsTooltipCurrentProfileCaption'
-			);
-			hbox.appendChild(label);
-			label = label.cloneNode(false);
-			label.setAttribute(
-				'value',
-				this.getProfileLabel(this.getProfileIndex())
-			);
-			label.setAttribute(
-				'id',
-				'autofillFormsTooltipCurrentProfileLabel'
-			);
-			hbox.appendChild(label);
-			this.tooltipCurrentProfile = hbox;
-		}
-		return this.tooltipCurrentProfile;
-	},
-
-	getTooltipGrid: function() {
-		if(!this.tooltipGrid) {
-			var commands = new Array();
-			for(var property in this.shortcut) {
-				commands.push(new Array(
-					this.getStringBundle().getString('tooltip'+property.replace(/shortcut/,'')),
-					this.getFormattedMouseButton(this.getMouseButton('mouseS'+property.substr(1))),
-					this.getFormattedShortcut(this.getShortcut(property))
-				));
-			}
-			var grid = document.createElement('grid');
-			grid.setAttribute(
-				'id',
-				'autofillFormsTooltipGrid'
-			);
-			var columns = document.createElement('columns');
-			var column = document.createElement('column');
-			var rows = document.createElement('rows');
-			var row = document.createElement('row');
-			var label = document.createElement('label');
-			columns.appendChild(column);
-			columns.appendChild(column.cloneNode(false));
-			columns.appendChild(column.cloneNode(false));
-			grid.appendChild(columns);
-			// Create the column headers:
-			label.setAttribute(
-				'class',
-				'autofillFormsTooltipGridHeader'
-			);
-			label.setAttribute(
-				'value',
-				this.getStringBundle().getString('command')
-			);
-			row.appendChild(label);
-			label = label.cloneNode(false);
-			label.setAttribute(
-				'value',
-				this.getStringBundle().getString('mousebutton')
-			);
-			row.appendChild(label);
-			label = label.cloneNode(false);
-			label.setAttribute(
-				'value',
-				this.getStringBundle().getString('keyboardShortcut')
-			);
-			row.appendChild(label);
-			rows.appendChild(row);
-			// Create a row for each command:
-			for(var i=0; i<commands.length; i++) {
-				row = row.cloneNode(false);
-				// Skip if neither mouseButton nor keyboard shortcut is set:
-				if(!commands[i][1] && !commands[i][2]) {
-					continue;
-				}
-				for(var j=0; j<commands[i].length; j++) {
-					label = label.cloneNode(false);
-					label.setAttribute(
-						'value',
-						commands[i][j]
-					);
-					if(j == 0) {
-						label.setAttribute(
-							'class',
-							'autofillFormsTooltipGridCommand'
-						);
-					} else if(j == 1) {
-						label.setAttribute(
-							'class',
-							'autofillFormsTooltipGridMouseButton'
-						);
-					} else {
-						label.setAttribute(
-							'class',
-							'autofillFormsTooltipGridKeyboardShortcut'
-						);
-					}
-					row.appendChild(label);
-				}
-				rows.appendChild(row);
-			}
-			grid.appendChild(rows);
-			this.tooltipGrid = grid;
-		}
-		return this.tooltipGrid;
-	},
-
-	resetAllProfiles: function() {
-		if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
-			// Confirmation dialog:
-			if(!this.getPrompts().confirm(
-					null,
-					this.getStringBundle().getString('resetAllProfilesTitle'),
-					this.getStringBundle().getString('resetAllProfilesText')
-				)
-			) {
-				return;
-			}
-		}
-
-		// Reset the user preferences:
-		if(this.autofillFormsPrefs.prefHasUserValue('useConfigDirectory')) {
-			this.autofillFormsPrefs.clearUserPref('useConfigDirectory');
-		}
-		if(this.autofillFormsPrefs.prefHasUserValue('storeEncrypted')) {
-			this.autofillFormsPrefs.clearUserPref('storeEncrypted');
-		}
-		if(this.autofillFormsPrefs.prefHasUserValue('profileIndex')) {
-			this.autofillFormsPrefs.clearUserPref('profileIndex');
-		}
-		if(this.autofillFormsPrefs.prefHasUserValue('profileLabels')) {
-			this.autofillFormsPrefs.clearUserPref('profileLabels');
-		}
-		if(this.autofillFormsPrefs.prefHasUserValue('profileSiteRules')) {
-			this.autofillFormsPrefs.clearUserPref('profileSiteRules');
-		}
-		if(this.autofillFormsPrefs.prefHasUserValue('fieldRules')) {
-			this.autofillFormsPrefs.clearUserPref('fieldRules');
-		}
-
-		this.profileIndex = null;
-		this.profileLabels = null;
-		this.profileSiteRules = null;
-		this.fieldRules = null;
-
-		// Re-init the profiles lists:
-		this.initProfilesLists();
-		// Re-init the fieldRules tree:
-		this.initTree();
-		// Re-initialize the simple interface:
-		this.initSimpleInterface();
-
-		if(this.tree && this.selection) {
-			try {
-				// Clear out the fieldRules tree selections
-				this.selection.select(-1);
-			} catch(e) {
-				this.log(e);
-			}
-		}
-	},
-
-	initProfilesLists: function(event) {
-		// The profiles tree:
-		this.initProfilesTree();
-
-		// Editable profiles menu list:
-		var profilesMenuList = document.getElementById('profilesMenuList');
-		if(profilesMenuList) {
-			profilesMenuList.removeAllItems();
-			for(var i=0; i < this.getProfileLabels().length; i++) {
-				profilesMenuList.appendItem(
-					this.getProfileLabel(i)
-				);
-			}
-			profilesMenuList.selectedIndex = this.getProfileIndex();
-		}
-		// Simple interface profiles menu list:
-		var simpleInterfaceProfileMenuList = document.getElementById('simpleInterfaceProfileMenuList');
-		if(simpleInterfaceProfileMenuList) {
-			simpleInterfaceProfileMenuList.removeAllItems();
-			for(var i=0; i < this.getProfileLabels().length; i++) {
-				simpleInterfaceProfileMenuList.appendItem(
-					this.getProfileLabel(i)
-				);
-			}
-			simpleInterfaceProfileMenuList.selectedIndex = this.getProfileIndex();
-		}
-		// Global profile selection:
-		var globalProfileMenuList = document.getElementById('globalProfileMenuList');
-		if(globalProfileMenuList) {
-			globalProfileMenuList.removeAllItems();
-			for(var i=0; i < this.getProfileLabels().length; i++) {
-				globalProfileMenuList.appendItem(
-					this.getProfileLabel(i)
-				);
-			}
-			globalProfileMenuList.selectedIndex = this.getGlobalProfileIndex();
-		}
-		// Form fields context menu selection:
-		var contextMenuProfileMenuList = document.getElementById('contextMenuProfileMenuList');
-		if(contextMenuProfileMenuList) {
-			// The first 3 items are "All profiles", "Active profile" and a menuseparator:
-			while(contextMenuProfileMenuList.firstChild.childNodes[3]) {
-				// The more convenient getItemAtIndex does not seem to work with Firefox versions < 3,
-				// so we use DOM methods on the menupopup child node of the menu node instead:
-				contextMenuProfileMenuList.firstChild.removeChild(
-					contextMenuProfileMenuList.firstChild.childNodes[3]
-				);
-			}
-			for(var i=0; i < this.getProfileLabels().length; i++) {
-				contextMenuProfileMenuList.appendItem(
-					this.getProfileLabel(i)
-				);
-			}
-			contextMenuProfileMenuList.selectedIndex
-				= this.getFormFieldsContextMenuProfileIndex()+3;
-		}
-
-		// The profile site rule textbox:
-		this.initProfileSiteRuleTextBox();
-	},
-
-	updateProfilesLists: function() {
-		// The more convenient getItemAtIndex does not seem to work with Firefox versions < 3,
-		// so we use DOM methods on the menupopup child node of the menu nodes instead:
-
-		// Editable profiles menu list:
-		var profilesMenuList = document.getElementById('profilesMenuList');
-		if(profilesMenuList) {
-			profilesMenuList
-				.firstChild.childNodes[this.getProfileIndex()].label
-				= this.getProfileLabel(this.getProfileIndex());
-		}
-		// Simple interface profiles menu list:
-		var simpleInterfaceProfileMenuList = document.getElementById('simpleInterfaceProfileMenuList');
-		if(simpleInterfaceProfileMenuList) {
-			simpleInterfaceProfileMenuList
-				.firstChild.childNodes[this.getProfileIndex()].label
-				= this.getProfileLabel(this.getProfileIndex());
-		}
-		// Global profile selection:
-		var globalProfileMenuList = document.getElementById('globalProfileMenuList');
-		if(globalProfileMenuList) {
-			globalProfileMenuList
-				.firstChild.childNodes[this.getProfileIndex()].label
-				= this.getProfileLabel(this.getProfileIndex());
-		}
-		// Form fields context menu selection:
-		var contextMenuProfileMenuList = document.getElementById('contextMenuProfileMenuList');
-		if(contextMenuProfileMenuList) {
-			// The first 3 items are "All profiles", "Active profile" and a menuseparator:
-			contextMenuProfileMenuList
-				.firstChild.childNodes[this.getProfileIndex()+3].label
-				= this.getProfileLabel(this.getProfileIndex());
-		}
-		// The profiles tree:
-		if(this.profilesTreeBox) {
-			this.profilesTreeBox.invalidateRow(this.getProfileIndex());
-		}
-	},
-
-	getProfileIndex: function() {
-		if(this.profileIndex == null)
-			this.profileIndex = this.autofillFormsPrefs.getIntPref('profileIndex');
-		return this.profileIndex;
-	},
-
-	setProfileIndex: function(index) {
-		if(this.profileIndex == index)
-			return;
-
-		// See method selectedFieldRule() why this has to be set to null:
-		this.lastSelectedIndex = null;
-
-		this.autofillFormsPrefs.setIntPref('profileIndex',parseInt(index));
-		// Update the tree view if present:
-		if(this.tree) {
-			// The settings page doesn't observe preferences changes - set the profileIndex manually:
-			this.profileIndex = index;
-			// Re-init the tree:
-			this.initTree();
-			// Re-initialize the simple interface:
-			this.initSimpleInterface();
-		}
-		// Update the profiles tree selection if present and not already updated:
-		if(this.profilesTree && this.profilesSelection.currentIndex != index) {
-			// Select the current profile:
-			this.profilesSelection.select(index);
-
-			// Ensure row is visible (scrolls if not):
-			this.profilesTreeBox.ensureRowIsVisible(index);
-		}
-		// Editable profiles menu list:
-		var profilesMenuList = document.getElementById('profilesMenuList');
-		if(profilesMenuList) {
-			profilesMenuList.selectedIndex = this.getProfileIndex();
-		}
-		// Simple interface profiles menu list:
-		var simpleInterfaceProfileMenuList = document.getElementById('simpleInterfaceProfileMenuList');
-		if(simpleInterfaceProfileMenuList) {
-			simpleInterfaceProfileMenuList.selectedIndex = this.getProfileIndex();
-		}
-
-		// The profile site rule textbox:
-		this.initProfileSiteRuleTextBox();
-	},
-
-	getGlobalProfileIndex: function() {
-		if(this.globalProfileIndex == null) {
-			this.globalProfileIndex = this.autofillFormsPrefs.getIntPref('globalProfileIndex');
-		}
-		return this.globalProfileIndex;
-	},
-
-	setGlobalProfileIndex: function(index) {
-		if(this.globalProfileIndex == index) {
-			return;
-		}
-		this.autofillFormsPrefs.setIntPref('globalProfileIndex',parseInt(index));
-		// The settings page doesn't observe preferences changes - set the profileIndex manually:
-		this.globalProfileIndex = index;
-	},
-
-	getFormFieldsContextMenuProfileIndex: function() {
-		if(this.formFieldsContextMenuProfileIndex == null) {
-			this.formFieldsContextMenuProfileIndex
-				= this.autofillFormsPrefs.getIntPref('formFieldsContextMenuProfileIndex');
-		}
-		return this.formFieldsContextMenuProfileIndex;
-	},
-
-	setFormFieldsContextMenuProfileIndex: function(index) {
-		if(this.formFieldsContextMenuProfileIndex == index) {
-			return;
-		}
-		this.autofillFormsPrefs.setIntPref('formFieldsContextMenuProfileIndex',parseInt(index));
-		// The settings page doesn't observe preferences changes - set the profileIndex manually:
-		this.formFieldsContextMenuProfileIndex = index;
-	},
-
-	getProfileLabelsFile: function() {
-		var file = this.getConfigDirectory();
-		file.append('profileLabels.txt');
-		if(!file.exists()) {
-			file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
-		}
-		return file;
-	},
-
-	exportProfileLabelsToConfigDirectory: function() {
-		var prefString;
-		// Get the profileLabels string from the preferences:
-		prefString = this.autofillFormsPrefs
-							.getComplexValue('profileLabels',Components.interfaces.nsIPrefLocalizedString)
-							.data;
-		if(prefString) {
-			this.setFileContent(this.getProfileLabelsFile(), prefString);
-		}
-	},
-
-	importProfileLabelsFromConfigDirectory: function() {
-		var prefString;
-		prefString = this.getFileContent(this.getProfileLabelsFile());
-		if(prefString) {
-			// Store the profileLabels as unicode string in the preferences:
-			this.autofillFormsPrefs.setComplexValue(
-				'profileLabels',
-				Components.interfaces.nsISupportsString,
-				this.getUnicodeString(prefString)
-			);
-		}
-	},
-
-	getProfileLabels: function() {
-		if(this.profileLabels == null) {
-			var prefString;
-			if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-				// Get the profileLabels string from the profileLabels file in the configDirectory:
-				prefString = this.getFileContent(this.getProfileLabelsFile());
-			}
-			if(!prefString) {
-				prefString = this.autofillFormsPrefs
-								.getComplexValue('profileLabels',Components.interfaces.nsIPrefLocalizedString)
-								.data;
-			}
-			// The profile labels are stored as a string with tabs as separators:
-			this.profileLabels = prefString.split('\t');
-		}
-		return this.profileLabels;
-	},
-
-	setProfileLabels: function(profileLabels) {
-		// Save the profile labels separated by tabs:
-		var prefString = profileLabels.join('\t');
-		if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-			this.setFileContent(this.getProfileLabelsFile(), prefString);
-		} else {
-			this.autofillFormsPrefs.setComplexValue(
-				'profileLabels',
-				Components.interfaces.nsISupportsString,
-				this.getUnicodeString(prefString)
-			);
-		}
-	},
-
-	getProfileLabel: function(index) {
-		while(this.getProfileLabels().length <= index) {
-			this.getProfileLabels().push(this.getUniqueProfileLabel());
-		}
-		return this.getProfileLabels()[index];
-	},
-
-	setProfileLabel: function(index, label) {
-		while(this.getProfileLabels().length <= index) {
-			this.getProfileLabels().push(this.getUniqueProfileLabel());
-		}
-		this.getProfileLabels()[index] = label;
-		// Save the profileLabels list in the preferences:
-		this.setProfileLabels(this.getProfileLabels());
-	},
-
-	getUniqueProfileLabel: function(profileLabel) {
-		if(!profileLabel) {
-			profileLabel = 'Profile';
-		}
-
-		// Make sure the profile label is unique:
-		if(!this.inArray(this.getProfileLabels(), profileLabel)) {
-			return profileLabel;
-		}
-		var i = profileLabel.lastIndexOf(' ');
-		var n = parseInt(profileLabel.substr(i+2));
-		if(isNaN(n)) {
-			return this.getUniqueProfileLabel(profileLabel+' (2)');
-		}
-		n++;
-		profileLabel = profileLabel.substr(0, i)+' ('+n+')';
-		return this.getUniqueProfileLabel(profileLabel);
-	},
-
-	changeProfileLabel: function(newProfileLabel) {
-		var profilesMenuList = document.getElementById('profilesMenuList');
-		if(profilesMenuList) {
-			// Make sure the new profile label is safe and unique:
-			newProfileLabel = this.getUniqueProfileLabel(this.makeSafe(newProfileLabel));
-			// Update the label of the selected profile:
-			this.setProfileLabel(this.getProfileIndex(), newProfileLabel);
-			// Update the profiles textbox contents:
-			profilesMenuList.inputField.value = newProfileLabel;
-			document.getElementById('profileLabelTextBox').value = newProfileLabel;
-			// Update the profiles lists:
-			this.updateProfilesLists();
-		}
-	},
-
-	initProfileSiteRuleTextBox: function(event) {
-		var profileSiteRuleTextBox = document.getElementById('profileSiteRuleTextBox');
-		if(profileSiteRuleTextBox) {
-			profileSiteRuleTextBox.value = this.getProfileSiteRule(this.getProfileIndex());
-		}
-	},
-
-	changeProfileSiteRule: function(siteRule) {
-		var profileSiteRuleTextBox = document.getElementById('profileSiteRuleTextBox');
-		if(profileSiteRuleTextBox) {
-			// Check the regular expression before updating the profile site rules:
-			try {
-				siteRule = this.getRegExpStr(
-					this.makeSafe(siteRule)
-				);
-				profileSiteRuleTextBox.value = siteRule;
-				document.getElementById('profileSiteRuleTextBox2').value = siteRule;
-
-				var newProfileSiteRules = this.getProfileSiteRules();
-				newProfileSiteRules[this.getProfileIndex()] = siteRule;
-				this.setProfileSiteRules(newProfileSiteRules);
-
-				// Update the profiles tree:
-				if(this.profilesTreeBox) {
-					this.profilesTreeBox.invalidateRow(this.getProfileIndex());
-				}
-			} catch(e) {
-				this.invalidRegExpAlert(e);
-			}
-		}
-	},
-
-	getProfileSiteRulesFile: function() {
-		var file = this.getConfigDirectory();
-		file.append('profileSiteRules.txt');
-		if(!file.exists()) {
-			file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
-		}
-		return file;
-	},
-
-	exportProfileSiteRulesToConfigDirectory: function() {
-		var prefString;
-		// Get the profileSiteRules string from the preferences:
-		prefString = this.autofillFormsPrefs
-							.getComplexValue('profileSiteRules',Components.interfaces.nsISupportsString)
-							.data;
-		if(prefString) {
-			this.setFileContent(this.getProfileSiteRulesFile(), prefString);
-		}
-	},
-
-	importProfileSiteRulesFromConfigDirectory: function() {
-		var prefString;
-		prefString = this.getFileContent(this.getProfileSiteRulesFile());
-		if(prefString) {
-			// Store the profileSiteRules as unicode string in the preferences:
-			this.autofillFormsPrefs.setComplexValue(
-				'profileSiteRules',
-				Components.interfaces.nsISupportsString,
-				this.getUnicodeString(prefString)
-			);
-		}
-	},
-
-	getProfileSiteRules: function() {
-		if(this.profileSiteRules == null) {
-			var prefString;
-			if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-				// Get the profileSiteRules string from the profileSiteRules file in the configDirectory:
-				prefString = this.getFileContent(this.getProfileSiteRulesFile());
-			}
-			if(!prefString) {
-				prefString = this.autofillFormsPrefs
-								.getComplexValue('profileSiteRules',Components.interfaces.nsISupportsString)
-								.data;
-			}
-			// The profile SiteRules are stored as a string with tabs as separators:
-			this.profileSiteRules = prefString.split('\t');
-		}
-		return this.profileSiteRules;
-	},
-
-	setProfileSiteRules: function(profileSiteRules) {
-		// Save the profile SiteRules separated by tabs:
-		var prefString = profileSiteRules.join('\t');
-		if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-			this.setFileContent(this.getProfileSiteRulesFile(), prefString);
-		} else {
-			this.autofillFormsPrefs.setComplexValue(
-				'profileSiteRules',
-				Components.interfaces.nsISupportsString,
-				this.getUnicodeString(prefString)
-			);
-		}
-	},
-
-	getProfileSiteRule: function(index) {
-		while(this.getProfileSiteRules().length <= index) {
-			this.getProfileSiteRules().push('(?:)');
-		}
-		return this.getProfileSiteRules()[index];
-	},
-
-	setProfileSiteRule: function(index, siteRule) {
-		while(this.getProfileSiteRules().length <= index) {
-			this.getProfileSiteRules().push('(?:)');
-		}
-		this.getProfileSiteRules()[index] = siteRule;
-		// Save the profileSiteRules in the preferences:
-		this.setProfileSiteRules(this.getProfileSiteRules());
-	},
-
-	addFormAsProfile: function(event) {
-		if(this.targetFormField && this.targetFormField.form) {
-			var elements = this.targetFormField.form.elements;
-			var doc = this.targetFormField.form.ownerDocument;
-
-			var newProfile = new Array();
-
-			// Go through the form elements:
-			for(var i=0; i<elements.length; i++) {
-				// Only use valid form fields:
-				if(this.isValidFormField(elements[i])) {
-					var value;
-					var overwrite = true;
-
-					// Create the fieldRule (from name, label or id):
-					var fieldRule = this.getFieldRuleForElement(elements[i]);
-
-					switch(elements[i].type) {
-						case 'checkbox':
-							// Add a rule to uncheck the checkbox if it is unchecked:
-							if(!elements[i].checked) {
-								overwrite = false;
-							}
-							value = this.getRegExpStrForValue(elements[i].value);
-							break;
-						case 'radio':
-							// Only add checked radio buttons:
-							if(!elements[i].checked) {
-								continue;
-							}
-							value = this.getRegExpStrForValue(elements[i].value);
-							break;
-						case 'select-one':
-							value = this.getRegExpStrForValue(elements[i].value);
-							break;
-						case 'select-multiple':
-							var fieldRuleLabel = this.makeSafe(this.getFieldRuleNameForElement(elements[i]));
-							// Add all options as fieldRules, set "overwrite" to true if selected:
-							for(var j = 0; j < elements[i].options.length; j++) {
-								newProfile.push(
-									this.createFieldRule(
-										fieldRuleLabel+' ('+j+')',
-										this.getRegExpStrForValue(elements[i].options[j].value),
-										fieldRule,
-										'(?:)',
-										elements[i].options[j].selected,
-										true
-									)
-								);
-							}
-							continue;
-						default:
-							value = this.makeSafe(this.replaceControlCharacters(elements[i].value));
-							break;
-					}
-
-					// Add the current element as new rule to the profile list:
-					newProfile.push(
-						this.createFieldRule(
-							this.makeSafe(this.getFieldRuleNameForElement(elements[i])),
-							value,
-							fieldRule,
-							'(?:)',
-							overwrite,
-							true
-						)
-					);
-				}
-			}
-
-			// Initialize the fieldRules:
-			this.getFieldRules();
-
-			// Add the new profile to the fieldRules:
-			this.fieldRules.push(newProfile);
-			// Save the profiles in the preferences:
-			this.setFieldRules();
-
-			// Add a label for default empty profile:
-			if(this.getProfileLabels().length == 0) {
-				this.getProfileLabels().push(this.getUniqueProfileLabel());
-			}
-			// Use the documents hostname as profile label and add it to the profile labels list:
-			this.getProfileLabels().push(this.getUniqueProfileLabel(this.makeSafe(doc.location.host)));
-			// Save the profileLabels list in the preferences:
-			this.setProfileLabels(this.getProfileLabels());
-
-			// Use the protocol and domain of the web form as profile siteRule:
-			this.getProfileSiteRules().push(this.getSiteRuleForURL(doc.location.protocol+'//'+doc.location.host));
-			// Save the profileSiteRules in the preferences:
-			this.setProfileSiteRules(this.getProfileSiteRules());
-
-			// Save the the new profile index as selected profileIndex:
-			this.setProfileIndex(this.getProfileLabels().length-1);
-
-			// Reset the target form field:
-			this.targetFormField = null;
-
-			// Create parameters for the settings page:
-			var params = new Object();
-			params.newProfileFromForm = true;
-
-			// Open up the settings page:
-			this.showDialog('chrome://autofillForms/content/autofillFormsOptions.xul', params);
-		}
-	},
-
-	addProfile: function(newProfileLabel) {
-		// Duplicate the selected profile (do a deep copy):
-		this.fieldRules.push(
-			this.copyFieldRules(this.getFieldRules())
-		);
-		// Save the profiles in the preferences:
-		this.setFieldRules();
-		// Add profile label for default empty profile:
-		if(this.getProfileLabels().length == 0) {
-			this.getProfileLabels().push(this.getUniqueProfileLabel());
-		}
-		// Add the (unique) newProfileLabel to the profileLabels list:
-		this.getProfileLabels().push(this.getUniqueProfileLabel(this.makeSafe(newProfileLabel)));
-		// Save the profileLabels list in the preferences:
-		this.setProfileLabels(this.getProfileLabels());
-		// Add a new empty profileSiteRule:
-		this.getProfileSiteRules().push('(?:)');
-		// Save the profileSiteRules in the preferences:
-		this.setProfileSiteRules(this.getProfileSiteRules());
-		// Save the the new profile index as selected profileIndex:
-		this.setProfileIndex(this.getProfileLabels().length-1);
-		// Update the profiles lists:
-		this.initProfilesLists();
-		// Re-init the fieldRules tree:
-		this.initTree();
-		// Re-initialize the simple interface:
-		this.initSimpleInterface();
-	},
-
-	removeProfile: function(event) {
-		if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
-			// Confirmation dialog:
-			if(!this.getPrompts().confirm(
-					null,
-					this.getStringBundle().getString('removeProfileTitle'),
-					this.getStringBundle().getString('removeProfileText')
-				)
-			) {
-				return;
-			}
-		}
-
-		// Remove the selected profile from the list:
-		this.fieldRules.splice(this.getProfileIndex(),1);
-		// Save the profiles in the preferences:
-		this.setFieldRules();
-		// Remove the selected profile from the profileLabels list:
-		this.getProfileLabels().splice(this.getProfileIndex(),1);
-		// Save the profileLabels list in the preferences:
-		this.setProfileLabels(this.getProfileLabels());
-		// Remove the selected profile's siteRule:
-		this.getProfileSiteRules().splice(this.getProfileIndex(),1);
-		// Save the profileSiteRules in the preferences:
-		this.setProfileSiteRules(this.getProfileSiteRules());
-		// Adjust the profileIndex if the last profile on the list has been deleted:
-		if(this.getProfileIndex()+1 > this.fieldRules.length) {
-			var newIndex = this.fieldRules.length>0 ? this.fieldRules.length-1 : 0;
-			this.setProfileIndex(newIndex);
-		}
-		// Update the profiles lists:
-		this.initProfilesLists();
-		// Re-init the tree:
-		this.initTree();
-		// Re-initialize the simple interface:
-		this.initSimpleInterface();
-	},
-
-	createFieldRule: function(name,value,fieldRule,siteRule,overwrite,enabled) {
-		var rule = new Object();
-		rule['fieldRuleName'] = name;
-		rule['fieldRuleValue'] = value;
-		rule['fieldRuleFieldRule'] = fieldRule;
-		rule['fieldRuleSiteRule'] = siteRule;
-		rule['fieldRuleOverwrite'] = overwrite;
-		rule['fieldRuleEnabled'] = enabled;
-		return rule;
-	},
-
-	getRegExpPasswordLabel: function() {
-		if(!arguments.callee.regExpPass) {
-			arguments.callee.regExpPass = new RegExp(
-								this.autofillFormsPrefs
-								.getComplexValue('regExpPasswordLabel',Components.interfaces.nsIPrefLocalizedString)
-								.data,
-								'i');
-		}
-		return arguments.callee.regExpPass;
-	},
-
-	initTree: function() {
-		// Get the tree:
-		this.tree = document.getElementById('fieldRulesTree');
-
-		if(this.tree) {
-
-			// Implement the TreeView interface:
-			this.treeView = {
-				rowCount: 0,
-				setTree: function(tree){},
-				getImageSrc: function(row,column) {},
-				getProgressMode: function(row,column) {},
-				getCellValue: function(row,column) {
-					var rowObj = this.parent.getFieldRules()[row];
-					if(rowObj) {
-						return rowObj[column.id];
-					}
-				},
-				getCellText: function(row,column){
-					var rowObj = this.parent.getFieldRules()[row];
-					if(rowObj) {
-						if(column.id=='fieldRuleValue' &&
-							this.parent.getRegExpPasswordLabel().test(rowObj['fieldRuleName'])) {
-							// Show passwords as asterisks:
-							return rowObj[column.id].replace(/./g, '*');
-						} else {
-							return rowObj[column.id];
-						}
-					}
-					return '';
-				},
-				isEditable: function(row,column){
-					// Only checkbox columns are editable:
-					if(column.id=='fieldRuleOverwrite' || column.id=='fieldRuleEnabled')
-						return true;
-					else
-						return false;
-				},
-				setCellValue: function(row,column,value){
-					var rowObj = this.parent.getFieldRules()[row];
-					if(rowObj) {
-						rowObj[column.id] = value;
-						// Notify the tree:
-						this.parent.treeBox.invalidateRow(row);
-						// Update the preferences:
-						this.parent.setFieldRules();
-						// Update the simple interface (add/remove enabled/disabled rules):
-						if(column.id=='fieldRuleEnabled') {
-							if(value == 'true') {
-								this.parent.addSimpleInterfaceRow(row);
-							} else {
-								this.parent.removeSimpleInterfaceRow(row);
-							}
-						}
-					}
-				},
-				isSeparator: function(index) {return false;},
-				isSorted: function() {return false;},
-				isContainer: function(index) {return false;},
-				cycleHeader: function(column) {},
-				getRowProperties: function(row,prop){},
-				getColumnProperties: function(column,prop){},
-				getCellProperties: function(row,column,prop){},
-				getParentIndex: function(index) {return -1}
-			};
-			// Set the autofillForms object as parent:
-			this.treeView.parent = this;
-
-			// Set the tree length using the fieldRules list length:
-			this.treeView.rowCount = this.getFieldRules().length;
-
-			// Assign the treeview:
-			this.tree.view = this.treeView;
-
-			// The TreeSelection object:
-			this.selection = this.tree.view.selection;
-
-			// The TreeBox object:
-			this.treeBox = this.tree.treeBoxObject;
-		}
-	},
-
-	sortFieldRules: function(event) {
-		// See method selectedFieldRule() why this has to be set to null:
-		this.lastSelectedIndex = null;
-
-		if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
-			// Confirmation dialog:
-			if(!this.getPrompts().confirm(
-					null,
-					this.getStringBundle().getString('sortFieldRulesTitle'),
-					this.getStringBundle().getString('sortFieldRulesText')
-				)
-			) {
-				return;
-			}
-		}
-
-		// Get the id of the column:
-		var id = event.target.id;
-
-		// Helper function to sort the fieldRules objects:
-		function customSort(a,b) {
-			// This enables comparison of boolean true and false:
-			var x = a[id].toString();
-			var y = b[id].toString();
-
-			if(x > y) return 1;
-			if(x < y) return -1;
-			return 0;
-		}
-
-		// Sort the form field rules using the helper function:
-		this.getFieldRules().sort(customSort);
-
-		// Change sort direction for next click:
-		if(this.ascending) {
-			this.ascending = false;
-		} else {
-			this.getFieldRules().reverse();
-			this.ascending = true;
-		}
-
-		// Notify the tree:
-		this.treeBox.invalidate();
-
-		// Clear out selections
-		this.selection.select(-1);
-
-		// Update the preferences:
-		this.setFieldRules();
-
-		// Re-initialize the simple interface:
-		this.initSimpleInterface();
-	},
-
-	selectedFieldRule: function(event) {
-		if(this.selection.currentIndex == -1) {
-			// Disable buttons:
-			document.getElementById('buttonRemoveFieldRule').setAttribute('disabled', 'true');
-			document.getElementById('buttonMoveUpFieldRule').setAttribute('disabled', 'true');
-			document.getElementById('buttonMoveDownFieldRule').setAttribute('disabled', 'true');
-
-			this.lastSelectedIndex = null;
-		} else if(this.selection.count == 1) {
-			// The onchange event (as well as onblur, etc.) of the textboxes seems to be ignored if a new item is selected,
-			// so we try and apply the field rules of the last element (if changed):
-			if(this.lastSelectedIndex !== null) {
-				this.applyFieldRuleOnIndex(this.lastSelectedIndex);
-			}
-
-			// Update the textboxes with the selected fieldRule:
-			var index = this.selection.currentIndex;
-			document.getElementById('fieldRuleNameTextBox').value = this.getFieldRules()[index]['fieldRuleName'];
-			document.getElementById('fieldRuleValueTextBox').value = this.getFieldRules()[index]['fieldRuleValue'];
-			document.getElementById('fieldRuleFieldRuleTextBox').value = this.getFieldRules()[index]['fieldRuleFieldRule'];
-			document.getElementById('fieldRuleSiteRuleTextBox').value = this.getFieldRules()[index]['fieldRuleSiteRule'];
-
-			// Enable/Disable buttons:
-			document.getElementById('buttonRemoveFieldRule').setAttribute('disabled', 'false');
-			document.getElementById('buttonMoveUpFieldRule').setAttribute(
-				'disabled',
-				(index == 0)
-			);
-			document.getElementById('buttonMoveDownFieldRule').setAttribute(
-				'disabled',
-				(index == this.getFieldRules().length-1)
-			);
-
-			// Save the last selected index and reset it to null for any other action than just a single selection:
-			this.lastSelectedIndex = index;
-		} else if(this.selection.count > 1) {
-			// Enable/Disable buttons:
-			document.getElementById('buttonRemoveFieldRule').setAttribute('disabled', 'false');
-			document.getElementById('buttonMoveUpFieldRule').setAttribute('disabled', 'true');
-			document.getElementById('buttonMoveDownFieldRule').setAttribute('disabled', 'true');
-
-			this.lastSelectedIndex = null;
-		}
-	},
-
-	initProfilesTree: function() {
-		this.profilesTree = document.getElementById('profilesTree');
-		if(this.profilesTree) {
-
-			// Implement the profiles TreeView interface:
-			this.profilesTreeView = {
-				rowCount: 0,
-				setTree: function(tree){},
-				getImageSrc: function(row,column) {},
-				getProgressMode: function(row,column) {},
-				getCellValue: function(row,column) {
-					if(column.id=='profilesTreeColName') {
-						return this.parent.getProfileLabel(row);
-					} else {
-						return this.parent.getProfileSiteRule(row);
-					}
-				},
-				getCellText: function(row,column){
-					if(column.id=='profilesTreeColName') {
-						return this.parent.getProfileLabel(row);
-					} else {
-						return this.parent.getProfileSiteRule(row);
-					}
-				},
-				isEditable: function(row,column){return false;},
-				setCellValue: function(row,column,value){},
-				isSeparator: function(index) {return false;},
-				isSorted: function() {return false;},
-				isContainer: function(index) {return false;},
-				cycleHeader: function(column) {},
-				getRowProperties: function(row,prop){},
-				getColumnProperties: function(column,prop){},
-				getCellProperties: function(row,column,prop){},
-				getParentIndex: function(index) {return -1}
-			};
-			// Set the autofillForms object as parent:
-			this.profilesTreeView.parent = this;
-
-			// Seems like we need to reset these arrays to have a consistens UI:
-			this.profileLabels = null;
-			this.profileSiteRules = null;
-
-			// Set the tree length using the profiles labels list length:
-			this.profilesTreeView.rowCount = this.getProfileLabels().length;
-
-			// Assign the treeview:
-			this.profilesTree.view = this.profilesTreeView;
-
-			// The TreeSelection object:
-			this.profilesSelection = this.profilesTree.view.selection;
-
-			// The TreeBox object:
-			this.profilesTreeBox = this.profilesTree.treeBoxObject;
-
-			// Select the current profile:
-			this.profilesSelection.select(this.getProfileIndex());
-
-			// Ensure row is visible (scrolls if not):
-			this.profilesTreeBox.ensureRowIsVisible(this.getProfileIndex());
-		}
-	},
-
-	selectedProfile: function(event) {
-		var index = this.profilesSelection.currentIndex;
-		if(index != -1) {
-			this.setProfileIndex(index);
-
-			if(index > 0) {
-				document.getElementById('buttonMoveUpProfile').disabled = false;
-			} else {
-				document.getElementById('buttonMoveUpProfile').disabled = true;
-			}
-			if(index+1 < this.getProfileLabels().length) {
-				document.getElementById('buttonMoveDownProfile').disabled = false;
-			} else {
-				document.getElementById('buttonMoveDownProfile').disabled = true;
-			}
-
-			if(document.getElementById('profileLabelTextBox')) {
-				document.getElementById('profileLabelTextBox').value = this.getProfileLabel(this.getProfileIndex());
-			}
-			if(document.getElementById('profileSiteRuleTextBox2')) {
-				document.getElementById('profileSiteRuleTextBox2').value = this.getProfileSiteRule(this.getProfileIndex());
-			}
-		} else {
-			document.getElementById('buttonMoveUpProfile').disabled = true;
-			document.getElementById('buttonMoveDownProfile').disabled = true;
-		}
-	},
-
-	moveUpProfile: function(event) {
-		var tmpProfile = this.getFieldRules(this.getProfileIndex()-1);
-		this.fieldRules[this.getProfileIndex()-1] = this.getFieldRules(this.getProfileIndex());
-		this.fieldRules[this.getProfileIndex()] = tmpProfile;
-		this.setFieldRules();
-
-		var tmpProfileLabel = this.getProfileLabel(this.getProfileIndex()-1);
-		this.getProfileLabels()[this.getProfileIndex()-1] = this.getProfileLabel(this.getProfileIndex());
-		this.getProfileLabels()[this.getProfileIndex()] = tmpProfileLabel;
-		this.setProfileLabels(this.getProfileLabels());
-
-		var tmpProfileSiteRule = this.getProfileSiteRule(this.getProfileIndex()-1);
-		this.getProfileSiteRules()[this.getProfileIndex()-1] = this.getProfileSiteRule(this.getProfileIndex());
-		this.getProfileSiteRules()[this.getProfileIndex()] = tmpProfileSiteRule;
-		this.setProfileSiteRules(this.getProfileSiteRules());
-
-		this.setProfileIndex(this.getProfileIndex()-1);
-
-		this.initProfilesLists();
-	},
-
-	moveDownProfile: function(event) {
-		var tmpProfile = this.getFieldRules(this.getProfileIndex()+1);
-		this.fieldRules[this.getProfileIndex()+1] = this.getFieldRules(this.getProfileIndex());
-		this.fieldRules[this.getProfileIndex()] = tmpProfile;
-		this.setFieldRules();
-
-		var tmpProfileLabel = this.getProfileLabel(this.getProfileIndex()+1);
-		this.getProfileLabels()[this.getProfileIndex()+1] = this.getProfileLabel(this.getProfileIndex());
-		this.getProfileLabels()[this.getProfileIndex()] = tmpProfileLabel;
-		this.setProfileLabels(this.getProfileLabels());
-
-		var tmpProfileSiteRule = this.getProfileSiteRule(this.getProfileIndex()+1);
-		this.getProfileSiteRules()[this.getProfileIndex()+1] = this.getProfileSiteRule(this.getProfileIndex());
-		this.getProfileSiteRules()[this.getProfileIndex()] = tmpProfileSiteRule;
-		this.setProfileSiteRules(this.getProfileSiteRules());
-
-		this.setProfileIndex(this.getProfileIndex()+1);
-
-		this.initProfilesLists();
-	},
-
-	sortProfiles: function(event) {
-		var newSelectedIndex = this.getProfileIndex();
-		var fieldArray = this.getFieldsArray();
-		var oldIndex;
-
-		switch(event.target.id) {
-			case 'profilesTreeColName':
-				//Sort by Profile Label
-				fieldArray.sort(function (a, b) {
-					if (a[1] == b[1]) {
-						return 0;
-					}
-					if (a[1] < b[1]) {
-						return -1;
-					}
-					return 1;
-				});
-				if (!this.profilesAscending) {
-					fieldArray.reverse();
-				}
-				for(var i=0; i<this.getProfileLabels().length; i++) {
-					oldIndex = fieldArray[i][0];
-					if(oldIndex == this.getProfileIndex()) {
-						newSelectedIndex = i;
-					}
-					this.getProfileLabels()[i] = fieldArray[i][1];
-					this.getProfileSiteRules()[i] = fieldArray[i][2];
-					this.fieldRules[i] = fieldArray[i][3];
-				}
-				break;
-
-			case 'profilesTreeColSiteRule':
-				//Sort by Profile Site Rule
-				fieldArray.sort(function (a, b) {
-					if (a[2] == b[2]) {
-						return 0;
-					}
-					if (a[2] < b[2]) {
-						return -1;
-					}
-					return 1;
-				});
-				if (!this.profilesAscending) {
-					fieldArray.reverse();
-				}
-				for(var i=0; i<this.getProfileLabels().length; i++) {
-					oldIndex = fieldArray[i][0];
-					if(oldIndex == this.getProfileIndex()) {
-						newSelectedIndex = i;
-					}
-					this.getProfileLabels()[i] = fieldArray[i][1];
-					this.getProfileSiteRules()[i] = fieldArray[i][2];
-					this.fieldRules[i] = fieldArray[i][3];
-				}
-				break;
-		}
-		// Change sort direction for next click:
-		this.profilesAscending = !this.profilesAscending;
-
-		this.setFieldRules();
-		this.setProfileLabels(this.getProfileLabels());
-		this.setProfileSiteRules(this.getProfileSiteRules());
-
-		this.setProfileIndex(newSelectedIndex);
-
-		this.initProfilesLists();
-	},
-	getFieldsArray: function() {
-		// This creates an array of [i, ProfileLabel, ProfileSiteRule, fieldRules] rows
-		// we can then sort by rows[1] or rows[2] and store the row elements back in
-		// their respective arrays.
-		var row;
-		var fieldArray = new Array();
-		var tmpProfileLabels = this.getProfileLabels().slice(0);
-		var tmpProfileSiteRules = this.getProfileSiteRules().slice(0);
-
-		for(var i=0; i<this.getProfileSiteRules().length; i++) {
-			row = new Array();
-			row.push(i);
-			row.push(tmpProfileLabels[i]);
-			row.push(tmpProfileSiteRules[i]);
-			row.push(this.getFieldRules(i));
-			fieldArray.push(row);
-		}
-		return fieldArray;
-	},
-	profilesTreeHandleKeyPress: function(event) {
-		if(event.keyCode == 46) {
-			this.removeProfile();
-		}
-	},
-
-	invalidRegExpAlert: function(error) {
-		// Invalid regular expression alert:
-		this.getPrompts().alert(
-			null,
-			this.getStringBundle().getString('invalidRegExpTitle'),
-			this.getStringBundle().getString('invalidRegExpText') + "\n\n" + error
-		);
-	},
-
-	makeSafe: function(str) {
-		// Remove all tabs and linefeeds from the given string
-		// (these are used as separators):
-		return str.replace(/\t|\n/g, '');
-	},
-
-	replaceControlCharacters: function(str) {
-		return str.replace(
-			/\n|\t/g,
-			this.replaceControlCharactersCallback
-		);
-	},
-
-	replaceControlCharactersCallback: function(str) {
-		switch(str) {
-			case "\n":
-				return autofillForms.autofillFormsPrefs.getCharPref('placeholderLineBreak');
-			case "\t":
-				return '	';
-			default:
-				return str;
-		}
-	},
-
-	replaceControlCharacterPlaceholders: function(str) {
-		try {
-			var regExpObj = new RegExp(
-				'('
-				+this.autofillFormsPrefs.getCharPref('placeholderLineBreak')
-				+')|('
-				+this.autofillFormsPrefs.getCharPref('placeholderTab')
-				+')',
-				'g'
-			);
-			return str.replace(
-				regExpObj,
-				this.replaceControlCharacterPlaceholdersCallback
-			);
-		} catch(e) {
-			return str;
-		}
-	},
-
-	replaceControlCharacterPlaceholdersCallback: function(str) {
-		switch(str) {
-			case autofillForms.autofillFormsPrefs.getCharPref('placeholderLineBreak'):
-				return "\n";
-			case autofillForms.autofillFormsPrefs.getCharPref('placeholderTab'):
-				return "\t";
-			default:
-				return str;
-		}
-	},
-
-	applyFieldRuleOnIndex: function(index) {
-		// Check the regular expressions:
-		try {
-			var fieldRule = this.getRegExpStr(
-				this.makeSafe(document.getElementById('fieldRuleFieldRuleTextBox').value)
-			);
-			document.getElementById('fieldRuleFieldRuleTextBox').value = fieldRule;
-
-			var siteRule = this.getRegExpStr(
-				this.makeSafe(document.getElementById('fieldRuleSiteRuleTextBox').value)
-			);
-			document.getElementById('fieldRuleSiteRuleTextBox').value = siteRule;
-		} catch(e) {
-			this.invalidRegExpAlert(e);
-			return;
-		}
-
-		var ruleName = this.makeSafe(document.getElementById('fieldRuleNameTextBox').value);
-		var ruleValue = this.makeSafe(document.getElementById('fieldRuleValueTextBox').value);
-
-		if(	this.getFieldRules()[index] && (
-			this.getFieldRules()[index]['fieldRuleName'] != ruleName ||
-			this.getFieldRules()[index]['fieldRuleValue'] != ruleValue ||
-			this.getFieldRules()[index]['fieldRuleFieldRule'] != fieldRule ||
-			this.getFieldRules()[index]['fieldRuleSiteRule'] != siteRule)) {
-			// Update the formFieldRule on the given index:
-			this.getFieldRules()[index]['fieldRuleName'] = ruleName;
-			this.getFieldRules()[index]['fieldRuleValue'] = ruleValue;
-			this.getFieldRules()[index]['fieldRuleFieldRule'] = fieldRule;
-			this.getFieldRules()[index]['fieldRuleSiteRule'] = siteRule;
-
-			// Notify the tree:
-			this.treeBox.invalidateRow(index);
-
-			// Update the preferences:
-			this.setFieldRules();
-
-			// Update the related row of the simple interface:
-			this.updateSimpleInterfaceRow(index);
-		}
-	},
-
-	applyFieldRule: function(event) {
-		// Only apply changes if one item is selected:
-		if(this.selection.count == 1) {
-			// Update the selected formFieldRule:
-			this.applyFieldRuleOnIndex(this.selection.currentIndex);
-		}
-	},
-
-	addFieldRule: function(event) {
-		// See method selectedFieldRule() why this has to be set to null:
-		this.lastSelectedIndex = null;
-
-		// Check the regular expressions:
-		try {
-			var fieldRuleFieldRuleTextBox = document.getElementById('fieldRuleFieldRuleTextBox');
-			var fieldRule = this.getRegExpStr(
-				this.makeSafe(fieldRuleFieldRuleTextBox.value)
-			);
-			fieldRuleFieldRuleTextBox.value = fieldRule;
-
-			var fieldRuleSiteRuleTextBox = document.getElementById('fieldRuleSiteRuleTextBox');
-			var siteRule = this.getRegExpStr(
-				this.makeSafe(fieldRuleSiteRuleTextBox.value)
-			);
-			fieldRuleSiteRuleTextBox.value = siteRule;
-		} catch(e) {
-			this.invalidRegExpAlert(e);
-			return;
-		}
-
-		var newFieldRule = 	this.createFieldRule(
-			this.makeSafe(document.getElementById('fieldRuleNameTextBox').value),
-			this.makeSafe(document.getElementById('fieldRuleValueTextBox').value),
-			fieldRule,
-			siteRule,
-			true,
-			true
-		)
-
-		var newFieldRuleIndex;
-
-		// Add the new formFieldRule right after the selected position or to the start of the list:
-		if(this.selection.currentIndex == -1 || this.selection.currentIndex == this.treeView.rowCount) {
-			this.getFieldRules().unshift(newFieldRule);
-			newFieldRuleIndex = 0;
-		} else {
-			newFieldRuleIndex = this.selection.currentIndex+1;
-			this.getFieldRules().splice(
-				newFieldRuleIndex,
-				0,
-				newFieldRule
-			);
-		}
-
-		// Update the tree count and notify the tree:
-		this.treeView.rowCount++;
-		this.treeBox.rowCountChanged(this.treeView.rowCount, +1);
-		this.treeBox.invalidate();
-
-		// Select the new item:
-		this.selection.select(newFieldRuleIndex);
-
-		// Ensure row is visible (scrolls if not):
-		this.treeBox.ensureRowIsVisible(newFieldRuleIndex);
-
-		// Update the preferences:
-		this.setFieldRules();
-
-		// Re-initialize the simple interface:
-		this.initSimpleInterface();
-	},
-
-	removeFieldRule: function(event) {
-		this.removeSelectedFieldRules();
-	},
-
-	moveUpFieldRule: function(event) {
-		// See method selectedFieldRule() why this has to be set to null:
-		this.lastSelectedIndex = null;
-
-		var index = this.selection.currentIndex;
-
-		// Change place with the next upper item:
-		var sibling = this.getFieldRules()[index-1];
-		this.getFieldRules()[index-1] = this.getFieldRules()[index];
-		this.getFieldRules()[index] = sibling;
-
-		// Keep moved item selected:
-		this.selection.select(index-1);
-
-		// Notify the tree:
-		this.treeBox.invalidate();
-
-		// Ensure row is visible (scrolls if not):
-		this.treeBox.ensureRowIsVisible(index-1);
-
-		// Update the preferences:
-		this.setFieldRules();
-
-		// Update the related rows of the simple interface:
-		this.updateSimpleInterfaceRow(index-1);
-		this.updateSimpleInterfaceRow(index);
-	},
-
-	moveDownFieldRule: function(event) {
-		// See method selectedFieldRule() why this has to be set to null:
-		this.lastSelectedIndex = null;
-
-		var index = this.selection.currentIndex;
-
-		// Change place with the next lower item:
-		var sibling = this.getFieldRules()[index+1];
-		this.getFieldRules()[index+1] = this.getFieldRules()[index];
-		this.getFieldRules()[index] = sibling;
-
-		// Keep moved item selected:
-		this.selection.select(index+1);
-
-		// Notify the tree:
-		this.treeBox.invalidate();
-
-		// Ensure row is visible (scrolls if not):
-		this.treeBox.ensureRowIsVisible(index+1);
-
-		// Update the preferences:
-		this.setFieldRules();
-
-		// Update the related rows of the simple interface:
-		this.updateSimpleInterfaceRow(index+1);
-		this.updateSimpleInterfaceRow(index);
-	},
-
-	removeSelectedFieldRules: function(event) {
-		// See method selectedFieldRule() why this has to be set to null:
-		this.lastSelectedIndex = null;
-
-		if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
-			// Confirmation dialog:
-			if(!this.getPrompts().confirm(
-					null,
-					this.getStringBundle().getString('removeFieldRulesTitle'),
-					this.getStringBundle().getString('removeFieldRulesText')
-				)
-			) {
-				return;
-			}
-		}
-
-		// Start of update batch:
-		this.treeBox.beginUpdateBatch();
-
-		// Helper object to store a range:
-		function Range(start, end) {
-			this.start = start.value;
-			this.end = end.value;
-		}
-
-		// List of ranges:
-		var ranges = new Array();
-
-		// Get the number of ranges:
-		var numRanges = this.selection.getRangeCount();
-
-		// Helper vars to store the range end points:
-		var start = new Object();
-		var end = new Object();
-
-		// We store the list of ranges first, as calling
-		// this.treeBox.rowCountChanged()
-		// seems to invalidate the current selection
-
-		for(var i=0; i < numRanges; i++) {
-			// Get the current range end points:
-			this.selection.getRangeAt(i,start,end);
-			// Store them as a Range object in the ranges list:
-			ranges[i] = new Range(start, end);
-		}
-
-		for(var i=0; i < numRanges; i++) {
-			// Go through the stored ranges:
-			for(var j = ranges[i].start; j <= ranges[i].end; j++) {
-				// Set the selected fieldRules to null:
-				this.getFieldRules()[j] = null;
-			}
-
-			// Calculate the new tree count:
-			var count = ranges[i].end - ranges[i].start + 1;
-
-			// Update the tree count and notify the tree:
-			this.treeView.rowCount -= count;
-			this.treeBox.rowCountChanged(ranges[i].start, -count);
-		}
-
-		// Collapse list by removing all the null entries
-		for (var i=0; i < this.getFieldRules().length; i++) {
-			if (!this.getFieldRules()[i]) {
-				var j = i;
-				while (j < this.getFieldRules().length && !this.getFieldRules()[j])
-					j++;
-				this.getFieldRules().splice(i, j-i);
-			}
-		}
-
-		// Clear out selections
-		this.selection.select(-1);
-
-		// End of update batch:
-		this.treeBox.endUpdateBatch();
-
-		// Update the preferences:
-		this.setFieldRules();
-
-		// Re-initialize the simple interface:
-		this.initSimpleInterface();
-	},
-
-	handleKeyPress: function(event) {
-		if(event.keyCode == 46) {
-			this.removeSelectedFieldRules();
-		} else if(event.ctrlKey && event.which == 97) {
-			if(this.tree && this.selection) {
-				try {
-					// Select all rows:
-					this.selection.selectAll();
-				} catch(e) {
-					this.log(e);
-				}
-			}
-		}
-	},
-
-	getGlobalFieldRules: function() {
-		// Return the fieldRules for the selected global profile if globalProfileIndex is not out of range:
-		if(this.getGlobalProfileIndex() >= 0 && this.getGlobalProfileIndex() < this.getProfileLabels().length) {
-			return this.getFieldRules(this.getGlobalProfileIndex());
-		} else {
-			this.globalProfileIndex = 0;
-			return this.getFieldRules(0);
-		}
-	},
-
-	getFileContent: function(file) {
-		var fileContent = null;
-		try {
-			var fis = Components.classes['@mozilla.org/network/file-input-stream;1']
-						.createInstance(Components.interfaces.nsIFileInputStream);
-			fis.init(file, -1, 0, 0);
-			var is = Components.classes['@mozilla.org/intl/converter-input-stream;1']
-						.createInstance(Components.interfaces.nsIConverterInputStream);
-			is.init(fis, 'UTF-8', 1024, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
-			if(is instanceof Components.interfaces.nsIUnicharLineInputStream) {
-				var line = {};
-				var cont;
-				do {
-					cont = is.readLine(line);
-					if(fileContent == null) {
-						fileContent = line.value;
-					} else {
-						fileContent += '\n'+line.value;
-					}
-				} while (cont);
-			}
-			is.close();
-			fis.close();
-		} catch(e) {
-			this.log(e);
-		}
-		return fileContent;
-	},
-
-	setFileContent: function(file, str) {
-		try {
-			var fos = Components.classes['@mozilla.org/network/file-output-stream;1']
-						.createInstance(Components.interfaces.nsIFileOutputStream);
-			fos.init(file, 0x02 | 0x08 | 0x20, 0664, 0);
-			var os = Components.classes['@mozilla.org/intl/converter-output-stream;1']
-						.createInstance(Components.interfaces.nsIConverterOutputStream);
-			os.init(fos, 'UTF-8', 4096, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
-			os.writeString(str);
-			os.close();
-			fos.close();
-		} catch(e) {
-			this.log(e);
-		}
-	},
-
-	getFieldRulesFile: function() {
-		var file = this.getConfigDirectory();
-		file.append('fieldRules.txt');
-		if(!file.exists()) {
-			file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
-		}
-		return file;
-	},
-
-	getConfigDirectory: function() {
-		var configDirectory;
-		if(this.autofillFormsPrefs.prefHasUserValue('configDirectory')) {
-			try {
-				configDirectory = this.autofillFormsPrefs.getComplexValue(
-										'configDirectory',
-										Components.interfaces.nsILocalFile
-				);
-			} catch(e) {
-				this.autofillFormsPrefs.clearUserPref('configDirectory');
-			}
-		}
-		if(!configDirectory) {
-			configDirectory = this.getDefaultConfigDirectory();
-		}
-		return configDirectory;
-	},
-
-	getDefaultConfigDirectory: function() {
-		// Use a directory "autofillForms at blueimp.net" inside Firefox profile directory as default:
-		var configDirectory = Components.classes['@mozilla.org/file/directory_service;1']
-								.getService(Components.interfaces.nsIProperties)
-								.get('ProfD', Components.interfaces.nsILocalFile);
-		configDirectory.append('autofillForms at blueimp.net');
-		if(!configDirectory.exists()) {
-		   configDirectory.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0770);
-		}
-		return configDirectory;
-	},
-
-	setConfigDirectory: function(textBox) {
-		try {
-			// Create a file picker instance:
-			var fp = Components.classes['@mozilla.org/filepicker;1']
-						.createInstance(Components.interfaces.nsIFilePicker);
-
-			// Initialize the file picker window:
-			fp.init(
-				window,
-				this.getStringBundle().getString('selectConfigDirectory'),
-				Components.interfaces.nsIFilePicker.modeGetFolder
-			);
-
-			// Show the file picker window:
-			var rv = fp.show();
-
-			if (rv == Components.interfaces.nsIFilePicker.returnOK) {
-				var newDir = fp.file;
-				if(newDir.path == this.getConfigDirectory().path) {
-					return;
-				}
-				this.moveConfigFiles(newDir);
-				// Save the selected directory in the preferences:
-				this.autofillFormsPrefs.setComplexValue(
-					'configDirectory',
-					Components.interfaces.nsILocalFile, newDir
-				);
-				if(textBox) {
-					// Set the textbox value to the directory path:
-					textBox.value = newDir.path;
-				}
-			}
-		} catch(e) {
-			this.log(e);
-		}
-	},
-
-	resetConfigDirectory: function(textBox) {
-		if(this.autofillFormsPrefs.prefHasUserValue('configDirectory')) {
-			var newDir = this.getDefaultConfigDirectory();
-			this.moveConfigFiles(newDir);
-			this.autofillFormsPrefs.clearUserPref('configDirectory');
-			if(textBox) {
-				// Set the textbox value to an empty string:
-				textBox.value = '';
-			}
-		}
-	},
-
-	openConfigDirectory: function() {
-		var configDirectory = this.getConfigDirectory();
-		if(configDirectory) {
-			try {
-				// Open the config directory in the operating system file manager:
-				configDirectory.reveal();
-			} catch(e) {
-				// reveal method may not be supported on some platforms,
-				// use nsIExternalProtocolService instead:
-				var uri = Components.classes["@mozilla.org/network/io-service;1"]
-					.getService(Components.interfaces.nsIIOService)
-					.newFileURI(configDirectory);
-				var protocolSvc =
-				Components.classes["@mozilla.org/uriloader/external-protocol-service;1"]
-					.getService(Components.interfaces.nsIExternalProtocolService);
-				protocolSvc.loadUrl(uri);
-			}
-		}
-	},
-
-	moveConfigFiles: function(newDir) {
-		if(this.checkConfigDirectoryOverwrite(newDir)) {
-			this.moveFile(this.getFieldRulesFile(), newDir);
-			this.moveFile(this.getDynamicTagsFile(), newDir);
-			this.moveFile(this.getDynamicTagCodesFile(), newDir);
-			this.moveFile(this.getProfileLabelsFile(), newDir);
-			this.moveFile(this.getProfileSiteRulesFile(), newDir);
-			return true;
-		}
-		return false;
-	},
-
-	importFromConfigDirectory: function() {
-		var ok = true;
-		if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
-			ok = this.getPrompts().confirm(
-				window,
-				this.getStringBundle().getString('importFromConfigDirectoryTitle'),
-				this.getStringBundle().getString('importFromConfigDirectoryText')
-			);
-		}
-		if(ok) {
-			this.importFieldRulesFromConfigDirectory();
-			this.importDynamicTagsFromConfigDirectory();
-			this.importDynamicTagCodesFromConfigDirectory();
-			this.importProfileLabelsFromConfigDirectory();
-			this.importProfileSiteRulesFromConfigDirectory();
-		}
-	},
-
-	exportToConfigDirectory: function() {
-		if(this.checkConfigDirectoryOverwrite(this.getConfigDirectory())) {
-			this.exportFieldRulesToConfigDirectory();
-			this.exportDynamicTagsToConfigDirectory();
-			this.exportDynamicTagCodesToConfigDirectory();
-			this.exportProfileLabelsToConfigDirectory();
-			this.exportProfileSiteRulesToConfigDirectory();
-			return true;
-		}
-		return false;
-	},
-
-	moveFile: function(file, newDir, newFileName) {
-		try {
-			// The new fileName - uses the current fileName if empty:
-			newFileName = (typeof newFileName == 'string') ? newFileName : null;
-
-			file.moveTo(newDir, newFileName);
-			return true;
-		} catch(e) {
-			this.log(e);
-			return false;
-		}
-	},
-
-	checkConfigDirectoryOverwrite: function(newDir) {
-		var ok = true;
-		if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
-			if(newDir.directoryEntries.hasMoreElements()) {
-				ok = this.getPrompts().confirm(
-					window,
-					this.getStringBundle().getString('newConfigDirectoryNotEmptyTitle'),
-					this.getStringBundle().getString('newConfigDirectoryNotEmptyText')
-				);
-			}
-		}
-		return ok;
-	},
-
-	exportFieldRulesToConfigDirectory: function() {
-		var prefString;
-		// Get the fieldRules string from the preferences:
-		prefString = this.autofillFormsPrefs
-							.getComplexValue('fieldRules',Components.interfaces.nsIPrefLocalizedString)
-							.data;
-		if(prefString) {
-			this.setFileContent(this.getFieldRulesFile(), prefString);
-		}
-	},
-
-	importFieldRulesFromConfigDirectory: function() {
-		var prefString;
-		prefString = this.getFileContent(this.getFieldRulesFile());
-		if(prefString) {
-			// Store the fieldRules as unicode string in the preferences:
-			this.autofillFormsPrefs.setComplexValue(
-				'fieldRules',
-				Components.interfaces.nsISupportsString,
-				this.getUnicodeString(prefString)
-			);
-		}
-	},
-
-	getFieldRules: function(profileIndex) {
-		if(this.fieldRules == null) {
-			this.fieldRules = new Array();
-
-			var prefString;
-			if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-				// Get the fieldRules string from the fieldRules file in the configDirectory:
-				prefString = this.getFileContent(this.getFieldRulesFile());
-			}
-			if(!prefString) {
-				// Get the fieldRules string from the preferences:
-				prefString = this.autofillFormsPrefs
-									.getComplexValue('fieldRules',Components.interfaces.nsIPrefLocalizedString)
-									.data;
-			}
-
-			// On change of the "storeEncrypted" setting, we must decrypt or may not decrypt
-			// the prefString in opposition to the setting - the "invertedSetting" helper var
-			// helps to identify this situation:
-			var boolTest = this.invertedSetting ? false : true;
-
-			// If the fieldRules are stored encrypted, decrypt the prefString:
-			if(this.autofillFormsPrefs.getBoolPref('storeEncrypted') == boolTest) {
-				try {
-					// nsISecretDecoderRing fails to handle characters above ISO-8859-1 charset
-					// The usage of encodeURI/decodeURI on the fieldRule properties bypasses this problem
-					prefString = this.getCryptoService().decryptString(prefString);
-				} catch(e) {
-					// Decrypting failed - return an empty default profile:
-					this.fieldRules.push(new Array());
-					this.profileIndex = 0;
-					return this.fieldRules[0];
-				}
-			}
-
-			// Get the profiles (separated by \n\n):
-			var profiles = prefString.split('\n\n');
-
-			for(var i=0; i<profiles.length; i++) {
-				// Create an array for each profile:
-				this.fieldRules.push(new Array());
-
-				// Get the fieldRules rows (separated by \n):
-				var rows = profiles[i].split('\n');
-				if(rows[0]) {
-					for(var j=0; j<rows.length; j++) {
-						if(!rows[j])
-							continue;
-
-						// Get the fieldRules column items (separated by \t):
-						var cols = rows[j].split('\t');
-
-						// Create fieldRules objects and save them in the current fieldRules Array:
-						if(cols.length && cols.length == 6) {
-
-							// Decode the fieldRule properties:
-							for(var k=0; k<cols.length; k++) {
-								cols[k] = decodeURI(cols[k]);
-							}
-
-							this.fieldRules[i].push(
-								this.createFieldRule(
-									cols[0],cols[1],cols[2],cols[3],
-									(cols[4] != 'false'),
-									(cols[5] != 'false')
-								)
-							);
-						}
-					}
-				} else
-					this.fieldRules[i] = new Array();
-			}
-		}
-
-		profileIndex = (typeof profileIndex != 'undefined') ? profileIndex : this.getProfileIndex();
-
-		// Return the fieldRules for the selected profile if profileIndex is not out of range:
-		if(profileIndex >= 0 && profileIndex < this.fieldRules.length)
-			return this.fieldRules[profileIndex];
-		else {
-			this.profileIndex = 0;
-			if(this.fieldRules[0] == null)
-				this.fieldRules[0] = new Array();
-			return this.fieldRules[0];
-		}
-	},
-
-	setFieldRules: function() {
-		if(this.fieldRules == null) {
-			// Initialize the field rules:
-			this.getFieldRules();
-		}
-
-		var profiles = '';
-		var rows, cols;
-		for(var i=0; i < this.fieldRules.length; i++) {
-			rows = '';
-			for(var j=0; j<this.fieldRules[i].length; j++) {
-				cols = null;
-				for(var property in this.fieldRules[i][j]) {
-					if(cols == null)
-						cols = '';
-					else
-						cols += '\t';
-					// Encode the fieldRule property before adding it to the string:
-					cols += encodeURI(this.fieldRules[i][j][property]);
-				}
-				if(j!=0)
-					rows += '\n';
-				rows += cols;
-			}
-			if(i!=0)
-				profiles += '\n\n';
-			profiles += rows;
-		}
-
-		// If the fieldRules are to be stored encrypted, encrypt the prefString:
-		if(this.autofillFormsPrefs.getBoolPref('storeEncrypted')) {
-			try {
-				// nsISecretDecoderRing fails to handle characters above ISO-8859-1 charset
-				// The usage of encodeURI/decodeURI on the fieldRule properties bypasses this problem
-				profiles = this.getCryptoService().encryptString(profiles);
-			} catch(e) {
-				// Decrypting failed - return:
-				return;
-			}
-		}
-
-		if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-			this.setFileContent(this.getFieldRulesFile(), profiles);
-		} else {
-			// Store the fieldRules objects as unicode string in the preferences:
-			this.autofillFormsPrefs.setComplexValue(
-				'fieldRules',
-				Components.interfaces.nsISupportsString,
-				this.getUnicodeString(profiles)
-			);
-		}
-	},
-
-	copyFieldRules: function(origin) {
-		var copy = new Array();
-		for(var i=0; i<origin.length; i++) {
-			copy.push(
-				this.createFieldRule(
-					origin[i]['fieldRuleName'],
-					origin[i]['fieldRuleValue'],
-					origin[i]['fieldRuleFieldRule'],
-					origin[i]['fieldRuleSiteRule'],
-					origin[i]['fieldRuleOverwrite'],
-					origin[i]['fieldRuleEnabled']
-				)
-			)
-		}
-		return copy;
-	},
-	importDynamicTagsFromSettings: function() {
-		//Here the tags are added directly
-		var prefString = null;
-
-		prefString = this.autofillFormsPrefs
-							.getComplexValue('dynamicTags',Components.interfaces.nsIPrefLocalizedString)
-							.data;
-		var dynamicTags = prefString.split('\t');
-
-		prefString = this.autofillFormsPrefs
-							.getComplexValue('dynamicTagCodes',Components.interfaces.nsIPrefLocalizedString)
-							.data;
-		var dynamicTagCodes = prefString.split('\t');
-
-		this.importDynamicTags(dynamicTags, dynamicTagCodes);
-		this.setDynamicTags(dynamicTags);
-		this.setDynamicTagCodes(dynamicTagCodes);
-	},
-	importDynamicTagsFromTagEditor: function() {
-		//Here the tags are added to the editor window, can be cancelled if necessary
-		var richlistbox = document.getElementById('tagList');
-		if(richlistbox) {
-			var richlistitems = richlistbox.getElementsByTagName('richlistitem');
-			var textboxes;
-
-			var dynamicTags = new Array();
-			var dynamicTagCodes = new Array();
-
-			// Go through the richlistbox items:
-			for(var i=0; i<richlistitems.length; i++) {
-				textboxes = richlistitems[i].getElementsByTagName('textbox');
-
-				// Add the dynamic tags and their associated tag codes to the lists:
-				if (textboxes[0].value != '' && textboxes[1].value != '') {
-					dynamicTags.push(this.makeSafe(textboxes[0].value));
-					dynamicTagCodes.push(this.makeSafe(textboxes[1].value));
-				}
-			}
-			this.importDynamicTags(dynamicTags, dynamicTagCodes);
-		}
-	},
-	importDynamicTags: function(dynamicTags, dynamicTagCodes) {
-		try {
-			var file = this.filePicker('modeOpen', this.getStringBundle().getString('importDynamicTags'));
-			if(file) {
-				var fis = Components.classes['@mozilla.org/network/file-input-stream;1']
-								.createInstance(Components.interfaces.nsIFileInputStream);
-				fis.init(file, -1, 0, 0);
-
-				var is = Components.classes['@mozilla.org/intl/converter-input-stream;1']
-							.createInstance(Components.interfaces.nsIConverterInputStream);
-				is.init(fis, 'UTF-8', 1024, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
-
-				if (is instanceof Components.interfaces.nsIUnicharLineInputStream) {
-					var line = {};
-					var cont;
-					var firstLine = true;
-					var i;
-
-					do {
-						cont = is.readLine(line);
-
-						// Get the dynamicTags column items (separated by \t) from the file:
-						var cols = line.value.split('\t');
-
-						if (firstLine == true) {
-							// The first row has the following syntax (added in version 0.9.5):
-							// autofillForms at blueimp.net	Version	dynamictags
-							if(cols.length && cols.length != 3)
-								cont = false;
-							else if (cols[0] != 'autofillForms at blueimp.net')
-								cont = false;
-							else if (cols[2] != 'dynamictags')
-								cont = false;
-							firstLine = false;
-						}
-						else if (cols.length && cols.length == 2) {
-							//Check the imported pair isn't already defined or empty.
-							i = dynamicTags.indexOf(cols[0]);
-							if ((i >= 0 && dynamicTagCodes[i] == cols[1])||(cols[0]=='' && cols[1]=='')) {
-								continue;
-							} else {
-								dynamicTags.push(cols[0]);
-								dynamicTagCodes.push(cols[1]);
-								this.tagEditorAdd(cols[0],cols[1])
-							}
-						}
-					} while (cont);
-
-				}
-				is.close();
-				fis.close();
-			}
-		} catch(e) {
-			this.log(e);
-		}
-	},
-	exportDynamicTagsFromSettings: function() {
-		var prefString = null;
-
-		// Write the tags to file analog to storing them in the preferences:
-		prefString = this.autofillFormsPrefs
-							.getComplexValue('dynamicTagCodes',Components.interfaces.nsIPrefLocalizedString)
-							.data;
-		var dynamicTagCodes = prefString.split('\t');
-
-		prefString = this.autofillFormsPrefs
-							.getComplexValue('dynamicTags',Components.interfaces.nsIPrefLocalizedString)
-							.data;
-		var dynamicTags = prefString.split('\t');
-		this.exportDynamicTags(dynamicTags, dynamicTagCodes);
-	},
-	exportDynamicTagsFromTagEditor: function() {
-		var richlistbox = document.getElementById('tagList');
-		if(richlistbox) {
-			var richlistitems = richlistbox.getElementsByTagName('richlistitem');
-			var textboxes;
-
-			var dynamicTags = new Array();
-			var dynamicTagCodes = new Array();
-
-			// Go through the richlistbox items:
-			for(var i=0; i<richlistitems.length; i++) {
-				textboxes = richlistitems[i].getElementsByTagName('textbox');
-
-				// Add the dynamic tags and their associated tag codes to the lists:
-				if (textboxes[0].value != '' && textboxes[1].value != '') {
-					dynamicTags.push(this.makeSafe(textboxes[0].value));
-					dynamicTagCodes.push(this.makeSafe(textboxes[1].value));
-				}
-			}
-			this.exportDynamicTags(dynamicTags, dynamicTagCodes);
-		}
-	},
-	exportDynamicTags: function(dynamicTags, dynamicTagCodes) {
-		try {
-			var file = this.filePicker(
-				'modeSave',
-				this.getStringBundle().getString('exportDynamicTags'),
-				this.getProfileLabel(this.getProfileIndex())+'.txt'
-			);
-			if(file) {
-				var fos = Components.classes['@mozilla.org/network/file-output-stream;1'].
-										createInstance(Components.interfaces.nsIFileOutputStream);
-				fos.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
-
-				var os = Components.classes['@mozilla.org/intl/converter-output-stream;1']
-							.createInstance(Components.interfaces.nsIConverterOutputStream);
-				os.init(fos, 'UTF-8', 4096, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
-
-
-				var header = 'autofillForms at blueimp.net' + '\t'
-								+ this.version + '\t'
-								+ 'dynamictags\n';
-				os.writeString(header);
-
-				var cols;
-				for(var i=0; i<dynamicTags.length; i++) {
-					cols = dynamicTags[i]+'\t'+dynamicTagCodes[i];
-					os.writeString('\n' + cols);
-				}
-				os.close();
-				fos.close();
-			}
-		} catch(e) {
-			this.log(e);
-		}
-	},
-	importProfile: function() {
-		try {
-			var file = this.filePicker('modeOpen', this.getStringBundle().getString('importProfile'));
-			if(file) {
-				var fis = Components.classes['@mozilla.org/network/file-input-stream;1']
-								.createInstance(Components.interfaces.nsIFileInputStream);
-				fis.init(file, -1, 0, 0);
-
-				var is = Components.classes['@mozilla.org/intl/converter-input-stream;1']
-							.createInstance(Components.interfaces.nsIConverterInputStream);
-				is.init(fis, 'UTF-8', 1024, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
-
-				if(this.fieldRules == null) {
-					// Initialize the field rules:
-					this.getFieldRules();
-				}
-
-				// Create a new fieldRule profile (index is incremented when a valid header is found):
-				var newProfileLabel = '';
-				var newProfileSiteRule = '(?:)';
-				var newProfileIndex = this.fieldRules.length-1;
-				var validProfile = false;
-
-				if (is instanceof Components.interfaces.nsIUnicharLineInputStream) {
-					var line = {};
-					var cont;
-					do {
-						cont = is.readLine(line);
-
-						// Get the fieldRules column items (separated by \t) from the file:
-						var cols = line.value.split('\t');
-
-						if(cols.length && cols.length < 6 && cols[0] == 'autofillForms at blueimp.net') {
-							// The first row has the following syntax (added SiteRule for version 0.9.1):
-							// autofillForms at blueimp.net	Version	Label	SiteRule
-							// Every time such a row is encountered, a new profile is generated.
-							if(cols.length >= 3) {
-								newProfileLabel = cols[2];
-								// Add profile label for default empty profile:
-								if(this.getProfileLabels().length == 0) {
-									this.getProfileLabels().push(this.getUniqueProfileLabel());
-								}
-								// Add the newProfileLabel to the profileLabels list (make sure it is unique):
-								this.getProfileLabels().push(this.getUniqueProfileLabel(newProfileLabel));
-							}
-							if(cols.length >= 4) {
-								try {
-									newProfileSiteRule = this.getRegExpStr(cols[3]);
-									// Add a new profileSiteRule:
-									this.getProfileSiteRules().push(newProfileSiteRule);
-								} catch(e) {
-									// Catch missing or invalid site rule
-								}
-							}
-							// Increment the ProfileIndex
-							newProfileIndex += 1;
-							this.fieldRules.push(new Array());
-							validProfile = true;
-						} else if(cols.length && cols.length == 6 && validProfile == true) {
-							// Create fieldRules objects and save them in the fieldRules Array:
-							this.fieldRules[newProfileIndex].push(
-								this.createFieldRule(
-									cols[0],cols[1],cols[2],cols[3],
-									(cols[4] != 'false'),
-									(cols[5] != 'false')
-								)
-							);
-						}
-
-					} while (cont);
-				}
-
-				// Save the profileLabels list in the preferences:
-				this.setProfileLabels(this.getProfileLabels());
-				// Save the profileSiteRules in the preferences:
-				this.setProfileSiteRules(this.getProfileSiteRules());
-				// Update the profiles lists:
-				this.initProfilesLists();
-
-				// Update the fieldRules:
-				this.setFieldRules();
-
-				is.close();
-				fis.close();
-			}
-		} catch(e) {
-			this.log(e);
-		}
-	},
-	exportProfile: function() {
-		try {
-			var file = this.filePicker(
-				'modeSave',
-				this.getStringBundle().getString('exportProfile'),
-				this.getProfileLabel(this.getProfileIndex())+'.txt'
-			);
-			if(file) {
-				var fos = Components.classes['@mozilla.org/network/file-output-stream;1'].
-										createInstance(Components.interfaces.nsIFileOutputStream);
-				fos.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
-
-				var os = Components.classes['@mozilla.org/intl/converter-output-stream;1']
-							.createInstance(Components.interfaces.nsIConverterOutputStream);
-				os.init(fos, 'UTF-8', 4096, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
-
-				var profileIndex = this.getProfileIndex();
-				this.writeProfile(os, profileIndex);
-
-				os.close();
-				fos.close();
-			}
-		} catch(e) {
-			this.log(e);
-		}
-	},
-	exportAllProfiles: function() {
-		try {
-			//use the first profile label as the filename
-			var file = this.filePicker(
-				'modeSave',
-				this.getStringBundle().getString('exportProfile'),
-				this.getProfileLabel(0)+'.txt'
-			);
-			if(file) {
-				var fos = Components.classes['@mozilla.org/network/file-output-stream;1'].
-										createInstance(Components.interfaces.nsIFileOutputStream);
-				fos.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
-
-				var os = Components.classes['@mozilla.org/intl/converter-output-stream;1']
-							.createInstance(Components.interfaces.nsIConverterOutputStream);
-
-				os.init(fos, 'UTF-8', 4096, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
-
-				for(var i=0; i<this.getProfileLabels().length; i++) {
-					this.writeProfile(os, i);
-					os.writeString('\n\n');
-				}
-				os.close();
-				fos.close();
-			}
-		} catch(e) {
-			this.log(e);
-		}
-	},
-	writeProfile: function(os, profileIndex) {
-		try {
-			var header = 'autofillForms at blueimp.net' + '\t'
-						+ this.version + '\t'
-						+ this.getProfileLabel(profileIndex) + '\t'
-						+ this.getProfileSiteRule(profileIndex) + '\n';
-
-
-			os.writeString(header);
-			// Write the rules to file analog to storing them in the preferences:
-			var cols;
-			for(var i=0; i<this.getFieldRules(profileIndex).length; i++) {
-				cols = null;
-				for(var property in this.getFieldRules(profileIndex)[i]) {
-					if(cols == null)
-						cols = '';
-					else
-						cols += '\t';
-					cols += this.getFieldRules(profileIndex)[i][property];
-				}
-				os.writeString('\n' + cols);
-			}
-		} catch(e) {
-			this.log(e);
-		}
-	},
-	filePicker: function(mode, title, fileName) {
-		try {
-			// Create a file picker instance:
-			var fp = Components.classes['@mozilla.org/filepicker;1']
-						.createInstance(Components.interfaces.nsIFilePicker);
-
-			// The filename suggested to the user as a default:
-			if(fileName) {
-				fp.defaultString = fileName;
-			}
-
-			// Initialize the file picker window:
-			fp.init(
-				window,
-				title,
-				Components.interfaces.nsIFilePicker[mode]
-			);
-
-			// Show the file picker window:
-			var rv = fp.show();
-
-			if(rv==Components.interfaces.nsIFilePicker.returnOK || rv==Components.interfaces.nsIFilePicker.returnReplace)
-				return fp.file;
-			else
-				return null;
-		} catch(e) {
-			return null;
-		}
-	},
-
-	getUnicodeString: function(stringData) {
-		// Create an Unicode String:
-		var str = Components.classes['@mozilla.org/supports-string;1']
-					.createInstance(Components.interfaces.nsISupportsString);
-		// Set the String value:
-		str.data = stringData;
-		// Return the Unicode String:
-		return str;
-	},
-
-	getStringBundle: function() {
-		return document.getElementById('autofillFormsStringBundle');
-	},
-
-	getDoc: function(win) {
-		if(win)
-			return win.document;
-		else if(content)
-			return content.document;
-		else
-			return this.getBrowser().contentDocument;
-	},
-
-	getWin: function() {
-		if(content)
-			return content;
-		else
-			return this.getBrowser().contentWindow;
-	},
-
-	getBrowser: function() {
-		try {
-			return gBrowser;
-		} catch(e) {
-			// gBrowser is not available, so make use of the WindowMediator service instead:
-			return this.getWindowMediator().getMostRecentWindow('navigator:browser').getBrowser();
-		}
-	},
-
-	getWindowMediator: function() {
-		return Components.classes['@mozilla.org/appshell/window-mediator;1']
-				.getService(Components.interfaces.nsIWindowMediator);
-	},
-
-	getRegExpStr: function(str) {
-		// Create a RegExp object using the given String:
-		var regExpStr = new RegExp(str).toString();
-		// Return the String representation without the surrounding slashes:
-		return regExpStr.substr(1,regExpStr.length-2);
-	},
-
-	getPrefManager: function() {
-		return Components.classes['@mozilla.org/preferences-service;1']
-				.getService(Components.interfaces.nsIPrefService);
-	},
-
-	getCryptoService: function() {
-		return Components.classes['@mozilla.org/security/sdr;1']
-				.createInstance(Components.interfaces.nsISecretDecoderRing);
-	},
-
-	getPrompts: function() {
-		return Components.classes['@mozilla.org/embedcomp/prompt-service;1']
-				.getService(Components.interfaces.nsIPromptService);
-	},
-
-	recognizeMouseButton: function(event) {
-		var modifiers = new Array();
-
-		// Get the modifiers:
-		if(event.altKey) modifiers.push('alt');
-		if(event.ctrlKey) modifiers.push('control');
-		if(event.metaKey) modifiers.push('meta');
-		if(event.shiftKey) modifiers.push('shift');
-
-		// Return a mouseButtonObj:
-		return this.mouseButtonFactory(modifiers, 'mousebutton'+event.button);
-	},
-
-	mouseButtonFactory: function(modifiers, mouseButton) {
-		if(typeof arguments.callee.mouseButtonObj == 'undefined') {
-			arguments.callee.mouseButtonObj = function(modifiers, mouseButton) {
-				this.modifiers = modifiers ? modifiers : new Array();
-				this.mouseButton = mouseButton;
-				this.toString = function() {
-					if(this.modifiers.length) {
-						return this.modifiers.join('+')+'+'+this.mouseButton;
-					} else {
-						return this.mouseButton;
-					}
-				}
-				this.equals = function(mouseButtonObj) {
-					if(this.mouseButton != mouseButtonObj.mouseButton) {
-						return false;
-					}
-					if(this.modifiers.length != mouseButtonObj.modifiers.length) {
-						return false;
-					}
-					for(var i=0; i<this.modifiers.length; i++) {
-						if(this.modifiers[i] != mouseButtonObj.modifiers[i]) {
-							return false;
-						}
-					}
-					return true;
-				}
-				return this;
-			}
-		}
-		return new arguments.callee.mouseButtonObj(modifiers, mouseButton);
-	},
-
-	getFormattedMouseButton: function(mouseButtonObj) {
-		var formattedMouseButton = '';
-		if(!mouseButtonObj.mouseButton) {
-			return formattedMouseButton;
-		}
-		// Add the modifiers:
-		for(var i=0; i < mouseButtonObj.modifiers.length; i++) {
-			try {
-				formattedMouseButton += this.getStringBundle().getString(mouseButtonObj.modifiers[i])+'+';
-			} catch(e) {
-				this.log(e);
-				// Error in shortcut string, return empty String:
-				return '';
-			}
-		}
-		try {
-			formattedMouseButton += this.getStringBundle().getString(mouseButtonObj.mouseButton);
-		} catch(e) {
-			// No localization for this mouse button, add generic button string :
-			formattedMouseButton += this.getStringBundle().getString('mousebutton');
-			// Add the index of the given mouseButton:
-			formattedMouseButton += ' '+mouseButtonObj.mouseButton.substr('mousebutton'.length);
-		}
-		return formattedMouseButton;
-	},
-
-	applyMouseButton: function(event, id) {
-		// Recognize the mouse button event:
-		var mouseButtonObj = this.recognizeMouseButton(event);
-		if(!mouseButtonObj)
-			return;
-		// Ignore the right mouse button (mousebutton2), as this already invokes the context menu:
-		if(mouseButtonObj.mouseButton == 'mousebutton2') {
-			return;
-		}
-		// Save the new mouse button object:
-		this.setMouseButton(id, mouseButtonObj);
-		// Update the mouse button textbox:
-		if(event.view.document && event.view.document.getElementById(id)) {
-			event.view.document.getElementById(id).value = this.getFormattedMouseButton(mouseButtonObj);
-		}
-	},
-
-	disableMouseButton: function(event, id) {
-		// Disable the mouse button:
-		this.setMouseButton(id, null);
-		// Update the mouse button textbox:
-		if(event.view.document && event.view.document.getElementById(id)) {
-			event.view.document.getElementById(id).value = '';
-		}
-	},
-
-	getMouseButton: function(id) {
-		if(this.mouseButton == null) {
-			// Create a new mouseButton container object:
-			this.mouseButton = new Object();
-		}
-		if(this.mouseButton[id] == null) {
-			var mouseButtonItems = this.autofillFormsPrefs.getCharPref(id).split('+');
-			var mouseButton;
-			if(mouseButtonItems.length == 0) {
-				mouseButton = '';
-			} else {
-				// Remove the last element and save it as mouseButton
-				// the remaining mouseButtonItems are the modifiers:
-				mouseButton = mouseButtonItems.pop();
-			}
-			// Create a new mouseButton object:
-			this.mouseButton[id] = this.mouseButtonFactory(mouseButtonItems, mouseButton);
-		}
-		return this.mouseButton[id];
-	},
-
-	setMouseButton: function(id, mouseButtonObj) {
-		var stringData;
-		if(mouseButtonObj) {
-			stringData = mouseButtonObj.toString();
-		} else {
-			stringData = '';
-		}
-		// Save the mouseButtonObj as Unicode String in the preferences:
-		this.autofillFormsPrefs.setComplexValue(
-			id,
-			Components.interfaces.nsISupportsString,
-			this.getUnicodeString(stringData)
-		);
-	},
-
-	recognizeKeys: function(event) {
-		var modifiers = new Array();
-		var key = '';
-		var keycode = '';
-
-		// Get the modifiers:
-		if(event.altKey) modifiers.push('alt');
-		if(event.ctrlKey) modifiers.push('control');
-		if(event.metaKey) modifiers.push('meta');
-		if(event.shiftKey) modifiers.push('shift');
-
-		// Get the key or keycode:
-		if(event.charCode) {
-			key = String.fromCharCode(event.charCode).toUpperCase();
-		} else {
-			// Get the keycode from the keycodes list:
-			keycode = this.getKeyCodes()[event.keyCode];
-			if(!keycode) {
-				return null;
-			}
-		}
-
-		// Shortcut may be anything, but not 'VK_TAB' alone (without modifiers),
-		// as this button is used to change focus to the 'Apply' button:
-		if(modifiers.length > 0 || keycode != 'VK_TAB') {
-			return this.shortcutFactory(modifiers, key, keycode);
-		}
-		return null;
-	},
-
-	shortcutFactory: function(modifiers, key, keycode) {
-		if(typeof arguments.callee.shortcut == 'undefined') {
-			arguments.callee.shortcut = function(modifiers, key, keycode) {
-				this.modifiers = modifiers ? modifiers : new Array();
-				this.key = key;
-				this.keycode = keycode;
-				this.toString = function() {
-					if(this.modifiers.length) {
-						return this.modifiers.join('+')+'+'+this.key+this.keycode;
-					} else {
-						return this.key+this.keycode;
-					}
-				}
-				this.equals = function(shortcut) {
-					if(this.key != shortcut.key) {
-						return false;
-					}
-					if(this.keycode != shortcut.keycode) {
-						return false;
-					}
-					if(this.modifiers.length != shortcut.modifiers.length) {
-						return false;
-					}
-					for(var i=0; i<this.modifiers.length; i++) {
-						if(this.modifiers[i] != shortcut.modifiers[i]) {
-							return false;
-						}
-					}
-					return true;
-				}
-				return this;
-			}
-		}
-		return new arguments.callee.shortcut(modifiers, key, keycode);
-	},
-
-	getKeyCodes: function() {
-		var keycodes = new Array();
-		// Get the list of keycodes from the KeyEvent object:
-		for(var property in KeyEvent) {
-			keycodes[KeyEvent[property]] = property.replace('DOM_','');
-		}
-		// VK_BACK_SPACE (index 8) must be VK_BACK:
-		keycodes[8] = 'VK_BACK';
-		return keycodes;
-	},
-
-	applyShortcut: function(event, id) {
-		// Recognize the pressed keys:
-		var shortcut = this.recognizeKeys(event)
-		if(!shortcut)
-			return;
-		// Save the new shortcut:
-		this.setShortcut(id, shortcut);
-		// Update the shortcut textbox:
-		if(event.view.document && event.view.document.getElementById(id)) {
-			event.view.document.getElementById(id).value = this.getFormattedShortcut(shortcut);
-		}
-	},
-
-	disableShortcut: function(event, id) {
-		// Disable the shortcut:
-		this.setShortcut(id, null);
-		// Update the shortcut textbox:
-		if(event.view.document && event.view.document.getElementById(id)) {
-			event.view.document.getElementById(id).value = '';
-		}
-	},
-
-	getShortcut: function(id) {
-		if(this.shortcut == null) {
-			// Create a new shortcut container object:
-			this.shortcut = new Object();
-		}
-		if(this.shortcut[id] == null) {
-			var key = null;
-			var keycode = null;
-			var shortcutItems = this.autofillFormsPrefs
-								.getComplexValue(id,Components.interfaces.nsIPrefLocalizedString)
-								.data.split('+');
-			if(shortcutItems.length > 0) {
-				// Remove the last element and save it as key
-				// the remaining shortcutItems are the modifiers:
-				key = shortcutItems.pop();
-				// Check if the key is a keycode:
-				if(key.indexOf('VK') == 0) {
-					keycode	= key;
-					key = null;
-				}
-			}
-			// Create a new shortcut object:
-			this.shortcut[id] = this.shortcutFactory(shortcutItems, key, keycode);
-		}
-		return this.shortcut[id];
-	},
-
-	setShortcut: function(id, shortcut) {
-		var stringData;
-		if(shortcut) {
-			stringData = shortcut.toString();
-		} else {
-			stringData = '';
-		}
-		// Save the shortcut as Unicode String in the preferences:
-		this.autofillFormsPrefs.setComplexValue(
-			id,
-			Components.interfaces.nsISupportsString,
-			this.getUnicodeString(stringData)
-		);
-	},
-
-	updateShortcut: function(id) {
-		if(this.shortcut == null) {
-			this.shortcut = new Object();
-		}
-		// Setting the shortcut object to "null" will update it on the next getShortcut() call:
-		this.shortcut[id] = null;
-
-		// Get the keyboard shortcut elements:
-		var modifiers = this.getShortcut(id).modifiers.join(' ');
-		var key = this.getShortcut(id).key;
-		var keycode = this.getShortcut(id).keycode;
-
-		var domId = 'autofillForms' + id.replace(/shortcut/, 'Shortcut');
-		var command = 'autofillForms' + id.replace(/shortcut/i, '');
-
-		// Remove current key if existing:
-		if(document.getElementById(domId)) {
-			document.getElementById('mainKeyset').removeChild(
-				document.getElementById(domId)
-			);
-		}
-
-		// Check if keyboard shortcut is enabled:
-		if(key || keycode) {
-			// Create a key element:
-			var keyNode = document.createElement('key');
-
-			keyNode.setAttribute('id', domId);
-			keyNode.setAttribute('command', command);
-
-			// Set the key attributes from saved shortcut:
-			keyNode.setAttribute('modifiers', modifiers);
-			if(key) {
-				keyNode.setAttribute('key', key);
-			} else {
-				keyNode.setAttribute('keycode', keycode);
-			}
-
-			// Add the key to the mainKeyset:
-			document.getElementById('mainKeyset').appendChild(keyNode);
-		}
-	},
-
-	getFormattedShortcut: function(shortcut) {
-		var formattedShortcut = '';
-		// Add the modifiers:
-		for(var i=0; i < shortcut.modifiers.length; i++) {
-			try {
-				formattedShortcut += this.getStringBundle().getString(shortcut.modifiers[i]) + '+';
-			} catch(e) {
-				// Error in shortcut string, return empty String;
-				return '';
-			}
-		}
-		if(shortcut.key) {
-			// Add the key:
-			if(shortcut.key == ' ') {
-				formattedShortcut += this.getStringBundle().getString('VK_SPACE');
-			} else {
-				formattedShortcut += shortcut.key;
-			}
-		} else if(shortcut.keycode) {
-			// Add the keycode (instead of the key):
-			try {
-				formattedShortcut += this.getStringBundle().getString(shortcut.keycode);
-			} catch(e) {
-				formattedShortcut += shortcut.keycode.replace('VK_', '');
-			}
-		}
-		return formattedShortcut;
-	},
-
-	replaceDynamicTags: function(fieldRuleValue) {
-		// Replace all dynamic tags with the return values of their associated tag codes:
-		for(var j=0; j<this.getDynamicTags().length; j++) {
-			// Catch if the number of tags doesn't match the number of tag codes or if the tag code is invalid:
-			try {
-				var regExpObj = new RegExp(this.getDynamicTags()[j],'g');
-				// We use eval() here without restrictions - the given tagCode must be trusted:
-				fieldRuleValue = fieldRuleValue.replace(regExpObj, eval(this.getDynamicTagCodes()[j]));
-			} catch(e) {
-				this.log(e);
-			}
-		}
-		return fieldRuleValue;
-	},
-
-	getDynamicTagsFile: function() {
-		var file = this.getConfigDirectory();
-		file.append('dynamicTags.txt');
-		if(!file.exists()) {
-			file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
-		}
-		return file;
-	},
-
-	exportDynamicTagsToConfigDirectory: function() {
-		var prefString;
-		// Get the dynamicTags string from the preferences:
-		prefString = this.autofillFormsPrefs
-							.getComplexValue('dynamicTags',Components.interfaces.nsIPrefLocalizedString)
-							.data;
-		if(prefString) {
-			this.setFileContent(this.getDynamicTagsFile(), prefString);
-		}
-	},
-
-	importDynamicTagsFromConfigDirectory: function() {
-		var prefString;
-		prefString = this.getFileContent(this.getDynamicTagsFile());
-		if(prefString) {
-			// Store the dynamicTags as unicode string in the preferences:
-			this.autofillFormsPrefs.setComplexValue(
-				'dynamicTags',
-				Components.interfaces.nsISupportsString,
-				this.getUnicodeString(prefString)
-			);
-		}
-	},
-
-	getDynamicTags: function() {
-		if(this.dynamicTags == null) {
-			var prefString;
-			if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-				// Get the dynamicTags string from the dynamicTags file in the configDirectory:
-				prefString = this.getFileContent(this.getDynamicTagsFile());
-			}
-			if(!prefString) {
-				prefString = this.autofillFormsPrefs
-									.getComplexValue('dynamicTags',Components.interfaces.nsIPrefLocalizedString)
-									.data;
-			}
-			this.dynamicTags = prefString.split('\t');
-		}
-		return this.dynamicTags;
-	},
-
-	setDynamicTags: function(dynamicTags) {
-		// Save the dynamic tags separated by tabs:
-		var prefString = dynamicTags.join('\t');
-		if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-			this.setFileContent(this.getDynamicTagsFile(), prefString);
-		} else {
-			this.autofillFormsPrefs.setComplexValue(
-				'dynamicTags',
-				Components.interfaces.nsISupportsString,
-				this.getUnicodeString(prefString)
-			);
-		}
-	},
-
-	getDynamicTagCodesFile: function() {
-		var file = this.getConfigDirectory();
-		file.append('dynamicTagCodes.txt');
-		if(!file.exists()) {
-			file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0660);
-		}
-		return file;
-	},
-
-	exportDynamicTagCodesToConfigDirectory: function() {
-		var prefString;
-		// Get the dynamicTagCodes string from the preferences:
-		prefString = this.autofillFormsPrefs
-							.getComplexValue('dynamicTagCodes',Components.interfaces.nsIPrefLocalizedString)
-							.data;
-		if(prefString) {
-			this.setFileContent(this.getDynamicTagCodesFile(), prefString);
-		}
-	},
-
-	importDynamicTagCodesFromConfigDirectory: function() {
-		var prefString;
-		prefString = this.getFileContent(this.getDynamicTagCodesFile());
-		if(prefString) {
-			// Store the dynamicTagCodes as unicode string in the preferences:
-			this.autofillFormsPrefs.setComplexValue(
-				'dynamicTagCodes',
-				Components.interfaces.nsISupportsString,
-				this.getUnicodeString(prefString)
-			);
-		}
-	},
-
-	getDynamicTagCodes: function() {
-		if(this.dynamicTagCodes == null) {
-			var prefString;
-			if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-				// Get the dynamicTagCodes string from the dynamicTagCodes file in the configDirectory:
-				prefString = this.getFileContent(this.getDynamicTagCodesFile());
-			}
-			if(!prefString) {
-				prefString = this.autofillFormsPrefs
-									.getComplexValue('dynamicTagCodes',Components.interfaces.nsIPrefLocalizedString)
-									.data;
-			}
-			this.dynamicTagCodes = prefString.split('\t');
-		}
-		return this.dynamicTagCodes;
-	},
-
-	setDynamicTagCodes: function(dynamicTagCodes) {
-		// Save the dynamic tag codes separated by tabs:
-		var prefString = dynamicTagCodes.join('\t');
-		if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-			this.setFileContent(this.getDynamicTagCodesFile(), prefString);
-		} else {
-			this.autofillFormsPrefs.setComplexValue(
-			'dynamicTagCodes',
-				Components.interfaces.nsISupportsString,
-				this.getUnicodeString(prefString)
-			);
-		}
-	},
-
-	optionsInitialize: function() {
-		// Save the reference to the Autofill Forms preferences branch:
-		this.autofillFormsPrefs = this.getPrefManager().getBranch('extensions.autofillForms at blueimp.net.');
-
-		// Initialize the profile lists:
-		this.initProfilesLists();
-		// Initialize the fieldRules tree:
-		this.initTree();
-		// Initialize the simple interface:
-		this.initSimpleInterface();
-
-		// Sort is to be ascending if clicked first:
-		this.ascending = true;
-		this.profilesAscending = true;
-
-		var configDirectoryTextbox = document.getElementById('configDirectoryTextBox');
-		if(configDirectoryTextbox && this.autofillFormsPrefs.prefHasUserValue('configDirectory')) {
-			var configDirectory = this.getConfigDirectory();
-			if(configDirectory) {
-				configDirectoryTextbox.value = configDirectory.path;
-			}
-		}
-
-		// Initialize the keyboard shortcut objects:
-		this.shortcut = new Object();
-		this.shortcut['shortcut'] = null;
-		this.shortcut['shortcutSubmit'] = null;
-		this.shortcut['shortcutAllTabs'] = null;
-		this.shortcut['shortcutFromProfileSelection'] = null;
-		this.shortcut['shortcutProfile'] = null;
-		this.shortcut['shortcutSettings'] = null;
-		this.shortcut['shortcutDisplayFormDetails'] = null;
-
-		// Display the shortcut combinations:
-		for(var property in this.shortcut) {
-			if(document.getElementById(property)) {
-				document.getElementById(property).value = this.getFormattedShortcut(this.getShortcut(property));
-			}
-		}
-
-		// Initialize the mouse button objects:
-		this.mouseButton = new Object();
-		this.mouseButton['mouseShortcut'] = null;
-		this.mouseButton['mouseShortcutSubmit'] = null;
-		this.mouseButton['mouseShortcutAllTabs'] = null;
-		this.mouseButton['mouseShortcutFromProfileSelection'] = null;
-		this.mouseButton['mouseShortcutProfile'] = null;
-		this.mouseButton['mouseShortcutSettings'] = null;
-		this.mouseButton['mouseShortcutDisplayFormDetails'] = null;
-
-		// Display the mouse button combinations:
-		for(var property in this.mouseButton) {
-			if(document.getElementById(property)) {
-				document.getElementById(property).value = this.getFormattedMouseButton(this.getMouseButton(property));
-			}
-		}
-
-		// Parse the window params (e.g. initializing the target form field values):
-		this.parseOptionsWindowParams();
-	},
-
-	initSimpleInterface: function() {
-		var rows = document.getElementById('simpleInterfaceRows');
-		if(rows) {
-			while(rows.hasChildNodes()) {
-				rows.removeChild(rows.firstChild);
-			}
-			for(var i=0; i<this.getFieldRules().length; i++) {
-				// Only show enabled fieldRules:
-				if(!this.getFieldRules()[i]['fieldRuleEnabled']) {
-					continue;
-				}
-				rows.appendChild(
-					this.getSimpleInterfaceRow(
-						i,
-						this.getFieldRules()[i]['fieldRuleName'],
-						this.getFieldRules()[i]['fieldRuleValue']
-					)
-				);
-			}
-		}
-	},
-
-	addSimpleInterfaceRow: function(index) {
-		var row = this.getSimpleInterfaceRow(
-						index,
-						this.getFieldRules()[index]['fieldRuleName'],
-						this.getFieldRules()[index]['fieldRuleValue']
-					)
-		var rows = document.getElementById('simpleInterfaceRows');
-		if(rows) {
-			var nextSibling;
-			if(rows.childNodes) {
-				for(var i=index+1; i<rows.childNodes.length; i++) {
-					nextSibling = document.getElementById('simpleInterfaceRow_'+i);
-					if(nextSibling) {
-						rows.insertBefore(row, nextSibling);
-						break;
-					}
-				}
-			}
-			if(!nextSibling) {
-				rows.appendChild(row);
-			}
-		}
-	},
-
-	removeSimpleInterfaceRow: function(index) {
-		var row = document.getElementById('simpleInterfaceRow_'+index);
-		if(row) {
-			row.parentNode.removeChild(row);
-		}
-	},
-
-	getSimpleInterfaceRow: function(index, name, value) {
-		if(!arguments.callee.row) {
-			arguments.callee.row = document.createElement('row');
-			arguments.callee.row.setAttribute('align', 'center');
-			var label = document.createElement('label');
-			var textbox = document.createElement('textbox');
-			textbox.setAttribute(
-				'onchange',
-				'autofillForms.applySimpleInterfaceValue(this)'
-			);
-			textbox.setAttribute(
-				'oninput',
-				'this.value=autofillForms.replaceControlCharacters(this.value)'
-			);
-			textbox.setAttribute('newlines', 'pasteintact');
-			arguments.callee.row.appendChild(label);
-			arguments.callee.row.appendChild(textbox);
-		}
-		var row = arguments.callee.row.cloneNode(true);
-		row.setAttribute('id', 'simpleInterfaceRow_'+index);
-		row.firstChild.setAttribute('value', name+':');
-		row.firstChild.setAttribute('id', 'simpleInterfaceLabel_'+index);
-		row.firstChild.setAttribute('control', 'simpleInterfaceTextbox_'+index);
-		row.lastChild.setAttribute('id', 'simpleInterfaceTextbox_'+index);
-		row.lastChild.setAttribute('value', value);
-		// Is textbox a password field?
-		if(this.getRegExpPasswordLabel().test(name)) {
-			row.lastChild.setAttribute('type', 'password');
-		}
-		return row;
-	},
-
-	applySimpleInterfaceValue: function(textBox) {
-		// See method selectedFieldRule() why this has to be set to null:
-		this.lastSelectedIndex = null;
-
-		var index = parseInt(textBox.getAttribute('id').split('_')[1]);
-		this.getFieldRules()[index]['fieldRuleValue'] = this.makeSafe(textBox.value);
-
-		// Notify the tree (of the advanced interface):
-		try {
-			this.treeBox.invalidateRow(index);
-		} catch(e) {
-		}
-
-		// Update the preferences:
-		this.setFieldRules();
-	},
-
-	updateSimpleInterfaceRow: function(index) {
-		var row = document.getElementById('simpleInterfaceRow_'+index);
-		if(row) {
-			row.firstChild.value = this.getFieldRules()[index]['fieldRuleName']+':';
-			row.lastChild.value = this.getFieldRules()[index]['fieldRuleValue'];
-			// Is textbox a password field?
-			if(this.getRegExpPasswordLabel().test(this.getFieldRules()[index]['fieldRuleName'])) {
-				row.lastChild.setAttribute('type', 'password');
-			} else {
-				row.lastChild.removeAttribute('type');
-			}
-		}
-	},
-
-	getFieldRuleNameForElement: function(element) {
-		// Use the form field label as name if available:
-		var labelValue = this.getLabelForElement(element);
-		// Remove the colon, if present:
-		if(labelValue && labelValue.charAt(labelValue.length-1) == ':') {
-			labelValue = labelValue.substr(0, labelValue.length-1);
-		}
-		// If no label could be found, use the name or the id with the first character in upper case:
-		if(!labelValue) {
-			labelValue = element.name;
-			if(!labelValue) {
-				labelValue = element.id;
-			}
-			if(labelValue) {
-				labelValue = labelValue.charAt(0).toUpperCase() + labelValue.substr(1);
-			}
-		}
-		return labelValue;
-	},
-
-	getRegExpStrForValue: function(value) {
-		try {
-			// Remove unsave characters, escape regexp characters and return the regexp string:
-			return this.getRegExpStr('(?:^'+this.escapeRegExp(this.makeSafe(value))+'$)');
-		} catch(e) {
-			// If an error occurs, return the safe value string.
-			// If using it as regular expression fails a simple string comparison is used:
-			return this.makeSafe(value);
-		}
-	},
-
-	getFieldRuleForElement: function(element) {
-		var name = element.name;
-		// If no name is available use the label as fallback:
-		if(!name) {
-			name = this.getLabelForElement(element);
-		}
-		// If no name and no label is available use the id as fallback:
-		if(!name) {
-			name = element.id;
-		}
-		try {
-			// Remove unsave characters, escape regexp characters and return the regexp string:
-			return this.getRegExpStr('(?:^'+this.escapeRegExp(this.makeSafe(name))+'$)');
-		} catch(e) {
-			// If an error occurs, return an always matching regexp string:
-			return '(?:)';
-		}
-	},
-
-	getSiteRuleForURL: function(url) {
-		try {
-			// Remove unsave characters, escape regexp characters and return the regexp string:
-			return this.getRegExpStr('(?:^'+this.escapeRegExp(this.makeSafe(url))+')');
-		} catch(e) {
-			// If an error occurs, return an always matching regexp string:
-			return '(?:)';
-		}
-	},
-
-	parseOptionsWindowParams: function() {
-		// Check the windows arguments:
-		if(window.arguments && window.arguments[0]) {
-			if(window.arguments[0].targetFormField) {
-				var formFieldObject = window.arguments[0].targetFormField;
-
-				var value;
-				switch(formFieldObject.type) {
-					case 'checkbox':
-					case 'radio':
-					case 'select-one':
-					case 'select-multiple':
-						value = this.getRegExpStrForValue(formFieldObject.value);
-						break;
-					default:
-						value = this.replaceControlCharacters(formFieldObject.value);
-						break;
-				}
-
-				var location = this.getDoc().location;
-
-				// Reset the targetFormField of the autofillForms object referenced by window.arguments[0]:
-				window.arguments[0].targetFormField = null;
-
-				// Set the textbox values using the form field properties and the current document location:
-				document.getElementById('fieldRuleNameTextBox').value
-					= this.getFieldRuleNameForElement(formFieldObject)
-					+ (location.hostname ? ' - ' + location.hostname : '');
-				document.getElementById('fieldRuleValueTextBox').value = value;
-				document.getElementById('fieldRuleFieldRuleTextBox').value
-					= this.getFieldRuleForElement(formFieldObject);
-				document.getElementById('fieldRuleSiteRuleTextBox').value
-					= this.getSiteRuleForURL(location.protocol + '//' + location.host);
-
-				// Make sure the main pane is selected:
-				document.getElementById('autofillFormsPrefs').showPane(
-					document.getElementById('autofillFormsPrefPaneMain')
-				);
-
-				// Set the focus to the name field:
-				document.getElementById('fieldRuleNameTextBox').focus();
-			} else if(window.arguments[0].newProfileFromForm) {
-				// Make sure the main pane is selected:
-				document.getElementById('autofillFormsPrefs').showPane(
-					document.getElementById('autofillFormsPrefPaneMain')
-				);
-			}
-		}
-	},
-
-	optionsFinalize: function() {
-	},
-
-	showProfileSwitcher: function() {
-		if(this.autofillFormsPrefs.getBoolPref('useConfigDirectory')) {
-			// Always retrieve the profile labels from file if useConfigDirectory is enabled:
-			this.profileLabels = null;
-		}
-		// The nsIPromptService select() method doesn't offer to set a preselection,
-		// so we switch the current profile label with the first item (which is selected by default):
-		var list;
-		var currentIndex = this.getProfileIndex();
-		if(currentIndex != 0) {
-			// Copy the profilLabels array (so we don't change the original):
-			list = new Array().concat(this.getProfileLabels());
-			// Switch the current profile label with the first item:
-			var tmp = list[0];
-			list[0] = list[currentIndex];
-			list[currentIndex] = tmp;
-		} else {
-			// Set the list to the profilLabels reference if it is not to be changed:
-			list = this.getProfileLabels();
-		}
-		var selected = {};
-		// Show the selection prompt:
-		var ok = this.getPrompts().select(
-			window,
-			this.getStringBundle().getString('profileSelectionWindowTitle'),
-			this.getStringBundle().getString('profileSelectionPrompt'),
-			list.length,
-			list,
-			selected
-		);
-		if(ok) {
-			// If nothing changed, return:
-			if(selected.value == 0)
-				return;
-			// If the currentIndex has been selected and is not 0, it is in fact the index 0:
-			if(currentIndex != 0 && selected.value == currentIndex)
-				selected.value = 0;
-			// Set the profile index to the selected one:
-			this.setProfileIndex(selected.value)
-		}
-	},
-
-	showDialog: function(url, params) {
-		if (this.currentDialogs == null) {
-			this.currentDialogs = new Object();
-		}
-
-		// Is the window already
-		var win = this.currentDialogs[url];
-		if (win == null || win.closed)
-		{
-			var paramObject = params ? params : this;
-			win = window.openDialog(
-				url,
-				'',
-				'chrome=yes,resizable=yes,toolbar=yes,centerscreen=yes,modal=no,dependent=no,dialog=no',
-				paramObject
-			);
-			this.currentDialogs[url] = win;
-			return win;
-		} else {
-			win.focus();
-		}
-	},
-
-	inArray: function(array, item) {
-		var i = array.length;
-		while(i--)
-			if(array[i] === item)
-				return true;
-		return false;
-	},
-
-	displayFormDetails: function() {
-		this.searchAndDisplayFormDetails(this.getWin());
-	},
-
-	searchAndDisplayFormDetails: function(win) {
-		win = win ? win : this.getWin();
-
-		var doc = this.getDoc(win);
-
-		// Check if any web forms are available on the current window:
-		if(doc && doc.forms && doc.forms.length > 0) {
-
-		 	// Go through the forms:
-		 	for(var i = 0; i < doc.forms.length; i++) {
-
-				// The form elements list:
-				var elements = doc.forms[i].elements;
-
-				// Go through the form elements:
-				for(var j = 0; j < elements.length; j++) {
-					this.displayFormElementDetails(elements[j], j, i, doc);
-				}
-			}
-		}
-
-		// Recursive call for all subframes:
-		for(var f=0; f < win.frames.length; f++) {
-			this.searchAndDisplayFormDetails(win.frames[f]);
-		}
-	},
-
-	isValidFormField: function(element) {
-		// ignore disabled (and return false) only if 'ignore disabled fields' is ticked
-		if(element.disabled && this.autofillFormsPrefs.getBoolPref('ignoreDisabledFields')) {
-			return false;
-		}
-		if(!arguments.callee.regExpFormFieldType) {
-			arguments.callee.regExpFormFieldType = new RegExp(
-				this.autofillFormsPrefs.getCharPref('regExpFormFieldTypes')
-			);
-		}
-		return arguments.callee.regExpFormFieldType.test(element.type);
-	},
-
-	displayFormElementDetails: function(element, elementNumber, formNumber, doc) {
-		// Create a unique id for the form element:
-		var id = 'autofillForms-f' + formNumber + '-e' + elementNumber;
-
-		// Remove the form details node if already present
-		// (nodeType 1 is an element node):
-		if(element.nextSibling && element.nextSibling.nodeType == 1 && element.nextSibling.getAttribute('id') == id) {
-			element.parentNode.removeChild(element.nextSibling);
-			return;
-		}
-
-		// Only display valid form fields:
-		if(this.isValidFormField(element)) {
-			// Create a "span" node with element details:
-			var text;
-			// Display the element name if available, else the element id if available, else an empty name:
-			if(element.name || !element.id) {
-				text = 'name="' + element.name;
-			} else {
-				text = 'id="' + element.id;
-			}
-			// Display the element value:
-			text += '" value="' +  element.value + '"';
-			var span = doc.createElement('span');
-			span.setAttribute('id', id);
-			span.setAttribute('style', this.autofillFormsPrefs.getCharPref('formDetailsStyle'));
-			span.setAttribute('title', text);
-			span.appendChild(doc.createTextNode(text));
-
-			// Insert the form details node after the element:
-			if(element.nextSibling)
-				element.parentNode.insertBefore(span, element.nextSibling);
-			else
-				element.parentNode.appendChild(span);
-		}
-	},
-
-	ruleEditorInitialize: function() {
-		// Save the reference to the Autofill Forms preferences branch:
-		this.autofillFormsPrefs = this.getPrefManager().getBranch('extensions.autofillForms at blueimp.net.');
-
-		if(window.arguments && window.arguments[0] && window.arguments[0].attributes) {
-			this.currentRuleField = window.arguments[0];
-		}
-
-		// Initialize the ruleElementTypes:
-		this.ruleElementTypes = new Array();
-		this.ruleElementTypes.push('contains');
-		this.ruleElementTypes.push('beginsWith');
-		this.ruleElementTypes.push('endsWith');
-		this.ruleElementTypes.push('equals');
-
-		// If the rule editor is used to edit the site rule, add two predefined protocol rules:
-		if(this.currentRuleField && this.currentRuleField.id && this.currentRuleField.id.indexOf('SiteRule') != -1) {
-			this.ruleEditorAdd('beginsWith', 'http:\/\/');
-			this.ruleEditorAdd('beginsWith', 'https:\/\/');
-		} else {
-			this.ruleEditorAdd();
-		}
-	},
-
-	ruleEditorSave: function() {
-		if(document.getElementById('ruleElementsList')) {
-			var str = '';
-			var richlistbox = document.getElementById('ruleElementsList');
-			var richlistitems = richlistbox.getElementsByTagName('richlistitem');
-			var menulists,textboxes;
-
-			// Go through the richlistbox items:
-			for(var i=0; i<richlistitems.length; i++) {
-				// Link the conditions as disjunctions (OR-Relations);
-				if(str.length != 0)
-					str += '|';
-				menulists = richlistitems[i].getElementsByTagName('menulist');
-				textboxes = richlistitems[i].getElementsByTagName('textbox');
-
-				// Add the current condition to the string:
-				switch(menulists[0].selectedItem.value) {
-					case 'contains':
-						str += '(?:' + textboxes[0].value + ')';
-						break;
-					case 'beginsWith':
-						str += '(?:^' + textboxes[0].value + ')';
-						break;
-					case 'endsWith':
-						str += '(?:' + textboxes[0].value + '$)';
-						break;
-					case 'equals':
-						str += '(?:^' + textboxes[0].value + '$)';
-						break;
-				}
-			}
-			if(this.currentRuleField) {
-				// Set the current field value to the created string:
-				this.currentRuleField.value = str;
-				// Call the onchange handler:
-				if(this.currentRuleField.onchange) {
-					this.currentRuleField.onchange();
-				}
-				// Call the focus handler:
-				if(this.currentRuleField.focus) {
-					this.currentRuleField.focus();
-				}
-			}
-		}
-		return true;
-	},
-
-	ruleEditorAdd: function(type, ruleElement) {
-		if(document.getElementById('ruleElementsList')) {
-			var richlistbox = document.getElementById('ruleElementsList');
-
-			var richlistitem,menulist,menupopup,menuitem,textbox,label;
-
-			richlistitem = document.createElement('richlistitem');
-
-			// Create the condition type menu:
-			menulist = document.createElement('menulist');
-			menupopup = document.createElement('menupopup');
-
-			var selectedIndex = 0;
-
-			// Create the menu of ruleElementTypes:
-			for(var i=0; i<this.ruleElementTypes.length; i++) {
-				menuitem = document.createElement('menuitem');
-				menuitem.setAttribute(
-					'value',
-					this.ruleElementTypes[i]
-				);
-				menuitem.setAttribute(
-					'label',
-					this.getStringBundle().getString(this.ruleElementTypes[i] + 'RuleType')
-				);
-				menupopup.appendChild(menuitem);
-
-				// Set the selectedIndex:
-				if(type != null && type == this.ruleElementTypes[i])
-					selectedIndex = i;
-			}
-
-			menulist.appendChild(menupopup);
-			richlistitem.appendChild(menulist);
-
-			// Create the textbox:
-			textbox = document.createElement('textbox');
-			if(ruleElement != null)
-				textbox.setAttribute('value',ruleElement);
-			textbox.setAttribute('flex','1');
-			richlistitem.appendChild(textbox);
-
-			richlistbox.appendChild(richlistitem);
-
-			// Select the menuitem:
-			menulist.selectedIndex = selectedIndex;
-		}
-	},
-
-	ruleEditorRemove: function(index) {
-		var ruleElementsList = document.getElementById('ruleElementsList');
-		if(ruleElementsList) {
-			if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
-				// Confirmation dialog:
-				if(!this.getPrompts().confirm(
-						null,
-						this.getStringBundle().getString('removeRuleConditionTitle'),
-						this.getStringBundle().getString('removeRuleConditionText')
-					)
-				) {
-					return;
-				}
-			}
-
-			var richlistbox = ruleElementsList;
-			if(index)
-				richlistbox.selectedIndex = index;
-			if(richlistbox.selectedItem && richlistbox.selectedIndex != -1)
-				richlistbox.removeChild(richlistbox.selectedItem);
-		}
-	},
-
-	ruleEditorIsTextBoxFocused: function() {
-		return this.ruleEditorTextBoxFocused;
-	},
-
-	ruleEditorFocus: function() {
-		var focusedElement = document.commandDispatcher.focusedElement;
-
-		// Monitor if a textbox is focused:
-		if(!this.ruleEditorTextBoxFocused && focusedElement && focusedElement.tagName == 'html:input') {
-			this.ruleEditorTextBoxFocused = true;
-		} else if(this.ruleEditorTextBoxFocused && focusedElement && focusedElement.tagName == 'richlistbox') {
-			this.ruleEditorTextBoxFocused = false;
-		}
-	},
-
-	ruleEditorHandleKeyPress: function(event) {
-		// Only remove a dynamic tag on delete key press if no textbox is focused:
-		if(event.keyCode == 46 && !this.ruleEditorIsTextBoxFocused()) {
-			this.ruleEditorRemove();
-		}
-	},
-
-	ruleEditorFinalize: function() {
-		this.currentRuleField = null;
-	},
-
-	tagEditorInitialize: function() {
-		// Save the reference to the Autofill Forms preferences branch:
-		this.autofillFormsPrefs = this.getPrefManager().getBranch('extensions.autofillForms at blueimp.net.');
-
-		// Add existing tags to the list:
-		for(var i=0; i<this.getDynamicTags().length; i++) {
-			// Catch if the number of tags doesn't match the number of tag codes:
-			try {
-				this.tagEditorAdd(this.getDynamicTags()[i],this.getDynamicTagCodes()[i])
-			} catch(e) {
-				this.log(e);
-			}
-		}
-	},
-
-	tagEditorSave: function() {
-		var richlistbox = document.getElementById('tagList');
-		if(richlistbox) {
-			var richlistitems = richlistbox.getElementsByTagName('richlistitem');
-			var textboxes;
-
-			var dynamicTags = new Array();
-			var dynamicTagCodes = new Array();
-
-			// Go through the richlistbox items:
-			for(var i=0; i<richlistitems.length; i++) {
-				textboxes = richlistitems[i].getElementsByTagName('textbox');
-
-				// Add the dynamic tags and their associated tag codes to the lists:
-				if (textboxes[0].value != '' && textboxes[1].value != '') {
-					dynamicTags.push(this.makeSafe(textboxes[0].value));
-					dynamicTagCodes.push(this.makeSafe(textboxes[1].value));
-				}
-			}
-			// Save the lists in the preferences:
-			this.setDynamicTags(dynamicTags);
-			this.setDynamicTagCodes(dynamicTagCodes);
-		}
-		return true;
-	},
-
-	tagEditorAdd: function(tag, tagCode) {
-		var richlistbox = document.getElementById('tagList');
-		if(richlistbox) {
-			var richlistitem,textbox;
-
-			richlistitem = document.createElement('richlistitem');
-
-			// Create the tag textbox:
-			textbox = document.createElement('textbox');
-			textbox.setAttribute('class','tag');
-			if(tag != null)
-				textbox.setAttribute('value',tag);
-			richlistitem.appendChild(textbox);
-
-			// Create the tagCode textbox:
-			textbox = document.createElement('textbox');
-			textbox.setAttribute('class','tagCode');
-			textbox.setAttribute('flex','1');
-			if(tagCode != null)
-				textbox.setAttribute('value',tagCode);
-			richlistitem.appendChild(textbox);
-
-			richlistbox.appendChild(richlistitem);
-		}
-	},
-
-	tagEditorRemove: function(index) {
-		var richlistbox = document.getElementById('tagList');
-		if(richlistbox) {
-			if(this.autofillFormsPrefs.getBoolPref('enableConfirmationDialogs')) {
-				// Confirmation dialog:
-				if(!this.getPrompts().confirm(
-						null,
-						this.getStringBundle().getString('removeDynamicTagTitle'),
-						this.getStringBundle().getString('removeDynamicTagText')
-					)
-				) {
-					return;
-				}
-			}
-			if(index)
-				richlistbox.selectedIndex = index;
-			if(richlistbox.selectedItem && richlistbox.selectedIndex != -1)
-			{
-				richlistbox.removeChild(richlistbox.selectedItem);
-			}
-		}
-	},
-
-	tagEditorValidate: function(index) {
-		var richlistbox = document.getElementById('tagList');
-		if(richlistbox) {
-			if(index)
-				richlistbox.selectedIndex = index;
-			if(richlistbox.selectedItem) {
-				var tagCode = richlistbox.selectedItem.lastChild.value;
-				var validationResultTextBox = document.getElementById('validationResultTextBox');
-				try {
-					validationResultTextBox.removeAttribute('style');
-					// We use eval() here without restrictions - the given tagCode must be trusted:
-					validationResultTextBox.value = eval(tagCode);
-				} catch(e) {
-					validationResultTextBox.setAttribute('style', 'color:red;');
-					validationResultTextBox.value = e;
-				}
-			}
-		}
-	},
-
-	tagEditorIsTextBoxFocused: function() {
-		return this.tagEditorTextBoxFocused;
-	},
-
-	tagEditorFocus: function() {
-		var focusedElement = document.commandDispatcher.focusedElement;
-
-		// Monitor if a textbox is focused:
-		if(!this.tagEditorTextBoxFocused && focusedElement && focusedElement.tagName == 'html:input') {
-			this.tagEditorTextBoxFocused = true;
-		} else if(this.tagEditorTextBoxFocused && focusedElement && focusedElement.tagName == 'richlistbox') {
-			this.tagEditorTextBoxFocused = false;
-		}
-	},
-
-	tagEditorHandleKeyPress: function(event) {
-		// Only remove a dynamic tag on delete key press if no textbox is focused:
-		if(event.keyCode == 46 && !this.tagEditorIsTextBoxFocused()) {
-			this.tagEditorRemove();
-		}
-	},
-
-	tagEditorFinalize: function() {
-	},
-
-	openHelp: function(topic) {
-		if(!topic) {
-			topic = '';
-		}
-		var url = this.autofillFormsPrefs.getCharPref('helpURL').replace(/\[TOPIC\]$/, topic);
-		this.openNewTab(url, true);
-	},
-
-	openNewTab: function(url, focus) {
-		var helpTab = this.getBrowser().addTab(url);
-		if(focus) {
-			this.getBrowser().selectedTab = helpTab;
-			this.getWindowMediator().getMostRecentWindow('navigator:browser').focus();
-		}
-	},
-
-	addLeadingZeros: function(number, length) {
-		number = number.toString();
-		while(number.length < length) {
-			number = '0'+number;
-		}
-		return number;
-	},
-
-	escapeRegExp: function(str) {
-		if (!arguments.callee.regExp) {
-			var specials = new Array(
-				'^', '$', '*', '+', '?', '.', '|', '/',
-				'(', ')', '[', ']', '{', '}', '\\'
-			);
-			arguments.callee.regExp = new RegExp(
-				'(\\' + specials.join('|\\') + ')', 'g'
-			);
-		}
-		return str.replace(arguments.callee.regExp, '\\$1');
-	},
-
-	getClipboardText: function() {
-		var clipboardText = null;
-		var clip  = Components.classes['@mozilla.org/widget/clipboard;1']
-						.getService(Components.interfaces.nsIClipboard);
-		if(!clip) {
-			return null;
-		}
-
-		var trans = Components.classes['@mozilla.org/widget/transferable;1']
-						.createInstance(Components.interfaces.nsITransferable);
-		if(!trans) {
-			return null;
-		}
-
-		trans.addDataFlavor('text/unicode');
-
-		clip.getData(trans, clip.kGlobalClipboard);
-
-		var str	   = new Object();
-		var strLength = new Object();
-
-		trans.getTransferData('text/unicode', str, strLength);
-
-		if(str) {
-			str = str.value.QueryInterface(Components.interfaces.nsISupportsString);
-		}
-		if(str) {
-			clipboardText = str.data.substring(0, strLength.value / 2);
-		}
-
-		return clipboardText
-	},
-
-	getMasterSecurityDevice: function() {
-		return Components.classes['@mozilla.org/security/pk11tokendb;1']
-				.getService(Components.interfaces.nsIPK11TokenDB);
-	},
-
-	log: function(aMessage, aSourceName, aSourceLine, aLineNumber, aColumnNumber, aFlags, aCategory) {
-		var consoleService = Components.classes['@mozilla.org/consoleservice;1']
-			.getService(Components.interfaces.nsIConsoleService);
-		if(aSourceName != 'undefined') {
-			var scriptError = Components.classes["@mozilla.org/scripterror;1"]
-				.createInstance(Components.interfaces.nsIScriptError);
-			scriptError.init(
-				aMessage,
-				aSourceName,
-				aSourceLine,
-				aLineNumber,
-				aColumnNumber,
-				aFlags,
-				aCategory
-			);
-			consoleService.logMessage(scriptError);
-		} else {
-			consoleService.logStringMessage(aMessage);
-		}
-	},
-
-	finalizeToolbarButtonStatus: function() {
-		var autofillFormsButton = document.getElementById('autofillFormsButton');
-		var hideToolbarButton = this.autofillFormsPrefs.getBoolPref('hideToolbarButton');
-		if(!autofillFormsButton && !hideToolbarButton) {
-			// If the toolbar button icon has been removed from the toolbar by drag&drop
-			// enable the hideToolbarButton setting:
-			this.autofillFormsPrefs.setBoolPref('hideToolbarButton', true);
-		} else if(autofillFormsButton && !autofillFormsButton.getAttribute('hidden')) {
-			// If the toolbar button icon has been added to the toolbar by drag&drop
-			// disable the hideToolbarButton setting:
-			this.autofillFormsPrefs.setBoolPref('hideToolbarButton', false);
-		}
-	},
-
-	finalize: function() {
-		this.finalizeToolbarButtonStatus();
-
-		// Remove the content area context menu listener:
-		var contentAreaContextMenu = document.getElementById('contentAreaContextMenu');
-		if(contentAreaContextMenu) {
-			contentAreaContextMenu.removeEventListener(
-				'popupshowing',
-				this.contentAreaContextMenuEventListener,
-				false
-			);
-		}
-
-		// Remove the preferences Observer:
-		this.autofillFormsPrefs.removeObserver('', this);
-	}
-
-}
diff --git a/src/chrome/skin/autofillForms.css b/src/chrome/skin/autofillForms.css
deleted file mode 100644
index efb7dec..0000000
--- a/src/chrome/skin/autofillForms.css
+++ /dev/null
@@ -1,46 +0,0 @@
-#autofillFormsButton,
-.autofillFormsButton {
-	list-style-image: url("pencil.png");
-}
-toolbar[iconsize="small"] #autofillFormsButton,
-toolbar[iconsize="small"] .autofillFormsButton,
-.autofillFormsIcon {
-	list-style-image: url("pencil-small.png");
-}
-
-.autofillFormsProfileIcon {
-	list-style-image: url("profile-small.png");
-}
-.autofillFormsSettingsIcon {
-	list-style-image: url("settings-small.png");
-}
-.autofillFormsHelpIcon {
-	list-style-image: url("help-small.png");
-}
-
-statusbarpanel.autofillFormsIcon {
-	cursor: pointer;
-}
-
-#autofillFormsTooltipCurrentProfile {
-	margin-bottom:10px;
-}
-#autofillFormsTooltipCurrentProfileCaption {
-}
-#autofillFormsTooltipCurrentProfileLabel {
-	font-weight: bold;
-}
-#autofillFormsTooltipGrid {
-}
-.autofillFormsTooltipGridHeader {
-	font-weight:bold;
-	margin-bottom:5px;
-}
-.autofillFormsTooltipGridCommand {
-}
-.autofillFormsTooltipGridMouseButton {
-	font-style:italic;
-}
-.autofillFormsTooltipGridKeyboardShortcut {
-	font-family:monospace;
-}
diff --git a/src/install.rdf b/src/install.rdf
deleted file mode 100644
index 57fcffb..0000000
--- a/src/install.rdf
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0"?>
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-	<Description about="urn:mozilla:install-manifest">
-		<em:id>autofillForms at blueimp.net</em:id>
-		<em:name>Autofill Forms</em:name>
-		<em:creator>Sebastian Tschan</em:creator>
-		<em:description>Fill out web forms automatically</em:description>
-		<em:iconURL>chrome://autofillForms/skin/icon.png</em:iconURL>
-		<em:optionsURL>chrome://autofillForms/content/autofillFormsOptions.xul</em:optionsURL>
-		<em:homepageURL>https://blueimp.net/mozilla/</em:homepageURL>
-		<em:version>0.9.9.0</em:version>
-		<em:targetApplication>
-			<Description>
-				<!-- Firefox -->
-				<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-				<em:minVersion>17.0</em:minVersion>
-				<em:maxVersion>19.*</em:maxVersion>
-			</Description>
-		</em:targetApplication>
-		<em:targetApplication>
-			<Description>
-				<!-- Midbrowser -->
-				<em:id>{aa5ca914-c309-495d-91cf-3141bbb04115}</em:id>
-				<em:minVersion>0.2</em:minVersion>
-				<em:maxVersion>2.0.0.6</em:maxVersion>
-			</Description>
-		</em:targetApplication>
-		<em:translator>PetrTwo (Czech)</em:translator>
-		<em:translator>Oliver Roth (German)</em:translator>
-		<em:translator>Koumen (Greek)</em:translator>
-		<em:translator>jesuspportillo (Spanish)</em:translator>
-		<em:translator>Unknown (Finnish)</em:translator>
-		<em:translator>myahoo (French)</em:translator>
-		<em:translator>YuvalSht (Hebrew)</em:translator>
-		<em:translator>Mikes Kaszmán István (Hungarian)</em:translator>
-		<em:translator>Underpass (Italian)</em:translator>
-		<em:translator>gonzalopirobutirro (Italian)</em:translator>
-		<em:translator>Godai71 (Italian)</em:translator>
-		<em:translator>markh (Dutch)</em:translator>
-		<em:translator>teo (Polish)</em:translator>
-		<em:translator>Alberto Eidh (Portuguese - Brazilian)</em:translator>
-		<em:translator>x10firefox (Romanian)</em:translator>
-		<em:translator>Unknown (Russian)</em:translator>
-		<em:translator>Umut (Swedish)</em:translator>
-		<em:translator>ch0ze (Slovak)</em:translator>
-		<em:translator>KenanBalamir (Turkish)</em:translator>
-		<em:translator>simophin (Chinese - Simplified)</em:translator>
-		<em:translator>Lu Ming-Tse (呂明澤) (Chinese - Traditional)</em:translator>
-	</Description>
-</RDF>
diff --git a/www/bugs.html b/www/bugs.html
deleted file mode 100644
index 994ff01..0000000
--- a/www/bugs.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<h5 class="page-header">Bugs</h5>
-
-<ul>
-<li>Enter a <a href="http://bugzilla.mozdev.org/enter_bug.cgi?product=autofillforms">new bug</a> for Autofill Forms</li>
-<li>View <a href="http://bugzilla.mozdev.org/buglist.cgi?product=autofillforms">all bugs</a></li> 
-<li>See all <a href="http://bugzilla.mozdev.org/buglist.cgi?bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&emailtype1=substring&emailassigned_to1=1&emailtype2=substring&emailreporter2=1&bugidtype=include&chfieldto=Now&product=autofillforms&short_desc_type=allwordssubstr&long_desc_type=allwordssubstr&bug_file_loc_type=allwordssubstr&field0-0-0=noop&type0-0-0=noop&cmdtype=doit&order=Bug+Numbe [...]
-<li>Search by Bug Number<br>
-<form action="http://bugzilla.mozdev.org/show_bug.cgi" method="get">
-<p><input type="submit" value="Find"><input size="6" name="id"></p>
-</form>
-</li>
-</ul>
diff --git a/www/changelog.html b/www/changelog.html
deleted file mode 100644
index 924ff72..0000000
--- a/www/changelog.html
+++ /dev/null
@@ -1,545 +0,0 @@
-<h4 class="page-header">Changelog</h4>
-
-<h5 id="v0.1">Version 0.1</h5>
-<p>07.04.2007</p>
-<ul>
-	<li>First release.</li>
-</ul>
-
-<h5 id="v0.2">Version 0.2</h5>
-<p>09.04.2007</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added option to encrypt the stored form field rules - using Firefox nsISecretDecoderRing interface</li>
-			<li>Improved method to set the form field value for non-text form elements - loop until "Value" matches</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.3">Version 0.3</h5>
-<p>10.05.2007</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added profiles</li>
-			<li>Added profile switcher</li>
-			<li>Added shortcuts for profile switcher and settings page</li>
-			<li>Extended toolbar button to include menu items for profile switcher and settings page</li>
-			<li>Added 'Display Form Details' button on settings page to support creating form field rules</li>
-			<li>Added Rule Editor to help creating custom rules without regular expression knowledge</li>
-			<li>Improved settings page (using tabs, better structuring)</li>
-			<li>Extended help page</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.4">Version 0.4</h5>
-<p>16.05.2007</p>
-<ul>
-	<li>Bugfixes:
-		<ul>
-			<li>When moving rules up or down or adding new rules, the view scrolls now to ensure visibility</li>
-			<li>Added rules are inserted after the currently selected item instead of at the end of the list</li>
-		</ul>
-	</li>
-	<li>New features:
-		<ul>
-			<li>If subsequent rules with the same fieldRule exist (Alternatives"), a prompt is displayed for selection</li>
-			<li>A new option defines if the selected alternatives index is to be used for subsequent selections</li>
-			<li>Extended help page to explain how the "Alternatives" work</li>
-		</ul>
-	<li>
-</ul>
-
-<h5 id="v0.5">Version 0.5</h5>
-<p>16.05.2007</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added support for textareas</li>
-			<li>A new option defines a placeholder to create line breaks in textareas</li>
-			<li>Extended help page to explain how to use placeholders for line breaks</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.6">Version 0.6</h5>
-<p>19.05.2007</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added Import/Export feature for profiles</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.6.1">Version 0.6.1</h5>
-<p>06.06.2007</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Improved default ruleset</li>
-			<li>Dialog windows independent from parent window</li>
-			<li>Highlight style using CSS declarations via about:config for matched and not matched form fields</li>
-			<li>Added support for password fields - for password management please rather use the Secure Login extension</li>
-			<li>Added french locale - Thanks to myahoo at babelzilla.org</li>
-			<li>Added dutch locale - Thanks to markh at babelzilla.org</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.6.1.1">Version 0.6.1.1</h5>
-<p>21.06.2007</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added czech locale - Thanks to PetrTwo at babelzilla.org</li>
-		</ul>
-</li>
-</ul>
-
-<h5 id="v0.6.2">Version 0.6.2</h5>
-<p>05.07.2007</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added support for file upload fields</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.6.2.1">Version 0.6.2.1</h5>
-<p>18.07.2007</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added Chinese (Simplified) locale - Thanks to simophin at babelzilla.org</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.7">Version 0.7</h5>
-<p>31.07.2007</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added possibility to deselect checkboxes/radio buttons by deactivating the "Overwrite" setting</li>
-			<li>Added support for dynamic tags which can be used to insert dynamic data in form fields, e.g. the current date</li>
-			<li>Added possibility to fill out forms on all open tabs via about:config setting "fillAllTabs"</li>
-			<li>Added confirmation dialog before deleting a profile</li>
-			<li>Removed "Apply" button for field rules - field rules are now updated as soon as the textboxes lose focus</li>
-			<li>Updated documentation</li>
-			<li>Added Hungarian locale - Thanks to Mikes Kaszmán István (Cashman) at babelzilla.org</li>
-			<li>Added Italian locale - Thanks to Underpass, gonzalopirobutirro and Godai71 at babelzilla.org</li>
-			<li>Added Polish locale - Thanks to teo at babelzilla.org</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.7.0.1">Version 0.7.0.1</h5>
-<p>09.08.2007</p>
-<ul>
-	<li>User Interface improvements:
-		<ul>
-			<li>FieldRule list now takes up the free space when resizing the settings window</li>
-			<li>Rule editor list now takes up the free space when resizing the rule editor window</li>
-			<li>Rule editor textboxes now take up the free space when resizing the rule editor window</li>
-			<li>Tag editor list now takes up the free space when resizing the tag editor window</li>
-			<li>Tag editor tag code textboxes now take up the free space when resizing the tag editor window</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.7.0.2">Version 0.7.0.2</h5>
-<p>21.08.2007</p>
-<ul>
-	<li>Bugfixes:
-		<ul>
-			<li>If browser.preferences.animateFadeIn is set to true (which is the default on a Mac) the rule list had been hidden - fixed.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.7.0.3">Version 0.7.0.3</h5>
-<p>11.09.2007</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added Chinese (Traditional) locale - Thanks to Lu Ming-Tse (呂明澤).</li>
-			<li>Added Midbrowser (Firefox for Mobile Internet Devices) GUID to target applications (BETA) - see http://www.moblin.org.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.8">Version 0.8</h5>
-<p>26.11.2007</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Adding the possibility to define a Global Profile, which is applied on form fields that cannot be filled out using the current profile.</li>
-			<li>Applying the siteRule on the whole url, not just on protocol and hostname.</li>
-			<li>Adding a validate button and result textbox to the dynamic tag editor.</li>
-			<li>Added confirmation dialogs to removal methods (can be disabled via about:config setting "enableConfirmationDialogs").</li>
-			<li>New hidden feature "matchAgainstLabels".
-			<br />Can be enabled via about:config by setting extensions.autofillForms at blueimp.net.matchAgainstLabels to true.
-			<br />If enabled, matches the fieldRules against the textual content of label tags assigned to the current element if the element name does not match.</li>
-			<li>Added a new help section: "Hidden settings".</li>
-			<li>The focus is now set on the last form element match - this allows to submit autofilled forms by hitting the enter key.</li>
-		</ul>
-	</li>
-	<li>Bugfixes:
-		<ul>
-			<li>Pressing the delete key (keyCode 46) doesn't call the remove method anymore if a textbox is focused.</li>
-			<li>The nsISecretDecoderRing methods encryptString/decryptString cannot handle characters above the Latin-1 (ISO-8859-1) charset.
-			<br />The usage of encodeURI/decodeURI on the fieldRule properties bypasses this problem as a workaround.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.8.0.1">Version 0.8.0.1</h5>
-<p>27.11.2007</p>
-<ul>
-	<li>Bugfixes:
-		<ul>
-			<li>Selecting an item right after changing a textbox value does not fire any onchange/onblur events which resulted in the changes not being saved.
-			<br />Applying the changes on the last selected item on a new selection as workaround.</li>
-			<li>Changes applied if more than one item has been selected could result in the wrong item being updated.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.8.0.2">Version 0.8.0.2</h5>
-<p>29.11.2007</p>
-<ul>
-	<li>Bugfixes:
-		<ul>
-			<li>The settings page didn't allow to enable the global profile - the enableGlobalProfile preference tag was missing inside the XUL document.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.8.0.3">Version 0.8.0.3</h5>
-<p>30.11.2007</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added (hidden) statusbar icon - can be made visible via about:config setting extensions.autofillForms at blueimp.net.hideStatusbarIcon.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.8.1">Version 0.8.1</h5>
-<p>17.12.2007</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added context menu item for form fields, allowing easier creation of Autofill Forms rules.</li>
-			<li>Updated help section.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.8.1.1">Version 0.8.1.1</h5>
-<p>17.12.2007</p>
-<ul>
-	<li>Changes:
-		<ul>
-			<li>Updated french locale - thanks to myahoo.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.8.1.2">Version 0.8.1.2</h5>
-<p>20.12.2007</p>
-<ul>
-	<li>Changes:
-		<ul>
-			<li>Updated italian locale - thanks to gonzalopirobutirro and Godai71.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.8.2">Version 0.8.2</h5>
-<p>31.01.2008</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Improved alternatives code and added alternatives support for selections and radio buttons.</li>
-			<li>Added "about:config" option "useConfigDirectory" which allows to store the fieldRules, dynamicTags and dynamicTagCodes as files.
-			<br />The files are stored in the directory "autofillForms at blueimp.net" beneath the Firefox profile directory by default.
-			<br />This can be changed using the "about:config" option "configDirectory" - it is recommended to keep the default.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.9">Version 0.9</h5>
-<p>16.02.2008</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added a more intuitive and much simpler interface to edit the field rules in addition to the main editing pane.</li>
-			<li>Made several hidden features accessible on the settings page.</li>
-			<li>Added button to reset all profiles to the simple interface pane.</li>
-			<li>Made sure profiles always get a unique name (label change, import or adding of profiles).</li>
-			<li>Slightly improved the default profile rules.</li>
-			<li>Added a toolbar button without menu (but with context menu).</li>
-		</ul>
-	</li>
-	<li>Other changes:
-		<ul>
-			<li>Unsetting the fieldRules object after each fillForms call instead of keeping them in memory.</li>
-			<li>Storing the profile labels as file if useConfigDirectory is enabled.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.9.1">Version 0.9.1</h5>
-<p>23.03.2008</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added the possibility to restrict profiles to certain websites by setting a profile site rule.</li>
-			<li>Added an option to automatically select the best matching profile dependent on the form url and the profile site rules.</li>
-		</ul>
-	</li>
-	<li>Bugfixes:
-		<ul>
-			<li>Editing a rule with the rule editor did not apply the changes automatically on confirmation.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.9.1.1">Version 0.9.1.1</h5>
-<p>25.03.2008</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added a selection of the available profiles to the Autofill Forms menu popup.</li>
-		</ul>
-	</li>
-	<li>Bugfixes:
-		<ul>
-			<li>Fixed a bug preventing the proper selection of the best matching profile.</li>
-		</ul>
-	</li>
-	<li>Other changes:
-		<ul>
-			<li>The option autoSelectBestProfile is now enabled by default.</li>
-			<li>The current profile is now declared best match for equal match lengths instead of the first matching profile in the list.</li>
-			<li>Resetting the profile to the manually selected one after using the best matching profile.
-			<br />This can be disabled by setting the "about:config" option "resetProfileAfterAutoSelect" to false.</li>
-		</ul>
-	</li>
-</ul>
-
-
-<h5 id="v0.9.2">Version 0.9.2</h5>
-<p>06.04.2008</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added the possibility to add a complete web form as Autofill Forms profile (by using the context menu of a form field).</li>
-		</ul>
-	</li>
-	<li>Bugfixes:
-		<ul>
-			<li>Added a workaround for the missing integrated help system which has been removed for Firefox 3.0b5 and later.</li>
-		</ul>
-	</li>
-	<li>Other changes:
-		<ul>
-			<li>Adding new rules to the start of the list (or right after the selection) instead of to the end.</li>
-			<li>Added the regular expression for valid form field types  as "about:config" option.</li>
-			<li>Hiding passwords in the simple interface and in the rules list behind asterisks (*).
-			<br />Passwords are defined by the label/name of a rule which is compared to a regular expression (regExpPasswordLabel in "about:config").</li>
-		</ul>
-	</li>
-</ul>
-
-
-<h5 id="v0.9.2.1">Version 0.9.2.1</h5>
-<p>10.04.2008</p>
-<ul>
-	<li>Changes:
-		<ul>
-			<li>Updated french locale - thanks to myahoo.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.9.2.2">Version 0.9.2.2</h5>
-<p>11.04.2008</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added new example dynamic tag <clipboard> to insert the current clipboard text content.
-			<br />The dynamic tag code to access the clipboard text is this.getClipboardText().</li>
-		</ul>
-	</li>
-	<li>Other changes:
-		<ul>
-			<li>Updated czech locale - thanks to PetrTwo.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.9.2.3">Version 0.9.2.3</h5>
-<p>24.04.2008</p>
-<ul>
-	<li>Bugfixes:
-		<ul>
-			<li>Fixed a bug which caused form element labels not assigned to any form element to always match.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.9.3">Version 0.9.3</h5>
-<p>08.05.2008</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added the possibility to manually fill out form fields via their context menu.
-			<br />This allows to insert data from the profiles while ignoring the form field rules.</li>
-			<li>Added support for element ids as fallback if a form element has no name or label assigned.</li>
-			<li>Added support to match form fields by position.
-				<br />This new feature is currently a hiddden option and has to be enabled via about:config (matchAgainstPositions).
-				<br />Position rules are identified by the character "#" adjustable via about:config (positionsIdentifier).
-				<br />A rule matching always the second form element would be "#2".
-				<br />Another rule matching  the third element on the second form would be "2#3".
-				<br />You can also combine matching form field names with matching form field positions:
-				<br />A rule matching the second form field or fields with the name "test" would be "(test)|(#2)".</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.9.4">Version 0.9.4</h5>
-<p>28.05.2008</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Automatically installing the toolbar button.</li>
-			<li>Added option to hide/display the toolbar button.</li>
-			<li>Added option to hide/display the toolbar button menu.</li>
-			<li>Middle mouse click on toolbar button or statusbar icon allows filling out forms by profile.</li>
-			<li>New content area context menu item allows filling out forms by profile.</li>
-		</ul>
-	</li>
-	<li>Bugfixes:
-		<ul>
-			<li>Fixed a bug preventing shortcut key combinations with keycodes (e.g. VK_ENTER) to work on Firefox 3 RC1.</li>
-			<li>Escaping special regexp characters in field names when adding them as new rules via the context menu.</li>
-		</ul>
-	</li>
-	<li>Other changes:
-		<ul>
-			<li>Removed the integrated help in favor of an online help.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.9.4.1">Version 0.9.4.1</h5>
-<p>03.06.2008</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Making all icons completely customizable via user CSS (userChrome.css).</li>
-		</ul>	
-	</li>
-	<li>Other changes:
-		<ul>
-			<li>Updating the help topics for the different settings dialogs.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.9.4.2">Version 0.9.4.2</h5>
-<p>03.06.2008</p>
-<ul>
-	<li>Bugfixes:
-		<ul>
-			<li>Fixing a bug related to the toolbar button style.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.9.5">Version 0.9.5</h5>
-<p>28.06.2008</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added new settings tabs for profile management.</li>
-			<li>Added the possibility to define keyboard shorcuts to autofill and submit forms, to autofill forms on all tabs and to fill forms from profile selection.</li>
-			<li>Added the possibility to configure different actions for different mouse button clicks on toolbar button and statusbar icon.</li>
-			<li>Adding access to all hidden preferences (except regExpFormFieldTypes and regExpPasswordLabel) to the settings dialog.</li>
-			<li>Rule values are now matched as regular expressions against selection options, checkboxes and radio buttons.</li>
-			<li>Improved performance by caching rules (and their regular expressions) within one form filling run.</li>
-			<li>Added option to identify form field labels which are no strict HTML label elements - the default is to identify labels in strict mode.</li>
-		</ul>	
-	</li>
-	<li>Bugfixes:
-		<ul>
-			<li>Adjusting the toolbar icons to the default theme on Firefox 3 for Mac.</li>
-			<li>Added a fix to show only a selection between radio buttons if the alternative rules are placed next to each other or the rule is the same.</li>
-		</ul>	
-	</li>
-	<li>Other changes:
-		<ul>
-			<li>Alternatives must be placed next to each other and match the field, but don't require the same field rule anymore.</li>
-			<li>Replacing control characters with placeholders when adding a new rule or profile via the context menu of form fields.</li>
-			<li>Replacing control characters with placeholders on text input for the rule values (Firefox >= 3).</li>
-			<li>Adding a preference for the tabulator placeholder (by default four space characters).</li>
-			<li>Adding version specific stylesheets instead of modifying the styles via JavaScript.</li>
-			<li>Adding the global skin as CSS import rule instead of inside the XUL files.</li>
-			<li>Suggesting the profile name as filename on profile export.</li>
-			<li>Automatically applying new keyboard shortcuts on key input.</li>
-			<li>Disabled rules are now moved to a submenu on the form fields context menu.</li>
-			<li>Reorganized the settings tabs.</li>
-			<li>Moved the "Display form details" command to the content area context menu.</li>
-			<li>Replaced the former "Display form details" button with the "Reset all profiles button".</li>
-			<li>Removed the unnecessary preference "resetProfileAfterAutoSelect".</li>
-			<li>Allow to use Autofill Forms on other protocols than http(s)://; e.g. on file:// to test local HTML forms.</li>
-			<li>Adding a default label for empty profile labels.</li>
-			<li>Adding all options of selections of type multiple as rules when adding a form as profile.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.9.5.1">Version 0.9.5.1</h5>
-<p>13.07.2008</p>
-<ul>
-	<li>New features:
-		<ul>
-			<li>Added the possibility to configure keyboard shortcut and mouse button for the "Display Form Details" feature.</li>
-			<li>Added (incomplete) romanian locale - thanks to x10firefox at babelzilla.org.</li>
-		</ul>
-	</li>
-	<li>Bugfixes:
-		<ul>
-			<li>Adjust the hideToolbarButton setting if the toolbar button has been removed/added by drag and drop.</li>
-		</ul>	
-	</li>
-	<li>Other changes:
-		<ul>
-			<li>Code refactoring to improve performance and readability - thanks to Robert Stewart for the performance notions.</li>
-		</ul>
-	</li>
-</ul>
-
-<h5 id="v0.9.5.2">Version 0.9.5.2</h5>
-<p>30.08.2008</p>
-<ul>
-	<li>Bugfixes:
-		<ul>
-			<li>Adjusting the "Add complete form as profile..." and "Add a rule for this field..." features to add the values of non-text fields as regular expressions.<br />
-			Adding the special characters for the beginning and end of the string makes sure no unwanted alternatives prompts are shown.</li>
-		</ul>	
-	</li>
-	<li>Other changes:
-		<ul>
-			<li>Use gBrowser if it is available and the WindowMediator service only as fallback to access the browser object.</li>
-			<li>Replaced multiple method calls to access the content document with local variables holding the document reference.</li>
-			<li>Parsing child frames after parsing the parent window.</li>
-		</ul>
-	</li>
-</ul>
\ No newline at end of file
diff --git a/www/css/closelabel.gif b/www/css/closelabel.gif
deleted file mode 100644
index af0cab2..0000000
Binary files a/www/css/closelabel.gif and /dev/null differ
diff --git a/www/css/loading.gif b/www/css/loading.gif
deleted file mode 100644
index e552f29..0000000
Binary files a/www/css/loading.gif and /dev/null differ
diff --git a/www/css/nextlabel.gif b/www/css/nextlabel.gif
deleted file mode 100644
index 7c66121..0000000
Binary files a/www/css/nextlabel.gif and /dev/null differ
diff --git a/www/css/prevlabel.gif b/www/css/prevlabel.gif
deleted file mode 100644
index 0641876..0000000
Binary files a/www/css/prevlabel.gif and /dev/null differ
diff --git a/www/css/slimbox.css b/www/css/slimbox.css
deleted file mode 100644
index 905b528..0000000
--- a/www/css/slimbox.css
+++ /dev/null
@@ -1,82 +0,0 @@
-/* SLIMBOX */
-
-#lbOverlay {
-	position: absolute;
-	z-index: 9999;
-	left: 0;
-	width: 100%;
-	background-color: #000;
-	cursor: pointer;
-}
-
-#lbCenter, #lbBottomContainer {
-	position: absolute;
-	z-index: 9999;
-	left: 50%;
-	overflow: hidden;
-	background-color: #fff;
-}
-
-.lbLoading {
-	background: #fff url(loading.gif) no-repeat center;
-}
-
-#lbImage {
-	position: absolute;
-	left: 0;
-	top: 0;
-	border: 10px solid #fff;
-	background-repeat: no-repeat;
-}
-
-#lbPrevLink, #lbNextLink {
-	display: block;
-	position: absolute;
-	top: 0;
-	width: 50%;
-	outline: none;
-}
-
-#lbPrevLink {
-	left: 0;
-}
-
-#lbPrevLink:hover {
-	background: transparent url(prevlabel.gif) no-repeat 0% 15%;
-}
-
-#lbNextLink {
-	right: 0;
-}
-
-#lbNextLink:hover {
-	background: transparent url(nextlabel.gif) no-repeat 100% 15%;
-}
-
-#lbBottom {
-	font-family: Verdana, Arial, Geneva, Helvetica, sans-serif;
-	font-size: 10px;
-	color: #666;
-	line-height: 1.4em;
-	text-align: left;
-	border: 10px solid #fff;
-	border-top-style: none;
-}
-
-#lbCloseLink {
-	display: block;
-	float: right;
-	width: 66px;
-	height: 22px;
-	background: transparent url(closelabel.gif) no-repeat center;
-	margin: 5px 0;
-	outline: none;
-}
-
-#lbCaption, #lbNumber {
-	margin-right: 71px;
-}
-
-#lbCaption {
-	font-weight: bold;
-}
diff --git a/www/donation.html b/www/donation.html
deleted file mode 100644
index 83bc4ba..0000000
--- a/www/donation.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<h4 class="page-header">Donation</h4>
-
-<h5>Thanks to the Donators:</h5>
-<table id="donators">
-	<thead>
-		<tr><th>Date</th><th>Name</th><th>Amount</th></tr>
-	</thead>
-	<tbody>
-		<tr><td>2009/02/21</td><td>James Ricks</td><td class="amount">3.00 €</td></tr>
-		<tr><td>2009/08/07</td><td>Jay Kridner</td><td class="amount">5.55 €</td></tr>
-		<tr><td>2008/12/28</td><td>Noelle Gillies</td><td class="amount">10.00 €</td></tr>
-		<tr><td>2008/10/24</td><td>Günter Müller</td><td class="amount">10.00 €</td></tr>
-		<tr><td>2008/07/10</td><td>mikeWorks</td><td class="amount">5.00 €</td></tr>
-		<tr><td>2008/07/10</td><td>Dragomir Iulian</td><td class="amount">25.00 €</td></tr>
-		<tr><td>2007/11/30</td><td>Marcus Schommler</td><td class="amount">5.00 €</td></tr>
-		<tr><td>2007/10/20</td><td>Steve Buss</td><td class="amount">5.00 €</td></tr>
-	</tbody>
-</table>
\ No newline at end of file
diff --git a/www/download.html b/www/download.html
deleted file mode 100644
index 2753b56..0000000
--- a/www/download.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<h4 class="page-header">Download and Installation</h4>
-<h5>addons.mozilla.org</h5>
-<p>It is recommended to download and install Autofill Forms from the official Mozilla Firefox Add-ons website:<br />
-<ul>
-<li><a href="https://addons.mozilla.org/firefox/addon/4775">Autofill Forms on addons.mozilla.org</a></li>
-</ul></p>
-<h5>downloads.mozdev.org</h5>
-<p>As an alternative, you may also download Autofill Forms from mozdev.org:
-<ul>
-<li><a href="http://downloads.mozdev.org/autofillforms/">Autofill Forms on downloads.mozdev.org</a></li>
-</ul></p>
\ No newline at end of file
diff --git a/www/error/404.html b/www/error/404.html
deleted file mode 100644
index cf87357..0000000
--- a/www/error/404.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-// $Id: 404.html,v 1.1 2008/05/16 16:12:04 petejc Exp $
-
-// r 1.11 look/www/org/helm/common/template/404.tem
-
-//<font color="#990000" face="helvetica"><B>Page Not Found</B></font>   
-//<img src="http://www.mozdev.org/sharedimages/boxes.gif"><br><br>
-
-// clashs with project_nav.html
-
-?><!-- testing for admin section -->
-
-<p>The page <font color="#990000"><b><?php PRINT PAGE; ?></b></font> was not found on this site.
-
-<p>To find the desired link, try checking the <?php print $project; ?> project's 
-<?php print "<a href=\"http://$project.mozdev.org/index.html\">"; ?>main page</a>.
-
-<p>If that doesn't have the link you were looking for, you could also check out the following links:
-
-<ul>
-<li><a href="http://www.mozdev.org/projects.html">List of announced projects</a>
-<li><a href="http://www.mozdev.org/categories/unannounced.html">List of unannounced projects</a>
-<li><a href="http://www.mozdev.org/faq.html">Frequently Asked Questions page</a>
-<li>Search query page (coming soon)
-</ul>
-
-<p>If those don't help, you could also try sending mail to a project's mailing list, to one of the project owners, or to the general 
-site feedback address:
-
-<ul>
-<li><a href="http://www.mozdev.org/mailing-lists.html">Mailing Lists</a>
-<li><a href="http://www.mozdev.org/contact.html">Project Owners</a>
-<li><a href="http://www.mozdev.org/feedback.html">Feedback</a>
-</ul>
diff --git a/www/favicon.ico b/www/favicon.ico
deleted file mode 100644
index ea61fc5..0000000
Binary files a/www/favicon.ico and /dev/null differ
diff --git a/www/footer.html b/www/footer.html
deleted file mode 100644
index afbf211..0000000
--- a/www/footer.html
+++ /dev/null
@@ -1,19 +0,0 @@
-    </div>
-
-    <p id="mozdev-feedback">
-    For questions or comments about Autofill Forms, please use the provided 
-    <a href="http://autofillforms.mozdev.org/support.html">support options</a>.
-	<br />
-	<br />
-	<a href="http://www.mozdev.org" title="mozdev.org - free project hosting for the mozilla community">
-		<img src="http://www.mozdev.org/sharedimages/mozdev_tiny.png" width="80" height="15" alt="mozdev.org" border="0">
-	</a>
-	<a href="https://blueimp.net/" title="blueimp.net - Free software and open source web applications">
-		<img src="https://blueimp.net/img/logo-tiny.png" width="80" height="15" alt="blueimp.net" border="0">
-	</a>
-	<br />
-    <a href="http://www.mozdev.org/copyright.html">Copyright</a> © 2004. All rights reserved. 
-    <a href="http://www.mozdev.org/community/terms.html">Terms of Use</a>.
-    </p>
-</body>
-</html>
diff --git a/www/graphics/Firefox-3-Mac-Toolbar-Button-Template.png b/www/graphics/Firefox-3-Mac-Toolbar-Button-Template.png
deleted file mode 100644
index c4fd86a..0000000
Binary files a/www/graphics/Firefox-3-Mac-Toolbar-Button-Template.png and /dev/null differ
diff --git a/www/graphics/logo.png b/www/graphics/logo.png
deleted file mode 100644
index 7597028..0000000
Binary files a/www/graphics/logo.png and /dev/null differ
diff --git a/www/graphics/paypal-donate.gif b/www/graphics/paypal-donate.gif
deleted file mode 100644
index b5cda14..0000000
Binary files a/www/graphics/paypal-donate.gif and /dev/null differ
diff --git a/www/graphics/pencil.png b/www/graphics/pencil.png
deleted file mode 100644
index d0ec488..0000000
Binary files a/www/graphics/pencil.png and /dev/null differ
diff --git a/www/graphics/pencil.svg b/www/graphics/pencil.svg
deleted file mode 100644
index 6ab4ac0..0000000
--- a/www/graphics/pencil.svg
+++ /dev/null
@@ -1,610 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="309.8573"
-   height="309.86777"
-   id="svg2"
-   sodipodi:version="0.32"
-   inkscape:version="0.46"
-   sodipodi:docbase="/home/madblueimp"
-   sodipodi:docname="pencil.svg"
-   inkscape:export-filename="/home/madblueimp/pencil.png"
-   inkscape:export-xdpi="9.2946014"
-   inkscape:export-ydpi="9.2946014"
-   version="1.0"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape">
-  <defs
-     id="defs4">
-    <inkscape:perspective
-       sodipodi:type="inkscape:persp3d"
-       inkscape:vp_x="0 : 194.43752 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_z="388.742 : 194.43752 : 1"
-       inkscape:persp3d-origin="194.371 : 129.62501 : 1"
-       id="perspective80" />
-    <linearGradient
-       id="linearGradient3401">
-      <stop
-         id="stop3403"
-         offset="0"
-         style="stop-color:#ff9191;stop-opacity:1;" />
-      <stop
-         id="stop3405"
-         offset="1"
-         style="stop-color:#ff9191;stop-opacity:1;" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3316">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop3318" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0;"
-         offset="1"
-         id="stop3320" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3706">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0.82653064;"
-         offset="0"
-         id="stop3708" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0;"
-         offset="1"
-         id="stop3710" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4497">
-      <stop
-         style="stop-color:#ffae2c;stop-opacity:1;"
-         offset="0"
-         id="stop4499" />
-      <stop
-         style="stop-color:#ff9e00;stop-opacity:1;"
-         offset="1"
-         id="stop4501" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4254">
-      <stop
-         style="stop-color:#ff9191;stop-opacity:1;"
-         offset="0"
-         id="stop4256" />
-      <stop
-         style="stop-color:#b55858;stop-opacity:1;"
-         offset="1"
-         id="stop4258" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3800">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop3802" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0;"
-         offset="1"
-         id="stop3804" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3707">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop3687" />
-      <stop
-         style="stop-color:#ffdd7c;stop-opacity:1;"
-         offset="1"
-         id="stop3711" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3692">
-      <stop
-         style="stop-color:#ff9e00;stop-opacity:1;"
-         offset="0"
-         id="stop3694" />
-      <stop
-         id="stop3705"
-         offset="0.5"
-         style="stop-color:#ffffff;stop-opacity:1;" />
-      <stop
-         style="stop-color:#ff9e00;stop-opacity:1;"
-         offset="1"
-         id="stop3696" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3800"
-       id="linearGradient3806"
-       x1="167.15625"
-       y1="298.17941"
-       x2="167.15625"
-       y2="311.57703"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient4260"
-       x1="148.70325"
-       y1="318.68668"
-       x2="185.48425"
-       y2="318.68668"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient4396"
-       gradientUnits="userSpaceOnUse"
-       x1="148.70325"
-       y1="318.68668"
-       x2="185.48425"
-       y2="318.68668"
-       gradientTransform="matrix(1,0,0,-1,0,1052.3622)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient4399"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(0,-1.7382813e-5)"
-       x1="148.70325"
-       y1="318.68668"
-       x2="185.48425"
-       y2="318.68668" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient4465"
-       gradientUnits="userSpaceOnUse"
-       x1="148.70325"
-       y1="318.68668"
-       x2="185.48425"
-       y2="318.68668" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient4481"
-       gradientUnits="userSpaceOnUse"
-       x1="148.70325"
-       y1="318.68668"
-       x2="185.48425"
-       y2="318.68668"
-       gradientTransform="matrix(0.6504406,0,0,0.6504406,239.12347,164.45229)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3707"
-       id="linearGradient4495"
-       x1="335.91367"
-       y1="425.20453"
-       x2="359.76996"
-       y2="425.20453"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4497"
-       id="linearGradient4503"
-       x1="335.91718"
-       y1="414.39426"
-       x2="359.75989"
-       y2="414.39426"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient4569"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.6504406,0,0,0.6504406,239.12347,164.45229)"
-       x1="148.70325"
-       y1="318.68668"
-       x2="185.48425"
-       y2="318.68668" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient4590"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.6504406,0,0,0.6504406,239.12347,164.45229)"
-       x1="148.70325"
-       y1="318.68668"
-       x2="185.48425"
-       y2="318.68668" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3707"
-       id="linearGradient4592"
-       gradientUnits="userSpaceOnUse"
-       x1="335.91367"
-       y1="425.20453"
-       x2="359.76996"
-       y2="425.20453" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4497"
-       id="linearGradient4594"
-       gradientUnits="userSpaceOnUse"
-       x1="335.91718"
-       y1="414.39426"
-       x2="359.75989"
-       y2="414.39426" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3706"
-       id="linearGradient2322"
-       gradientUnits="userSpaceOnUse"
-       x1="335.71875"
-       y1="414.35938"
-       x2="353.75"
-       y2="414.35938"
-       gradientTransform="matrix(3.5733281,-1.5578977e-3,-1.5578977e-3,3.5733281,-872.34737,-1020.0829)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3707"
-       id="linearGradient2332"
-       gradientUnits="userSpaceOnUse"
-       x1="331.71732"
-       y1="437.79453"
-       x2="365.74753"
-       y2="437.79453"
-       gradientTransform="matrix(3.5733281,-1.5578977e-3,-1.5578977e-3,3.5733281,-872.34737,-1020.0829)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient2339"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.3154492,-1.4454678e-3,-1.4454678e-3,3.3154492,-180.47767,-785.1168)"
-       x1="148.70325"
-       y1="318.68668"
-       x2="185.48425"
-       y2="318.68668" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3316"
-       id="linearGradient3322"
-       x1="349.15182"
-       y1="707.90222"
-       x2="373.04395"
-       y2="707.90222"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3706"
-       id="linearGradient3326"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.5733281,-1.5578977e-3,-1.5578977e-3,3.5733281,-872.34737,-1100.0829)"
-       x1="335.71875"
-       y1="414.35938"
-       x2="353.75"
-       y2="414.35938" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3706"
-       id="linearGradient3386"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.5733281,1.5578977e-3,-1.5578977e-3,-3.5733281,-872.34737,2152.4451)"
-       x1="335.71875"
-       y1="414.35938"
-       x2="353.75"
-       y2="414.35938" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient3393"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.5733281,-1.5578977e-3,-1.5578977e-3,3.5733281,-872.34737,-1100.0829)"
-       x1="335.71875"
-       y1="414.35938"
-       x2="353.75"
-       y2="414.35938" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient3430"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.3154492,-1.4454678e-3,-1.4454678e-3,3.3154492,-180.47767,-785.1168)"
-       x1="148.70325"
-       y1="318.68668"
-       x2="185.48425"
-       y2="318.68668" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3707"
-       id="linearGradient3432"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.5733281,-1.5578977e-3,-1.5578977e-3,3.5733281,-872.34737,-1020.0829)"
-       x1="331.71732"
-       y1="437.79453"
-       x2="365.74753"
-       y2="437.79453" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3706"
-       id="linearGradient3434"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.5733281,-1.5578977e-3,-1.5578977e-3,3.5733281,-872.34737,-1020.0829)"
-       x1="335.71875"
-       y1="414.35938"
-       x2="353.75"
-       y2="414.35938" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3316"
-       id="linearGradient3436"
-       gradientUnits="userSpaceOnUse"
-       x1="349.15182"
-       y1="707.90222"
-       x2="373.04395"
-       y2="707.90222" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3316"
-       id="linearGradient4267"
-       gradientUnits="userSpaceOnUse"
-       x1="349.15182"
-       y1="707.90222"
-       x2="373.04395"
-       y2="707.90222"
-       gradientTransform="translate(15.365248,6.2927944)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3706"
-       id="linearGradient4270"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.5733281,-1.5578977e-3,-1.5578977e-3,3.5733281,-856.98212,-1013.7901)"
-       x1="335.71875"
-       y1="414.35938"
-       x2="353.75"
-       y2="414.35938" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3707"
-       id="linearGradient4279"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.5733281,-1.5578977e-3,-1.5578977e-3,3.5733281,-856.98212,-1013.7901)"
-       x1="331.71732"
-       y1="437.79453"
-       x2="365.74753"
-       y2="437.79453" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient4286"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.3154492,-1.4454678e-3,-1.4454678e-3,3.3154492,-165.11242,-778.82401)"
-       x1="148.70325"
-       y1="318.68668"
-       x2="185.48425"
-       y2="318.68668" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient4306"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.3154492,-1.4454678e-3,-1.4454678e-3,3.3154492,-165.11242,-778.82401)"
-       x1="148.70325"
-       y1="318.68668"
-       x2="185.48425"
-       y2="318.68668" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3707"
-       id="linearGradient4308"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.5733281,-1.5578977e-3,-1.5578977e-3,3.5733281,-856.98212,-1013.7901)"
-       x1="331.71732"
-       y1="437.79453"
-       x2="365.74753"
-       y2="437.79453" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3706"
-       id="linearGradient4310"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.5733281,-1.5578977e-3,-1.5578977e-3,3.5733281,-856.98212,-1013.7901)"
-       x1="335.71875"
-       y1="414.35938"
-       x2="353.75"
-       y2="414.35938" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3706"
-       id="linearGradient4314"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.5733281,-1.5578977e-3,-1.5578977e-3,3.5733281,-856.98212,-1013.7901)"
-       x1="335.71875"
-       y1="414.35938"
-       x2="353.75"
-       y2="414.35938" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3707"
-       id="linearGradient4323"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.5733281,-1.5578977e-3,-1.5578977e-3,3.5733281,-856.98212,-1013.7901)"
-       x1="331.71732"
-       y1="437.79453"
-       x2="365.74753"
-       y2="437.79453" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient4330"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(3.3154492,-1.4454678e-3,-1.4454678e-3,3.3154492,-165.11242,-778.82401)"
-       x1="148.70325"
-       y1="318.68668"
-       x2="185.48425"
-       y2="318.68668" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3706"
-       id="linearGradient7803"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2.527826,2.525623,-2.527826,2.525623,1119.475,-1457.151)"
-       x1="335.71875"
-       y1="414.35938"
-       x2="353.75"
-       y2="414.35938" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3707"
-       id="linearGradient7812"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2.5278262,2.525623,-2.5278262,2.525623,565.91117,-1456.1414)"
-       x1="331.71732"
-       y1="437.79453"
-       x2="365.74753"
-       y2="437.79453" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4254"
-       id="linearGradient7819"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2.345399,2.343355,-2.345399,2.343355,808.1061,-719.7623)"
-       x1="148.70325"
-       y1="318.68668"
-       x2="185.48425"
-       y2="318.68668" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1"
-     inkscape:cx="260.28083"
-     inkscape:cy="165.25621"
-     inkscape:document-units="px"
-     inkscape:current-layer="g7826"
-     inkscape:window-width="1272"
-     inkscape:window-height="924"
-     inkscape:window-x="4"
-     inkscape:window-y="71"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     showgrid="false" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:source>https://blueimp.net</dc:source>
-        <dc:creator>
-          <cc:Agent>
-            <dc:title>Sebastian Tschan</dc:title>
-          </cc:Agent>
-        </dc:creator>
-        <cc:license
-           rdf:resource="GNU Free Documentation license - http://www.gnu.org/licenses/fdl.html" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     style="display:inline"
-     transform="translate(-208.33745,-352.78704)" />
-  <g
-     inkscape:groupmode="layer"
-     id="layer2"
-     inkscape:label="layer2"
-     style="display:inline"
-     transform="translate(-208.33745,-352.78704)">
-    <g
-       id="g7826">
-      <g
-         id="g2273"
-         style="opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-         inkscape:export-filename="/home/madblueimp/pencil.png"
-         inkscape:export-xdpi="4.0700002"
-         inkscape:export-ydpi="4.0700002">
-        <path
-           inkscape:export-ydpi="6.4299998"
-           inkscape:export-xdpi="6.4299998"
-           inkscape:export-filename="/home/madblueimp/pencil.png"
-           style="fill:url(#linearGradient7812);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-           d="M 429.20661,356.02971 L 244.3069,540.76828 L 209.33745,661.6548 L 220.30359,658.48966 L 330.3294,626.71581 L 515.22912,441.97725 L 498.53641,425.29909 L 492.68789,419.45566 L 477.09173,403.87309 L 475.14215,401.9252 L 469.29362,396.08178 L 467.34405,394.13391 L 451.74805,378.5515 L 445.89934,372.7079 L 437.00475,363.82106 L 429.20661,356.02971 z"
-           id="path4106" />
-        <path
-           inkscape:export-ydpi="6.4299998"
-           inkscape:export-xdpi="6.4299998"
-           inkscape:export-filename="/home/madblueimp/pencil.png"
-           style="fill:#ffc700;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-           d="M 429.20661,356.02971 L 244.3069,540.76828 L 286.03514,542.05018 L 287.31817,583.74205 L 329.04638,585.02394 L 330.3294,626.71581 L 515.22912,441.97725 L 493.72349,420.49036 L 472.21788,399.00349 L 450.71225,377.5166 L 429.20661,356.02971 z"
-           id="path3424"
-           sodipodi:nodetypes="ccccccccccc" />
-        <path
-           inkscape:export-ydpi="6.4299998"
-           inkscape:export-xdpi="6.4299998"
-           inkscape:export-filename="/home/madblueimp/pencil.png"
-           style="fill:#ffda00;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-           d="M 429.20661,356.02971 L 244.3069,540.76828 L 286.03514,542.05018 L 450.71225,377.5166 L 429.20661,356.02971 z"
-           id="path3426"
-           sodipodi:nodetypes="ccccc" />
-        <path
-           inkscape:export-ydpi="6.4299998"
-           inkscape:export-xdpi="6.4299998"
-           inkscape:export-filename="/home/madblueimp/pencil.png"
-           style="fill:#ff8a00;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-           d="M 329.04638,585.02394 L 330.3294,626.71581 L 515.22912,441.97725 L 493.72349,420.49036 L 329.04638,585.02394 z"
-           id="path3428"
-           sodipodi:nodetypes="ccccc" />
-        <path
-           inkscape:export-ydpi="6.4299998"
-           inkscape:export-xdpi="6.4299998"
-           inkscape:export-filename="/home/madblueimp/pencil.png"
-           style="fill:#ffa100;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-           d="M 287.31817,583.74205 L 329.04638,585.02394 L 493.72349,420.49036 L 472.21788,399.00349 L 287.31817,583.74205 z"
-           id="path3430"
-           sodipodi:nodetypes="ccccc" />
-        <path
-           inkscape:export-ydpi="6.4299998"
-           inkscape:export-xdpi="6.4299998"
-           inkscape:export-filename="/home/madblueimp/pencil.png"
-           style="fill:url(#linearGradient7819);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
-           d="M 486.49403,384.44598 C 462.75184,360.72447 436.83161,348.11762 428.67868,356.26343 C 428.12537,356.81626 427.64194,357.4406 427.27733,358.15035 L 375.61513,409.76751 L 383.41327,417.55886 L 413.75257,447.87172 L 423.50025,457.6109 L 461.63764,495.71505 L 515.00577,442.39344 C 514.97622,442.29755 514.97518,442.18579 514.94495,442.0892 L 514.884,442.02831 C 514.90223,442.00869 514.92667,441.98735 514.9448,441.96757 C 522.62989,433.5672 510.01079,407.94222 486.49403,384.44598 z"
-           id="path4217" />
-        <path
-           inkscape:export-ydpi="6.4299998"
-           inkscape:export-xdpi="6.4299998"
-           inkscape:export-filename="/home/madblueimp/pencil.png"
-           style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
-           d="M 467.48484,490.16915 L 381.46234,404.22161 L 377.56322,408.11734 L 375.61363,410.06522 L 461.63614,496.01276 L 463.58572,494.06487 L 467.48484,490.16915 z"
-           id="path4147" />
-      </g>
-      <path
-         sodipodi:nodetypes="ccccc"
-         id="path3990"
-         d="M 256.88237,647.92525 L 239.98074,631.03834 L 223.0791,614.15144 L 209.33745,661.6548 L 256.88237,647.92525 z"
-         style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.16400003;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         inkscape:export-filename="/home/madblueimp/pencil.png"
-         inkscape:export-xdpi="4.0700002"
-         inkscape:export-ydpi="4.0700002" />
-      <path
-         sodipodi:nodetypes="cccc"
-         id="path4288"
-         d="M 239.98074,631.03834 L 228.73595,619.80829 L 209.33745,661.6548 L 239.98074,631.03834 z"
-         style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.16400003;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         inkscape:export-filename="/home/madblueimp/pencil.png"
-         inkscape:export-xdpi="4.0700002"
-         inkscape:export-ydpi="4.0700002" />
-    </g>
-  </g>
-</svg>
diff --git a/www/graphics/screenshots/autofill-forms-01.png b/www/graphics/screenshots/autofill-forms-01.png
deleted file mode 100644
index 1b1b890..0000000
Binary files a/www/graphics/screenshots/autofill-forms-01.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-02.png b/www/graphics/screenshots/autofill-forms-02.png
deleted file mode 100644
index a089544..0000000
Binary files a/www/graphics/screenshots/autofill-forms-02.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-03.png b/www/graphics/screenshots/autofill-forms-03.png
deleted file mode 100644
index bf96b63..0000000
Binary files a/www/graphics/screenshots/autofill-forms-03.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-04.png b/www/graphics/screenshots/autofill-forms-04.png
deleted file mode 100644
index f8860f1..0000000
Binary files a/www/graphics/screenshots/autofill-forms-04.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-05.png b/www/graphics/screenshots/autofill-forms-05.png
deleted file mode 100644
index 5a81981..0000000
Binary files a/www/graphics/screenshots/autofill-forms-05.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-06.png b/www/graphics/screenshots/autofill-forms-06.png
deleted file mode 100644
index 47da17c..0000000
Binary files a/www/graphics/screenshots/autofill-forms-06.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-07.png b/www/graphics/screenshots/autofill-forms-07.png
deleted file mode 100644
index 7ea856b..0000000
Binary files a/www/graphics/screenshots/autofill-forms-07.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-08.png b/www/graphics/screenshots/autofill-forms-08.png
deleted file mode 100644
index 07cc119..0000000
Binary files a/www/graphics/screenshots/autofill-forms-08.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-09.png b/www/graphics/screenshots/autofill-forms-09.png
deleted file mode 100644
index a9487a1..0000000
Binary files a/www/graphics/screenshots/autofill-forms-09.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-10.png b/www/graphics/screenshots/autofill-forms-10.png
deleted file mode 100644
index 60e3a0c..0000000
Binary files a/www/graphics/screenshots/autofill-forms-10.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-11.png b/www/graphics/screenshots/autofill-forms-11.png
deleted file mode 100644
index 415e92c..0000000
Binary files a/www/graphics/screenshots/autofill-forms-11.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-12.png b/www/graphics/screenshots/autofill-forms-12.png
deleted file mode 100644
index 38c1d06..0000000
Binary files a/www/graphics/screenshots/autofill-forms-12.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-13.png b/www/graphics/screenshots/autofill-forms-13.png
deleted file mode 100644
index c2c697d..0000000
Binary files a/www/graphics/screenshots/autofill-forms-13.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-14.png b/www/graphics/screenshots/autofill-forms-14.png
deleted file mode 100644
index 087a29e..0000000
Binary files a/www/graphics/screenshots/autofill-forms-14.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-15.png b/www/graphics/screenshots/autofill-forms-15.png
deleted file mode 100644
index 921e68d..0000000
Binary files a/www/graphics/screenshots/autofill-forms-15.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-16.png b/www/graphics/screenshots/autofill-forms-16.png
deleted file mode 100644
index cc0ec71..0000000
Binary files a/www/graphics/screenshots/autofill-forms-16.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-17.png b/www/graphics/screenshots/autofill-forms-17.png
deleted file mode 100644
index 426e975..0000000
Binary files a/www/graphics/screenshots/autofill-forms-17.png and /dev/null differ
diff --git a/www/graphics/screenshots/autofill-forms-18.png b/www/graphics/screenshots/autofill-forms-18.png
deleted file mode 100644
index 1930a50..0000000
Binary files a/www/graphics/screenshots/autofill-forms-18.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-01.png b/www/graphics/screenshots/preview/autofill-forms-01.png
deleted file mode 100644
index f1573ed..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-01.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-02.png b/www/graphics/screenshots/preview/autofill-forms-02.png
deleted file mode 100644
index e579dd7..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-02.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-03.png b/www/graphics/screenshots/preview/autofill-forms-03.png
deleted file mode 100644
index 2604567..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-03.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-04.png b/www/graphics/screenshots/preview/autofill-forms-04.png
deleted file mode 100644
index f503f9a..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-04.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-05.png b/www/graphics/screenshots/preview/autofill-forms-05.png
deleted file mode 100644
index b2c8877..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-05.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-06.png b/www/graphics/screenshots/preview/autofill-forms-06.png
deleted file mode 100644
index 4d5eeb6..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-06.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-07.png b/www/graphics/screenshots/preview/autofill-forms-07.png
deleted file mode 100644
index 448ad7d..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-07.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-08.png b/www/graphics/screenshots/preview/autofill-forms-08.png
deleted file mode 100644
index 22c3f8e..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-08.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-09.png b/www/graphics/screenshots/preview/autofill-forms-09.png
deleted file mode 100644
index 2c2be86..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-09.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-10.png b/www/graphics/screenshots/preview/autofill-forms-10.png
deleted file mode 100644
index 5ad22c7..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-10.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-11.png b/www/graphics/screenshots/preview/autofill-forms-11.png
deleted file mode 100644
index 75efe68..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-11.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-12.png b/www/graphics/screenshots/preview/autofill-forms-12.png
deleted file mode 100644
index 684eedf..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-12.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-13.png b/www/graphics/screenshots/preview/autofill-forms-13.png
deleted file mode 100644
index c1b9363..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-13.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-14.png b/www/graphics/screenshots/preview/autofill-forms-14.png
deleted file mode 100644
index ea4e8e6..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-14.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-15.png b/www/graphics/screenshots/preview/autofill-forms-15.png
deleted file mode 100644
index c95a776..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-15.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-16.png b/www/graphics/screenshots/preview/autofill-forms-16.png
deleted file mode 100644
index ff6f7b1..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-16.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-17.png b/www/graphics/screenshots/preview/autofill-forms-17.png
deleted file mode 100644
index e1a81e0..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-17.png and /dev/null differ
diff --git a/www/graphics/screenshots/preview/autofill-forms-18.png b/www/graphics/screenshots/preview/autofill-forms-18.png
deleted file mode 100644
index 08e990f..0000000
Binary files a/www/graphics/screenshots/preview/autofill-forms-18.png and /dev/null differ
diff --git a/www/head.txt b/www/head.txt
deleted file mode 100644
index 36ff85e..0000000
--- a/www/head.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-<link rel="stylesheet" href="/project.css" type="text/css" />
-<link rel="stylesheet" href="/css/slimbox.css" type="text/css" media="screen" />
-<link rel="shortcut icon" href="/favicon.ico" />
-<title>Autofill Forms - Mozilla Firefox Add-on</title>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<meta http-equiv="Content-Style-Type" content="text/css"/>
-<meta http-equiv="Content-Script-Type" content="text/javascript">
-<meta name="robots" content="index,follow" />
-<meta name="keywords" content="autofill, forms, mozilla, firefox, add-on" />
-<meta name="description" content="Autofill Forms - Mozilla Firefox Add-on to fill out web forms automatically." />
-<meta name="author" content="Sebastian Tschan" />
diff --git a/www/hide_from_ns4.css b/www/hide_from_ns4.css
deleted file mode 100644
index eb9a01a..0000000
--- a/www/hide_from_ns4.css
+++ /dev/null
@@ -1,15 +0,0 @@
-#project-navigation a {
-  border-left: 1px solid black;
-  padding-left: 6px;
-  padding-right: 5px;
-}
-
-#project-navigation a.first-item {
-  border-left: none;
-}
-
-#project-navigation th {
-  margin-right: 3px;
-}
-
-
diff --git a/www/html_body.html b/www/html_body.html
deleted file mode 100644
index fe169e1..0000000
--- a/www/html_body.html
+++ /dev/null
@@ -1,84 +0,0 @@
- </head>
- <body>
-
-	<!-- ################### BEGIN TOP ################## -->
-	<h1 id="mozdev-logo"><a href="https://blueimp.net/mozilla/">Autofill Forms</a></h1>
-	<div id="mozdev-date">
-		<!--$mind-it-ignore$-->
-
-		<ul id="community-links">
-			<li class="mozdev-date"><?php print DATE;?></li>
-			<li class="mozdev-fries">Fill out web forms automatically</li>
-		</ul>
-		<!--$/mind-it-ignore$-->
-	</div>
-
-<!--  ########################## BEGIN LEFT NAV ########################### -->
-		<div id="mozdev-navigation">
-
-			<!-- skip navigation -->
-			<p class="invisible"><a class="nav-link" href="#content" title="Skip Navigation Entirely">Skip to Content</a></p>
-
-			<!--form action="https://www.paypal.com/cgi-bin/webscr" method="post">
-				<div id="mozdev-donate">
-					<a href="https://www.paypal.com/cgi-bin/webscr&cmd=_s-xclick&hosted_button_id=">
-						<img src="./graphics/paypal-donate.gif" alt="Donate">
-					</a>
-				</div>
-			</form-->
-
-			<div id="mozdev-searchbox">
-				<h4 id="search" title="Search">Search</h4>
-				<!-- skip navigation -->
-				<p class="invisible"><a accesskey="C" class="nav-link" href="#content" title="Skip to Content">Skip to Content</a></p>
-				<!-- Google search form -->
-				 <form action="http://www.google.com/custom" method="get">
-					<div>
-					 <label accesskey="S" class="invisible" for="inputField">Search For</label>
-
-					 <input class="mozdev-textbox" id="inputField" maxlength="255" name="q" size="15" type="text" value=""><button class="mozdev-searchbutton" type="submit" title="Google Search">Go</button>
-					 <input type="hidden" name="sitesearch" value="autofillforms.mozdev.org"/>
-					 <input type="hidden" name="cof" value="S:http://autofillforms.mozdev.org;L:http://www.mozdev.org/sharedimages/header.gif;LW:458;LH:69;AH:left;"/>
-					</div>
-				 </form>
-				<!-- /Google search form -->
-			</div>
-
-			<div id="mozdev-style"></div>
-
-			<div class="menu" id="mozdev-projects">
-				<h4 id="projects" title="Projects">Projects</h4>
-				<ul id="prj-ul">
-				<li><a href="http://securelogin.mozdev.org/">Secure Login</a></li>
-				<li><a href="http://netnotes.mozdev.org/">Net Notes</a></li>
-				</ul>
-			</div>
-
-			<div class="menu" id="mozdev-resources">
-				<h4 id="nav-resources" title="Resources">Resources</h4>
-
-				<ul id="res-ul">
-				<li><a href="http://www.mozdev.org" title="mozdev.org - free project hosting for the mozilla community">Project Hosting</a></li>
-				<li><a href="https://blueimp.net" title="blueimp.net - Free software and open source web applications">Development</a></li>
-				</ul>
-			</div>
-
-			<div class="menu" id="mozdev-community">
-				<h4 id="community" title="Community">Community</h4>
-				<ul id="com-ul">
-				<li><a href="http://forums.mozillazine.org/viewtopic.php?t=537839">Forum topic [en]</a></li>
-				<li><a href="http://www.firefox-browser.de/forum/viewtopic.php?t=48988">Forum topic [de]</a></li>
-				<li><a href="http://www.babelzilla.org/forum/index.php?showtopic=3068">Translations</a></li>
-				<li><a href="https://addons.mozilla.org/firefox/addon/4775#reviews">Reviews</a></li>
-				<li><a href="./donation.html">Donators</a></li>
-				</ul>
-			</div>
-
-
-	</div>
-
-	<div id="mozdev-fluff"><b></b></div>
-
-	<div id="mozdev-fluff2"><i></i></div>
-
-<!-- ########################## END LEFT NAV ############################# -->
diff --git a/www/index.html b/www/index.html
deleted file mode 100644
index 12022d9..0000000
--- a/www/index.html
+++ /dev/null
@@ -1,60 +0,0 @@
-
-<!-- MAIN CONTENT -->
-<h4 class="page-header">Autofill Forms - Mozilla Firefox add-on</h4>
-<a style="float:right; margin-left:20px;" href="/screenshots.html">
-	<img src="./graphics/screenshots/preview/autofill-forms-01.png" alt="screenshot-01"/>
-</a>
-<p>Autofill Forms enables you to fill out web forms with one click or a keyboard shortcut.</p>
-<h3>Features:</h3>
-<ul>
-	<li>Easy installation through Mozilla Firefox add-ons system.</li>
-	<li>Easy configuration with a simple interface.</li>
-	<li>Fills out web forms with one click or a keyboard shortcut.</li>
-	<li>Input fields not automatically matched can be filled out via the context menu.</li>
-	<li>Features a completely customizable ruleset to determine the input for each form element.</li>
-	<li>Provides a simple rule editor to define custom rules.</li>
-	<li>Advanced users can customize the ruleset using JavaScript Regular Expressions.</li>
-	<li>Allows to match form fields by name, label (in strict mode or by proximity) or by position.</li>
-	<li>Works with input fields, textareas, selections, checkboxes, radio buttons and any valid form fields.</li>
-	<li>Allows to use multiline input with line break tags.</li>
-	<li>Allows dynamically created input data using special <em>Dynamic Tags</em>.</li>
-	<li>Profiles can be used to switch betweeen several sets of rules.</li>
-	<li>Possibility to define site specific profiles and rules.</li>
-	<li>Automatically selects the best matching profile based on the assigned site.</li>
-	<li>Possibility to define a global profile.</li>
-	<li>Profiles can be exported and imported.</li>
-	<li>Profiles can be stored in Firefox preferences system or in a custom config directory.</li>
-	<li>Provides the possibility to define alternatives inside a profile.</li>
-	<li>Allows to add new rules or complete forms as profiles via the context menu of form fields.</li>
-	<li>Can be used with a toolbar button, a statusbar icon, a keyboard shortcut or via the context menu.</li>
-	<li>Completely customizable interface (buttons, icons and menus can be enabled/disabled).</li>
-	<li>Autofilled and not autofilled form fields can be highlighted using <acronym title="Cascading Style Sheets">CSS</acronym> declarations.</li>
-	<li>Provides customizable keyboard shortcuts</li>
-	<li>Makes use of additional mouse buttons to perform differenct actions on click of the toolbar button.</li>
-	<li>Can fill out and automatically submit forms.</li>
-	<li>Can fill out forms on all open browser tabs.</li>
-	<li>Can fill out forms from a profile selection.</li>
-	<li>Only active when filling out forms so it doesn't consume any system resources while surfing.</li>
-	<li>Provides secure encryption for the stored form data using Firefox Master Password.</li>
-	<li>Integrates with the <a href="http://securelogin.mozdev.org/">Secure Login</a> add-on.</li>
-</ul>
-
-<h3>TODO:</h3>
-<ul>
-  <li>Create an improved default profile.</li>
-  <li>Add option to disable "Alternatives" (always use first match).</li>
-  <li>Append highlight styles instead of replacing them.</li>
-  <li>Add a dynamic tag to input the value of other fields.</li>
-  <li>Highlight the field for which the Alternatives selection prompts.</li>
-  <li>Add option to call the onchange event after filling out fields.</li>
-  <li>Add option to fill out and submit forms on all tabs</li>
-  <li>Add option to select which profiles are shown for context menu autofill.</li>
-  <li>Add option to give the Global Profile a higher priority.</li>
-  <li>Add option to "add a rule for this field" at a specific position in the current rules list.</li>
-  <li>Add option to fill out forms on page load.</li>
-  <li>Add option to highlight form fields on page load.</li>
-  <li>Add option to append to a field value instead of overwrite.</li>
-  <li>Add option to keep autoselected profile as the selected profile.</li>
-  <li>Add option to use next best matching profile if AF invoked repeatedly on the same site.</li>
-  <li>Add support for rich text fields.</li>
-</ul>
diff --git a/www/local.conf b/www/local.conf
deleted file mode 100644
index 1e66c11..0000000
--- a/www/local.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-<?php
-
-$local_conf_commits=ON;
-$local_conf_nav_off=ON;
-$local_conf_use_local_header=ON;
-$local_conf_use_local_footer=ON;
-$local_conf_ignore_holidays = ON;
-$local_conf_style_2004=ON;
-$local_conf_download_file_feed=OFF;
-
-  echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' . "\n";
-
-?>
diff --git a/www/project.css b/www/project.css
deleted file mode 100644
index a67c79b..0000000
--- a/www/project.css
+++ /dev/null
@@ -1,38 +0,0 @@
- at import url("http://www.mozdev.org/project.css");
-
-h1#mozdev-logo a
-{
-	background-image:url(./graphics/logo.png);
-	width: 250px;
-}
-
-h1#mozdev-logo
-{
-	background-position: 250px 0pt;
-}
-
-#main-content-no-nav {
-	margin: 2em 1em 1em 176px;
-	text-align: justify;
-}
-
-#mozdev-donate {
-	margin:10px;
-}
-
-li li {
-	margin-left:18px;
-}
-
-#donators td.amount {
-	text-align:right;
-}
-
-#donators td {
-	padding-top:5px;
-	padding-right:5px;
-}
-
-#screenshots-gallery {
-	text-align:left;
-}
diff --git a/www/project_nav.html b/www/project_nav.html
deleted file mode 100644
index 527ec2e..0000000
--- a/www/project_nav.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<h1 class="project-name" id="content">Autofill Forms</h1>
-
-<table id="project-navigation">
-
-  <tbody id="resources" class="project-navigations">
-  <tr>
-  <th scope="row">resources:</th>
-  <td class="navigation-list">
-  <a class="first-item" href="/">Home</a>
-  <a href="/screenshots.html">Screenshots</a>
-  <a href="/download.html">Download</a>
-  <a href="/changelog.html">Changelog</a>
-  <a href="/source.html">Source Code</a>
-  <a href="/bugs.html">Bugs</a>
-  <a href="/support.html">Support</a>
-  <a href="/members.html">Members</a>
-  <a href="/drupal/wiki">Wiki</a>
-  </td>
-  </tr>
-  </tbody>
-</table>
diff --git a/www/screenshots.html b/www/screenshots.html
deleted file mode 100644
index 963adda..0000000
--- a/www/screenshots.html
+++ /dev/null
@@ -1,62 +0,0 @@
-<!-- MAIN CONTENT -->
-<h5 class="page-header">Screenshots</h5>
-
-<script type="text/javascript" src="./js/mootools.js"></script>
-<script type="text/javascript" src="./js/slimbox.js"></script>
-
-<p id="screenshots-gallery">
-	<a href="./graphics/screenshots/autofill-forms-01.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-01.png" alt="screenshot-01"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-02.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-02.png" alt="screenshot-02"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-03.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-03.png" alt="screenshot-03"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-04.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-04.png" alt="screenshot-04"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-05.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-05.png" alt="screenshot-05"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-06.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-06.png" alt="screenshot-06"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-07.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-07.png" alt="screenshot-07"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-08.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-08.png" alt="screenshot-08"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-09.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-09.png" alt="screenshot-09"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-10.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-10.png" alt="screenshot-10"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-11.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-11.png" alt="screenshot-11"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-12.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-12.png" alt="screenshot-12"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-13.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-13.png" alt="screenshot-13"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-14.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-14.png" alt="screenshot-14"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-15.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-15.png" alt="screenshot-15"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-16.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-16.png" alt="screenshot-16"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-17.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-17.png" alt="screenshot-17"/>
-	</a>
-	<a href="./graphics/screenshots/autofill-forms-18.png" rel="lightbox[screenshots]">
-		<img src="./graphics/screenshots/preview/autofill-forms-18.png" alt="screenshot-18"/>
-	</a>
-</p>
diff --git a/www/source.html b/www/source.html
deleted file mode 100644
index 4f475b3..0000000
--- a/www/source.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- MAIN CONTENT -->
-<h5 class="page-header">Source Code</h5>
-
-<p id="src-intro">
-  The Autofill Forms source code can be accessed in either of the following ways:
-</p>
-
-<ul id="get-the-src">
-<li>Extract the source code from the <a href="download.html">installation file</a> (e.g. with <a href="http://www.7-zip.org/">7-zip</a>)</li>
-<li>View the source using the <abbr title="Concurrent Versions System">CVS</abbr> <a href="http://www.mozdev.org/source/browse/autofillforms/">web interface</a></li>
-<li>Check out the source using anonymous CVS with the following commands (password is guest):
-<pre>
-cvs -d :pserver:guest at mozdev.org:/cvs login
-cvs -z3 -d :pserver:guest at mozdev.org:/cvs co autofillforms/src autofillforms/www
-</pre>
-</li>
-</ul>
\ No newline at end of file
diff --git a/www/support.html b/www/support.html
deleted file mode 100644
index 15118a6..0000000
--- a/www/support.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<h4 class="page-header">Support</h4>
-<p>Before requesting support please have a look at the available <a href="/drupal/wiki">documentation</a>.</p>
-<p>You have several options to post questions or comments about Autofill Forms:
-<ul>
-	<li>
-		<strong>Web forum</strong><br />
-		Post a message to the <a href="http://forums.mozillazine.org/viewtopic.php?p=2831644">Autofill Forms forum topic</a> on the MozillaZine forums</a>.
-	</li>
-	<li>
-		<strong>Mailing list</strong><br />
-		Post a message to the <a href="http://autofillforms.mozdev.org/list.html">Autofill Forms mailing list</a>.
-		<form action="http://groups.google.com/group/autofill-forms/search" method="get">
-			<div>	
-				<input name="q" size="30" type="text" value="">
-				<button type="submit">Search list archives</button>
-			</div>
-		</form>
-		You may also post to the mailing list via <a href="http://groups.google.com/group/autofill-forms/post">Gougle Groups</a>.
-	</li>
-	<li>
-		<strong>Newsgroup</strong><br />
-		Post a message to the <a href="news://news.mozdev.org/public.mozdev.autofillforms">Autofill Forms newsgroup</a>.<br />
-		You need a <a href="http://en.wikipedia.org/wiki/List_of_news_clients">news client</a> to be able to read and post on Newsgroups.<br />
-		In order to access newsgroups on mozdev, you will need to provide a global userrname and password:
-		<ul>
-			<li>Username: mozdev</li>
-			<li>Password: maduser</li>
-		</ul>
-		This authentication applies to every public mozdev newsgroup and is an effort to help reduce spam.
-	</li>
-</ul>
-</p>
-<p><strong>Notes:</strong>
-<ul>
-	<li>All support requests are available to the public. <strong>Do not post any confidential information in your support messages.</strong></li>
-	<li>The mailing list is linked to the newsgroup. Postings to the mailing list also appear on the newsgroup and vice versa.</li>
-	<li>All mailing list posts are archived on <a href="http://groups.google.com/group/autofill-forms">Gougle Groups</a>.</li>
-</ul>
-</p>
diff --git a/www/test.html b/www/test.html
deleted file mode 100644
index e944283..0000000
--- a/www/test.html
+++ /dev/null
@@ -1,95 +0,0 @@
-<h4 class="page-header">Autofill Forms Test Page</h4>
-<form action="" method="post">
-<p>
-	<fieldset>
-		<legend>Textfields</legend>
-		<table>
-			<tr>
-				<td><label for="user_name">Username:</label></td>
-				<td><input type="text" id="user_name" name="user_name"/></td>
-			</tr>
-			<tr>
-				<td><label for="email">E-Mail:</label></td>
-				<td><input type="text" id="email" name="email"/></td>
-			</tr>
-			<tr>
-				<td><label for="full_name">Full Name:</label></td>
-				<td><input type="text" id="full_name" name="full_name" value="Tom Bombadil"/></td>
-			</tr>
-			<tr>
-				<td><label for="street_1">Street Line 1:</label></td>
-				<td><input type="text" id="street_1" name="street_1"/></td>
-			</tr>
-			<tr>
-				<td><label for="street_2">Street Line 2:</label></td>
-				<td><input type="text" id="street_2" name="street_2"/></td>
-			</tr>
-			<tr>
-				<td><label for="city">City:</label></td>
-				<td><input type="text" id="city" name="city"/></td>
-			</tr>
-			<tr>
-				<td><label for="state">State:</label></td>
-				<td><input type="text" id="state" name="state"/></td>
-			</tr>
-			<tr>
-				<td><label for="zip">ZIP/Postal Code:</label></td>
-				<td><input type="text" id="zip" name="zip"/></td>
-			</tr>
-			<tr>
-				<td><label for="phone">Phone Number:</label></td>
-				<td><input type="text" id="phone" name="phone"/></td>
-			</tr>
-			<tr>
-				<td><label for="homepage">Homepage:</label></td>
-				<td><input type="text" id="homepage" name="homepage"/></td>
-			</tr>
-		</table>
-	</fieldset>
-</p>
-<p>
-	<fieldset>
-		<legend>Selections, Checkboxes and Radio Buttons</legend>
-		<p>
-			<label for="selection_single">Hitchhiker books:</label><br />
-			<select id="selection_single" name="selection_single">
-				<option>The Hitchhiker's Guide to the Galaxy </option>
-				<option>The Restaurant at the End of the Universe</option>
-				<option>Life, the Universe and Everything</option>
-				<option>So Long, and Thanks For All the Fish</option>
-				<option>Mostly Harmless</option>
-			</select>
-		</p>
-		<p>
-			<label for="selection_single">Star Wars episodes:</label><br />
-			<select id="selection_multiple" name="selection_multiple[]" multiple="multiple">
-				<option>Star Wars Episode IV: A New Hope</option>
-				<option>Star Wars Episode V: The Empire Strikes Back</option>
-				<option selected="selected">Star Wars Episode VI: Return of the Jedi</option>
-			</select>
-		</p>
-		<p>
-			<input type="checkbox" id="silmaril" value="silmaril" name="checkbox[]"/><label for="silmaril">The Silmarillion</label><br />
-			<input type="checkbox" id="hobbit" value="hobbit" name="checkbox[]" checked="checked"/><label for="hobbit">The Hobbit</label><br />
-			<input type="checkbox" id="lotr" value="lotr" name="checkbox[]"/><label for="lotr">The Lord of The Rings</label><br />
-		</p>
-		<p>
-			<input type="radio" id="martin" value="martin" name="radio" checked="checked"/><label for="martin">Goerge R.R. Martin</label><br />
-			<input type="radio" id="tolkien" value="tolkien" name="radio"/><label for="tolkien">J.R.R. Tolkien</label><br />
-			<input type="radio" id="adams" value="adams" name="radio"/><label for="adams">Douglas Adams</label><br />
-			<input type="radio" id="pratchett" value="pratchett" name="radio"/><label for="pratchett">Terry Pratchett</label><br />
-		</p>
-	</fieldset>
-</p>
-<p>
-	<fieldset>
-		<legend>Textarea</legend>
-		<p>
-		<label for="textarea">Multiline text:</label><br />
-		<textarea id="textarea" name="textarea" cols="50" rows="5">"In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move."
-		Douglas Adams</textarea>
-		</p>
-	</fieldset>
-</p>
-<p><input type="submit" value="Submit"/></p>
-</form>
\ No newline at end of file

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/autofill-forms.git



More information about the Pkg-mozext-commits mailing list