Bug 777732 - Remove compose windows recycling (part 1). r=mkmelin a=jorgk SM CLOSED TREE
authorJorg K
Mon, 28 Mar 2016 18:40:21 +0200
changeset 19122 158bced7b1295d82b8dcde3db82bdd691066a7be
parent 19121 4d8a8c737743d20de2ac9e48943a3f03e2571908
child 19123 2738399062904a73b1de05fd351584286f849c76
push id11741
push usermozilla@jorgk.com
push dateMon, 28 Mar 2016 18:03:41 +0000
treeherdercomm-central@158bced7b129 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin, jorgk
bugs777732
Bug 777732 - Remove compose windows recycling (part 1). r=mkmelin a=jorgk SM CLOSED TREE
mail/components/compose/content/MsgComposeCommands.js
mail/extensions/smime/content/msgCompSMIMEOverlay.js
mail/test/mozmill/composition/test-attachment-reminder.js
mail/test/mozmill/composition/test-charset-upgrade.js
mail/test/mozmill/composition/test-drafts.js
mailnews/compose/public/nsIMsgCompose.idl
mailnews/compose/public/nsIMsgComposeService.idl
mailnews/compose/src/nsMsgCompose.cpp
mailnews/compose/src/nsMsgCompose.h
mailnews/compose/src/nsMsgComposeService.cpp
mailnews/compose/src/nsMsgComposeService.h
mailnews/extensions/smime/content/msgCompSMIMEOverlay.js
mailnews/mailnews.js
suite/mailnews/compose/MsgComposeCommands.js
suite/profile/migration/src/nsThunderbirdProfileMigrator.cpp
--- a/mail/components/compose/content/MsgComposeCommands.js
+++ b/mail/components/compose/content/MsgComposeCommands.js
@@ -166,100 +166,16 @@ function updateEditableFields(aDisable)
   else
     gMsgCompose.editor.flags &= ~nsIPlaintextEditorMail.eEditorReadonlyMask;
 
   let elements = document.querySelectorAll('[disableonsend="true"]');
   for (let i = 0; i < elements.length; i++)
     elements[i].disabled = aDisable;
 }
 
-var gComposeRecyclingListener = {
-  onClose: function() {
-    //Clear the subject
-    GetMsgSubjectElement().value = "";
-    // be sure to clear the transaction manager for the subject
-    GetMsgSubjectElement().editor.transactionManager.clear();
-    SetComposeWindowTitle();
-
-    //Reset recipients and attachments
-    awResetAllRows();
-    RemoveAllAttachments();
-
-    // We need to clear the identity popup menu in case the user will change them.
-    // It will be rebuilt later in ComposeStartup
-    ClearIdentityListPopup(document.getElementById("msgIdentityPopup"));
-    var identityElement = document.getElementById("msgIdentity");
-    identityElement.editable = false;
-    identityElement.setAttribute("type", "description");
-    var customizeMenuitem = document.getElementById("cmd_customizeFromAddress");
-    customizeMenuitem.removeAttribute("disabled");
-    customizeMenuitem.setAttribute("checked", "false");
-
-    // Do not listen to changes to spell check dictionary.
-    document.removeEventListener("spellcheck-changed", updateDocumentLanguage);
-
-    // Disconnect the observer, we'll attach a new one when recycling the
-    // window.
-    gLanguageObserver.disconnect();
-
-    // Stop observing dictionary removals.
-    dictionaryRemovalObserver.removeObserver();
-
-    // Stop gSpellChecker so personal dictionary is saved.
-    // We need to do this before disabling the editor.
-    enableInlineSpellCheck(false);
-    // clear any suggestions in the context menu
-    gSpellChecker.clearSuggestionsFromMenu();
-    gSpellChecker.clearDictionaryListFromMenu();
-
-    SetContentAndBodyAsUnmodified();
-    updateEditableFields(true);
-
-    // Clear the focus
-    awGetInputElement(1).removeAttribute('focused');
-
-    //Reset Boxes size
-    document.getElementById("headers-box").removeAttribute("height");
-    document.getElementById("appcontent").removeAttribute("height");
-    document.getElementById("addresses-box").removeAttribute("width");
-
-    //Reset menu options
-    document.getElementById("format_auto").setAttribute("checked", "true");
-    document.getElementById("priority_normal").setAttribute("checked", "true");
-
-    // Reset the Customize Toolbars panel/sheet if open.
-    if (getMailToolbox().customizing && gCustomizeSheet)
-      document.getElementById("customizeToolbarSheetIFrame")
-              .contentWindow.finishToolbarCustomization();
-
-    //Reset editor
-    EditorResetFontAndColorAttributes();
-    EditorCleanup();
-    gAttachmentNotifier.redetectKeywords();
-
-    //Release the nsIMsgComposeParams object
-    if (window.arguments && window.arguments[0])
-      window.arguments[0] = null;
-    document.getElementById("msgcomposeWindow").dispatchEvent(
-      new Event("compose-window-close", { bubbles: false , cancelable: true }));
-    if (gAutoSaveTimeout)
-      clearTimeout(gAutoSaveTimeout);
-    ReleaseGlobalVariables(); 	// This line must be the last in onClose();
-  },
-
-  onReopen: function(params) {
-    InitializeGlobalVariables();
-    ComposeStartup(true, params);
-
-    var event = document.createEvent('Events');
-    event.initEvent('compose-window-reopen', false, true);
-    document.getElementById("msgcomposeWindow").dispatchEvent(event);
-  }
-};
-
 var PrintPreviewListener = {
   getPrintPreviewBrowser: function() {
     var browser = document.getElementById("cppBrowser");
     if (!browser) {
       browser = document.createElement("browser");
       browser.setAttribute("id", "cppBrowser");
       browser.setAttribute("flex", "1");
       browser.setAttribute("disablehistory", "true");
@@ -374,17 +290,17 @@ var stateListener = {
         SetContentAndBodyAsUnmodified();
 
       if (gCloseWindowAfterSave)
       {
         // Notify the SendListener that Send has been aborted and Stopped
         if (gMsgCompose)
           gMsgCompose.onSendNotPerformed(null, Components.results.NS_ERROR_ABORT);
 
-        MsgComposeCloseWindow(true);
+        MsgComposeCloseWindow();
       }
     }
     // else if we failed to save, and we're autosaving, need to re-mark the editor
     // as changed, so that we won't lose the changes.
     else if (gAutoSaving)
     {
       gMsgCompose.bodyModified = true;
       gContentChanged = true;
@@ -1666,18 +1582,18 @@ function MessageComposeOfflineStateChang
 function DoCommandClose()
 {
   if (ComposeCanClose()) {
 
     // Notify the SendListener that Send has been aborted and Stopped
     if (gMsgCompose)
       gMsgCompose.onSendNotPerformed(null, Components.results.NS_ERROR_ABORT);
 
-    // note: if we're not caching this window, this destroys it for us
-    MsgComposeCloseWindow(true);
+    // This destroys the window for us.
+    MsgComposeCloseWindow();
   }
 
   return false;
 }
 
 function DoCommandPrint()
 {
   try {
@@ -2097,28 +2013,24 @@ var dictionaryRemovalObserver =
   isAdded: false,
 
   addObserver: function() {
     Services.obs.addObserver(this, "spellcheck-dictionary-remove", false);
     this.isAdded = true;
   },
 
   removeObserver: function() {
-    // We need to protect against double removal:
-    // The window can be recycled and later destroyed (at shutdown or when the
-    // composition style changes from HTML to plain text or vice versa) or
-    // only destroyed if it was never recycled before.
     if (this.isAdded) {
       Services.obs.removeObserver(this, "spellcheck-dictionary-remove");
       this.isAdded = false;
     }
   }
 }
 
-function ComposeStartup(recycled, aParams)
+function ComposeStartup(aParams)
 {
   // Findbar overlay
   if (!document.getElementById("findbar-replaceButton")) {
     let replaceButton = document.createElement("toolbarbutton");
     replaceButton.setAttribute("id", "findbar-replaceButton");
     replaceButton.setAttribute("class", "findbar-button tabbable");
     replaceButton.setAttribute("label", getComposeBundle().getString("replaceButton.label"));
     replaceButton.setAttribute("accesskey", getComposeBundle().getString("replaceButton.accesskey"));
@@ -2292,60 +2204,49 @@ function ComposeStartup(recycled, aParam
     }
   }
   LoadIdentity(true);
 
   // Get the <editor> element to startup an editor
   var editorElement = GetCurrentEditorElement();
   gMsgCompose = MailServices.compose.initCompose(params, window, editorElement.docShell);
 
-  // Set the close listener.
-  gMsgCompose.recyclingListener = gComposeRecyclingListener;
   gMsgCompose.addMsgSendListener(gSendListener);
-  // Lets the compose object know that we are dealing with a recycled window.
-  gMsgCompose.recycledWindow = recycled;
 
   document.getElementById("returnReceiptMenu")
           .setAttribute('checked', gMsgCompose.compFields.returnReceipt);
   document.getElementById("dsnMenu")
           .setAttribute("checked", gMsgCompose.compFields.DSN);
   document.getElementById("cmd_attachVCard")
           .setAttribute("checked", gMsgCompose.compFields.attachVCard);
   toggleAttachmentReminder(gMsgCompose.compFields.attachmentReminder);
   gSendFormat = gMsgCompose.compFields.deliveryFormat;
   SetCompositionAsPerDeliveryFormat(gSendFormat);
   SelectDeliveryFormatMenuOption(gSendFormat);
 
-  // If recycle, editor is already created.
-  if (!recycled)
+  let editortype = gMsgCompose.composeHTML ? "htmlmail" : "textmail";
+  editorElement.makeEditable(editortype, true);
+
+  // setEditorType MUST be called before setContentWindow
+  if (gMsgCompose.composeHTML)
+  {
+    initLocalFontFaceMenu(document.getElementById("FontFacePopup"));
+  }
+  else
   {
-    let editortype = gMsgCompose.composeHTML ? "htmlmail" : "textmail";
-    editorElement.makeEditable(editortype, true);
-
-    // setEditorType MUST be called before setContentWindow
-    if (gMsgCompose.composeHTML)
-    {
-      initLocalFontFaceMenu(document.getElementById("FontFacePopup"));
-    }
-    else
-    {
-      // We are editing in plain text mode.
-      // The SetCompositionAsPerDeliveryFormat call above already hid
-      // the HTML toolbar, format and insert menus.
-      // Also remove the delivery format from the options menu.
-      // We only do that when the window is first created ("!recycled")
-      // as we will never need to restore it since a plain text window will
-      // never be used for a HTML composition.
-      document.getElementById("outputFormatMenu").setAttribute("hidden", true);
-    }
-
-    // Do setup common to Message Composer and Web Composer.
-    EditorSharedStartup();
+    // We are editing in plain text mode.
+    // The SetCompositionAsPerDeliveryFormat call above already hid
+    // the HTML toolbar, format and insert menus.
+    // Also remove the delivery format from the options menu.
+    document.getElementById("outputFormatMenu").setAttribute("hidden", true);
   }
 
+  // Do setup common to Message Composer and Web Composer.
+  EditorSharedStartup();
+
   if (params.bodyIsLink)
   {
     let body = gMsgCompose.compFields.body;
     if (gMsgCompose.composeHTML)
     {
       let cleanBody;
       try {
         cleanBody = decodeURI(body);
@@ -2365,43 +2266,26 @@ function ComposeStartup(recycled, aParam
 
   AddAttachments(gMsgCompose.compFields.attachments);
 
   document.getElementById("msgcomposeWindow").dispatchEvent(
     new Event("compose-window-init", { bubbles: false , cancelable: true }));
 
   gMsgCompose.RegisterStateListener(stateListener);
 
-  if (recycled)
-  {
-    InitEditor();
-
-    if (gMsgCompose.composeHTML)
-    {
-      // Force color picker on toolbar to show document colors.
-      onFontColorChange();
-      onBackgroundColorChange();
-    }
-
-    // Reset the priority field for recycled windows.
-    updatePriorityToolbarButton("Normal");
-  }
-  else
-  {
-    // Add an observer to be called when document is done loading,
-    // which creates the editor.
-    try {
-      GetCurrentCommandManager().
-              addCommandObserver(gMsgEditorCreationObserver, "obs_documentCreated");
-
-      // Load empty page to create the editor.
-      editorElement.webNavigation.loadURI("about:blank", 0, null, null, null);
-    } catch (e) {
-      Components.utils.reportError(e);
-    }
+  // Add an observer to be called when document is done loading,
+  // which creates the editor.
+  try {
+    GetCurrentCommandManager().
+            addCommandObserver(gMsgEditorCreationObserver, "obs_documentCreated");
+
+    // Load empty page to create the editor.
+    editorElement.webNavigation.loadURI("about:blank", 0, null, null, null);
+  } catch (e) {
+    Components.utils.reportError(e);
   }
 
   gEditingDraft = gMsgCompose.compFields.draftId;
 
   // finally, see if we need to auto open the address sidebar.
   var sideBarBox = document.getElementById('sidebar-box');
   if (sideBarBox.getAttribute("sidebarVisible") == "true")
   {
@@ -2451,17 +2335,17 @@ var gMsgEditorCreationObserver =
 function WizCallback(state)
 {
   if (state){
     ComposeStartup(false, null);
   }
   else
   {
     // The account wizard is still closing so we can't close just yet
-    setTimeout(MsgComposeCloseWindow, 0, false); // Don't recycle a bogus window
+    setTimeout(MsgComposeCloseWindow, 0);
   }
 }
 
 function ComposeLoad()
 {
   try {
     var other_headers = getPref("mail.compose.other.header");
   }
@@ -2490,24 +2374,24 @@ function ComposeLoad()
 
     if (other_headers) {
       var selectNode = document.getElementById('addressCol1#1');
       var other_headers_Array = other_headers.split(",");
       for (let i = 0; i < other_headers_Array.length; i++)
         selectNode.appendItem(other_headers_Array[i] + ":", "addr_other");
     }
     if (state)
-      ComposeStartup(false, null);
+      ComposeStartup(null);
   }
   catch (ex) {
     Components.utils.reportError(ex);
     Services.prompt.alert(window, getComposeBundle().getString("initErrorDlogTitle"),
                           getComposeBundle().getString("initErrorDlgMessage"));
 
-    MsgComposeCloseWindow(false); // Don't try to recycle a bogus window
+    MsgComposeCloseWindow();
     return;
   }
 
   ToolbarIconColor.init();
 
   // initialize the customizeDone method on the customizeable toolbar
   var toolbox = document.getElementById("compose-toolbox");
   toolbox.customizeDone = function(aEvent) { MailToolboxCustomizeDone(aEvent, "CustomizeComposeToolbar"); };
@@ -3659,20 +3543,20 @@ function RemoveDraft()
 }
 
 function SetContentAndBodyAsUnmodified()
 {
   gMsgCompose.bodyModified = false;
   gContentChanged = false;
 }
 
-function MsgComposeCloseWindow(recycleIt)
+function MsgComposeCloseWindow()
 {
   if (gMsgCompose)
-    gMsgCompose.CloseWindow(recycleIt);
+    gMsgCompose.CloseWindow();
   else
     window.close();
 }
 
 function GetLastAttachDirectory()
 {
   var lastDirectory;
 
@@ -4988,19 +4872,18 @@ function InitEditor()
   // We use addOverrideStyleSheet rather than addStyleSheet so that we get
   // a synchronous load, rather than having a late-finishing async load
   // mark our editor as modified when the user hasn't typed anything yet,
   // but that means the sheet must not @import slow things, especially
   // not over the network.
   editor.addOverrideStyleSheet("chrome://messenger/content/composerOverlay.css");
   gMsgCompose.initEditor(editor, window.content);
 
-  // We always go through this function everytime we init an editor, be it a
-  // recycled editor, or a fresh one. First step is making sure we can spell
-  // check.
+  // We always go through this function everytime we init an editor.
+  // First step is making sure we can spell check.
   gSpellChecker.init(editor);
   document.getElementById('menu_inlineSpellCheck')
           .setAttribute('disabled', !gSpellChecker.canSpellCheck);
   document.getElementById('spellCheckEnable')
           .setAttribute('disabled', !gSpellChecker.canSpellCheck);
   // If canSpellCheck = false, then hidden = false, i.e. show it so that we can
   // still add dictionaries. Else, hide that.
   document.getElementById('spellCheckAddDictionariesMain')
--- a/mail/extensions/smime/content/msgCompSMIMEOverlay.js
+++ b/mail/extensions/smime/content/msgCompSMIMEOverlay.js
@@ -68,18 +68,17 @@ function onComposerReOpen()
   if (gSMFields.signMessage)
     setSignatureUI();
   else
     setNoSignatureUI();
 }
 
 addEventListener("load", smimeComposeOnLoad, false);
 
-// this function gets called multiple times,
-// but only on first open, not on composer recycling
+// this function gets called multiple times.
 function smimeComposeOnLoad()
 {
   removeEventListener("load", smimeComposeOnLoad, false);
 
   onComposerReOpen();
 
   top.controllers.appendController(SecurityController);
 
--- a/mail/test/mozmill/composition/test-attachment-reminder.js
+++ b/mail/test/mozmill/composition/test-attachment-reminder.js
@@ -550,52 +550,16 @@ function test_disabled_attachment_remind
   click_send_and_handle_send_error(cwc);
 
   close_compose_window(cwc);
 
   Services.prefs.setBoolPref(kReminderPref, true);
 }
 
 /**
- * Bug 1099866
- * Check if reminder does not stay open on compose window reopen
- * due to window recycling.
- */
-function test_recycling_attachment_reminder() {
-  let recycledWindows = Services.prefs.getIntPref("mail.compose.max_recycled_windows");
-  assert_true(recycledWindows > 0);
-  // Open a sample message with no attachment keywords.
-  let cwc = open_compose_new_mail();
-  setupComposeWin(cwc, "test@example.invalid", "Testing recycling a reminder!",
-                  "Some body...");
-
-  // There should be no attachment notification.
-  assert_automatic_reminder_state(cwc, false);
-
-  // Add some keyword so the automatic notification
-  // could potentially show up.
-  setupComposeWin(cwc, "", "", " and look for your attachment!");
-  // Give the notification time to appear. It should.
-  wait_for_reminder_state(cwc, true);
-
-  close_compose_window(cwc, true);
-
-  // Another compose window without any keywords.
-  cwc = open_compose_new_mail();
-  setupComposeWin(cwc, "test@example.invalid", "Testing reminder after recycling!",
-                  "Some body...");
-
-  // There should be no attachment notification.
-  assert_automatic_reminder_state(cwc, false);
-
-  close_compose_window(cwc);
-}
-
-
-/**
  * Click the send button and handle the send error dialog popping up.
  * It will return us back to the compose window.
  *
  * @param aController
  * @param aAlreadySending  Set this to true if sending was already triggered
  *                         by other means.
  */
 function click_send_and_handle_send_error(aController, aAlreadySending) {
--- a/mail/test/mozmill/composition/test-charset-upgrade.js
+++ b/mail/test/mozmill/composition/test-charset-upgrade.js
@@ -154,18 +154,20 @@ function test_encoding_upgrade_html_comp
   if (!draftMsg2Content.includes('content="text/html; charset=UTF-8"'))
     throw new Error("Expected content type not in msg; draftMsg2Content=" +
                     draftMsg2Content);
 
   if (!draftMsg2Content.includes(CHINESE))
     throw new Error("Chinese text not in msg; CHINESE=" + CHINESE +
                     ", draftMsg2Content=" + draftMsg2Content);
 
-  // Ctrl+Shift+Return = Send Later
-  compWin.keypress(null, "VK_RETURN", {shiftKey: true, accelKey: true});
+  compWin.window.setTimeout(function() {
+    // Ctrl+Shift+Return = Send Later
+    compWin.keypress(null, "VK_RETURN", {shiftKey: true, accelKey: true});
+  }, 0);
 
   be_in_folder(outboxFolder);
   let outMsg = select_click_row(0);
   let outMsgContent = getMsgSource(outMsg);
 
   // This message should be multipart/alternative.
   if (!outMsgContent.includes("Content-Type: multipart/alternative"))
     throw new Error("Expected multipart/alternative; content=" + outMsgContent);
@@ -227,18 +229,20 @@ function test_encoding_upgrade_plaintext
   if (draftMsg2Content.includes("<html>"))
     throw new Error("Plaintext draft contained <html>; "+
                     "draftMsg2Content=" + draftMsg2Content);
 
   if (!draftMsg2Content.includes(CHINESE))
     throw new Error("Chinese text not in msg; CHINESE=" + CHINESE +
                     ", draftMsg2Content=" + draftMsg2Content);
 
-  // Ctrl+Shift+Return = Send Later.
-  compWin.keypress(null, "VK_RETURN", {shiftKey: true, accelKey: true});
+  compWin.window.setTimeout(function() {
+    // Ctrl+Shift+Return = Send Later.
+    compWin.keypress(null, "VK_RETURN", {shiftKey: true, accelKey: true});
+  }, 0);
 
   be_in_folder(outboxFolder);
   let outMsg = select_click_row(0);
   let outMsgContent = getMsgSource(outMsg);
 
   // This message should be text/plain;
   if (!outMsgContent.includes("Content-Type: text/plain"))
     throw new Error("Expected text/plain; content=" + outMsgContent);
--- a/mail/test/mozmill/composition/test-drafts.js
+++ b/mail/test/mozmill/composition/test-drafts.js
@@ -138,17 +138,17 @@ function test_save_delivery_format() {
   cwc.window.SaveAsDraft();
   utils.waitFor(() => !cwc.window.gSaveOperationInProgress && !cwc.window.gWindowLock,
                 "Saving of draft did not finish");
   wait_for_window_focused(cwc.window);
 
   close_compose_window(cwc);
 
   // Open a new composition see if the menu is again at default value, not the one
-  // chosen above, even in a recycled compose window.
+  // chosen above.
   cwc = open_compose_new_mail();
 
   assert_format_value("format_auto", Ci.nsIMsgCompSendFormat.AskUser);
 
   close_compose_window(cwc);
 
   be_in_folder(draftsFolder);
   select_click_row(0);
--- a/mailnews/compose/public/nsIMsgCompose.idl
+++ b/mailnews/compose/public/nsIMsgCompose.idl
@@ -86,23 +86,16 @@ interface nsIMsgComposeNotificationType
     const long ComposeProcessDone = 1;
     const long SaveInFolderDone   = 2;
     const long ComposeBodyReady   = 3;
 };
 
 native nsString(nsString);
 [ref] native nsStringRef(nsString);
 
-/* recycling listener interface */
-[scriptable, uuid(0b28cc56-1dd2-11b2-bbe4-99e6a314f8ba)]
-interface nsIMsgComposeRecyclingListener : nsISupports {
-  void onClose();
-  void onReopen(in nsIMsgComposeParams params);
-};
-
 [scriptable, uuid(c6544b6b-06dd-43ac-89b5-949d7c81bb7b)]
 interface nsIMsgCompose : nsIMsgSendListener {
 
   /**
    * Initializes the msg compose object.
    *
    * @param aParams   An nsIMsgComposeParams object containing the initial
    *                  details for the compose.
@@ -135,17 +128,17 @@ interface nsIMsgCompose : nsIMsgSendList
    * @param identity The message identity.
    * @param accountKey The message account key.
    */
   void sendMsgToServer(in MSG_DeliverMode deliverMode,
                        in nsIMsgIdentity identity,
                        in string accountKey);
 
   /* ... */
-  void CloseWindow(in boolean reclycleIt);
+  void CloseWindow();
 
   /* ... */
   void abort();
     
   /* ... */
   void quoteMessage(in string msgURI);
 
   /*
@@ -279,22 +272,16 @@ interface nsIMsgCompose : nsIMsgSendList
   [noscript] void buildBodyMessageAndSignature();
   
 	/* ... */
   [noscript] void buildQuotedMessageAndSignature();
 
  	/* ... */
   [noscript] void getQuotingToFollow(out boolean quotingToFollow);
 
- 	/* ... */
-  attribute nsIMsgComposeRecyclingListener recyclingListener;
-  
-  /* ... */
-  attribute boolean recycledWindow;
-  
   readonly attribute string originalMsgURI;
 
   attribute boolean deleteDraft;
 
   /* true when the compose window is in the process of inserting quoted content
      (i.e. via reply, forward inline or a quoting operation) into the document 
    */
   attribute boolean insertingQuotedContent;
--- a/mailnews/compose/public/nsIMsgComposeService.idl
+++ b/mailnews/compose/public/nsIMsgComposeService.idl
@@ -41,18 +41,17 @@ interface nsIMsgComposeService : nsISupp
   void OpenComposeWindowWithURI(in string msgComposeWindowURL,
                                 in nsIURI aURI,
                                 [optional] in nsIMsgIdentity aIdentity);
 
   /* ... */
   void OpenComposeWindowWithParams(in string msgComposeWindowURL, in nsIMsgComposeParams params);
 
   /**
-   * Creates an nsIMsgCompose instance, initalizes it, and manages the window
-   * recycling cache.
+   * Creates an nsIMsgCompose instance and initalizes it.
    *
    * @param aParams   An nsIMsgComposeParams object containing the initial
    *                  details for the compose.
    * @param aWindow   The optional window associated with this compose object.
    * @param aDocShell The optional docShell of the editor element that is used
    *                  for composing.
    */
   nsIMsgCompose initCompose(in nsIMsgComposeParams aParams,
@@ -68,18 +67,16 @@ interface nsIMsgComposeService : nsISupp
 
   /* This function is use for debugging purpose only and may go away at anytime without warning */
   void TimeStamp(in string label, in boolean resetTime);  
   
   /* This attribute is use for debugging purposes for determining whether to PR_LOG or not */
   readonly attribute boolean logComposePerformance;
 
   [noscript] boolean determineComposeHTML(in nsIMsgIdentity aIdentity, in MSG_ComposeFormat aFormat);
-  [noscript] void cacheWindow(in mozIDOMWindowProxy aWindow, in boolean aComposeHTML, in nsIMsgComposeRecyclingListener listener);
-  boolean isCachedWindow(in mozIDOMWindowProxy aWindow);
 
   /** 
    * given a mailto url, parse the attributes and turn them into a nsIMsgComposeParams object
    * @return nsIMsgComposeParams which corresponds to the passed in mailto url
    */
   nsIMsgComposeParams getParamsForMailto(in nsIURI aURI); 
 
   /**
@@ -125,17 +122,17 @@ interface nsIMsgComposeService : nsISupp
    *
    * @param aDocShell The nsIDocShell of the editor element. 
    * @param aMsgCompose The compose object associated with the compose window
    */
   void registerComposeDocShell(in nsIDocShell aDocShell,
                                in nsIMsgCompose aMsgCompose);
 
   /** 
-   * When an editor docShell is being closed (or recycled), you should
+   * When an editor docShell is being closed, you should
    * unregister it from this service. nsIMsgCompose normally calls this
    * automatically for items passed to initCompose.
    *
    * @param aDocShell The nsIDocShell of the editor element. 
    */
   void unregisterComposeDocShell(in nsIDocShell aDocShell);
   
   /**
--- a/mailnews/compose/src/nsMsgCompose.cpp
+++ b/mailnews/compose/src/nsMsgCompose.cpp
@@ -182,17 +182,16 @@ nsMsgCompose::nsMsgCompose()
   // For TagConvertible
   // Read and cache pref
   mConvertStructs = false;
   nsCOMPtr<nsIPrefBranch> prefBranch (do_GetService(NS_PREFSERVICE_CONTRACTID));
   if (prefBranch)
     prefBranch->GetBoolPref("converter.html2txt.structs", &mConvertStructs);
 
   m_composeHTML = false;
-  mRecycledWindow = true;
 }
 
 
 nsMsgCompose::~nsMsgCompose()
 {
   NS_IF_RELEASE(m_compFields);
   NS_IF_RELEASE(mQuoteStreamListener);
 }
@@ -605,27 +604,16 @@ nsMsgCompose::ConvertAndLoadComposeWindo
 
   // First, get the nsIEditor interface for future use
   nsCOMPtr<nsIDOMNode> nodeInserted;
 
   TranslateLineEnding(aPrefix);
   TranslateLineEnding(aBuf);
   TranslateLineEnding(aSignature);
 
-  // We're going to be inserting stuff, and MsgComposeCommands
-  // may have set the editor to readonly in the recycled case.
-  // So set it back to writable.
-  // Note!  enableEditableFields in gComposeRecyclingListener::onReopen
-  // will redundantly set this flag to writable, but it gets there
-  // too late.
-  uint32_t flags = 0;
-  m_editor->GetFlags(&flags);
-  flags &= ~nsIPlaintextEditor::eEditorReadonlyMask;
-  m_editor->SetFlags(flags);
-
   m_editor->EnableUndo(false);
 
   // Ok - now we need to figure out the charset of the aBuf we are going to send
   // into the editor shell. There are I18N calls to sniff the data and then we need
   // to call the new routine in the editor that will allow us to send in the charset
   //
 
   // Now, insert it into the editor...
@@ -1483,44 +1471,16 @@ NS_IMETHODIMP nsMsgCompose::SendMsg(MSG_
 
     if (progress)
       progress->CloseProgressDialog(true);
   }
 
   return rv;
 }
 
-// XXX when do we break this ref to the listener?
-NS_IMETHODIMP nsMsgCompose::SetRecyclingListener(nsIMsgComposeRecyclingListener *aRecyclingListener)
-{
-  mRecyclingListener = aRecyclingListener;
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsMsgCompose::GetRecyclingListener(nsIMsgComposeRecyclingListener **aRecyclingListener)
-{
-  NS_ENSURE_ARG_POINTER(aRecyclingListener);
-  *aRecyclingListener = mRecyclingListener;
-  NS_IF_ADDREF(*aRecyclingListener);
-  return NS_OK;
-}
-
-/* attribute boolean recycledWindow; */
-NS_IMETHODIMP nsMsgCompose::GetRecycledWindow(bool *aRecycledWindow)
-{
-  NS_ENSURE_ARG_POINTER(aRecycledWindow);
-  *aRecycledWindow = mRecycledWindow;
-  return NS_OK;
-}
-NS_IMETHODIMP nsMsgCompose::SetRecycledWindow(bool aRecycledWindow)
-{
-  mRecycledWindow = aRecycledWindow;
-  return NS_OK;
-}
-
 /* attribute boolean deleteDraft */
 NS_IMETHODIMP nsMsgCompose::GetDeleteDraft(bool *aDeleteDraft)
 {
   NS_ENSURE_ARG_POINTER(aDeleteDraft);
   *aDeleteDraft = mDeleteDraft;
   return NS_OK;
 }
 
@@ -1548,88 +1508,47 @@ bool nsMsgCompose::IsLastWindow()
       if (NS_SUCCEEDED(windowEnumerator->GetNext(getter_AddRefs(isupports))))
         if (NS_SUCCEEDED(windowEnumerator->HasMoreElements(&more)))
           return !more;
     }
   }
   return true;
 }
 
-NS_IMETHODIMP nsMsgCompose::CloseWindow(bool recycleIt)
+NS_IMETHODIMP nsMsgCompose::CloseWindow(void)
 {
   nsresult rv;
 
   nsCOMPtr<nsIMsgComposeService> composeService = do_GetService(NS_MSGCOMPOSESERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv,rv);
 
   // unregister the compose object with the compose service
   rv = composeService->UnregisterComposeDocShell(mDocShell);
   NS_ENSURE_SUCCESS(rv, rv);
   mDocShell = nullptr;
 
   // ensure that the destructor of nsMsgSend is invoked to remove
   // temporary files.
   mMsgSend = nullptr;
 
-  recycleIt = recycleIt && !IsLastWindow();
-  if (recycleIt)
-  {
-    rv = composeService->CacheWindow(m_window, m_composeHTML, mRecyclingListener);
-    if (NS_SUCCEEDED(rv))
-    {
-      nsCOMPtr<nsIHTMLEditor> htmlEditor (do_QueryInterface(m_editor));
-      NS_ASSERTION(htmlEditor, "no editor");
-      if (htmlEditor)
-      {
-        // XXX clear undo txn manager?
-
-        rv = m_editor->EnableUndo(false);
-        NS_ENSURE_SUCCESS(rv,rv);
-
-        rv = htmlEditor->RebuildDocumentFromSource(EmptyString());
-        NS_ENSURE_SUCCESS(rv,rv);
-
-        rv = m_editor->EnableUndo(true);
-        NS_ENSURE_SUCCESS(rv,rv);
-
-        SetBodyModified(false);
-      }
-      if (mRecyclingListener)
-      {
-        mRecyclingListener->OnClose();
-
-        /**
-         * In order to really free the memory, we need to call the JS garbage collector for our window.
-         * If we don't call GC, the nsIMsgCompose object held by JS will not be released despite we set
-         * the JS global that held it to null. Each time we reopen a recycled window, we allocate a new
-         * nsIMsgCompose that we really need to be released when we recycle the window. In fact despite
-         * we call GC here, the release won't occur right away. But if we don't call it, the release
-         * will happen only when we physically close the window which will happen only on quit.
-         */
-        nsJSContext::PokeGC(JS::gcreason::NSJSCONTEXT_DESTROY);
-      }
-      return NS_OK;
-    }
-  }
-
   //We are going away for real, we need to do some clean up first
   if (m_baseWindow)
   {
     if (m_editor)
     {
-        /* The editor will be destroyed during yje close window.
-         * Set it to null to be sure we won't use it anymore
-         */
+      // The editor will be destroyed during the close window.
+      // Set it to null to be sure we won't use it anymore.
       m_editor = nullptr;
     }
     nsIBaseWindow * window = m_baseWindow;
     m_baseWindow = nullptr;
     rv = window->Destroy();
   }
 
+  m_window = nullptr;
   return rv;
 }
 
 nsresult nsMsgCompose::Abort()
 {
   if (mMsgSend)
     mMsgSend->Abort();
 
@@ -3754,31 +3673,31 @@ nsresult nsMsgComposeSendListener::OnSto
           {
             msgCompose->NotifyStateListeners(nsIMsgComposeNotificationType::ComposeProcessDone, NS_OK);
             if (progress)
             {
               progress->UnregisterListener(this);
               progress->CloseProgressDialog(false);
             }
             if (hasDomWindow)
-              msgCompose->CloseWindow(true);
+              msgCompose->CloseWindow();
           }
         }
       }
       else
       {
         msgCompose->NotifyStateListeners(nsIMsgComposeNotificationType::ComposeProcessDone, NS_OK);
         if (progress)
         {
           progress->UnregisterListener(this);
           progress->CloseProgressDialog(false);
         }
         if (hasDomWindow)
-          msgCompose->CloseWindow(true);  // if we fail on the simple GetFcc call, close the window to be safe and avoid
-                                              // windows hanging around to prevent the app from exiting.
+          msgCompose->CloseWindow();  // if we fail on the simple GetFcc call, close the window to be safe and avoid
+                                      // windows hanging around to prevent the app from exiting.
       }
 
       // Remove the current draft msg when sending draft is done.
       bool deleteDraft;
       msgCompose->GetDeleteDraft(&deleteDraft);
       if (deleteDraft)
         RemoveCurrentDraftMessage(msgCompose, false);
     }
@@ -3870,17 +3789,17 @@ nsMsgComposeSendListener::OnStopCopy(nsr
       {
         // Remove (possible) draft if we're in send later mode
         if (mDeliverMode == nsIMsgSend::nsMsgQueueForLater ||
             mDeliverMode == nsIMsgSend::nsMsgDeliverBackground)
         {
           msgCompose->SetDeleteDraft(true);
           RemoveCurrentDraftMessage(msgCompose, true);
         }
-        msgCompose->CloseWindow(true);
+        msgCompose->CloseWindow();
       }
     }
     msgCompose->ClearMessageSend();
   }
 
   return rv;
 }
 
--- a/mailnews/compose/src/nsMsgCompose.h
+++ b/mailnews/compose/src/nsMsgCompose.h
@@ -108,18 +108,16 @@ protected:
   nsCOMPtr<nsIDocShell>                     mDocShell;
   nsCOMPtr<nsIBaseWindow>                   m_baseWindow;
   nsMsgCompFields                           *m_compFields;
   nsCOMPtr<nsIMsgIdentity>                  m_identity;
   bool                                      m_composeHTML;
   QuotingOutputStreamListener               *mQuoteStreamListener;
   nsCOMPtr<nsIOutputStream>                 mBaseStream;
 
-  nsCOMPtr<nsIMsgComposeRecyclingListener>  mRecyclingListener;
-  bool                                      mRecycledWindow;
   nsCOMPtr<nsIMsgSend>                      mMsgSend;           // for composition back end
   nsCOMPtr<nsIMsgProgress>                  mProgress;          // use by the back end to report progress to the front end
 
   // Deal with quoting issues...
   nsString                                  mCiteReference;
   nsCOMPtr<nsIMsgQuote>                     mQuote;
   bool                                      mQuotingToFollow;   // Quoting indicator
   MSG_ComposeType                           mType;              // Message type
--- a/mailnews/compose/src/nsMsgComposeService.cpp
+++ b/mailnews/compose/src/nsMsgComposeService.cpp
@@ -67,18 +67,16 @@
 #ifdef XP_WIN32
 #include <windows.h>
 #include <shellapi.h>
 #include "nsIWidget.h"
 #endif
 
 #define DEFAULT_CHROME  "chrome://messenger/content/messengercompose/messengercompose.xul"
 
-#define PREF_MAIL_COMPOSE_MAXRECYCLEDWINDOWS  "mail.compose.max_recycled_windows"
-
 #define PREF_MAILNEWS_REPLY_QUOTING_SELECTION            "mailnews.reply_quoting_selection"
 #define PREF_MAILNEWS_REPLY_QUOTING_SELECTION_MULTI_WORD "mailnews.reply_quoting_selection.multi_word"
 #define PREF_MAILNEWS_REPLY_QUOTING_SELECTION_ONLY_IF    "mailnews.reply_quoting_selection.only_if_chars"
 
 #define MAIL_ROOT_PREF                             "mail."
 #define MAILNEWS_ROOT_PREF                         "mailnews."
 #define HTMLDOMAINUPDATE_VERSION_PREF_NAME         "global_html_domains.version"
 #define HTMLDOMAINUPDATE_DOMAINLIST_PREF_NAME      "global_html_domains"
@@ -113,104 +111,50 @@ nsMsgComposeService::nsMsgComposeService
 #ifdef MSGCOMP_TRACE_PERFORMANCE
   if (!MsgComposeLogModule)
       MsgComposeLogModule = PR_NewLogModule("msgcompose");
 
   mStartTime = PR_IntervalNow();
   mPreviousTime = mStartTime;
 #endif
 
-  mMaxRecycledWindows = 0;
-  mCachedWindows = nullptr;
 }
 
 NS_IMPL_ISUPPORTS(nsMsgComposeService,
                    nsIMsgComposeService,
-                   nsIObserver,
                    ICOMMANDLINEHANDLER,
                    nsISupportsWeakReference)
 
 nsMsgComposeService::~nsMsgComposeService()
 {
-  if (mCachedWindows)
-  {
-    DeleteCachedWindows();
-    delete [] mCachedWindows;
-  }
-
   mOpenComposeWindows.Clear();
 }
 
 nsresult nsMsgComposeService::Init()
 {
   nsresult rv = NS_OK;
-  // Register observers
-
-  // Register for quit application and profile change, we will need to clear the cache.
-  nsCOMPtr<nsIObserverService> observerService =
-    mozilla::services::GetObserverService();
-  if (observerService)
-  {
-    rv = observerService->AddObserver(this, "quit-application", true);
-    rv = observerService->AddObserver(this, "profile-do-change", true);
-  }
-
-  // Register some pref observer
-  nsCOMPtr<nsIPrefBranch> pbi = do_GetService(NS_PREFSERVICE_CONTRACTID);
-  if (pbi)
-    rv = pbi->AddObserver(PREF_MAIL_COMPOSE_MAXRECYCLEDWINDOWS, this, true);
 
   Reset();
 
   AddGlobalHtmlDomains();
   // Since the compose service should only be initialized once, we can
   // be pretty sure there aren't any existing compose windows open.
   MsgCleanupTempFiles("nsmail", "tmp");
   MsgCleanupTempFiles("nsemail", "html");
   MsgCleanupTempFiles("nscopy", "tmp");
   return rv;
 }
 
 void nsMsgComposeService::Reset()
 {
-  nsresult rv = NS_OK;
-
-  if (mCachedWindows)
-  {
-    DeleteCachedWindows();
-    delete [] mCachedWindows;
-    mCachedWindows = nullptr;
-    mMaxRecycledWindows = 0;
-  }
-
   mOpenComposeWindows.Clear();
 
   nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
-  if(prefs)
-    rv = prefs->GetIntPref(PREF_MAIL_COMPOSE_MAXRECYCLEDWINDOWS, &mMaxRecycledWindows);
-  if (NS_SUCCEEDED(rv) && mMaxRecycledWindows > 0)
-  {
-    mCachedWindows = new nsMsgCachedWindowInfo[mMaxRecycledWindows];
-    if (!mCachedWindows)
-      mMaxRecycledWindows = 0;
-  }
-
-  rv = prefs->GetBoolPref("mailnews.logComposePerformance", &mLogComposePerformance);
-
-  return;
-}
-
-void nsMsgComposeService::DeleteCachedWindows()
-{
-  int32_t i;
-  for (i = 0; i < mMaxRecycledWindows; i ++)
-  {
-    CloseHiddenCachedWindow(mCachedWindows[i].window);
-    mCachedWindows[i].Clear();
-  }
+  if (prefs)
+    prefs->GetBoolPref("mailnews.logComposePerformance", &mLogComposePerformance);
 }
 
 // Function to open a message compose window and pass an nsIMsgComposeParams
 // parameter to it.
 NS_IMETHODIMP
 nsMsgComposeService::OpenComposeWindowWithParams(const char *chrome,
                                                  nsIMsgComposeParams *params)
 {
@@ -230,48 +174,17 @@ nsMsgComposeService::OpenComposeWindowWi
   nsCOMPtr<nsIMsgIdentity> identity;
   params->GetIdentity(getter_AddRefs(identity));
   if (!identity)
   {
     GetDefaultIdentity(getter_AddRefs(identity));
     params->SetIdentity(identity);
   }
 
-  //if we have a cached window for the default chrome, try to reuse it...
-  if (!chrome || PL_strcasecmp(chrome, DEFAULT_CHROME) == 0)
-  {
-    MSG_ComposeFormat format;
-    params->GetFormat(&format);
-
-    bool composeHTML = true;
-    rv = DetermineComposeHTML(identity, format, &composeHTML);
-    if (NS_SUCCEEDED(rv))
-    {
-      int32_t i;
-      for (i = 0; i < mMaxRecycledWindows; i ++)
-      {
-        if (mCachedWindows[i].window && (mCachedWindows[i].htmlCompose == composeHTML) && mCachedWindows[i].listener)
-        {
-          /* We need to save the window pointer as OnReopen will call nsMsgComposeService::InitCompose which will
-             clear the cache entry if everything goes well
-          */
-          nsCOMPtr<mozIDOMWindowProxy> domWindow(mCachedWindows[i].window);
-          nsCOMPtr<nsIXULWindow> xulWindow(mCachedWindows[i].xulWindow);
-          rv = ShowCachedComposeWindow(domWindow, xulWindow, true);
-          if (NS_SUCCEEDED(rv))
-          {
-            mCachedWindows[i].listener->OnReopen(params);
-            return NS_OK;
-          }
-        }
-      }
-    }
-  }
-
-  //Else, create a new one...
+  // Create a new window.
   nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
   if (!wwatch)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsISupportsInterfacePointer> msgParamsWrapper =
     do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -281,73 +194,16 @@ nsMsgComposeService::OpenComposeWindowWi
   nsCOMPtr<mozIDOMWindowProxy> newWindow;
   rv = wwatch->OpenWindow(0, chrome && *chrome ? chrome : DEFAULT_CHROME,
                  "_blank", "all,chrome,dialog=no,status,toolbar", msgParamsWrapper,
                  getter_AddRefs(newWindow));
 
   return rv;
 }
 
-void nsMsgComposeService::CloseHiddenCachedWindow(mozIDOMWindowProxy *domWindow)
-{
-  if (domWindow)
-  {
-    nsCOMPtr<nsIDocShell> docshell;
-    if (domWindow)
-    {
-      nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(domWindow);
-      nsCOMPtr<nsIDocShellTreeItem> treeItem =
-        do_QueryInterface(window->GetDocShell());
-
-      if (treeItem)
-      {
-        nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
-        treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
-        if (treeOwner)
-        {
-          nsCOMPtr<nsIBaseWindow> baseWindow;
-          baseWindow = do_QueryInterface(treeOwner);
-          if (baseWindow) {
-            // HACK ALERT: when we hid this window we fired the "xul-window-destroyed"
-            // notification for it. Now that it's being really-destroyed it will fire that
-            // notification *again* for itself. The appstartup code maintains an internal
-            // reference count of windows that block app shutdown: we want to increment that
-            // count without cancelling app shutdown (so don't use "xul-window-registered").
-            nsCOMPtr<nsIAppStartup> appStartup(do_GetService(NS_APPSTARTUP_CONTRACTID));
-            if (appStartup)
-              appStartup->EnterLastWindowClosingSurvivalArea();
-
-            baseWindow->Destroy();
-          }
-        }
-      }
-    }
-  }
-}
-
-NS_IMETHODIMP
-nsMsgComposeService::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *someData)
-{
-  if (!strcmp(aTopic, "profile-do-change") || !strcmp(aTopic, "quit-application"))
-  {
-    DeleteCachedWindows();
-    return NS_OK;
-  }
-
-  if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID))
-  {
-    nsDependentString prefName(someData);
-    if (prefName.EqualsLiteral(PREF_MAIL_COMPOSE_MAXRECYCLEDWINDOWS))
-      Reset();
-    return NS_OK;
-  }
-
-  return NS_OK;
-}
-
 NS_IMETHODIMP
 nsMsgComposeService::DetermineComposeHTML(nsIMsgIdentity *aIdentity, MSG_ComposeFormat aFormat, bool *aComposeHTML)
 {
   NS_ENSURE_ARG_POINTER(aComposeHTML);
 
   *aComposeHTML = true;
   switch (aFormat)
   {
@@ -709,25 +565,16 @@ NS_IMETHODIMP nsMsgComposeService::OpenC
   return rv;
 }
 
 NS_IMETHODIMP nsMsgComposeService::InitCompose(nsIMsgComposeParams *aParams,
                                                mozIDOMWindowProxy *aWindow,
                                                nsIDocShell *aDocShell,
                                                nsIMsgCompose **_retval)
 {
-  // We need to remove the window from the cache.
-  int32_t i;
-  for (i = 0; i < mMaxRecycledWindows; i ++)
-    if (mCachedWindows[i].window == aWindow)
-    {
-      mCachedWindows[i].Clear();
-      break;
-    }
-
   nsresult rv;
   nsCOMPtr<nsIMsgCompose> msgCompose =
     do_CreateInstance(NS_MSGCOMPOSE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv,rv);
 
   rv = msgCompose->Initialize(aParams, aWindow, aDocShell);
   NS_ENSURE_SUCCESS(rv,rv);
 
@@ -785,99 +632,16 @@ NS_IMETHODIMP nsMsgComposeService::TimeS
   MOZ_LOG(MsgComposeLogModule, mozilla::LogLevel::Info, ("[%3.2f][%3.2f] - %s\n",
 ((double)totalTime/1000.0) + 0.005, ((double)deltaTime/1000.0) + 0.005, label));
 
   mPreviousTime = now;
 #endif
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsMsgComposeService::IsCachedWindow(mozIDOMWindowProxy *aCachedWindow, bool *aIsCachedWindow)
-{
-  NS_ENSURE_ARG_POINTER(aCachedWindow);
-  NS_ENSURE_ARG_POINTER(aIsCachedWindow);
-
-  int32_t i;
-  for (i = 0; i < mMaxRecycledWindows; i ++)
-    if (mCachedWindows[i].window.get() == aCachedWindow)
-    {
-      *aIsCachedWindow = true;
-      return NS_OK;
-    }
-
- *aIsCachedWindow = false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsMsgComposeService::CacheWindow(mozIDOMWindowProxy *aWindow, bool aComposeHTML, nsIMsgComposeRecyclingListener * aListener)
-{
-  NS_ENSURE_ARG_POINTER(aWindow);
-  NS_ENSURE_ARG_POINTER(aListener);
-
-  nsresult rv;
-  nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
-
-  nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(window->GetDocShell(), &rv));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr <nsIDocShellTreeOwner> treeOwner;
-  rv = treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
-  NS_ENSURE_SUCCESS(rv,rv);
-
-  nsCOMPtr<nsIXULWindow> xulWindow(do_GetInterface(treeOwner, &rv));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  int32_t i;
-  int32_t sameTypeId = -1;
-  int32_t oppositeTypeId = -1;
-
-  for (i = 0; i < mMaxRecycledWindows; i ++)
-  {
-    if (!mCachedWindows[i].window)
-    {
-      rv = ShowCachedComposeWindow(aWindow, xulWindow, false);
-      if (NS_SUCCEEDED(rv))
-        mCachedWindows[i].Initialize(aWindow, xulWindow, aListener, aComposeHTML);
-
-      return rv;
-    }
-    else
-      if (mCachedWindows[i].htmlCompose == aComposeHTML)
-      {
-        if (sameTypeId == -1)
-          sameTypeId = i;
-      }
-      else
-      {
-        if (oppositeTypeId == -1)
-          oppositeTypeId = i;
-      }
-  }
-
-  /* Looks like the cache is full. In the case we try to cache a type (html or plain text) of compose window which is not
-     already cached, we should replace an opposite one with this new one. That would allow users to be able to take advantage
-     of the cached compose window when they switch from one type to another one
-  */
-  if (sameTypeId == -1 && oppositeTypeId != -1)
-  {
-    CloseHiddenCachedWindow(mCachedWindows[oppositeTypeId].window);
-    mCachedWindows[oppositeTypeId].Clear();
-
-    rv = ShowCachedComposeWindow(aWindow, xulWindow, false);
-    if (NS_SUCCEEDED(rv))
-      mCachedWindows[oppositeTypeId].Initialize(aWindow, xulWindow, aListener, aComposeHTML);
-
-    return rv;
-  }
-
-  return NS_ERROR_NOT_AVAILABLE;
-}
-
 class nsMsgTemplateReplyHelper final: public nsIStreamListener,
                                       public nsIUrlListener
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIURLLISTENER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
@@ -1290,84 +1054,16 @@ nsMsgComposeService::ForwardMessage(cons
   // nsMsgCompose::ProcessReplyFlags usually takes care of marking messages
   // as forwarded. ProcessReplyFlags is normally called from
   // nsMsgComposeSendListener::OnStopSending but for this case the msgCompose
   // object is not set so ProcessReplyFlags won't get called.
   // Therefore, let's just mark it here instead.
   return folder->AddMessageDispositionState(aMsgHdr, nsIMsgFolder::nsMsgDispositionState_Forwarded);
 }
 
-nsresult nsMsgComposeService::ShowCachedComposeWindow(mozIDOMWindowProxy *aComposeWindow, nsIXULWindow *aXULWindow, bool aShow)
-{
-  nsresult rv = NS_OK;
-
-  nsCOMPtr<nsIObserverService> obs =
-    mozilla::services::GetObserverService();
-  NS_ENSURE_TRUE(obs, NS_ERROR_UNEXPECTED);
-
-  NS_ENSURE_TRUE(aComposeWindow, NS_ERROR_FAILURE);
-  nsCOMPtr <nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aComposeWindow);
-
-  nsIDocShell *docShell = window->GetDocShell();
-
-  nsCOMPtr <nsIDocShellTreeItem> treeItem = do_QueryInterface(docShell, &rv);
-  NS_ENSURE_SUCCESS(rv,rv);
-
-  nsCOMPtr <nsIDocShellTreeOwner> treeOwner;
-  rv = treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
-  NS_ENSURE_SUCCESS(rv,rv);
-
-  if (treeOwner) {
-    // the window need to be sticky before we hide it.
-    nsCOMPtr<nsIContentViewer> contentViewer;
-    rv = docShell->GetContentViewer(getter_AddRefs(contentViewer));
-    NS_ENSURE_SUCCESS(rv,rv);
-
-    rv = contentViewer->SetSticky(!aShow);
-    NS_ENSURE_SUCCESS(rv,rv);
-
-    // disable (enable) the cached window
-    nsCOMPtr<nsIBaseWindow> baseWindow;
-    baseWindow = do_QueryInterface(treeOwner, &rv);
-    NS_ENSURE_SUCCESS(rv,rv);
-
-    baseWindow->SetEnabled(aShow);
-    NS_ENSURE_SUCCESS(rv,rv);
-
-    nsCOMPtr<nsIWindowMediator> windowMediator =
-	         do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv);
-    NS_ENSURE_SUCCESS(rv,rv);
-
-    // if showing, reinstate the window with the mediator
-    if (aShow) {
-      rv = windowMediator->RegisterWindow(aXULWindow);
-      NS_ENSURE_SUCCESS(rv,rv);
-
-      obs->NotifyObservers(aXULWindow, "xul-window-registered", nullptr);
-    }
-
-    // hide (show) the cached window
-    rv = baseWindow->SetVisibility(aShow);
-    NS_ENSURE_SUCCESS(rv,rv);
-
-    // if hiding, remove the window from the mediator,
-    // so that it will be removed from the task list
-    if (!aShow) {
-      rv = windowMediator->UnregisterWindow(aXULWindow);
-      NS_ENSURE_SUCCESS(rv,rv);
-
-      obs->NotifyObservers(aXULWindow, "xul-window-destroyed", nullptr);
-    }
-  }
-  else {
-    rv = NS_ERROR_FAILURE;
-  }
-  return rv;
-}
-
 nsresult nsMsgComposeService::AddGlobalHtmlDomains()
 {
 
   nsresult rv;
   nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv,rv);
 
   nsCOMPtr<nsIPrefBranch> prefBranch;
--- a/mailnews/compose/src/nsMsgComposeService.h
+++ b/mailnews/compose/src/nsMsgComposeService.h
@@ -12,85 +12,53 @@
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "nsIMimeStreamConverter.h"
 #include "nsInterfaceHashtable.h"
 
 #include "nsICommandLineHandler.h"
 #define ICOMMANDLINEHANDLER nsICommandLineHandler
 
-class nsMsgCachedWindowInfo
-{
-public:
-  void Initialize(mozIDOMWindowProxy *aWindow, nsIXULWindow *aXULWindow, nsIMsgComposeRecyclingListener *aListener, bool aHtmlCompose)
-  {
-    window = aWindow;
-    xulWindow = aXULWindow;
-    listener = aListener;
-    htmlCompose = aHtmlCompose;
-  }
-    
-  void Clear()
-  {
-    window = nullptr;
-    listener = nullptr;
-  }
-  
-  nsCOMPtr<mozIDOMWindowProxy>              window;
-  nsCOMPtr<nsIXULWindow>                    xulWindow;
-  nsCOMPtr<nsIMsgComposeRecyclingListener>  listener;
-  bool                                      htmlCompose;
-};
-
 class nsMsgComposeService : 
   public nsIMsgComposeService,
-  public nsIObserver,
   public ICOMMANDLINEHANDLER,
   public nsSupportsWeakReference
 {
 public: 
 	nsMsgComposeService();
 
 	NS_DECL_ISUPPORTS
   NS_DECL_NSIMSGCOMPOSESERVICE
-  NS_DECL_NSIOBSERVER
   NS_DECL_NSICOMMANDLINEHANDLER
 
   nsresult Init();
   void Reset();
   void DeleteCachedWindows();
   nsresult AddGlobalHtmlDomains();
 
 private:
 	virtual ~nsMsgComposeService();
   bool mLogComposePerformance;
 
-  int32_t mMaxRecycledWindows;
-  nsMsgCachedWindowInfo *mCachedWindows;
-  
-  void CloseHiddenCachedWindow(mozIDOMWindowProxy *domWindow);
-
   nsresult LoadDraftOrTemplate(const nsACString& aMsgURI, nsMimeOutputType aOutType, 
                                nsIMsgIdentity * aIdentity, const char * aOriginalMsgURI, 
                                nsIMsgDBHdr * aOrigMsgHdr, bool aForwardInline,
                                bool overrideComposeFormat,
                                nsIMsgWindow *aMsgWindow);
 
   nsresult RunMessageThroughMimeDraft(const nsACString& aMsgURI,
                                       nsMimeOutputType aOutType,
                                       nsIMsgIdentity * aIdentity,
                                       const char * aOriginalMsgURI,
                                       nsIMsgDBHdr * aOrigMsgHdr,
                                       bool aForwardInline,
                                       const nsAString &forwardTo,
                                       bool overrideComposeFormat,
                                       nsIMsgWindow *aMsgWindow);
 
-  nsresult ShowCachedComposeWindow(mozIDOMWindowProxy *aComposeWindow, nsIXULWindow *aXULWindow, bool aShow);
-
   // hash table mapping dom windows to nsIMsgCompose objects
   nsInterfaceHashtable<nsISupportsHashKey, nsIWeakReference> mOpenComposeWindows;
 
   // When doing a reply and the settings are enabled, get the HTML of the selected text
   // in the original message window so that it can be quoted instead of the entire message.
   nsresult GetOrigWindowSelection(MSG_ComposeType type, nsIMsgWindow *aMsgWindow, nsACString& aSelHTML);
 
 #ifdef MSGCOMP_TRACE_PERFORMANCE
--- a/mailnews/extensions/smime/content/msgCompSMIMEOverlay.js
+++ b/mailnews/extensions/smime/content/msgCompSMIMEOverlay.js
@@ -66,18 +66,17 @@ function onComposerReOpen()
   if (gSMFields.signMessage)
     setSignatureUI();
   else
     setNoSignatureUI();
 }
 
 addEventListener("load", smimeComposeOnLoad, false);
 
-// this function gets called multiple times,
-// but only on first open, not on composer recycling
+// this function gets called multiple times
 function smimeComposeOnLoad()
 {
   removeEventListener("load", smimeComposeOnLoad, false);
 
   onComposerReOpen();
 
   top.controllers.appendController(SecurityController);
 
--- a/mailnews/mailnews.js
+++ b/mailnews/mailnews.js
@@ -727,18 +727,16 @@ pref("mailnews.ui.addressbook_panel_resu
 // to hide the non default columns in the select addresses dialog
 // see abCommon.js and abSelectAddressesDialog.js
 pref("mailnews.ui.select_addresses_results.version", 1);
 // for manual upgrades of certain UI features.
 // 1 -> 2 is for the ab results pane
 // to hide the non default columns in the advanced directory search dialog
 // see abCommon.js and ABSearchDialog.js
 pref("mailnews.ui.advanced_directory_search_results.version", 1);
-//If set to a number greater than 0, msg compose windows will be recycled in order to open them quickly
-pref("mail.compose.max_recycled_windows", 1);
 
 // from/recipient columns will be replaced with correspondents column
 pref("mailnews.ui.upgrade.correspondents", true);
 
 // default description and color prefs for tags
 // (we keep the .labels. names for backwards compatibility)
 pref("mailnews.labels.description.1", "chrome://messenger/locale/messenger.properties");
 pref("mailnews.labels.description.2", "chrome://messenger/locale/messenger.properties");
--- a/suite/mailnews/compose/MsgComposeCommands.js
+++ b/suite/mailnews/compose/MsgComposeCommands.js
@@ -138,97 +138,16 @@ function enableEditableFields()
 {
   gMsgCompose.editor.flags &= ~nsIPlaintextEditorMail.eEditorReadonlyMask;
   var enableElements = document.getElementsByAttribute("disableonsend", "true");
   for (let i = 0; i < enableElements.length; i++)
     enableElements[i].removeAttribute('disabled');
 
 }
 
-var gComposeRecyclingListener = {
-  onClose: function() {
-    //Reset recipients and attachments
-    awResetAllRows();
-    RemoveAllAttachments();
-
-    // We need to clear the identity popup menu in case the user will change them. It will be rebuilded later in ComposeStartup
-    ClearIdentityListPopup(document.getElementById("msgIdentityPopup"));
-
-    // Stop listening to changes in the spell check dictionary.
-    document.removeEventListener("spellcheck-changed", updateDocumentLanguage);
-
-    // Stop InlineSpellCheckerUI so personal dictionary is saved.
-    // We need to do this before disabling the editor.
-    EnableInlineSpellCheck(false);
-    // clear any suggestions in the context menu
-    InlineSpellCheckerUI.clearSuggestionsFromMenu();
-    InlineSpellCheckerUI.clearDictionaryListFromMenu();
-
-    //Clear the subject
-    GetMsgSubjectElement().value = "";
-    SetComposeWindowTitle();
-
-    SetContentAndBodyAsUnmodified();
-    disableEditableFields();
-    ReleaseGlobalVariables();
-
-    // Clear the focus
-    awGetInputElement(1).removeAttribute('focused');
-
-    //Reset Boxes size
-    document.getElementById("compose-toolbox").removeAttribute("height");
-    document.getElementById("appcontent").removeAttribute("height");
-    document.getElementById("addresses-box").removeAttribute("width");
-    document.getElementById("attachments-box").removeAttribute("width");
-
-    //Reset menu options
-    document.getElementById("format_auto").setAttribute("checked", "true");
-
-    //Reset toolbars that could be hidden
-    if (gHideMenus) {
-      document.getElementById("formatMenu").hidden = false;
-      document.getElementById("insertMenu").hidden = false;
-      var showFormat = document.getElementById("menu_showFormatToolbar")
-      showFormat.hidden = false;
-      if (showFormat.getAttribute("checked") == "true")
-        document.getElementById("FormatToolbar").hidden = false;
-    }
-
-    //Reset the Customize Toolbars panel/sheet if open.
-    if (getMailToolbox().customizing && gCustomizeSheet)
-      document.getElementById("customizeToolbarSheetIFrame")
-              .contentWindow.finishToolbarCustomization();
-
-    //Reset editor
-    EditorResetFontAndColorAttributes();
-    EditorCleanup();
-
-    //Release the nsIMsgComposeParams object
-    if (window.arguments && window.arguments[0])
-      window.arguments[0] = null;
-
-    var event = document.createEvent('Events');
-    event.initEvent('compose-window-close', false, true);
-    document.getElementById("msgcomposeWindow").dispatchEvent(event);
-    if (gAutoSaveTimeout)
-      clearTimeout(gAutoSaveTimeout);
-  },
-
-  onReopen: function(params) {
-    // Reset focus to avoid undesirable visual effect when reopening the window
-
-    InitializeGlobalVariables();
-    ComposeStartup(true, params);
-
-    var event = document.createEvent('Events');
-    event.initEvent('compose-window-reopen', false, true);
-    document.getElementById("msgcomposeWindow").dispatchEvent(event);
-  }
-};
-
 var stateListener = {
   NotifyComposeFieldsReady: function() {
     ComposeFieldsReady();
   },
 
   NotifyComposeBodyReady: function() {
     if (gMsgCompose.composeHTML)
       loadHTMLMsgPrefs();
@@ -246,17 +165,17 @@ var stateListener = {
         SetContentAndBodyAsUnmodified();
 
       if (gCloseWindowAfterSave)
       {
         // Notify the SendListener that Send has been aborted and Stopped
         if (gMsgCompose)
           gMsgCompose.onSendNotPerformed(null, Components.results.NS_ERROR_ABORT);
 
-        MsgComposeCloseWindow(true);
+        MsgComposeCloseWindow();
       }
     }
     // else if we failed to save, and we're autosaving, need to re-mark the editor
     // as changed, so that we won't lose the changes.
     else if (gAutoSaving)
     {
       gMsgCompose.bodyModified = true;
       gContentChanged = true;
@@ -729,17 +648,17 @@ function MessageComposeOfflineStateChang
 function DoCommandClose()
 {
   if (ComposeCanClose()) {
     // Notify the SendListener that Send has been aborted and Stopped
     if (gMsgCompose)
       gMsgCompose.onSendNotPerformed(null, Components.results.NS_ERROR_ABORT);
 
     // note: if we're not caching this window, this destroys it for us
-    MsgComposeCloseWindow(true);
+    MsgComposeCloseWindow();
   }
 
   return false;
 }
 
 function DoCommandPreferences()
 {
   goPreferences('composing_messages_pane');
@@ -925,17 +844,17 @@ function handleMailtoArgs(mailtoUrl)
 
     if (uri)
       return sMsgComposeService.getParamsForMailto(uri);
   }
 
   return null;
 }
 
-function ComposeStartup(recycled, aParams)
+function ComposeStartup(aParams)
 {
   var params = null; // New way to pass parameters to the compose window as a nsIMsgComposeParameters object
   var args = null;   // old way, parameters are passed as a string
 
   if (aParams)
     params = aParams;
   else if (window.arguments && window.arguments[0]) {
     try {
@@ -1050,63 +969,53 @@ function ComposeStartup(recycled, aParam
   if (sMsgComposeService)
   {
     // Get the <editor> element to startup an editor
     var editorElement = GetCurrentEditorElement();
     gMsgCompose = sMsgComposeService.initCompose(params, window,
                                                  editorElement.docShell);
     if (gMsgCompose)
     {
-      // set the close listener
-      gMsgCompose.recyclingListener = gComposeRecyclingListener;
-
-      //Lets the compose object knows that we are dealing with a recycled window
-      gMsgCompose.recycledWindow = recycled;
-
       if (!editorElement)
       {
         dump("Failed to get editor element!\n");
         return;
       }
 
       document.getElementById("returnReceiptMenu")
               .setAttribute("checked", gMsgCompose.compFields.returnReceipt);
       document.getElementById("dsnMenu")
               .setAttribute('checked', gMsgCompose.compFields.DSN);
       document.getElementById("cmd_attachVCard")
               .setAttribute("checked", gMsgCompose.compFields.attachVCard);
       document.getElementById("menu_inlineSpellCheck")
               .setAttribute("checked", getPref("mail.spellcheck.inline"));
 
-      // If recycle, editor is already created
-      if (!recycled)
+      try {
+        var editortype = gMsgCompose.composeHTML ? "htmlmail" : "textmail";
+        editorElement.makeEditable(editortype, true);
+      } catch (e) { dump(" FAILED TO START EDITOR: "+e+"\n"); }
+
+      // setEditorType MUST be call before setContentWindow
+      if (gMsgCompose.composeHTML)
       {
-        try {
-          var editortype = gMsgCompose.composeHTML ? "htmlmail" : "textmail";
-          editorElement.makeEditable(editortype, true);
-        } catch (e) { dump(" FAILED TO START EDITOR: "+e+"\n"); }
-
-        // setEditorType MUST be call before setContentWindow
-        if (gMsgCompose.composeHTML)
-        {
-          initLocalFontFaceMenu(document.getElementById("FontFacePopup"));
-        }
-        else
-        {
-          //Remove HTML toolbar, format and insert menus as we are editing in plain text mode
-          document.getElementById("outputFormatMenu").setAttribute("hidden", true);
-          document.getElementById("FormatToolbar").setAttribute("hidden", true);
-          document.getElementById("formatMenu").setAttribute("hidden", true);
-          document.getElementById("insertMenu").setAttribute("hidden", true);
-          document.getElementById("menu_showFormatToolbar").setAttribute("hidden", true);
-        }
-
-        // Do setup common to Message Composer and Web Composer
-        EditorSharedStartup();
+        initLocalFontFaceMenu(document.getElementById("FontFacePopup"));
       }
+      else
+      {
+        //Remove HTML toolbar, format and insert menus as we are editing in plain text mode
+        document.getElementById("outputFormatMenu").setAttribute("hidden", true);
+        document.getElementById("FormatToolbar").setAttribute("hidden", true);
+        document.getElementById("formatMenu").setAttribute("hidden", true);
+        document.getElementById("insertMenu").setAttribute("hidden", true);
+        document.getElementById("menu_showFormatToolbar").setAttribute("hidden", true);
+      }
+
+      // Do setup common to Message Composer and Web Composer
+      EditorSharedStartup();
 
       var msgCompFields = gMsgCompose.compFields;
       if (msgCompFields)
       {
         if (params.bodyIsLink)
         {
           var body = msgCompFields.body;
           if (gMsgCompose.composeHTML)
@@ -1133,45 +1042,30 @@ function ComposeStartup(recycled, aParam
       }
 
       var event = document.createEvent('Events');
       event.initEvent('compose-window-init', false, true);
       document.getElementById("msgcomposeWindow").dispatchEvent(event);
 
       gMsgCompose.RegisterStateListener(stateListener);
 
-      if (recycled)
-      {
-        InitEditor(GetCurrentEditor());
-
-        if (gMsgCompose.composeHTML)
-        {
-          // Force color picker on toolbar to show document colors
-          onFontColorChange();
-          onBackgroundColorChange();
-          // XXX todo: reset paragraph select to "Body Text"
-        }
-      }
-      else
-      {
-        // Add an observer to be called when document is done loading,
-        //   which creates the editor
-        try {
-          GetCurrentCommandManager().
-                addCommandObserver(gMsgEditorCreationObserver, "obs_documentCreated");
-
-          // Load empty page to create the editor
-          editorElement.webNavigation.loadURI("about:blank", // uri string
-                               0,                            // load flags
-                               null,                         // referrer
-                               null,                         // post-data stream
-                               null);
-        } catch (e) {
-          dump(" Failed to startup editor: "+e+"\n");
-        }
+      // Add an observer to be called when document is done loading,
+      //   which creates the editor
+      try {
+        GetCurrentCommandManager().
+              addCommandObserver(gMsgEditorCreationObserver, "obs_documentCreated");
+
+        // Load empty page to create the editor
+        editorElement.webNavigation.loadURI("about:blank", // uri string
+                             0,                            // load flags
+                             null,                         // referrer
+                             null,                         // post-data stream
+                             null);
+      } catch (e) {
+        dump(" Failed to startup editor: "+e+"\n");
       }
     }
   }
 
   // create URI of the folder from draftId
   var draftId = msgCompFields.draftId;
   var folderURI = draftId.substring(0, draftId.indexOf("#")).replace("-message", "");
 
@@ -1223,17 +1117,17 @@ var gMsgEditorCreationObserver =
 function WizCallback(state)
 {
   if (state){
     ComposeStartup(false, null);
   }
   else
   {
     // The account wizard is still closing so we can't close just yet
-    setTimeout(MsgComposeCloseWindow, 0, false); // Don't recycle a bogus window
+    setTimeout(MsgComposeCloseWindow, 0);
   }
 }
 
 function ComposeLoad()
 {
   sComposeMsgsBundle = document.getElementById("bundle_composeMsgs");
   sBrandBundle = document.getElementById("brandBundle");
 
@@ -1264,17 +1158,17 @@ function ComposeLoad()
       ComposeStartup(false, null);
   }
   catch (ex) {
     Components.utils.reportError(ex);
     var errorTitle = sComposeMsgsBundle.getString("initErrorDlogTitle");
     var errorMsg = sComposeMsgsBundle.getString("initErrorDlgMessage");
     Services.prompt.alert(window, errorTitle, errorMsg);
 
-    MsgComposeCloseWindow(false); // Don't try to recycle a bogus window
+    MsgComposeCloseWindow();
     return;
   }
   if (gLogComposePerformance)
     sMsgComposeService.TimeStamp("Done with the initialization (ComposeLoad). Waiting on editor to load about:blank", false);
 
   // Before and after callbacks for the customizeToolbar code
   var mailToolbox = getMailToolbox();
   mailToolbox.customizeInit = MailToolboxCustomizeInit;
@@ -2157,20 +2051,20 @@ function RemoveDraft()
 }
 
 function SetContentAndBodyAsUnmodified()
 {
   gMsgCompose.bodyModified = false;
   gContentChanged = false;
 }
 
-function MsgComposeCloseWindow(recycleIt)
+function MsgComposeCloseWindow()
 {
   if (gMsgCompose)
-    gMsgCompose.CloseWindow(recycleIt);
+    gMsgCompose.CloseWindow();
   else
     window.close();
 }
 
 // attachedLocalFile must be a nsILocalFile
 function SetLastAttachDirectory(attachedLocalFile)
 {
   try {
--- a/suite/profile/migration/src/nsThunderbirdProfileMigrator.cpp
+++ b/suite/profile/migration/src/nsThunderbirdProfileMigrator.cpp
@@ -278,17 +278,16 @@ nsThunderbirdProfileMigrator::PrefTransf
   MAKESAMETYPEPREFTRANSFORM("mail.collect_email_address_incoming",     Bool),
   MAKESAMETYPEPREFTRANSFORM("mail.collect_email_address_newsgroup",    Bool),
   MAKESAMETYPEPREFTRANSFORM("mail.collect_email_address_outgoing",     Bool),
   MAKESAMETYPEPREFTRANSFORM("mail.compose.add_undisclosed_recipients", Bool),
   MAKESAMETYPEPREFTRANSFORM("mail.compose.autosave",                   Bool),
   MAKESAMETYPEPREFTRANSFORM("mail.compose.autosaveinterval",           Int),
   MAKESAMETYPEPREFTRANSFORM("mail.compose.dont_attach_source_of_local_network_links", Bool),
   MAKESAMETYPEPREFTRANSFORM("mail.compose.dontWarnMail2Newsgroup",     Bool),
-  MAKESAMETYPEPREFTRANSFORM("mail.compose.max_recycled_windows",       Int),
   MAKESAMETYPEPREFTRANSFORM("mail.compose.other.header",               String),
   MAKESAMETYPEPREFTRANSFORM("mail.compose.wrap_to_window_width",       Bool),
   MAKESAMETYPEPREFTRANSFORM("mail.content_disposition_type",           Int),
 
   MAKESAMETYPEPREFTRANSFORM("mail.default_html_action",                Int),
   MAKESAMETYPEPREFTRANSFORM("mail.default_sendlater_uri",              String),
   MAKESAMETYPEPREFTRANSFORM("mail.delete_matches_sort_order",          Bool),
   MAKESAMETYPEPREFTRANSFORM("mail.display_glyph",                      Bool),