Bug 607295 - Provide UI for new archive granularity and folder structure options; r=bienvenu ui-r=bwinton
authorJim Porter <squibblyflabbetydoo@gmail.com>
Tue, 26 Apr 2011 02:00:07 -0500
changeset 7613 14758a3132354c9cc8b98a4f8a4754f770b33297
parent 7612 d938fa0debf7b083be0edf5a3a7285ec7ea9259b
child 7614 fa4ea41c266d2c16495ea82d7dcfc9bbfac45487
push idunknown
push userunknown
push dateunknown
reviewersbienvenu, bwinton
bugs607295
Bug 607295 - Provide UI for new archive granularity and folder structure options; r=bienvenu ui-r=bwinton
mail/locales/en-US/chrome/messenger/am-archiveoptions.dtd
mail/locales/en-US/chrome/messenger/am-copies.dtd
mail/locales/jar.mn
mail/test/mozmill/account/test-account-port-setting.js
mail/test/mozmill/account/test-archive-options.js
mail/test/mozmill/shared-modules/test-account-manager-helpers.js
mail/themes/gnomestripe/mail/accountManage.css
mail/themes/pinstripe/mail/accountManage.css
mail/themes/qute/mail/accountManage.css
mailnews/base/prefs/content/am-archiveoptions.js
mailnews/base/prefs/content/am-archiveoptions.xul
mailnews/base/prefs/content/am-copies.js
mailnews/base/prefs/content/am-copiesOverlay.xul
mailnews/base/prefs/content/am-identity-edit.js
mailnews/base/util/nsMsgIdentity.cpp
mailnews/jar.mn
suite/locales/en-US/chrome/mailnews/pref/am-archiveoptions.dtd
suite/locales/en-US/chrome/mailnews/pref/am-copies.dtd
suite/locales/jar.mn
new file mode 100644
--- /dev/null
+++ b/mail/locales/en-US/chrome/messenger/am-archiveoptions.dtd
@@ -0,0 +1,19 @@
+<!-- extracted from am-archiveoptions.xul -->
+
+<!ENTITY dialogTitle.label "Archive Options">
+<!ENTITY archiveGranularityPrefix.label "When archiving messages, place them in:">
+<!ENTITY archiveFlat.label "A single folder">
+<!ENTITY archiveFlat.accesskey "s">
+<!ENTITY archiveYearly.label "Yearly archived folders">
+<!ENTITY archiveYearly.accesskey "Y">
+<!ENTITY archiveMonthly.label "Monthly archived folders">
+<!ENTITY archiveMonthly.accesskey "M">
+<!ENTITY keepFolderStructure.label "Keep existing folder structure of archived messages">
+<!ENTITY keepFolderStructure.accesskey "K">
+<!ENTITY archiveExample.label "Example">
+<!-- LOCALIZATION NOTE (archiveFolderName.label): this should match the default
+     name for the "Archives" folder -->
+<!ENTITY archiveFolderName.label "Archives">
+<!-- LOCALIZATION NOTE (inboxFolderName.label): this should match the default
+     name for the "Inbox" folder -->
+<!ENTITY inboxFolderName.label "Inbox">
--- a/mail/locales/en-US/chrome/messenger/am-copies.dtd
+++ b/mail/locales/en-US/chrome/messenger/am-copies.dtd
@@ -16,27 +16,31 @@
 <!ENTITY bccAddressList.placeholder "Separate addresses with commas">
 <!ENTITY saveMessageDlg.label "Show confirmation dialog when messages are saved">
 <!ENTITY saveMessageDlg.accesskey "w">
 <!-- LOCALIZATION NOTE (sentFolderOn.label): OK to translate this, bug #57440 -->
 <!ENTITY sentFolderOn.label "&quot;Sent&quot; Folder on:">
 <!ENTITY sentFolderOn.accesskey "S">
 <!ENTITY sentInOtherFolder.label "Other:">
 <!ENTITY sentInOtherFolder.accesskey "O">
+<!-- LOCALIZATION NOTE (archivesFolderOn.label): OK to translate this, bug #57440 -->
+<!ENTITY archivesTitle.label "Message Archives">
+<!ENTITY keepArchives.label "Keep message archives in:">
+<!ENTITY keepArchives.accesskey "K">
+<!ENTITY archiveHierarchyButton.label "Archive options…">
+<!ENTITY archiveHierarchyButton.accesskey "A">
+<!ENTITY archivesFolderOn.label "&quot;Archives&quot; Folder on:">
+<!ENTITY archivesFolderOn.accesskey "n">
+<!ENTITY archiveInOtherFolder.label "Other:">
+<!ENTITY archiveInOtherFolder.accesskey "h">
+<!ENTITY specialFolders.label "Drafts and Templates">
+<!ENTITY keepDrafts.label "Keep message drafts in:">
 <!-- LOCALIZATION NOTE (draftsFolderOn.label): OK to translate this, bug #57440 -->
 <!ENTITY draftsFolderOn.label "&quot;Drafts&quot; Folder on:">
 <!ENTITY draftsFolderOn.accesskey "D">
 <!ENTITY draftInOtherFolder.label "Other:">
 <!ENTITY draftInOtherFolder.accesskey "t">
-<!-- LOCALIZATION NOTE (archivesFolderOn.label): OK to translate this, bug #57440 -->
-<!ENTITY archivesFolderOn.label "&quot;Archives&quot; Folder on:">
-<!ENTITY archivesFolderOn.accesskey "n">
-<!ENTITY archiveInOtherFolder.label "Other:">
-<!ENTITY archiveInOtherFolder.accesskey "h">
+<!ENTITY keepTemplates.label "Keep message templates in:">
 <!-- LOCALIZATION NOTE (templatesFolderOn.label): OK to translate this, bug #57440 -->
 <!ENTITY templatesFolderOn.label "&quot;Templates&quot; Folder on:">
 <!ENTITY templatesFolderOn.accesskey "m">
 <!ENTITY templateInOtherFolder.label "Other:">
 <!ENTITY templateInOtherFolder.accesskey "e">
-<!ENTITY specialFoldersTitle.label "Drafts, Archives, and Templates">
-<!ENTITY keepDrafts.label "Keep message drafts in:">
-<!ENTITY keepArchives.label "Keep message archives in:">
-<!ENTITY keepTempltes.label "Keep message templates in:">
--- a/mail/locales/jar.mn
+++ b/mail/locales/jar.mn
@@ -76,16 +76,17 @@
   locale/@AB_CD@/messenger/news.properties                              (%chrome/messenger/news.properties)
   locale/@AB_CD@/messenger/mime.properties                              (%chrome/messenger/mime.properties)
   locale/@AB_CD@/messenger/mimeheader.properties                        (%chrome/messenger/mimeheader.properties)
   locale/@AB_CD@/messenger/vcard.properties                             (%chrome/messenger/vcard.properties)
   locale/@AB_CD@/messenger/smime.properties                             (%chrome/messenger/smime.properties)
   locale/@AB_CD@/messenger/markByDate.dtd                               (%chrome/messenger/markByDate.dtd)
   locale/@AB_CD@/messenger/am-mdn.dtd                                   (%chrome/messenger/am-mdn.dtd)
   locale/@AB_CD@/messenger/am-mdn.properties                            (%chrome/messenger/am-mdn.properties)
+  locale/@AB_CD@/messenger/am-archiveoptions.dtd                        (%chrome/messenger/am-archiveoptions.dtd)
   locale/@AB_CD@/messenger/msgmdn.properties                            (%chrome/messenger/msgmdn.properties)
   locale/@AB_CD@/messenger/mailviews.properties                         (%chrome/messenger/mailviews.properties)
   locale/@AB_CD@/messenger/msgViewPickerOverlay.dtd                     (%chrome/messenger/msgViewPickerOverlay.dtd)
   locale/@AB_CD@/messenger/mailViewSetup.dtd                            (%chrome/messenger/mailViewSetup.dtd)
   locale/@AB_CD@/messenger/mailViewList.dtd                             (%chrome/messenger/mailViewList.dtd)
   locale/@AB_CD@/messenger/offlineStartup.properties                    (%chrome/messenger/offlineStartup.properties)
   locale/@AB_CD@/messenger/importMsgs.properties                        (%chrome/messenger/importMsgs.properties)
   locale/@AB_CD@/messenger/importDialog.dtd                             (%chrome/messenger/importDialog.dtd)
--- a/mail/test/mozmill/account/test-account-port-setting.js
+++ b/mail/test/mozmill/account/test-account-port-setting.js
@@ -55,55 +55,18 @@ const PORT_NUMBERS_TO_TEST =
     "110", // The original port number. We don't input this though.
     "456", // Random port number.
     "995", // The SSL port number.
     "110"  // Back to the original.
   ];
 
 var gTestNumber;
 
-/**
- * Click the specified tree cell
- *
- * @param {MozMillController} controller
- *        MozMillController of the browser window to operate on
- * @param {tree} tree
- *        Tree to operate on
- * @param {number } rowIndex
- *        Index of the row
- * @param {number} columnIndex
- *        Index of the column
- * @param {object} eventDetails
- *        Details about the mouse event
- */
-function clickTreeCell(controller, tree, rowIndex, columnIndex, eventDetails)
-{
-  var selection = tree.view.selection;
-  selection.select(rowIndex);
-  tree.treeBoxObject.ensureRowIsVisible(rowIndex);
-
-  // get cell coordinates
-  var x = {}, y = {}, width = {}, height = {};
-  var column = tree.columns[columnIndex];
-  tree.treeBoxObject.getCoordsForCellItem(rowIndex, column, "text",
-                                           x, y, width, height);
-
-  controller.sleep(0);
-  EventUtils.synthesizeMouse(tree.body, x.value + 4, y.value + 4,
-                             eventDetails, tree.ownerDocument.defaultView);
-  controller.sleep(0);
-}
-
 function subtest_check_set_port_number(amc, aDontSet) {
-  amc.waitForEval("subject.currentAccount != null", 6000, 600, amc.window);
-
-  clickTreeCell(amc, amc.window.document.getElementById("accounttree"),
-                1, 0, {});
-
-  amc.waitForEval("subject.pendingAccount == null", 6000, 600, amc.window);
+  click_account_tree_row(amc, 1);
 
   let iframe = amc.window.document.getElementById("contentFrame");
   let portElem = iframe.contentDocument.getElementById("server.port");
   portElem.focus();
 
   if (portElem.value != PORT_NUMBERS_TO_TEST[gTestNumber - 1])
     throw new Error("Port Value is not " +
                     PORT_NUMBERS_TO_TEST[gTestNumber - 1] +
new file mode 100644
--- /dev/null
+++ b/mail/test/mozmill/account/test-archive-options.js
@@ -0,0 +1,150 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Jim Porter <squibblyflabbetydoo@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+var MODULE_NAME = "test-archive-options";
+
+var RELATIVE_ROOT = "../shared-modules";
+var MODULE_REQUIRES = ["folder-display-helpers", "window-helpers",
+                       "account-manager-helpers"];
+
+var mozmill = {};
+Components.utils.import("resource://mozmill/modules/mozmill.js", mozmill);
+var controller = {};
+Components.utils.import("resource://mozmill/modules/controller.js", controller);
+var elib = {};
+Components.utils.import("resource://mozmill/modules/elementslib.js", elib);
+
+var defaultIdentity;
+
+function setupModule(module) {
+  let wh = collector.getModule("window-helpers");
+  wh.installInto(module);
+  let fdh = collector.getModule("folder-display-helpers");
+  fdh.installInto(module);
+  let amh = collector.getModule("account-manager-helpers");
+  amh.installInto(module);
+
+  let accountManager = Components.classes["@mozilla.org/messenger/account-manager;1"]
+                                 .getService(Components.interfaces.nsIMsgAccountManager);
+
+  defaultIdentity = accountManager.defaultAccount.defaultIdentity;
+}
+
+function subtest_initial_state(identity) {
+  plan_for_modal_dialog("archive-options", function(ac) {
+    assert_equals(ac.e("archiveGranularity").selectedIndex,
+                  identity.archiveGranularity);
+    assert_equals(ac.e("archiveKeepFolderStructure").checked,
+                  identity.archiveKeepFolderStructure);
+  });
+  mc.window.openDialog("chrome://messenger/content/am-archiveoptions.xul",
+                       "", "centerscreen,chrome,modal,titlebar,resizable=yes",
+                       identity);
+  wait_for_modal_dialog("archive-options");
+}
+
+function test_open_archive_options() {
+  let accountManager = Components.classes["@mozilla.org/messenger/account-manager;1"]
+                                 .getService(Components.interfaces.nsIMsgAccountManager);
+
+  for (let granularity = 0; granularity < 3; granularity++) {
+    defaultIdentity.archiveGranularity = granularity;
+    for (let kfs = 0; kfs < 2; kfs++) {
+      defaultIdentity.archiveKeepFolderStructure = kfs;
+      subtest_initial_state(defaultIdentity);
+    }
+  }
+}
+
+function subtest_save_state(identity, granularity, kfs) {
+  plan_for_modal_dialog("archive-options", function(ac) {
+    ac.e("archiveGranularity").selectedIndex = granularity;
+    ac.e("archiveKeepFolderStructure").checked = kfs;
+    ac.keypress(null, "VK_RETURN", {});
+  });
+  mc.window.openDialog("chrome://messenger/content/am-archiveoptions.xul",
+                       "", "centerscreen,chrome,modal,titlebar,resizable=yes",
+                       identity);
+  wait_for_modal_dialog("archive-options");
+}
+
+function test_save_archive_options() {
+  defaultIdentity.archiveGranularity = 0;
+  defaultIdentity.archiveKeepFolderStructure = false;
+  subtest_save_state(defaultIdentity, 1, true);
+
+  assert_equals(defaultIdentity.archiveGranularity, 1);
+  assert_equals(defaultIdentity.archiveKeepFolderStructure, true);
+}
+
+function subtest_check_archive_enabled(amc, archiveEnabled) {
+  defaultIdentity.archiveEnabled = archiveEnabled;
+
+  click_account_tree_row(amc, 2);
+
+  let iframe = amc.window.document.getElementById("contentFrame");
+  let checkbox = iframe.contentDocument.getElementById("identity.archiveEnabled");
+
+  assert_equals(checkbox.checked, archiveEnabled);
+}
+
+function test_archive_enabled() {
+  open_advanced_settings(function(amc) {
+    subtest_check_archive_enabled(amc, true);
+  });
+
+  open_advanced_settings(function(amc) {
+    subtest_check_archive_enabled(amc, false);
+  });
+}
+
+function subtest_disable_archive(amc) {
+  defaultIdentity.archiveEnabled = true;
+  click_account_tree_row(amc, 2);
+
+  let iframe = amc.window.document.getElementById("contentFrame");
+  let checkbox = iframe.contentDocument.getElementById("identity.archiveEnabled");
+
+  amc.click(new elib.Elem(checkbox));
+  amc.window.document.getElementById("accountManager").acceptDialog();
+
+  assert_equals(defaultIdentity.archiveEnabled, false);
+}
+
+function test_disable_archive() {
+  open_advanced_settings(subtest_disable_archive);
+}
--- a/mail/test/mozmill/shared-modules/test-account-manager-helpers.js
+++ b/mail/test/mozmill/shared-modules/test-account-manager-helpers.js
@@ -38,16 +38,18 @@
 var Ci = Components.interfaces;
 var Cc = Components.classes;
 var Cu = Components.utils;
 
 var elib = {};
 Cu.import('resource://mozmill/modules/elementslib.js', elib);
 var mozmill = {};
 Cu.import('resource://mozmill/modules/mozmill.js', mozmill);
+var EventUtils = {};
+Cu.import('resource://mozmill/stdlib/EventUtils.js', EventUtils);
 
 const MODULE_NAME = 'account-manager-helpers';
 const RELATIVE_ROOT = '../shared-modules';
 
 // we need this for the main controller
 const MODULE_REQUIRES = ['folder-display-helpers', 'window-helpers'];
 
 var wh, fdh, mc;
@@ -60,16 +62,17 @@ function setupModule() {
 
 function installInto(module) {
   setupModule();
 
   // Now copy helper functions
   module.open_advanced_settings = open_advanced_settings;
   module.open_advanced_settings_from_account_wizard =
     open_advanced_settings_from_account_wizard;
+  module.click_account_tree_row = click_account_tree_row;
 }
 
 /**
  * Opens the Account Manager.
  *
  * @param callback Callback for the modal dialog that is opened.
  */
 function open_advanced_settings(aCallback, aController) {
@@ -88,8 +91,37 @@ function open_advanced_settings(aCallbac
  */
 function open_advanced_settings_from_account_wizard(aCallback, aController) {
   wh.plan_for_modal_dialog("mailnews:accountmanager", aCallback);
   aController.e("manual-edit_button").click();
   aController.e("advanced-setup_button").click();
   return wh.wait_for_modal_dialog("mailnews:accountmanager");
 }
 
+/**
+ * Click a row in the account settings tree
+ *
+ * @param controller the Mozmill controller for the account settings dialog
+ * @param rowIndex the row to click
+ */
+function click_account_tree_row(controller, rowIndex) {
+  controller.waitForEval("subject.currentAccount != null", 6000, 600,
+                         controller.window);
+
+  var tree = controller.window.document.getElementById("accounttree");
+  var selection = tree.view.selection;
+  selection.select(rowIndex);
+  tree.treeBoxObject.ensureRowIsVisible(rowIndex);
+
+  // get cell coordinates
+  var x = {}, y = {}, width = {}, height = {};
+  var column = tree.columns[0];
+  tree.treeBoxObject.getCoordsForCellItem(rowIndex, column, "text",
+                                           x, y, width, height);
+
+  controller.sleep(0);
+  EventUtils.synthesizeMouse(tree.body, x.value + 4, y.value + 4,
+                             {}, tree.ownerDocument.defaultView);
+  controller.sleep(0);
+
+  controller.waitForEval("subject.pendingAccount == null", 6000, 600,
+                         controller.window);
+}
--- a/mail/themes/gnomestripe/mail/accountManage.css
+++ b/mail/themes/gnomestripe/mail/accountManage.css
@@ -83,8 +83,11 @@ treechildren::-moz-tree-cell-text(isDefa
   background-color: #FFFFFF;
   opacity: 0.5;
 }
 
 #smtpServerInfoBox textbox {
   background-color: transparent;
 }
 
+#archiveTree > treechildren {
+  background-color: -moz-Field;
+}
--- a/mail/themes/pinstripe/mail/accountManage.css
+++ b/mail/themes/pinstripe/mail/accountManage.css
@@ -75,8 +75,12 @@
 
 button:not(.spinbuttons-button):not(.dialog-button) {
   min-height: 19px; /* aqua size for small buttons */
 }
 
 page > description {
      margin: 4px 4px 8px;
 }
+
+#archiveTree > treechildren {
+  background-color: #FFFFFF;
+}
--- a/mail/themes/qute/mail/accountManage.css
+++ b/mail/themes/qute/mail/accountManage.css
@@ -83,8 +83,11 @@ treechildren::-moz-tree-cell-text(isDefa
   background-color: #FFFFFF;
   opacity: 0.5;
 }
 
 #smtpServerInfoBox textbox {
   background-color: transparent;
 }
 
+#archiveTree > treechildren {
+  background-color: -moz-Field;
+}
new file mode 100644
--- /dev/null
+++ b/mailnews/base/prefs/content/am-archiveoptions.js
@@ -0,0 +1,102 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Mail Code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Jim Porter <squibblyflabbetydoo@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+var gIdentity = null;
+
+/**
+ * Load the archive options dialog, set the radio/checkbox items to the
+ * appropriate values, and update the archive hierarchy example.
+ */
+function onLoadArchiveOptions() {
+  // extract the account
+  gIdentity = window.arguments[0];
+
+  let granularity = document.getElementById("archiveGranularity");
+  granularity.selectedIndex = gIdentity.archiveGranularity;
+  granularity.addEventListener("command", updateArchiveExample, false);
+
+  let kfs = document.getElementById("archiveKeepFolderStructure");
+  kfs.checked = gIdentity.archiveKeepFolderStructure;
+  kfs.addEventListener("command", updateArchiveExample, false);
+
+  updateArchiveExample();
+}
+
+/**
+ * Save the archive settings to the current identity.
+ */
+function onAcceptArchiveOptions() {
+  gIdentity.archiveGranularity =
+    document.getElementById("archiveGranularity").selectedIndex;
+  gIdentity.archiveKeepFolderStructure =
+    document.getElementById("archiveKeepFolderStructure").checked;
+}
+
+/**
+ * Update the example tree to show what the current options would look like.
+ */
+function updateArchiveExample() {
+  let granularity = document.getElementById("archiveGranularity").selectedIndex;
+  let kfs = document.getElementById("archiveKeepFolderStructure").checked;
+  let hierarchy = [ document.getElementsByClassName("root"),
+                    document.getElementsByClassName("year"),
+                    document.getElementsByClassName("month") ];
+
+  // First, show/hide the appropriate levels in the hierarchy and turn the
+  // necessary items into containers.
+  for (let i = 0; i < hierarchy.length; i++) {
+    for (let j = 0; j < hierarchy[i].length; j++) {
+      hierarchy[i][j].setAttribute("container", granularity > i);
+      hierarchy[i][j].setAttribute("open", granularity > i);
+      hierarchy[i][j].hidden = granularity < i;
+    }
+  }
+
+  // Next, handle the "keep folder structures" case by moving a tree item around
+  // and making sure its parent is a container.
+  let folders = document.getElementById("folders");
+  folders.hidden = !kfs;
+  if (kfs) {
+    let parent = hierarchy[granularity][0];
+    parent.setAttribute("container", true);
+    parent.setAttribute("open", true);
+
+    let treechildren = parent.children[1];
+    treechildren.appendChild(folders);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/mailnews/base/prefs/content/am-archiveoptions.xul
@@ -0,0 +1,132 @@
+<?xml version="1.0"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+   - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+   -
+   - The contents of this file are subject to the Mozilla Public License Version
+   - 1.1 (the "License"); you may not use this file except in compliance with
+   - the License. You may obtain a copy of the License at
+   - http://www.mozilla.org/MPL/
+   -
+   - Software distributed under the License is distributed on an "AS IS" basis,
+   - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+   - for the specific language governing rights and limitations under the
+   - License.
+   -
+   - The Original Code is Mozilla Communicator client code.
+   -
+   - The Initial Developer of the Original Code is
+   - The Mozilla Foundation.
+   - Portions created by the Initial Developer are Copyright (C) 2011
+   - the Initial Developer. All Rights Reserved.
+   -
+   - Contributor(s):
+   -   Jim Porter <squibblyflabbetydoo@gmail.com>
+   -
+   - Alternatively, the contents of this file may be used under the terms of
+   - either the GNU General Public License Version 2 or later (the "GPL"), or
+   - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+   - in which case the provisions of the GPL or the LGPL are applicable instead
+   - of those above. If you wish to allow use of your version of this file only
+   - under the terms of either the GPL or the LGPL, and not to allow others to
+   - use your version of this file under the terms of the MPL, indicate your
+   - decision by deleting the provisions above and replace them with the notice
+   - and other provisions required by the LGPL or the GPL. If you do not delete
+   - the provisions above, a recipient may use your version of this file under
+   - the terms of any one of the MPL, the GPL or the LGPL.
+   -
+   - ***** END LICENSE BLOCK ***** -->
+
+<?xml-stylesheet href="chrome://messenger/skin/accountManage.css" type="text/css"?>
+<?xml-stylesheet href="chrome://messenger/skin/messenger.css" type="text/css"?>
+<?xml-stylesheet href="chrome://messenger/skin/folderPane.css" type="text/css"?>
+
+<!DOCTYPE dialog SYSTEM "chrome://messenger/locale/am-archiveoptions.dtd" >
+
+<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        id="archive-options"
+        title="&dialogTitle.label;"
+        width="350" height="350"
+        persist="width height"
+        onload="onLoadArchiveOptions();"
+        ondialogaccept="onAcceptArchiveOptions();">
+
+  <script type="application/javascript" src="chrome://messenger/content/am-archiveoptions.js"/>
+
+  <vbox flex="1">
+    <label>&archiveGranularityPrefix.label;</label>
+    <radiogroup id="archiveGranularity">
+      <radio label="&archiveFlat.label;" accesskey="&archiveFlat.accesskey;"
+             class="indent"/>
+      <radio label="&archiveYearly.label;"
+             accesskey="&archiveYearly.accesskey;" class="indent"/>
+      <radio label="&archiveMonthly.label;"
+             accesskey="&archiveMonthly.accesskey;" class="indent"/>
+    </radiogroup>
+    <checkbox id="archiveKeepFolderStructure"
+              label="&keepFolderStructure.label;"
+              accesskey="&keepFolderStructure.accesskey;"/>
+
+    <groupbox flex="1">
+      <caption label="&archiveExample.label;"/>
+      <tree id="archiveTree" hidecolumnpicker="true" disabled="true" flex="1">
+        <treecols>
+          <treecol primary="true" hideheader="true" flex="1"
+                   id="folderNameCol"/>
+        </treecols>
+        <treechildren>
+          <treeitem class="root">
+            <treerow>
+              <treecell properties="specialFolder-Archive"
+                        label="&archiveFolderName.label;"/>
+            </treerow>
+            <treechildren>
+              <treeitem id="folders">
+                <treerow>
+                  <treecell label="&inboxFolderName.label;"/>
+                </treerow>
+              </treeitem>
+              <treeitem class="year">
+                <treerow>
+                  <treecell label="2010"/>
+                </treerow>
+                <treechildren>
+                  <treeitem class="month">
+                    <treerow>
+                      <treecell label="2010-11"/>
+                    </treerow>
+                    <treechildren/>
+                  </treeitem>
+                  <treeitem class="month">
+                    <treerow>
+                      <treecell label="2010-12"/>
+                    </treerow>
+                    <treechildren/>
+                  </treeitem>
+                </treechildren>
+              </treeitem>
+              <treeitem class="year">
+                <treerow>
+                  <treecell label="2011"/>
+                </treerow>
+                <treechildren>
+                  <treeitem class="month">
+                    <treerow>
+                      <treecell label="2011-01"/>
+                    </treerow>
+                    <treechildren/>
+                  </treeitem>
+                  <treeitem class="month">
+                    <treerow>
+                      <treecell label="2011-02"/>
+                    </treerow>
+                    <treechildren/>
+                  </treeitem>
+                </treechildren>
+              </treeitem>
+            </treechildren>
+          </treeitem>
+        </treechildren>
+      </tree>
+    </groupbox>
+  </vbox>
+</dialog>
--- a/mailnews/base/prefs/content/am-copies.js
+++ b/mailnews/base/prefs/content/am-copies.js
@@ -1,9 +1,9 @@
-/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
  *
@@ -86,16 +86,17 @@ function onInitCopiesAndFolders()
                      "tmpl",
                      "msgStationeryAccountPicker",
                      "identity.stationeryFolder",
                      "msgStationeryFolderPicker");
 
     setupCcTextbox();
     setupBccTextbox();
     setupFccItems();
+    setupArchiveItems();
 
     SetSpecialFolderNamesWithDelims();
 }
 
 // Initialize the picker mode choices (account/folder picker) into global vars
 function SetGlobalRadioElemChoices()
 {
     var pickerModeElement = document.getElementById("identity.fccFolderPickerMode");
@@ -433,8 +434,51 @@ function setPickersState(enablePickerId,
 
 // This routine is to restore the correct radio element 
 // state when the fcc self checkbox broadcasts the change
 function SetRadioButtons(selectPickerId, unselectPickerId)
 {
     var activeRadioElem = document.getElementById(selectPickerId);
     activeRadioElem.radioGroup.selectedItem = activeRadioElem;
 }
+
+/**
+ * Enable or disable (as appropriate) the controls for setting archive options
+ */
+function setupArchiveItems() {
+  var broadcaster = document.getElementById("broadcaster_archiveEnabled");
+
+  var checked = document.getElementById("identity.archiveEnabled").checked;
+  if (checked) {
+    broadcaster.removeAttribute("disabled");
+    switch (gArchivesRadioElemChoice) {
+      case "0":
+        if (!gArchivesRadioElemChoiceLocked)
+          SetPickerEnabling("msgArchivesAccountPicker", "msgArchivesFolderPicker");
+        SetRadioButtons("archive_selectAccount", "archive_selectFolder");
+        break;
+
+      case "1":
+        if (!gArchivesRadioElemChoiceLocked)
+          SetPickerEnabling("msgArchivesFolderPicker", "msgArchivesAccountPicker");
+        SetRadioButtons("archive_selectFolder", "archive_selectAccount");
+        break;
+
+      default:
+        dump("Error in setting Archive elements.\n");
+        break;
+    }
+  }
+  else
+    broadcaster.setAttribute("disabled", "true");
+}
+
+/**
+ * Open a dialog to edit the folder hierarchy used when archiving messages.
+ */
+function ChangeArchiveHierarchy() {
+  let identity = parent.gIdentity || parent.getCurrentAccount().defaultIdentity;
+
+  top.window.openDialog("chrome://messenger/content/am-archiveoptions.xul",
+                        "", "centerscreen,chrome,modal,titlebar,resizable=yes",
+                        identity);
+  return true;
+}
--- a/mailnews/base/prefs/content/am-copiesOverlay.xul
+++ b/mailnews/base/prefs/content/am-copiesOverlay.xul
@@ -42,28 +42,29 @@
 <?xml-stylesheet href="chrome://messenger/skin/folderMenus.css" type="text/css"?>
 
 <!DOCTYPE overlay [
 <!ENTITY % copiesDTD SYSTEM "chrome://messenger/locale/am-copies.dtd">%copiesDTD;
 <!ENTITY % pickerDTD SYSTEM "chrome://messenger/locale/msgFolderPickerOverlay.dtd"> %pickerDTD;
 ]>
 
 <overlay xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">                                                       
+         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <script type="application/javascript" src="chrome://messenger/content/widgetglue.js"/>
   <script type="application/javascript" src="chrome://messenger/content/am-copies.js"/>
 
-  <vbox flex="1" id="copiesAndFolders">  
-    <!-- stringbundle is used by msgFolderPickerOverlay.js-->     
+  <vbox flex="1" id="copiesAndFolders">
+    <!-- stringbundle is used by msgFolderPickerOverlay.js-->
     <stringbundleset id="stringbundleset">
     <stringbundle id="bundle_messenger" src="chrome://messenger/locale/messenger.properties"/>
-    </stringbundleset>   
-      
+    </stringbundleset>
+
     <broadcaster id="broadcaster_doFcc"/>
+    <broadcaster id="broadcaster_archiveEnabled"/>
 
     <label hidden="true" wsm_persist="true" id="identity.fccFolder"
                   pref="true" preftype="string" prefattribute="value"
                   prefstring="mail.identity.%identitykey%.fcc_folder"/>
     <label hidden="true" wsm_persist="true" id="identity.draftFolder"
                   pref="true" preftype="string" prefattribute="value"
                   prefstring="mail.identity.%identitykey%.draft_folder"/>
     <label hidden="true" wsm_persist="true" id="identity.archiveFolder"
@@ -79,56 +80,56 @@
     <label hidden="true" wsm_persist="true" id="identity.draftsFolderPickerMode"
                   pref="true" preftype="int" prefattribute="value"
                   prefstring="mail.identity.%identitykey%.drafts_folder_picker_mode"/>
     <label hidden="true" wsm_persist="true" id="identity.archivesFolderPickerMode"
                   pref="true" preftype="int" prefattribute="value"
                   prefstring="mail.identity.%identitykey%.archives_folder_picker_mode"/>
     <label hidden="true" wsm_persist="true" id="identity.tmplFolderPickerMode"
                   pref="true" preftype="int" prefattribute="value"
-                  prefstring="mail.identity.%identitykey%.tmpl_folder_picker_mode"/> 
+                  prefstring="mail.identity.%identitykey%.tmpl_folder_picker_mode"/>
     <groupbox>
       <caption label="&sendingPrefix.label;"/>
 
       <hbox align="center">
-        <checkbox wsm_persist="true" id="identity.doFcc" label="&fccMailFolder.label;" 
+        <checkbox wsm_persist="true" id="identity.doFcc" label="&fccMailFolder.label;"
                   accesskey="&fccMailFolder.accesskey;"
                   prefattribute="value"
                   prefstring="mail.identity.%identitykey%.fcc"
                   oncommand="setupFccItems();"/>
       </hbox>
         <radiogroup id="doFcc" aria-labelledby="identity.doFcc">
         <grid class="specialFolderPickerGrid">
           <columns>
             <column/>
             <column flex="1"/>
           </columns>
           <rows>
             <row align="center">
-              <radio id="fcc_selectAccount" 
+              <radio id="fcc_selectAccount"
                      value="0" label="&sentFolderOn.label;"
                      accesskey="&sentFolderOn.accesskey;"
-                     oncommand="setPickersState('msgFccAccountPicker', 'msgFccFolderPicker', event)" 
+                     oncommand="setPickersState('msgFccAccountPicker', 'msgFccFolderPicker', event)"
                      observes="broadcaster_doFcc"/>
                 <menulist id="msgFccAccountPicker"
                           aria-labelledby="fcc_selectAccount"
                           observes="broadcaster_doFcc">
                   <menupopup id="msgFccAccountPopup" type="folder" mode="filing"
                              expandFolders="false"/>
                 </menulist>
-            </row> 
+            </row>
             <row align="center">
-              <radio id="fcc_selectFolder" 
+              <radio id="fcc_selectFolder"
                      value="1" label="&sentInOtherFolder.label;"
                      accesskey="&sentInOtherFolder.accesskey;"
-                     oncommand="setPickersState('msgFccFolderPicker', 'msgFccAccountPicker', event)" 
+                     oncommand="setPickersState('msgFccFolderPicker', 'msgFccAccountPicker', event)"
                      observes="broadcaster_doFcc"/>
-                <menulist id="msgFccFolderPicker" 
+                <menulist id="msgFccFolderPicker"
                           aria-labelledby="fcc_selectFolder"
-                          oncommand="noteSelectionChange('fcc_selectFolder', event)" 
+                          oncommand="noteSelectionChange('fcc_selectFolder', event)"
                           observes="broadcaster_doFcc">
                   <menupopup id="msgFccFolderPopup" type="folder" mode="filing"
                              class="menulist-menupopup"
                              showFileHereLabel="true"
                              fileHereLabel="&filemessageschoosethis.label;"/>
                 </menulist>
             </row>
           </rows>
@@ -163,55 +164,114 @@
                   prefstring="mail.identity.%identitykey%.doCcList" class="uri-element"
                   placeholder="&ccAddressList.placeholder;"/>
           </row>
           <row align="center">
             <checkbox wsm_persist="true" id="identity.doBcc" label="&bccAddress.label;"
                   accesskey="&bccAddress.accesskey;"
                   control="identity.doBccList"
                   oncommand="setupBccTextbox();"
-                  prefattribute="value" 
+                  prefattribute="value"
                   prefstring="mail.identity.%identitykey%.doBcc"/>
             <textbox wsm_persist="true" id="identity.doBccList" flex="1"
                   aria-labelledby="identity.doBcc"
                   prefstring="mail.identity.%identitykey%.doBccList" class="uri-element"
                   placeholder="&bccAddressList.placeholder;"/>
           </row>
         </rows>
       </grid>
 
     </groupbox>
 
     <groupbox>
-      <caption label="&specialFoldersTitle.label;"/>
+      <caption label="&archivesTitle.label;"/>
+
+      <hbox align="center">
+        <checkbox wsm_persist="true" id="identity.archiveEnabled"
+                  label="&keepArchives.label;"
+                  accesskey="&fccMailFolder.accesskey;"
+                  prefattribute="value"
+                  prefstring="mail.identity.%identitykey%.archive_enabled"
+                  oncommand="setupArchiveItems();"/>
+        <spacer flex="1"/>
+        <button id="archiveHierarchyButton"
+                label="&archiveHierarchyButton.label;"
+                accesskey="&archiveHierarchyButton.accesskey;"
+                oncommand="ChangeArchiveHierarchy();"
+                observes="broadcaster_archiveEnabled"/>
+      </hbox>
+
+      <radiogroup id="messageArchives">
+        <grid class="specialFolderPickerGrid">
+          <columns>
+            <column/>
+            <column flex="1"/>
+          </columns>
+          <rows>
+            <row align="center">
+              <radio id="archive_selectAccount"
+                     value="0" label="&archivesFolderOn.label;"
+                     accesskey="&archivesFolderOn.accesskey;"
+                     oncommand="setPickersState('msgArchivesAccountPicker', 'msgArchivesFolderPicker', event)"
+                     observes="broadcaster_archiveEnabled"/>
+                <menulist id="msgArchivesAccountPicker"
+	                      aria-labelledby="archive_selectAccount"
+                          observes="broadcaster_archiveEnabled">
+                <menupopup id="msgArchivesAccountPopup" type="folder" mode="filing"
+                           expandFolders="false"/>
+              </menulist>
+            </row>
+            <row align="center">
+              <radio id="archive_selectFolder"
+                     value="1" label="&archiveInOtherFolder.label;"
+                     accesskey="&archiveInOtherFolder.accesskey;"
+                     oncommand="setPickersState('msgArchivesFolderPicker', 'msgArchivesAccountPicker', event)"
+                     observes="broadcaster_archiveEnabled"/>
+                <menulist id="msgArchivesFolderPicker"
+                          aria-labelledby="archive_selectFolder"
+                          oncommand="noteSelectionChange('archive_selectFolder', event)"
+                          observes="broadcaster_archiveEnabled">
+                <menupopup id="msgArchivesFolderPopup" type="folder" mode="filing"
+                           class="menulist-menupopup"
+                           showFileHereLabel="true"
+                           fileHereLabel="&filemessageschoosethis.label;"/>
+              </menulist>
+            </row>
+          </rows>
+        </grid>
+      </radiogroup>
+    </groupbox>
+
+    <groupbox>
+      <caption label="&specialFolders.label;"/>
 
       <hbox align="center">
         <label value="&keepDrafts.label;" control="messageDrafts"/>
       </hbox>
-    
+
       <radiogroup id="messageDrafts">
         <grid class="specialFolderPickerGrid">
           <columns>
             <column/>
             <column flex="1"/>
           </columns>
           <rows>
             <row align="center">
-              <radio id="draft_selectAccount" 
+              <radio id="draft_selectAccount"
                      oncommand="setPickersState('msgDraftsAccountPicker', 'msgDraftsFolderPicker', event)"
                      value="0" label="&draftsFolderOn.label;"
                      accesskey="&draftsFolderOn.accesskey;"/>
- 	      <menulist id="msgDraftsAccountPicker" 
+ 	      <menulist id="msgDraftsAccountPicker"
 	                aria-labelledby="draft_selectAccount">
                 <menupopup id="msgDraftAccountPopup" type="folder" mode="filing"
                            expandFolders="false"/>
               </menulist>
-            </row> 
+            </row>
             <row align="center">
-              <radio id="draft_selectFolder" 
+              <radio id="draft_selectFolder"
                      oncommand="setPickersState('msgDraftsFolderPicker', 'msgDraftsAccountPicker', event)"
                      value="1" label="&draftInOtherFolder.label;"
                      accesskey="&draftInOtherFolder.accesskey;"/>
   	      <menulist id="msgDraftsFolderPicker"
                         aria-labelledby="draft_selectFolder"
                         oncommand="noteSelectionChange('draft_selectFolder', event)">
                 <menupopup id="msgDraftFolderPopup" type="folder" mode="filing"
                            class="menulist-menupopup"
@@ -219,79 +279,39 @@
                            fileHereLabel="&filemessageschoosethis.label;"/>
               </menulist>
             </row>
           </rows>
         </grid>
       </radiogroup>
 
       <hbox align="center">
-        <label value="&keepArchives.label;" control="messageArchives"/>
+        <label value="&keepTemplates.label;" control="messageTemplates"/>
       </hbox>
-    
-      <radiogroup id="messageArchives">
-        <grid class="specialFolderPickerGrid">
-          <columns>
-            <column/>
-            <column flex="1"/>
-          </columns>
-          <rows>
-            <row align="center">
-              <radio id="archive_selectAccount"
-                     oncommand="setPickersState('msgArchivesAccountPicker', 'msgArchivesFolderPicker', event)"
-                     value="0" label="&archivesFolderOn.label;"
-                     accesskey="&archivesFolderOn.accesskey;"/>
-                <menulist id="msgArchivesAccountPicker"
-	                aria-labelledby="archive_selectAccount">
-                <menupopup id="msgArchivesAccountPopup" type="folder" mode="filing"
-                           expandFolders="false"/>
-              </menulist>
-            </row>
-            <row align="center">
-              <radio id="archive_selectFolder"
-                     oncommand="setPickersState('msgArchivesFolderPicker', 'msgArchivesAccountPicker', event)"
-                     value="1" label="&archiveInOtherFolder.label;"
-                     accesskey="&archiveInOtherFolder.accesskey;"/>
-                <menulist id="msgArchivesFolderPicker"
-                        aria-labelledby="archive_selectFolder"
-                        oncommand="noteSelectionChange('archive_selectFolder', event)">
-                <menupopup id="msgArchivesFolderPopup" type="folder" mode="filing"
-                           class="menulist-menupopup"
-                           showFileHereLabel="true"
-                           fileHereLabel="&filemessageschoosethis.label;"/>
-              </menulist>
-            </row>
-          </rows>
-        </grid>
-      </radiogroup>
-      
-      <hbox align="center">
-        <label value="&keepTempltes.label;" control="messageTemplates"/>
-      </hbox>
-	  
+
       <radiogroup id="messageTemplates">
         <grid class="specialFolderPickerGrid">
           <columns>
             <column/>
             <column flex="1"/>
           </columns>
           <rows>
             <row align="center">
-              <radio id="tmpl_selectAccount" 
+              <radio id="tmpl_selectAccount"
                      oncommand="setPickersState('msgStationeryAccountPicker', 'msgStationeryFolderPicker', event)"
                      value="0" label="&templatesFolderOn.label;"
                      accesskey="&templatesFolderOn.accesskey;"/>
   	      <menulist id="msgStationeryAccountPicker"
                         aria-labelledby="tmpl_selectAccount">
                 <menupopup id="msgFccAccountPopup" type="folder" mode="filing"
                            expandFolders="false"/>
               </menulist>
-            </row> 
+            </row>
             <row align="center">
-              <radio id="tmpl_selectFolder" 
+              <radio id="tmpl_selectFolder"
                      oncommand="setPickersState('msgStationeryFolderPicker', 'msgStationeryAccountPicker', event)"
                      value="1" label="&templateInOtherFolder.label;"
                      accesskey="&templateInOtherFolder.accesskey;"/>
               <menulist id="msgStationeryFolderPicker"
                         aria-labelledby="tmpl_selectFolder"
                         oncommand="noteSelectionChange('tmpl_selectFolder', event)">
                 <menupopup id="msgTemplFolderPopup" type="folder" mode="filing"
                            class="menulist-menupopup"
--- a/mailnews/base/prefs/content/am-identity-edit.js
+++ b/mailnews/base/prefs/content/am-identity-edit.js
@@ -103,16 +103,18 @@ function initCopiesAndFolder(identity)
 
   document.getElementById('identity.doCc').checked = copiesAndFoldersIdentity.doCc;
   document.getElementById('identity.doCcList').value = copiesAndFoldersIdentity.doCcList;
   document.getElementById('identity.doBcc').checked = copiesAndFoldersIdentity.doBcc;
   document.getElementById('identity.doBccList').value = copiesAndFoldersIdentity.doBccList;
   document.getElementById('identity.doFcc').checked = copiesAndFoldersIdentity.doFcc;
   document.getElementById('identity.fccReplyFollowsParent').checked = copiesAndFoldersIdentity.fccReplyFollowsParent;
   document.getElementById('identity.showSaveMsgDlg').checked = copiesAndFoldersIdentity.showSaveMsgDlg;
+  document.getElementById('identity.archiveEnabled').checked = copiesAndFoldersIdentity.archiveEnabled;
+
   onInitCopiesAndFolders(); // am-copies.js method
 }
 
 function initCompositionAndAddressing(identity)
 {
   // if we are editing an existing identity, use it...otherwise copy our values from the default identity
   var addressingIdentity = identity ? identity : gAccount.defaultIdentity;
 
--- a/mailnews/base/util/nsMsgIdentity.cpp
+++ b/mailnews/base/util/nsMsgIdentity.cpp
@@ -567,16 +567,21 @@ nsMsgIdentity::Copy(nsIMsgIdentity *iden
     COPY_IDENTITY_WSTR_VALUE(identity,GetFullName,SetFullName)
     COPY_IDENTITY_WSTR_VALUE(identity,GetOrganization,SetOrganization)
     COPY_IDENTITY_STR_VALUE(identity,GetDraftFolder,SetDraftFolder)
     COPY_IDENTITY_STR_VALUE(identity,GetArchiveFolder,SetArchiveFolder)
     COPY_IDENTITY_STR_VALUE(identity,GetFccFolder,SetFccFolder)
     COPY_IDENTITY_BOOL_VALUE(identity,GetFccReplyFollowsParent,
                              SetFccReplyFollowsParent)
     COPY_IDENTITY_STR_VALUE(identity,GetStationeryFolder,SetStationeryFolder)
+    COPY_IDENTITY_BOOL_VALUE(identity,GetArchiveEnabled,SetArchiveEnabled)
+    COPY_IDENTITY_INT_VALUE(identity,GetArchiveGranularity,
+                            SetArchiveGranularity)
+    COPY_IDENTITY_BOOL_VALUE(identity,GetArchiveKeepFolderStructure,
+                             SetArchiveKeepFolderStructure)
     COPY_IDENTITY_BOOL_VALUE(identity,GetAttachSignature,SetAttachSignature)
     COPY_IDENTITY_FILE_VALUE(identity,GetSignature,SetSignature)
     COPY_IDENTITY_WSTR_VALUE(identity,GetHtmlSigText,SetHtmlSigText)
     COPY_IDENTITY_BOOL_VALUE(identity,GetHtmlSigFormat,SetHtmlSigFormat)
     COPY_IDENTITY_BOOL_VALUE(identity,GetAutoQuote,SetAutoQuote)
     COPY_IDENTITY_INT_VALUE(identity,GetReplyOnTop,SetReplyOnTop)
     COPY_IDENTITY_BOOL_VALUE(identity,GetSigBottom,SetSigBottom)
     COPY_IDENTITY_BOOL_VALUE(identity,GetSigOnForward,SetSigOnForward)
--- a/mailnews/jar.mn
+++ b/mailnews/jar.mn
@@ -38,16 +38,18 @@ messenger.jar:
     content/messenger/am-smtp.xul                                              (base/prefs/content/am-smtp.xul)
     content/messenger/am-smtp.js                                               (base/prefs/content/am-smtp.js)
     content/messenger/am-prefs.js                                              (base/prefs/content/am-prefs.js)
     content/messenger/am-identities-list.js                                    (base/prefs/content/am-identities-list.js)
     content/messenger/am-identities-list.xul                                   (base/prefs/content/am-identities-list.xul)
 *   content/messenger/am-identity-edit.js                                      (base/prefs/content/am-identity-edit.js)
     content/messenger/am-identity-edit.xul                                     (base/prefs/content/am-identity-edit.xul)
     content/messenger/am-copiesOverlay.xul                                     (base/prefs/content/am-copiesOverlay.xul)
+    content/messenger/am-archiveoptions.xul                                    (base/prefs/content/am-archiveoptions.xul)
+    content/messenger/am-archiveoptions.js                                     (base/prefs/content/am-archiveoptions.js)
 *   content/messenger/AccountWizard.xul                                        (base/prefs/content/AccountWizard.xul)
     content/messenger/AccountWizard.js                                         (base/prefs/content/AccountWizard.js)
     content/messenger/aw-accounttype.js                                        (base/prefs/content/aw-accounttype.js)
     content/messenger/aw-identity.js                                           (base/prefs/content/aw-identity.js)
     content/messenger/aw-server.js                                             (base/prefs/content/aw-server.js)
     content/messenger/aw-login.js                                              (base/prefs/content/aw-login.js)
     content/messenger/aw-accname.js                                            (base/prefs/content/aw-accname.js)
     content/messenger/aw-done.js                                               (base/prefs/content/aw-done.js)
new file mode 100644
--- /dev/null
+++ b/suite/locales/en-US/chrome/mailnews/pref/am-archiveoptions.dtd
@@ -0,0 +1,19 @@
+<!-- extracted from am-archiveoptions.xul -->
+
+<!ENTITY dialogTitle.label "Archive Options">
+<!ENTITY archiveGranularityPrefix.label "When archiving messages, place them in:">
+<!ENTITY archiveFlat.label "A single folder">
+<!ENTITY archiveFlat.accesskey "s">
+<!ENTITY archiveYearly.label "Yearly archived folders">
+<!ENTITY archiveYearly.accesskey "Y">
+<!ENTITY archiveMonthly.label "Monthly archived folders">
+<!ENTITY archiveMonthly.accesskey "M">
+<!ENTITY keepFolderStructure.label "Keep existing folder structure of archived messages">
+<!ENTITY keepFolderStructure.accesskey "K">
+<!ENTITY archiveExample.label "Example">
+<!-- LOCALIZATION NOTE (archiveFolderName.label): this should match the default
+     name for the "Archives" folder -->
+<!ENTITY archiveFolderName.label "Archives">
+<!-- LOCALIZATION NOTE (inboxFolderName.label): this should match the default
+     name for the "Inbox" folder -->
+<!ENTITY inboxFolderName.label "Inbox">
--- a/suite/locales/en-US/chrome/mailnews/pref/am-copies.dtd
+++ b/suite/locales/en-US/chrome/mailnews/pref/am-copies.dtd
@@ -14,29 +14,33 @@
 <!ENTITY bccAddress.label "Bcc these email addresses:">
 <!ENTITY bccAddress.accesskey "B">
 <!ENTITY bccAddressList.placeholder "Separate addresses with commas">
 <!ENTITY saveMessageDlg.label "Show confirmation dialog when messages are saved">
 <!ENTITY saveMessageDlg.accesskey "w">
 <!-- LOCALIZATION NOTE (sentFolderOn.label): OK to translate this, bug #57440 -->
 <!ENTITY sentFolderOn.label "&quot;Sent&quot; Folder on:">
 <!ENTITY sentFolderOn.accesskey "S">
-<!ENTITY sentInOtherFolder.label "Other Folder:">
+<!ENTITY sentInOtherFolder.label "Other:">
 <!ENTITY sentInOtherFolder.accesskey "O">
+<!-- LOCALIZATION NOTE (archivesFolderOn.label): OK to translate this, bug #57440 -->
+<!ENTITY archivesTitle.label "Message Archives">
+<!ENTITY keepArchives.label "Keep message archives in:">
+<!ENTITY keepArchives.accesskey "K">
+<!ENTITY archiveHierarchyButton.label "Archive options…">
+<!ENTITY archiveHierarchyButton.accesskey "A">
+<!ENTITY archivesFolderOn.label "&quot;Archives&quot; Folder on:">
+<!ENTITY archivesFolderOn.accesskey "n">
+<!ENTITY archiveInOtherFolder.label "Other:">
+<!ENTITY archiveInOtherFolder.accesskey "h">
+<!ENTITY specialFolders.label "Drafts and Templates">
+<!ENTITY keepDrafts.label "Keep message drafts in:">
 <!-- LOCALIZATION NOTE (draftsFolderOn.label): OK to translate this, bug #57440 -->
 <!ENTITY draftsFolderOn.label "&quot;Drafts&quot; Folder on:">
-<!ENTITY draftsFolderOn.accesskey "n">
-<!ENTITY draftInOtherFolder.label "Other Folder:">
+<!ENTITY draftsFolderOn.accesskey "D">
+<!ENTITY draftInOtherFolder.label "Other:">
 <!ENTITY draftInOtherFolder.accesskey "t">
-<!-- LOCALIZATION NOTE (archivesFolderOn.label): OK to translate this, bug #57440 -->
-<!ENTITY archivesFolderOn.label "&quot;Archives&quot; Folder on:">
-<!ENTITY archivesFolderOn.accesskey "v">
-<!ENTITY archiveInOtherFolder.label "Other Folder:">
-<!ENTITY archiveInOtherFolder.accesskey "d">
+<!ENTITY keepTemplates.label "Keep message templates in:">
 <!-- LOCALIZATION NOTE (templatesFolderOn.label): OK to translate this, bug #57440 -->
 <!ENTITY templatesFolderOn.label "&quot;Templates&quot; Folder on:">
 <!ENTITY templatesFolderOn.accesskey "m">
-<!ENTITY templateInOtherFolder.label "Other Folder:">
+<!ENTITY templateInOtherFolder.label "Other:">
 <!ENTITY templateInOtherFolder.accesskey "e">
-<!ENTITY specialFoldersTitle.label "Drafts, Archives, and Templates">
-<!ENTITY keepDrafts.label "Keep message drafts in:">
-<!ENTITY keepArchives.label "Keep message archives in:">
-<!ENTITY keepTempltes.label "Keep message templates in:">
--- a/suite/locales/jar.mn
+++ b/suite/locales/jar.mn
@@ -232,16 +232,17 @@
   locale/@AB_CD@/messenger/am-junk.dtd                                      (%chrome/mailnews/pref/am-junk.dtd)
   locale/@AB_CD@/messenger/am-main.dtd                                      (%chrome/mailnews/pref/am-main.dtd)
   locale/@AB_CD@/messenger/am-mdn.dtd                                       (%chrome/mailnews/pref/am-mdn.dtd)
   locale/@AB_CD@/messenger/am-mdn.properties                                (%chrome/mailnews/pref/am-mdn.properties)
   locale/@AB_CD@/messenger/am-offline.dtd                                   (%chrome/mailnews/pref/am-offline.dtd)
   locale/@AB_CD@/messenger/am-serverwithnoidentities.dtd                    (%chrome/mailnews/pref/am-serverwithnoidentities.dtd)
   locale/@AB_CD@/messenger/am-server-advanced.dtd                           (%chrome/mailnews/pref/am-server-advanced.dtd)
   locale/@AB_CD@/messenger/am-server-top.dtd                                (%chrome/mailnews/pref/am-server-top.dtd)
+  locale/@AB_CD@/messenger/am-archiveoptions.dtd                            (%chrome/mailnews/pref/am-archiveoptions.dtd)
   locale/@AB_CD@/messenger/appleMailImportMsgs.properties                   (%chrome/mailnews/appleMailImportMsgs.properties)
   locale/@AB_CD@/messenger/comm4xMailImportMsgs.properties                  (%chrome/mailnews/comm4xMailImportMsgs.properties)
   locale/@AB_CD@/messenger/custom.properties                                (%chrome/mailnews/custom.properties)
   locale/@AB_CD@/messenger/CustomHeaders.dtd                                (%chrome/mailnews/CustomHeaders.dtd)
   locale/@AB_CD@/messenger/eudoraImportMsgs.properties                      (%chrome/mailnews/eudoraImportMsgs.properties)
   locale/@AB_CD@/messenger/downloadheaders.dtd                              (%chrome/mailnews/downloadheaders.dtd)
   locale/@AB_CD@/messenger/fieldMapImport.dtd                               (%chrome/mailnews/fieldMapImport.dtd)
   locale/@AB_CD@/messenger/filter.properties                                (%chrome/mailnews/filter.properties)