Bug 1682941 - Remove nsISimpleEnumerator from nsIMsgFolder.subFolders property. r=mkmelin
authorBen Campbell <benc@thunderbird.net>
Fri, 12 Feb 2021 21:31:17 +1300
changeset 41303 d0c8f7c8585e0f485a80f67ccb483b329115eedd
parent 41302 0587ca622bb8502e2553c96f69681d2832bd56b4
child 41304 4cce61b48bab9cf6af62c5b3b13bd77764d4fb85
push id2979
push userthunderbird@calypsoblue.org
push dateMon, 22 Feb 2021 19:16:38 +0000
treeherdercomm-beta@259046204c22 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1682941
Bug 1682941 - Remove nsISimpleEnumerator from nsIMsgFolder.subFolders property. r=mkmelin
mail/base/content/folderPane.js
mail/base/content/msgViewNavigation.js
mail/components/extensions/parent/ext-mail.js
mail/components/extensions/test/browser/browser_ext_commands_execute_message_display_action.js
mail/components/extensions/test/browser/browser_ext_menus.js
mail/components/extensions/test/browser/browser_ext_messageDisplayAction.js
mail/components/extensions/test/browser/browser_ext_quickFilter.js
mail/components/extensions/test/browser/browser_ext_tabs_content.js
mail/components/extensions/test/xpcshell/test_ext_accounts.js
mail/components/im/IMIncomingServer.jsm
mail/extensions/openpgp/content/modules/autoSetup.jsm
mail/test/browser/folder-pane/browser_folderNamesInRecentMode.js
mailnews/base/content/folder-menupopup.js
mailnews/base/public/nsIMsgFolder.idl
mailnews/base/src/nsMsgAccount.cpp
mailnews/base/src/nsMsgAccountManager.cpp
mailnews/base/src/nsMsgDBFolder.cpp
mailnews/extensions/newsblog/test/browser/browser_feedDisplay.js
mailnews/imap/src/nsImapIncomingServer.cpp
mailnews/imap/src/nsImapMailFolder.cpp
mailnews/imap/src/nsImapMailFolder.h
mailnews/import/src/nsBeckyFilters.cpp
mailnews/import/src/nsImportMail.cpp
mailnews/import/test/unit/resources/import_helper.js
mailnews/local/src/nsLocalMailFolder.cpp
mailnews/local/src/nsLocalMailFolder.h
mailnews/local/src/nsMsgBrkMBoxStore.cpp
mailnews/local/src/nsMsgMaildirStore.cpp
mailnews/local/src/nsPop3IncomingServer.cpp
mailnews/news/src/nsNewsFolder.cpp
mailnews/news/src/nsNewsFolder.h
mailnews/news/src/nsNntpIncomingServer.cpp
suite/mailnews/content/SearchDialog.js
suite/mailnews/content/folderPane.js
suite/mailnews/content/mailContextMenus.js
suite/mailnews/content/msgViewNavigation.js
--- a/mail/base/content/folderPane.js
+++ b/mail/base/content/folderPane.js
@@ -1368,17 +1368,17 @@ var gFolderTreeView = {
     if (this._tree) {
       this._tree.rowCountChanged(aIndex + 1, -1 * count);
       this.clearFolderCacheProperty(this._rowMap[aIndex]._folder, "properties");
       this._tree.invalidateRow(aIndex);
     }
   },
 
   _subFoldersWithStringProperty(folder, folders, aFolderName, deep) {
-    for (let child of fixIterator(folder.subFolders, Ci.nsIMsgFolder)) {
+    for (let child of folder.subFolders) {
       // if the folder selection is based on a string property, use that
       if (aFolderName == getSmartFolderName(child)) {
         folders.push(child);
         // Add sub-folders if requested.
         if (deep) {
           this.addSubFolders(child, folders);
         }
       } else {
@@ -2608,17 +2608,17 @@ var gFolderTreeView = {
   /**
    * This is a recursive function to add all subfolders to the array. It
    * assumes that the passed in folder itself has already been added.
    *
    * @param aFolder  the folder whose subfolders should be added
    * @param folders  the array to add the folders to.
    */
   addSubFolders(folder, folders) {
-    for (let f of fixIterator(folder.subFolders, Ci.nsIMsgFolder)) {
+    for (let f of folder.subFolders) {
       folders.push(f);
       this.addSubFolders(f, folders);
     }
   },
 
   /**
    * This updates the rowmap and invalidates the right row(s) in the tree
    */
@@ -3190,32 +3190,32 @@ FtvItem.prototype = {
       MsgOpenNewWindowForFolder(this._folder.URI, -1 /* key */);
     }
   },
 
   _children: null,
   get children() {
     // We're caching our child list to save perf.
     if (!this._children) {
-      let iter;
+      let subFolders;
       try {
-        iter = fixIterator(this._folder.subFolders, Ci.nsIMsgFolder);
+        subFolders = this._folder.subFolders;
       } catch (ex) {
         Services.console.logStringMessage(
           "Discovering children for " +
             this._folder.URI +
             " failed with exception: " +
             ex
         );
-        iter = [];
+        subFolders = [];
       }
       this._children = [];
       // Out of all children, only keep those that match the _folderFilter
       // and those that contain such children.
-      for (let folder of iter) {
+      for (let folder of subFolders) {
         if (!this._folderFilter || this._folderFilter(folder)) {
           this._children.push(new FtvItem(folder, this._folderFilter));
         }
       }
       sortFolderItems(this._children);
       // Each child is a level one below us
       for (let child of this._children) {
         child._level = this._level + 1;
@@ -3873,23 +3873,21 @@ function FtvSmartItem(aFolder) {
 FtvSmartItem.prototype = {
   __proto__: FtvItem.prototype,
   get children() {
     let smartMode = gFolderTreeView.getFolderTreeMode("smart");
 
     // We're caching our child list to save perf.
     if (!this._children) {
       this._children = [];
-      let iter = fixIterator(this._folder.subFolders, Ci.nsIMsgFolder);
-      for (let folder of iter) {
+      for (let folder of this._folder.subFolders) {
         if (!smartMode.isSmartFolder(folder)) {
           this._children.push(new FtvSmartItem(folder));
         } else if (folder.getFlag(Ci.nsMsgFolderFlags.Inbox)) {
-          let subIter = fixIterator(folder.subFolders, Ci.nsIMsgFolder);
-          for (let subfolder of subIter) {
+          for (let subfolder of folder.subFolders) {
             if (!smartMode.isSmartFolder(subfolder)) {
               this._children.push(new FtvSmartItem(subfolder));
             }
           }
         }
       }
       sortFolderItems(this._children);
       // Each child is a level one below us
--- a/mail/base/content/msgViewNavigation.js
+++ b/mail/base/content/msgViewNavigation.js
@@ -11,28 +11,21 @@
 /* import-globals-from messageDisplay.js */
 
 var { allAccountsSorted } = ChromeUtils.import(
   "resource:///modules/folderUtils.jsm"
 );
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 function GetSubFoldersInFolderPaneOrder(folder) {
-  var msgFolders = [];
-
-  // get all the subfolders
-  msgFolders = [...folder.subFolders];
-
   function compareFolderSortKey(folder1, folder2) {
     return folder1.compareSortKeys(folder2);
   }
-
   // sort the subfolders
-  msgFolders.sort(compareFolderSortKey);
-  return msgFolders;
+  return folder.subFolders.sort(compareFolderSortKey);
 }
 
 function FindNextChildFolder(aParent, aAfter) {
   // Search the child folders of aParent for unread messages
   // but in the case that we are working up from the current folder
   // we need to skip up to and including the current folder
   // we skip the current folder in case a mail view is hiding unread messages
   if (aParent.getNumUnread(true) > 0) {
--- a/mail/components/extensions/parent/ext-mail.js
+++ b/mail/components/extensions/parent/ext-mail.js
@@ -1510,17 +1510,17 @@ function convertFolder(folder, accountId
  * @param {nsIMsgFolder} folder - The folder to convert.
  * @param {string} [accountId] - An optimization to avoid looking up the
  *     account. The value from nsIMsgHdr.accountKey must not be used here.
  * @return {Array}
  */
 function traverseSubfolders(folder, accountId) {
   let f = convertFolder(folder, accountId);
   f.subFolders = [];
-  for (let subFolder of fixIterator(folder.subFolders, Ci.nsIMsgFolder)) {
+  for (let subFolder of folder.subFolders) {
     f.subFolders.push(traverseSubfolders(subFolder, accountId || f.accountId));
   }
   return f;
 }
 
 class FolderManager {
   constructor(extension) {
     this.extension = extension;
--- a/mail/components/extensions/test/browser/browser_ext_commands_execute_message_display_action.js
+++ b/mail/components/extensions/test/browser/browser_ext_commands_execute_message_display_action.js
@@ -137,17 +137,17 @@ async function testExecuteMessageDisplay
   }
 
   await extension.unload();
 }
 
 add_task(async function prepare_test() {
   let account = createAccount();
   let rootFolder = account.incomingServer.rootFolder;
-  let subFolders = [...rootFolder.subFolders];
+  let subFolders = rootFolder.subFolders;
   createMessages(subFolders[0], 10);
   gMessages = [...subFolders[0].messages];
 
   window.gFolderTreeView.selectFolder(subFolders[0]);
   window.gFolderDisplay.selectViewIndex(0);
   await BrowserTestUtils.browserLoaded(window.getMessagePaneBrowser());
 });
 
--- a/mail/components/extensions/test/browser/browser_ext_menus.js
+++ b/mail/components/extensions/test/browser/browser_ext_menus.js
@@ -253,17 +253,17 @@ function createExtension(...permissions)
   });
 }
 
 add_task(async function set_up() {
   await Services.search.init();
 
   gAccount = createAccount();
   addIdentity(gAccount);
-  gFolders = [...gAccount.incomingServer.rootFolder.subFolders];
+  gFolders = gAccount.incomingServer.rootFolder.subFolders;
   createMessages(gFolders[0], {
     count: 1,
     body: {
       contentType: "text/html",
       body: await fetch(`${URL_BASE}/content.html`).then(r => r.text()),
     },
   });
   gMessage = gFolders[0].messages.getNext().QueryInterface(Ci.nsIMsgDBHdr);
--- a/mail/components/extensions/test/browser/browser_ext_messageDisplayAction.js
+++ b/mail/components/extensions/test/browser/browser_ext_messageDisplayAction.js
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 let account;
 
 add_task(async () => {
   account = createAccount();
   let rootFolder = account.incomingServer.rootFolder;
-  let subFolders = [...rootFolder.subFolders];
+  let subFolders = rootFolder.subFolders;
   createMessages(subFolders[0], 10);
 
   window.gFolderTreeView.selectFolder(subFolders[0]);
   window.gFolderDisplay.selectViewIndex(0);
   await BrowserTestUtils.browserLoaded(window.getMessagePaneBrowser());
 });
 
 add_task(async () => {
--- a/mail/components/extensions/test/browser/browser_ext_quickFilter.js
+++ b/mail/components/extensions/test/browser/browser_ext_quickFilter.js
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 let account, rootFolder, subFolders;
 
 add_task(async () => {
   account = createAccount();
   rootFolder = account.incomingServer.rootFolder;
-  subFolders = [...rootFolder.subFolders];
+  subFolders = rootFolder.subFolders;
   createMessages(subFolders[0], 10);
 
   window.gFolderTreeView.selectFolder(rootFolder);
   await new Promise(resolve => executeSoon(resolve));
 });
 
 add_task(async () => {
   async function background() {
--- a/mail/components/extensions/test/browser/browser_ext_tabs_content.js
+++ b/mail/components/extensions/test/browser/browser_ext_tabs_content.js
@@ -135,17 +135,17 @@ add_task(async function testFirstTab() {
     document.getElementById("folderpane_splitter").getAttribute("state") ==
     "collapsed"
   ) {
     window.MsgToggleFolderPane();
   }
 
   let gAccount = createAccount();
   window.gFolderTreeView.selectFolder(
-    [...gAccount.incomingServer.rootFolder.subFolders][0]
+    gAccount.incomingServer.rootFolder.subFolders[0]
   );
   window.ClearMessagePane();
   return subTest(createTab, getBrowser, false);
 });
 
 add_task(async function testContentTab() {
   let createTab = async () => {
     window.createTab = async function() {
--- a/mail/components/extensions/test/xpcshell/test_ext_accounts.js
+++ b/mail/components/extensions/test/xpcshell/test_ext_accounts.js
@@ -175,22 +175,22 @@ add_task(async function test_accounts() 
   IMAPServer.open();
   account2.incomingServer.port = IMAPServer.port;
   account2.incomingServer.username = "user";
   account2.incomingServer.password = "password";
   MailServices.accounts.defaultAccount = account2;
   extension.sendMessage(account2.key, account2.incomingServer.prettyName);
 
   await extension.awaitMessage("create folders");
-  let inbox1 = [...account1.incomingServer.rootFolder.subFolders][0];
+  let inbox1 = account1.incomingServer.rootFolder.subFolders[0];
   // Test our code can handle characters that might be escaped.
   inbox1.createSubfolder("foo 'bar'(!)", null);
   inbox1.createSubfolder("Ϟ", null); // Test our code can handle unicode.
 
-  let inbox2 = [...account2.incomingServer.rootFolder.subFolders][0];
+  let inbox2 = account2.incomingServer.rootFolder.subFolders[0];
   inbox2.QueryInterface(Ci.nsIMsgImapMailFolder).hierarchyDelimiter = "/";
   // Test our code can handle characters that might be escaped.
   inbox2.createSubfolder("foo 'bar'(!)", null);
   await PromiseTestUtils.promiseFolderAdded("foo 'bar'(!)");
   inbox2.createSubfolder("Ϟ", null); // Test our code can handle unicode.
   await PromiseTestUtils.promiseFolderAdded("Ϟ");
 
   extension.sendMessage();
--- a/mail/components/im/IMIncomingServer.jsm
+++ b/mail/components/im/IMIncomingServer.jsm
@@ -1,17 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var EXPORTED_SYMBOLS = ["IMIncomingServer"];
 
-var { EmptyEnumerator } = ChromeUtils.import(
-  "resource:///modules/imXPCOMUtils.jsm"
-);
 var { Services } = ChromeUtils.import("resource:///modules/imServices.jsm");
 
 function IMIncomingServer() {}
 
 IMIncomingServer.prototype = {
   get wrappedJSObject() {
     return this;
   },
@@ -322,17 +319,17 @@ IMIncomingServer.prototype = {
       },
       AddFolderListener() {},
       RemoveFolderListener() {},
       descendants: [],
       getFlag: () => false,
       getFolderWithFlags: aFlags => null,
       getFoldersWithFlags: aFlags => [],
       get subFolders() {
-        return EmptyEnumerator;
+        return [];
       },
       getStringProperty: aPropertyName => "",
       getNumUnread: aDeep => 0,
       Shutdown() {},
       QueryInterface: ChromeUtils.generateQI(["nsIMsgFolder"]),
     });
   },
 
--- a/mail/extensions/openpgp/content/modules/autoSetup.jsm
+++ b/mail/extensions/openpgp/content/modules/autoSetup.jsm
@@ -411,20 +411,18 @@ var EnigmailAutoSetup = {
  */
 
 function getMsgFolders(folder, msgFolderArr) {
   if (folder.getTotalMessages(false) > 0) {
     msgFolderArr.push(folder);
   }
 
   // add all subfolders
-  if (folder.hasSubFolders) {
-    for (let folder of folder.subFolders) {
-      getMsgFolders(folder, msgFolderArr);
-    }
+  for (let folder of folder.subFolders) {
+    getMsgFolders(folder, msgFolderArr);
   }
 }
 
 // Util Function for Extracting manually added Headers
 function streamListener(callback) {
   let streamListener = {
     mAttachments: [],
     mHeaders: [],
--- a/mail/test/browser/folder-pane/browser_folderNamesInRecentMode.js
+++ b/mail/test/browser/folder-pane/browser_folderNamesInRecentMode.js
@@ -17,34 +17,28 @@ var {
   mc,
 } = ChromeUtils.import(
   "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
 );
 
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
-var { fixIterator } = ChromeUtils.import(
-  "resource:///modules/iteratorUtils.jsm"
-);
 
 add_task(function setupModule(module) {
   assert_folder_mode("all");
   assert_folder_tree_view_row_count(7);
 });
 
 add_task(function test_folder_names_in_recent_view_mode() {
   // We need 2 local accounts that have pristine folders with
   // unmodified times, so that it does not influence the
   // list of Recent folders. So clear out the most-recently-used time.
   for (let acc of MailServices.accounts.accounts) {
-    for (let fld of fixIterator(
-      acc.incomingServer.rootFolder.subFolders,
-      Ci.nsIMsgFolder
-    )) {
+    for (let fld of acc.incomingServer.rootFolder.subFolders) {
       fld.setStringProperty("MRUTime", "0");
     }
   }
 
   let acc1 = MailServices.accounts.accounts[1];
   let acc2 = MailServices.accounts.accounts[0];
   let rootFolder1 = acc1.incomingServer.rootFolder;
   let rootFolder2 = acc2.incomingServer.rootFolder;
--- a/mailnews/base/content/folder-menupopup.js
+++ b/mailnews/base/content/folder-menupopup.js
@@ -13,19 +13,16 @@
 {
   const { FeedUtils } = ChromeUtils.import("resource:///modules/FeedUtils.jsm");
   const {
     allAccountsSorted,
     folderNameCompare,
     getSpecialFolderString,
     getMostRecentFolders,
   } = ChromeUtils.import("resource:///modules/folderUtils.jsm");
-  const { fixIterator, toArray } = ChromeUtils.import(
-    "resource:///modules/iteratorUtils.jsm"
-  );
   const { MailServices } = ChromeUtils.import(
     "resource:///modules/MailServices.jsm"
   );
   const { MailUtils } = ChromeUtils.import("resource:///modules/MailUtils.jsm");
   const { Services } = ChromeUtils.import(
     "resource://gre/modules/Services.jsm"
   );
 
@@ -445,19 +442,17 @@
        * @param {string[]} excludeServers    Server keys for the servers to exclude.
        * @param {Function} [filterFunction]  Function for filtering the folders.
        */
       _getFolders(parentFolder, excludeServers, filterFunction) {
         let folders;
 
         // If we have a parent folder, just get the subFolders for that parent.
         if (parentFolder) {
-          folders = toArray(
-            fixIterator(parentFolder.subFolders, Ci.nsIMsgFolder)
-          );
+          folders = parentFolder.subFolders;
         } else {
           // If we don't have a parent, then we assume we should build the
           // top-level accounts. (Actually we build the fake root folders for
           // those accounts.)
           let accounts = allAccountsSorted(true);
 
           // Now generate our folder list. Note that we'll special case this
           // situation elsewhere, to avoid destroying the sort order we just made.
--- a/mailnews/base/public/nsIMsgFolder.idl
+++ b/mailnews/base/public/nsIMsgFolder.idl
@@ -648,20 +648,20 @@ interface nsIMsgFolder : nsISupports {
 
   ACString getStringProperty(in string propertyName);
   void setStringProperty(in string propertyName, in ACString propertyValue);
 
   /* does not persist across sessions */
   attribute nsMsgKey lastMessageLoaded;
 
   /**
-   * Returns an enumerator containing a list of nsIMsgFolder items that are
+   * Returns an array containing nsIMsgFolder items that are
    * subfolders of the instance this is called on.
    */
-  readonly attribute nsISimpleEnumerator subFolders;
+  readonly attribute Array<nsIMsgFolder> subFolders;
 
   /**
    * Returns true if this folder has sub folders.
    */
   readonly attribute boolean hasSubFolders;
 
   /**
    * Returns the number of sub folders that this folder has.
--- a/mailnews/base/src/nsMsgAccount.cpp
+++ b/mailnews/base/src/nsMsgAccount.cpp
@@ -133,27 +133,21 @@ nsMsgAccount::SetIncomingServer(nsIMsgIn
     notifier->NotifyFolderAdded(rootFolder);
 
     nsCOMPtr<nsIMsgAccountManager> accountManager =
         do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
     if (NS_SUCCEEDED(rv)) accountManager->NotifyServerLoaded(aIncomingServer);
 
     // Force built-in folders to be created and discovered. Then, notify
     // listeners about them.
-    nsCOMPtr<nsISimpleEnumerator> enumerator;
-    rv = rootFolder->GetSubFolders(getter_AddRefs(enumerator));
+    nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+    rv = rootFolder->GetSubFolders(subFolders);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    bool hasMore;
-    while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
-      nsCOMPtr<nsISupports> item;
-      enumerator->GetNext(getter_AddRefs(item));
-
-      nsCOMPtr<nsIMsgFolder> msgFolder(do_QueryInterface(item));
-      if (!msgFolder) continue;
+    for (nsIMsgFolder* msgFolder : subFolders) {
       mailSession->OnItemAdded(rootFolder, msgFolder);
       notifier->NotifyFolderAdded(msgFolder);
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/mailnews/base/src/nsMsgAccountManager.cpp
+++ b/mailnews/base/src/nsMsgAccountManager.cpp
@@ -1469,35 +1469,26 @@ nsMsgAccountManager::CleanupOnExit() {
           nsCOMPtr<nsIUrlListener> urlListener;
           nsCOMPtr<nsIMsgAccountManager> accountManager =
               do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
           if (NS_FAILED(rv)) continue;
 
           if (isImap) urlListener = do_QueryInterface(accountManager, &rv);
 
           if (isImap && cleanupInboxOnExit) {
-            nsCOMPtr<nsISimpleEnumerator> enumerator;
-            rv = root->GetSubFolders(getter_AddRefs(enumerator));
+            nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+            rv = root->GetSubFolders(subFolders);
             if (NS_SUCCEEDED(rv)) {
-              bool hasMore;
-              while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) &&
-                     hasMore) {
-                nsCOMPtr<nsISupports> item;
-                enumerator->GetNext(getter_AddRefs(item));
-
-                nsCOMPtr<nsIMsgFolder> inboxFolder(do_QueryInterface(item));
-                if (!inboxFolder) continue;
-
+              for (nsIMsgFolder* folder : subFolders) {
                 uint32_t flags;
-                inboxFolder->GetFlags(&flags);
+                folder->GetFlags(&flags);
                 if (flags & nsMsgFolderFlags::Inbox) {
-                  rv = inboxFolder->Compact(urlListener,
-                                            nullptr /* msgwindow */);
+                  rv = folder->Compact(urlListener, nullptr /* msgwindow */);
                   if (NS_SUCCEEDED(rv))
-                    accountManager->SetFolderDoingCleanupInbox(inboxFolder);
+                    accountManager->SetFolderDoingCleanupInbox(folder);
                   break;
                 }
               }
             }
           }
 
           if (emptyTrashOnExit) {
             rv = root->EmptyTrash(nullptr, urlListener);
--- a/mailnews/base/src/nsMsgDBFolder.cpp
+++ b/mailnews/base/src/nsMsgDBFolder.cpp
@@ -2659,20 +2659,23 @@ nsMsgDBFolder::GetURI(nsACString& name) 
 ////////////////////////////////////////////////////////////////////////////////
 #if 0
 typedef bool
 (*nsArrayFilter)(nsISupports* element, void* data);
 #endif
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP
-nsMsgDBFolder::GetSubFolders(nsISimpleEnumerator** aResult) {
-  return aResult ? NS_NewArrayEnumerator(aResult, mSubFolders,
-                                         NS_GET_IID(nsIMsgFolder))
-                 : NS_ERROR_NULL_POINTER;
+nsMsgDBFolder::GetSubFolders(nsTArray<RefPtr<nsIMsgFolder>>& folders) {
+  folders.ClearAndRetainStorage();
+  folders.SetCapacity(mSubFolders.Length());
+  for (nsIMsgFolder* f : mSubFolders) {
+    folders.AppendElement(f);
+  }
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsMsgDBFolder::FindSubFolder(const nsACString& aEscapedSubFolderName,
                              nsIMsgFolder** aFolder) {
   // XXX use necko here
   nsAutoCString uri;
   uri.Append(mURI);
@@ -3108,71 +3111,63 @@ NS_IMETHODIMP nsMsgDBFolder::SetName(con
 // For default, just return name
 NS_IMETHODIMP nsMsgDBFolder::GetAbbreviatedName(nsAString& aAbbreviatedName) {
   return GetName(aAbbreviatedName);
 }
 
 NS_IMETHODIMP
 nsMsgDBFolder::GetChildNamed(const nsAString& aName, nsIMsgFolder** aChild) {
   NS_ENSURE_ARG_POINTER(aChild);
-  nsCOMPtr<nsISimpleEnumerator> dummy;
-  GetSubFolders(getter_AddRefs(dummy));  // initialize mSubFolders
+  nsTArray<RefPtr<nsIMsgFolder>> dummy;
+  GetSubFolders(dummy);  // initialize mSubFolders
   *aChild = nullptr;
-  int32_t count = mSubFolders.Count();
-
-  for (int32_t i = 0; i < count; i++) {
+
+  for (nsIMsgFolder* child : mSubFolders) {
     nsString folderName;
-    nsresult rv = mSubFolders[i]->GetName(folderName);
+    nsresult rv = child->GetName(folderName);
     // case-insensitive compare is probably LCD across OS filesystems
     if (NS_SUCCEEDED(rv) &&
         folderName.Equals(aName, nsCaseInsensitiveStringComparator)) {
-      NS_ADDREF(*aChild = mSubFolders[i]);
+      NS_ADDREF(*aChild = child);
       return NS_OK;
     }
   }
   // don't return NS_OK if we didn't find the folder
   // see http://bugzilla.mozilla.org/show_bug.cgi?id=210089#c15
   // and http://bugzilla.mozilla.org/show_bug.cgi?id=210089#c17
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP nsMsgDBFolder::GetChildWithURI(const nsACString& uri, bool deep,
                                              bool caseInsensitive,
                                              nsIMsgFolder** child) {
   NS_ENSURE_ARG_POINTER(child);
   // will return nullptr if we can't find it
   *child = nullptr;
-  nsCOMPtr<nsISimpleEnumerator> enumerator;
-  nsresult rv = GetSubFolders(getter_AddRefs(enumerator));
-  if (NS_FAILED(rv)) return rv;
-
-  bool hasMore;
-  while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
-    nsCOMPtr<nsISupports> item;
-    enumerator->GetNext(getter_AddRefs(item));
-
-    nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(item));
-    if (folder) {
-      nsCString folderURI;
-      rv = folder->GetURI(folderURI);
-      NS_ENSURE_SUCCESS(rv, rv);
-      bool equal =
-          (caseInsensitive
-               ? uri.Equals(folderURI, nsCaseInsensitiveCStringComparator)
-               : uri.Equals(folderURI));
-      if (equal) {
-        folder.forget(child);
-        return NS_OK;
-      }
-      if (deep) {
-        rv = folder->GetChildWithURI(uri, deep, caseInsensitive, child);
-        if (NS_FAILED(rv)) return rv;
-
-        if (*child) return NS_OK;
-      }
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  nsresult rv = GetSubFolders(subFolders);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  for (nsIMsgFolder* folder : subFolders) {
+    nsCString folderURI;
+    rv = folder->GetURI(folderURI);
+    NS_ENSURE_SUCCESS(rv, rv);
+    bool equal =
+        (caseInsensitive
+             ? uri.Equals(folderURI, nsCaseInsensitiveCStringComparator)
+             : uri.Equals(folderURI));
+    if (equal) {
+      NS_ADDREF(*child = folder);
+      return NS_OK;
+    }
+    if (deep) {
+      rv = folder->GetChildWithURI(uri, deep, caseInsensitive, child);
+      if (NS_FAILED(rv)) return rv;
+
+      if (*child) return NS_OK;
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsMsgDBFolder::GetShowDeletedMessages(bool* showDeletedMessages) {
   NS_ENSURE_ARG_POINTER(showDeletedMessages);
   *showDeletedMessages = false;
@@ -3410,28 +3405,21 @@ NS_IMETHODIMP nsMsgDBFolder::EmptyTrash(
                                         nsIUrlListener* aListener) {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsresult nsMsgDBFolder::CheckIfFolderExists(const nsAString& newFolderName,
                                             nsIMsgFolder* parentFolder,
                                             nsIMsgWindow* msgWindow) {
   NS_ENSURE_ARG_POINTER(parentFolder);
-  nsCOMPtr<nsISimpleEnumerator> subFolders;
-  nsresult rv = parentFolder->GetSubFolders(getter_AddRefs(subFolders));
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  nsresult rv = parentFolder->GetSubFolders(subFolders);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  bool hasMore;
-  while (NS_SUCCEEDED(subFolders->HasMoreElements(&hasMore)) && hasMore) {
-    nsCOMPtr<nsISupports> item;
-    rv = subFolders->GetNext(getter_AddRefs(item));
-
-    nsCOMPtr<nsIMsgFolder> msgFolder(do_QueryInterface(item));
-    if (!msgFolder) break;
-
+  for (nsIMsgFolder* msgFolder : subFolders) {
     nsString folderName;
 
     msgFolder->GetName(folderName);
     if (folderName.Equals(newFolderName, nsCaseInsensitiveStringComparator)) {
       ThrowAlertMsg("folderExists", msgWindow);
       return NS_MSG_FOLDER_EXISTS;
     }
   }
@@ -3950,41 +3938,41 @@ NS_IMETHODIMP nsMsgDBFolder::SetFlags(ui
 
 NS_IMETHODIMP nsMsgDBFolder::GetFolderWithFlags(uint32_t aFlags,
                                                 nsIMsgFolder** aResult) {
   if ((mFlags & aFlags) == aFlags) {
     NS_ADDREF(*aResult = this);
     return NS_OK;
   }
 
-  nsCOMPtr<nsISimpleEnumerator> dummy;
-  GetSubFolders(getter_AddRefs(dummy));  // initialize mSubFolders
+  nsTArray<RefPtr<nsIMsgFolder>> dummy;
+  GetSubFolders(dummy);  // initialize mSubFolders
 
   int32_t count = mSubFolders.Count();
   *aResult = nullptr;
   for (int32_t i = 0; !*aResult && i < count; ++i)
     mSubFolders[i]->GetFolderWithFlags(aFlags, aResult);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsMsgDBFolder::GetFoldersWithFlags(
     uint32_t aFlags, nsTArray<RefPtr<nsIMsgFolder>>& aResult) {
   aResult.Clear();
 
   // Ensure initialisation of mSubFolders.
-  nsCOMPtr<nsISimpleEnumerator> dummy;
-  GetSubFolders(getter_AddRefs(dummy));
+  nsTArray<RefPtr<nsIMsgFolder>> dummy;
+  GetSubFolders(dummy);
 
   if ((mFlags & aFlags) == aFlags) {
     aResult.AppendElement(this);
   }
 
   // Recurse down through children.
-  for (auto child : mSubFolders) {
+  for (nsIMsgFolder* child : mSubFolders) {
     nsTArray<RefPtr<nsIMsgFolder>> subMatches;
     child->GetFoldersWithFlags(aFlags, subMatches);
     aResult.AppendElements(subMatches);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsMsgDBFolder::IsSpecialFolder(uint32_t aFlags,
--- a/mailnews/extensions/newsblog/test/browser/browser_feedDisplay.js
+++ b/mailnews/extensions/newsblog/test/browser/browser_feedDisplay.js
@@ -110,17 +110,17 @@ add_task(async () => {
         {},
         dialogWindow
       );
     }
   );
   EventUtils.synthesizeMouseAtCenter(menuItem, {});
   await Promise.all([hiddenPromise, dialogPromise]);
 
-  let folder = [...rootFolder.subFolders].find(f => f.name == "Test Feed");
+  let folder = rootFolder.subFolders.find(f => f.name == "Test Feed");
   Assert.ok(folder);
 
   index = window.gFolderTreeView.getIndexOfFolder(folder);
   folderTreeClick(index);
 
   Assert.equal(threadTree.view.rowCount, 1);
 
   // Description mode.
--- a/mailnews/imap/src/nsImapIncomingServer.cpp
+++ b/mailnews/imap/src/nsImapIncomingServer.cpp
@@ -1527,79 +1527,62 @@ bool nsImapIncomingServer::CheckSpecialF
     return true;
   }
 
   return false;
 }
 
 bool nsImapIncomingServer::NoDescendentsAreVerified(
     nsIMsgFolder* parentFolder) {
-  bool nobodyIsVerified = true;
-  nsCOMPtr<nsISimpleEnumerator> subFolders;
-  nsresult rv = parentFolder->GetSubFolders(getter_AddRefs(subFolders));
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  nsresult rv = parentFolder->GetSubFolders(subFolders);
   if (NS_SUCCEEDED(rv)) {
-    bool moreFolders;
-    while (NS_SUCCEEDED(subFolders->HasMoreElements(&moreFolders)) &&
-           moreFolders && nobodyIsVerified) {
-      nsCOMPtr<nsISupports> child;
-      rv = subFolders->GetNext(getter_AddRefs(child));
-      if (NS_SUCCEEDED(rv) && child) {
+    for (nsIMsgFolder* child : subFolders) {
+      nsCOMPtr<nsIMsgImapMailFolder> childImapFolder =
+          do_QueryInterface(child, &rv);
+      if (NS_SUCCEEDED(rv) && childImapFolder) {
         bool childVerified = false;
-        nsCOMPtr<nsIMsgImapMailFolder> childImapFolder =
-            do_QueryInterface(child, &rv);
-        if (NS_SUCCEEDED(rv) && childImapFolder) {
-          nsCOMPtr<nsIMsgFolder> childFolder = do_QueryInterface(child, &rv);
-          rv = childImapFolder->GetVerifiedAsOnlineFolder(&childVerified);
-          nobodyIsVerified =
-              !childVerified && NoDescendentsAreVerified(childFolder);
+        rv = childImapFolder->GetVerifiedAsOnlineFolder(&childVerified);
+        if (NS_SUCCEEDED(rv) && childVerified) {
+          return false;
+        }
+        if (!NoDescendentsAreVerified(child)) {
+          return false;
         }
       }
     }
   }
-  return nobodyIsVerified;
+  // If we get this far we didn't find any verified.
+  return true;
 }
 
 bool nsImapIncomingServer::AllDescendentsAreNoSelect(
     nsIMsgFolder* parentFolder) {
-  bool allDescendentsAreNoSelect = true;
-  nsCOMPtr<nsISimpleEnumerator> subFolders;
-  nsresult rv = parentFolder->GetSubFolders(getter_AddRefs(subFolders));
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  nsresult rv = parentFolder->GetSubFolders(subFolders);
   if (NS_SUCCEEDED(rv)) {
-    bool moreFolders;
-    while (NS_SUCCEEDED(subFolders->HasMoreElements(&moreFolders)) &&
-           moreFolders && allDescendentsAreNoSelect) {
-      nsCOMPtr<nsISupports> child;
-      rv = subFolders->GetNext(getter_AddRefs(child));
-      if (NS_SUCCEEDED(rv) && child) {
-        bool childIsNoSelect = false;
-        nsCOMPtr<nsIMsgImapMailFolder> childImapFolder =
-            do_QueryInterface(child, &rv);
-        if (NS_SUCCEEDED(rv) && childImapFolder) {
-          uint32_t flags;
-          nsCOMPtr<nsIMsgFolder> childFolder = do_QueryInterface(child, &rv);
-          rv = childFolder->GetFlags(&flags);
-          childIsNoSelect =
-              NS_SUCCEEDED(rv) && (flags & nsMsgFolderFlags::ImapNoselect);
-          allDescendentsAreNoSelect =
-              !childIsNoSelect && AllDescendentsAreNoSelect(childFolder);
+    for (nsIMsgFolder* child : subFolders) {
+      nsCOMPtr<nsIMsgImapMailFolder> childImapFolder =
+          do_QueryInterface(child, &rv);
+      if (NS_SUCCEEDED(rv) && childImapFolder) {
+        uint32_t flags;
+        rv = child->GetFlags(&flags);
+        bool isNoSelect =
+            NS_SUCCEEDED(rv) && (flags & nsMsgFolderFlags::ImapNoselect);
+        if (!isNoSelect) {
+          return false;
+        }
+        if (!AllDescendentsAreNoSelect(child)) {
+          return false;
         }
       }
     }
   }
-#if 0
-  int numberOfSubfolders = parentFolder->GetNumSubFolders();
-
-  for (int childIndex=0; allDescendantsAreNoSelect && (childIndex < numberOfSubfolders); childIndex++)
-  {
-    MSG_IMAPFolderInfoMail *currentChild = (MSG_IMAPFolderInfoMail *) parentFolder->GetSubFolder(childIndex);
-    allDescendentsAreNoSelect = (currentChild->GetFolderPrefFlags() & MSG_FOLDER_PREF_IMAPNOSELECT) &&
-      AllDescendentsAreNoSelect(currentChild);
-  }
-#endif  // 0
-  return allDescendentsAreNoSelect;
+  // If we get this far we found none without the Noselect flag.
+  return true;
 }
 
 NS_IMETHODIMP
 nsImapIncomingServer::PromptLoginFailed(nsIMsgWindow* aMsgWindow,
                                         int32_t* aResult) {
   nsAutoCString hostName;
   GetRealHostName(hostName);
 
@@ -1780,36 +1763,27 @@ nsresult nsImapIncomingServer::ResetFold
   nsresult rv = NS_OK;
   if (!parentFolder) {
     nsCOMPtr<nsIMsgFolder> rootFolder;
     rv = GetRootFolder(getter_AddRefs(rootFolder));
     NS_ENSURE_SUCCESS(rv, rv);
     return ResetFoldersToUnverified(rootFolder);
   }
 
-  nsCOMPtr<nsISimpleEnumerator> subFolders;
   nsCOMPtr<nsIMsgImapMailFolder> imapFolder =
       do_QueryInterface(parentFolder, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = imapFolder->SetVerifiedAsOnlineFolder(false);
-  rv = parentFolder->GetSubFolders(getter_AddRefs(subFolders));
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  rv = parentFolder->GetSubFolders(subFolders);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  bool moreFolders = false;
-  while (NS_SUCCEEDED(subFolders->HasMoreElements(&moreFolders)) &&
-         moreFolders) {
-    nsCOMPtr<nsISupports> child;
-    rv = subFolders->GetNext(getter_AddRefs(child));
-    if (NS_SUCCEEDED(rv) && child) {
-      nsCOMPtr<nsIMsgFolder> childFolder = do_QueryInterface(child, &rv);
-      if (NS_SUCCEEDED(rv) && childFolder) {
-        rv = ResetFoldersToUnverified(childFolder);
-        if (NS_FAILED(rv)) break;
-      }
-    }
+  for (nsIMsgFolder* child : subFolders) {
+    rv = ResetFoldersToUnverified(child);
+    NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return rv;
 }
 
 void nsImapIncomingServer::GetUnverifiedFolders(
     nsCOMArray<nsIMsgImapMailFolder>& aFoldersArray) {
   nsCOMPtr<nsIMsgFolder> rootFolder;
@@ -1833,28 +1807,20 @@ void nsImapIncomingServer::GetUnverified
     nsresult rv = imapFolder->GetVerifiedAsOnlineFolder(&verified);
     if (NS_SUCCEEDED(rv))
       rv = imapFolder->GetExplicitlyVerify(&explicitlyVerify);
 
     if (NS_SUCCEEDED(rv) && (!verified || explicitlyVerify))
       aFoldersArray.AppendObject(imapFolder);
   }
 
-  nsCOMPtr<nsISimpleEnumerator> subFolders;
-  if (NS_SUCCEEDED(parentFolder->GetSubFolders(getter_AddRefs(subFolders)))) {
-    bool moreFolders;
-
-    while (NS_SUCCEEDED(subFolders->HasMoreElements(&moreFolders)) &&
-           moreFolders) {
-      nsCOMPtr<nsISupports> child;
-      subFolders->GetNext(getter_AddRefs(child));
-      if (child) {
-        nsCOMPtr<nsIMsgFolder> childFolder(do_QueryInterface(child));
-        if (childFolder) GetUnverifiedSubFolders(childFolder, aFoldersArray);
-      }
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  if (NS_SUCCEEDED(parentFolder->GetSubFolders(subFolders))) {
+    for (nsIMsgFolder* child : subFolders) {
+      GetUnverifiedSubFolders(child, aFoldersArray);
     }
   }
 }
 
 NS_IMETHODIMP nsImapIncomingServer::ForgetSessionPassword() {
   nsresult rv = nsMsgIncomingServer::ForgetSessionPassword();
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -2755,30 +2721,20 @@ nsImapIncomingServer::GetNewMessagesForN
     if (gUseStatus && !isOpen) {
       if (!isServer && m_foldersToStat.IndexOf(imapFolder) == -1)
         m_foldersToStat.AppendObject(imapFolder);
     } else
       aFolder->UpdateFolder(aWindow);
   }
 
   // Loop through all subfolders to get new messages for them.
-  nsCOMPtr<nsISimpleEnumerator> enumerator;
-  rv = aFolder->GetSubFolders(getter_AddRefs(enumerator));
-  if (NS_FAILED(rv)) return rv;
-
-  bool hasMore;
-  while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
-    nsCOMPtr<nsISupports> item;
-    enumerator->GetNext(getter_AddRefs(item));
-
-    nsCOMPtr<nsIMsgFolder> msgFolder(do_QueryInterface(item));
-    if (!msgFolder) {
-      NS_WARNING("Not an nsIMsgFolder");
-      continue;
-    }
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  rv = aFolder->GetSubFolders(subFolders);
+  NS_ENSURE_SUCCESS(rv, rv);
+  for (nsIMsgFolder* msgFolder : subFolders) {
     GetNewMessagesForNonInboxFolders(msgFolder, aWindow, forceAllFolders,
                                      performingBiff);
   }
   if (isServer && m_foldersToStat.Count() > 0)
     m_foldersToStat[0]->UpdateStatus(this, nullptr);
   return NS_OK;
 }
 
--- a/mailnews/imap/src/nsImapMailFolder.cpp
+++ b/mailnews/imap/src/nsImapMailFolder.cpp
@@ -509,17 +509,18 @@ nsresult nsImapMailFolder::CreateSubFold
       if (!currentFolderNameStr.IsEmpty())
         child->SetPrettyName(currentFolderNameStr);
       child->SetMsgDatabase(nullptr);
     }
   }
   return rv;
 }
 
-NS_IMETHODIMP nsImapMailFolder::GetSubFolders(nsISimpleEnumerator** aResult) {
+NS_IMETHODIMP nsImapMailFolder::GetSubFolders(
+    nsTArray<RefPtr<nsIMsgFolder>>& folders) {
   bool isServer;
   nsresult rv = GetIsServer(&isServer);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!m_initialized) {
     nsCOMPtr<nsIFile> pathFile;
     rv = GetFilePath(getter_AddRefs(pathFile));
     if (NS_FAILED(rv)) return rv;
@@ -549,28 +550,30 @@ NS_IMETHODIMP nsImapMailFolder::GetSubFo
       GetFolderWithFlags(nsMsgFolderFlags::Inbox, getter_AddRefs(inboxFolder));
       if (!inboxFolder) {
         // create an inbox if we don't have one.
         CreateClientSubfolderInfo("INBOX"_ns, kOnlineHierarchySeparatorUnknown,
                                   0, true);
       }
     }
 
-    int32_t count = mSubFolders.Count();
-    nsCOMPtr<nsISimpleEnumerator> dummy;
-    for (int32_t i = 0; i < count; i++)
-      mSubFolders[i]->GetSubFolders(getter_AddRefs(dummy));
+    // Force initialisation recursively.
+    for (nsIMsgFolder* f : mSubFolders) {
+      nsTArray<RefPtr<nsIMsgFolder>> dummy;
+      rv = f->GetSubFolders(dummy);
+      if (NS_FAILED(rv)) {
+        break;
+      }
+    }
 
     UpdateSummaryTotals(false);
     if (NS_FAILED(rv)) return rv;
   }
 
-  return aResult ? NS_NewArrayEnumerator(aResult, mSubFolders,
-                                         NS_GET_IID(nsIMsgFolder))
-                 : NS_ERROR_NULL_POINTER;
+  return nsMsgDBFolder::GetSubFolders(folders);
 }
 
 // Makes sure the database is open and exists.  If the database is valid then
 // returns NS_OK.  Otherwise returns a failure error value.
 nsresult nsImapMailFolder::GetDatabase() {
   nsresult rv = NS_OK;
   if (!mDatabase) {
     nsCOMPtr<nsIMsgDBService> msgDBService =
@@ -1367,41 +1370,24 @@ NS_IMETHODIMP nsImapMailFolder::EmptyTra
       nsCOMPtr<nsIUrlListener> urlListener = do_QueryInterface(trashFolder);
       rv = imapService->DeleteAllMessages(trashFolder, urlListener, nullptr);
     }
     // Return an error if this failed. We want the empty trash on exit code
     // to know if this fails so that it doesn't block waiting for empty trash to
     // finish.
     NS_ENSURE_SUCCESS(rv, rv);
 
-    bool hasSubfolders = false;
-    rv = trashFolder->GetHasSubFolders(&hasSubfolders);
+    // Delete any subfolders under Trash.
+    nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+    rv = trashFolder->GetSubFolders(subFolders);
     NS_ENSURE_SUCCESS(rv, rv);
-    if (hasSubfolders) {
-      nsCOMPtr<nsISimpleEnumerator> enumerator;
-      nsCOMPtr<nsISupports> item;
-      nsCOMArray<nsIMsgFolder> array;
-
-      rv = trashFolder->GetSubFolders(getter_AddRefs(enumerator));
+    while (!subFolders.IsEmpty()) {
+      RefPtr<nsIMsgFolder> f = subFolders.PopLastElement();
+      rv = trashFolder->PropagateDelete(f, true, aMsgWindow);
       NS_ENSURE_SUCCESS(rv, rv);
-
-      bool hasMore;
-      while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
-        rv = enumerator->GetNext(getter_AddRefs(item));
-        if (NS_SUCCEEDED(rv)) {
-          nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(item, &rv));
-          if (NS_SUCCEEDED(rv)) array.AppendObject(folder);
-        }
-      }
-      for (int32_t i = array.Count() - 1; i >= 0; i--) {
-        trashFolder->PropagateDelete(array[i], true, aMsgWindow);
-        // Remove the object, presumably to free it up before we delete the
-        // next.
-        array.RemoveObjectAt(i);
-      }
     }
 
     nsCOMPtr<nsIDBFolderInfo> transferInfo;
     rv = trashFolder->GetDBTransferInfo(getter_AddRefs(transferInfo));
     NS_ENSURE_SUCCESS(rv, rv);
     // Bulk-delete all the messages by deleting the msf file and storage.
     // This is a little kludgy.
     rv = trashFolder->DeleteStorage();
@@ -7157,45 +7143,39 @@ nsImapFolderCopyState::OnStopRunningUrl(
           // copy service when this whole process is done.
           if (!m_newDestFolder)
             m_newDestFolder =
                 static_cast<nsImapMailFolder*>(newMsgFolder.get());
 
           // check if the source folder has children. If it does, list them
           // into m_srcChildFolders, and set m_destParents for the
           // corresponding indexes to the newly created folder.
-          nsCOMPtr<nsISimpleEnumerator> enumerator;
-          rv = m_curSrcFolder->GetSubFolders(getter_AddRefs(enumerator));
+          nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+          rv = m_curSrcFolder->GetSubFolders(subFolders);
           NS_ENSURE_SUCCESS(rv, rv);
-
-          nsCOMPtr<nsISupports> item;
-          bool hasMore = false;
           uint32_t childIndex = 0;
-          while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) &&
-                 hasMore) {
-            rv = enumerator->GetNext(getter_AddRefs(item));
-            nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(item, &rv));
-            if (NS_SUCCEEDED(rv)) {
-              m_srcChildFolders.InsertElementAt(m_childIndex + childIndex + 1,
-                                                folder);
-              m_destParents.InsertElementAt(m_childIndex + childIndex + 1,
-                                            newMsgFolder);
-            }
+          for (nsIMsgFolder* folder : subFolders) {
+            m_srcChildFolders.InsertElementAt(m_childIndex + childIndex + 1,
+                                              folder);
+            m_destParents.InsertElementAt(m_childIndex + childIndex + 1,
+                                          newMsgFolder);
             ++childIndex;
           }
 
+          nsCOMPtr<nsISimpleEnumerator> enumerator;
           rv = m_curSrcFolder->GetMessages(getter_AddRefs(enumerator));
           nsTArray<RefPtr<nsIMsgDBHdr>> msgArray;
-          hasMore = false;
+          bool hasMore = false;
 
           if (enumerator) rv = enumerator->HasMoreElements(&hasMore);
 
           if (!hasMore) return AdvanceToNextFolder(NS_OK);
 
           while (NS_SUCCEEDED(rv) && hasMore) {
+            nsCOMPtr<nsISupports> item;
             rv = enumerator->GetNext(getter_AddRefs(item));
             NS_ENSURE_SUCCESS(rv, rv);
             nsCOMPtr<nsIMsgDBHdr> hdr(do_QueryInterface(item, &rv));
             NS_ENSURE_SUCCESS(rv, rv);
             msgArray.AppendElement(hdr);
             rv = enumerator->HasMoreElements(&hasMore);
           }
 
@@ -7813,63 +7793,55 @@ NS_IMETHODIMP nsImapMailFolder::ResetNam
   GetHierarchyDelimiter(&hierarchyDelimiter);
   m_namespace = nsImapNamespaceList::GetNamespaceForFolder(
       serverKey.get(), onlineName.get(), hierarchyDelimiter);
   m_folderIsNamespace = m_namespace ? nsImapNamespaceList::GetFolderIsNamespace(
                                           serverKey.get(), onlineName.get(),
                                           hierarchyDelimiter, m_namespace)
                                     : false;
 
-  nsCOMPtr<nsISimpleEnumerator> enumerator;
-  GetSubFolders(getter_AddRefs(enumerator));
-  if (!enumerator) return NS_OK;
-
-  nsresult rv;
-  bool hasMore;
-  while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
-    nsCOMPtr<nsISupports> item;
-    rv = enumerator->GetNext(getter_AddRefs(item));
-    if (NS_FAILED(rv)) break;
-
-    nsCOMPtr<nsIMsgImapMailFolder> folder(do_QueryInterface(item, &rv));
-    if (NS_FAILED(rv)) return rv;
-
-    folder->ResetNamespaceReferences();
-  }
-  return rv;
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  nsresult rv = GetSubFolders(subFolders);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  for (nsIMsgFolder* f : subFolders) {
+    nsCOMPtr<nsIMsgImapMailFolder> imapFolder(do_QueryInterface(f, &rv));
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = imapFolder->ResetNamespaceReferences();
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+  return NS_OK;
 }
 
 NS_IMETHODIMP nsImapMailFolder::FindOnlineSubFolder(
     const nsACString& targetOnlineName, nsIMsgImapMailFolder** aResultFolder) {
+  *aResultFolder = nullptr;
   nsresult rv = NS_OK;
 
   nsCString onlineName;
   GetOnlineName(onlineName);
 
-  if (onlineName.Equals(targetOnlineName))
+  if (onlineName.Equals(targetOnlineName)) {
     return QueryInterface(NS_GET_IID(nsIMsgImapMailFolder),
                           (void**)aResultFolder);
-
-  nsCOMPtr<nsISimpleEnumerator> enumerator;
-  GetSubFolders(getter_AddRefs(enumerator));
-  if (!enumerator) return NS_OK;
-
-  bool hasMore;
-  while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
-    nsCOMPtr<nsISupports> item;
-    rv = enumerator->GetNext(getter_AddRefs(item));
-    if (NS_FAILED(rv)) break;
-
-    nsCOMPtr<nsIMsgImapMailFolder> folder(do_QueryInterface(item, &rv));
-    if (NS_FAILED(rv)) return rv;
-
-    rv = folder->FindOnlineSubFolder(targetOnlineName, aResultFolder);
-    if (*aResultFolder) return rv;
-  }
-  return rv;
+  }
+
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  rv = GetSubFolders(subFolders);
+  NS_ENSURE_SUCCESS(rv, rv);
+  for (nsIMsgFolder* f : subFolders) {
+    nsCOMPtr<nsIMsgImapMailFolder> imapFolder(do_QueryInterface(f, &rv));
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = imapFolder->FindOnlineSubFolder(targetOnlineName, aResultFolder);
+    NS_ENSURE_SUCCESS(rv, rv);
+    if (*aResultFolder) {
+      return NS_OK;  // Found it!
+    }
+  }
+  return NS_OK;  // Not found.
 }
 
 NS_IMETHODIMP nsImapMailFolder::GetFolderNeedsAdded(bool* bVal) {
   NS_ENSURE_ARG_POINTER(bVal);
   *bVal = m_folderNeedsAdded;
   return NS_OK;
 }
 
@@ -8055,30 +8027,23 @@ NS_IMETHODIMP nsImapMailFolder::RenameCl
     NotifyItemAdded(child);
   }
   return rv;
 }
 
 NS_IMETHODIMP nsImapMailFolder::RenameSubFolders(nsIMsgWindow* msgWindow,
                                                  nsIMsgFolder* oldFolder) {
   m_initialized = true;
-  nsCOMPtr<nsISimpleEnumerator> enumerator;
-  nsresult rv = oldFolder->GetSubFolders(getter_AddRefs(enumerator));
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  nsresult rv = oldFolder->GetSubFolders(subFolders);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  bool hasMore;
-  while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
-    nsCOMPtr<nsISupports> item;
-    if (NS_FAILED(enumerator->GetNext(getter_AddRefs(item)))) continue;
-
-    nsCOMPtr<nsIMsgFolder> msgFolder(do_QueryInterface(item, &rv));
-    if (NS_FAILED(rv)) return rv;
-
+  for (nsIMsgFolder* msgFolder : subFolders) {
     nsCOMPtr<nsIMsgImapMailFolder> folder(do_QueryInterface(msgFolder, &rv));
-    if (NS_FAILED(rv)) return rv;
+    NS_ENSURE_SUCCESS(rv, rv);
 
     char hierarchyDelimiter = '/';
     folder->GetHierarchyDelimiter(&hierarchyDelimiter);
 
     int32_t boxflags;
     folder->GetBoxFlags(&boxflags);
 
     bool verified;
--- a/mailnews/imap/src/nsImapMailFolder.h
+++ b/mailnews/imap/src/nsImapMailFolder.h
@@ -216,17 +216,17 @@ class nsImapMailFolder : public nsMsgDBF
   static const uint32_t PLAYBACK_TIMER_INTERVAL_IN_MS = 500;
 
  public:
   nsImapMailFolder();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIMsgFolder methods:
-  NS_IMETHOD GetSubFolders(nsISimpleEnumerator** aResult) override;
+  NS_IMETHOD GetSubFolders(nsTArray<RefPtr<nsIMsgFolder>>& folders) override;
 
   NS_IMETHOD UpdateFolder(nsIMsgWindow* aWindow) override;
 
   NS_IMETHOD CreateSubfolder(const nsAString& folderName,
                              nsIMsgWindow* msgWindow) override;
   NS_IMETHOD AddSubfolder(const nsAString& aName,
                           nsIMsgFolder** aChild) override;
   NS_IMETHODIMP CreateStorageIfMissing(nsIUrlListener* urlListener) override;
--- a/mailnews/import/src/nsBeckyFilters.cpp
+++ b/mailnews/import/src/nsBeckyFilters.cpp
@@ -604,36 +604,28 @@ nsBeckyFilters::Import(char16_t** aError
 nsresult nsBeckyFilters::FindMessageFolder(const nsAString& aName,
                                            nsIMsgFolder* aParentFolder,
                                            nsIMsgFolder** _retval) {
   nsresult rv;
 
   nsCOMPtr<nsIMsgFolder> found;
   rv = aParentFolder->GetChildNamed(aName, getter_AddRefs(found));
   if (found) {
-    found.forget(_retval);
+    NS_ADDREF(*_retval = found);
     return NS_OK;
   }
 
-  nsCOMPtr<nsISimpleEnumerator> children;
-  rv = aParentFolder->GetSubFolders(getter_AddRefs(children));
+  nsTArray<RefPtr<nsIMsgFolder>> children;
+  rv = aParentFolder->GetSubFolders(children);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  bool more;
-  nsCOMPtr<nsISupports> entry;
-  while (NS_SUCCEEDED(children->HasMoreElements(&more)) && more) {
-    rv = children->GetNext(getter_AddRefs(entry));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsCOMPtr<nsIMsgFolder> child = do_QueryInterface(entry, &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-
+  for (nsIMsgFolder* child : children) {
     rv = FindMessageFolder(aName, child, getter_AddRefs(found));
     if (found) {
-      found.forget(_retval);
+      NS_ADDREF(*_retval = found);
       return NS_OK;
     }
   }
 
   return NS_MSG_ERROR_INVALID_FOLDER_NAME;
 }
 
 nsresult nsBeckyFilters::FindMessageFolderInServer(
--- a/mailnews/import/src/nsImportMail.cpp
+++ b/mailnews/import/src/nsImportMail.cpp
@@ -705,18 +705,18 @@ bool nsImportGenericMail::CreateFolder(n
   }
 
   if (NS_SUCCEEDED(rv) && server) {
     nsCOMPtr<nsIMsgFolder> localRootFolder;
     rv = server->GetRootMsgFolder(getter_AddRefs(localRootFolder));
     if (localRootFolder) {
       // we need to call GetSubFolders() so that the folders get initialized
       // if they are not initialized yet.
-      nsCOMPtr<nsISimpleEnumerator> aEnumerator;
-      rv = localRootFolder->GetSubFolders(getter_AddRefs(aEnumerator));
+      nsTArray<RefPtr<nsIMsgFolder>> dummy;
+      rv = localRootFolder->GetSubFolders(dummy);
       if (NS_SUCCEEDED(rv)) {
         // check if the folder name we picked already exists.
         bool exists = false;
         rv = localRootFolder->ContainsChildNamed(folderName, &exists);
         if (exists) {
           nsString name;
           localRootFolder->GenerateUniqueSubfolderName(folderName, nullptr,
                                                        name);
@@ -767,18 +767,18 @@ class GetSubFoldersRunnable : public moz
  private:
   nsCOMPtr<nsIMsgFolder> m_folder;
 };
 
 GetSubFoldersRunnable::GetSubFoldersRunnable(nsIMsgFolder* aFolder)
     : mozilla::Runnable("GetSubFoldersRunnable"), m_folder(aFolder) {}
 
 NS_IMETHODIMP GetSubFoldersRunnable::Run() {
-  nsCOMPtr<nsISimpleEnumerator> dummy;
-  mResult = m_folder->GetSubFolders(getter_AddRefs(dummy));
+  nsTArray<RefPtr<nsIMsgFolder>> dummy;
+  mResult = m_folder->GetSubFolders(dummy);
   return NS_OK;  // Sync runnable must return OK.
 }
 
 nsresult ProxyGetSubFolders(nsIMsgFolder* aFolder) {
   RefPtr<GetSubFoldersRunnable> getSubFolders =
       new GetSubFoldersRunnable(aFolder);
   nsresult rv = NS_DispatchToMainThread(getSubFolders, NS_DISPATCH_SYNC);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/mailnews/import/test/unit/resources/import_helper.js
+++ b/mailnews/import/test/unit/resources/import_helper.js
@@ -402,34 +402,27 @@ function MailImportHelper(aFile, aModule
   this.mExpected = aExpected;
 }
 
 MailImportHelper.prototype = {
   __proto__: GenericImportHelper.prototype,
   interfaceType: Ci.nsIImportGeneric,
   _checkEqualFolder(expectedFolder, actualFolder) {
     Assert.equal(expectedFolder.leafName, actualFolder.name);
-    let expectedSubFolderCount = 0;
 
     let expectedSubFolders = [];
     for (let entry of expectedFolder.directoryEntries) {
       if (entry.isDirectory()) {
-        expectedSubFolderCount++;
         expectedSubFolders.push(entry);
       }
     }
-    Assert.equal(expectedSubFolderCount, actualFolder.numSubFolders);
-
-    let actualEnumerator = actualFolder.subFolders;
-    for (let i = 0; i < expectedSubFolderCount; i++) {
-      let expectedSubFolder = expectedSubFolders[i];
-      let actualSubFolder = actualEnumerator
-        .getNext()
-        .QueryInterface(Ci.nsIMsgFolder);
-      this._checkEqualFolder(expectedSubFolder, actualSubFolder);
+    let actualSubFolders = actualFolder.subFolders;
+    Assert.equal(expectedSubFolders.length, actualSubFolders.length);
+    for (let i = 0; i < expectedSubFolders.length; i++) {
+      this._checkEqualFolder(expectedSubFolders[i], actualSubFolders[i]);
     }
   },
 
   checkResults() {
     let rootFolder = MailServices.accounts.localFoldersServer.rootFolder;
     Assert.ok(rootFolder.containsChildNamed(this.mFile.leafName));
     let importedFolder = rootFolder.getChildNamed(this.mFile.leafName);
     Assert.notEqual(importedFolder, null);
--- a/mailnews/local/src/nsLocalMailFolder.cpp
+++ b/mailnews/local/src/nsLocalMailFolder.cpp
@@ -166,17 +166,17 @@ NS_IMETHODIMP nsMsgLocalMailFolder::Pars
 
 // this won't force a reparse of the folder if the db is invalid.
 NS_IMETHODIMP
 nsMsgLocalMailFolder::GetMsgDatabase(nsIMsgDatabase** aMsgDatabase) {
   return GetDatabaseWOReparse(aMsgDatabase);
 }
 
 NS_IMETHODIMP
-nsMsgLocalMailFolder::GetSubFolders(nsISimpleEnumerator** aResult) {
+nsMsgLocalMailFolder::GetSubFolders(nsTArray<RefPtr<nsIMsgFolder>>& folders) {
   if (!mInitialized) {
     nsCOMPtr<nsIMsgIncomingServer> server;
     nsresult rv = GetServer(getter_AddRefs(server));
     NS_ENSURE_SUCCESS(rv, NS_MSG_INVALID_OR_MISSING_SERVER);
     nsCOMPtr<nsIMsgPluggableStore> msgStore;
     // need to set this flag here to avoid infinite recursion
     mInitialized = true;
     rv = server->GetMsgStore(getter_AddRefs(msgStore));
@@ -213,19 +213,17 @@ nsMsgLocalMailFolder::GetSubFolders(nsIS
         // must happen after CreateSubFolders, or the folders won't exist.
         rv = localMailServer->SetFlagsOnDefaultMailboxes();
         if (NS_FAILED(rv)) return rv;
       }
     }
     UpdateSummaryTotals(false);
   }
 
-  return aResult ? NS_NewArrayEnumerator(aResult, mSubFolders,
-                                         NS_GET_IID(nsIMsgFolder))
-                 : NS_ERROR_NULL_POINTER;
+  return nsMsgDBFolder::GetSubFolders(folders);
 }
 
 nsresult nsMsgLocalMailFolder::GetDatabase() {
   nsCOMPtr<nsIMsgDatabase> msgDB;
   return GetDatabaseWOReparse(getter_AddRefs(msgDB));
 }
 
 // we treat failure as null db returned
@@ -538,23 +536,23 @@ NS_IMETHODIMP nsMsgLocalMailFolder::Empt
   nsCOMPtr<nsIMsgFolder> trashFolder;
   rv = GetTrashFolder(getter_AddRefs(trashFolder));
   if (NS_SUCCEEDED(rv)) {
     uint32_t flags;
     trashFolder->GetFlags(&flags);
     int32_t totalMessages = 0;
     rv = trashFolder->GetTotalMessages(true, &totalMessages);
     if (totalMessages <= 0) {
-      nsCOMPtr<nsISimpleEnumerator> enumerator;
-      rv = trashFolder->GetSubFolders(getter_AddRefs(enumerator));
+      // Any folders to deal with?
+      nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+      rv = trashFolder->GetSubFolders(subFolders);
       NS_ENSURE_SUCCESS(rv, rv);
-      // Any folders to deal with?
-      bool hasMore;
-      rv = enumerator->HasMoreElements(&hasMore);
-      if (NS_FAILED(rv) || !hasMore) return NS_OK;
+      if (subFolders.IsEmpty()) {
+        return NS_OK;
+      }
     }
     nsCOMPtr<nsIMsgFolder> parentFolder;
     rv = trashFolder->GetParent(getter_AddRefs(parentFolder));
     if (NS_SUCCEEDED(rv) && parentFolder) {
       nsCOMPtr<nsIDBFolderInfo> transferInfo;
       trashFolder->GetDBTransferInfo(getter_AddRefs(transferInfo));
       trashFolder->SetParent(nullptr);
       parentFolder->PropagateDelete(trashFolder, true, msgWindow);
@@ -750,18 +748,18 @@ NS_IMETHODIMP nsMsgLocalMailFolder::Rena
     bool changed = false;
     MatchOrChangeFilterDestination(newFolder, true /*case-insensitive*/,
                                    &changed);
     if (changed) AlertFilterChanged(msgWindow);
 
     if (count > 0) newFolder->RenameSubFolders(msgWindow, this);
 
     // Discover the subfolders inside this folder (this is recursive)
-    nsCOMPtr<nsISimpleEnumerator> dummy;
-    newFolder->GetSubFolders(getter_AddRefs(dummy));
+    nsTArray<RefPtr<nsIMsgFolder>> dummy;
+    newFolder->GetSubFolders(dummy);
 
     // the newFolder should have the same flags
     newFolder->SetFlags(mFlags);
     if (parentFolder) {
       SetParent(nullptr);
       parentFolder->PropagateDelete(this, false, msgWindow);
       parentFolder->NotifyItemAdded(newFolder);
     }
@@ -780,28 +778,21 @@ NS_IMETHODIMP nsMsgLocalMailFolder::Rena
                                                      nsIMsgFolder* oldFolder) {
   nsresult rv = NS_OK;
   mInitialized = true;
 
   uint32_t flags;
   oldFolder->GetFlags(&flags);
   SetFlags(flags);
 
-  nsCOMPtr<nsISimpleEnumerator> enumerator;
-  rv = oldFolder->GetSubFolders(getter_AddRefs(enumerator));
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  rv = oldFolder->GetSubFolders(subFolders);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  bool hasMore;
-  while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
-    nsCOMPtr<nsISupports> item;
-    enumerator->GetNext(getter_AddRefs(item));
-
-    nsCOMPtr<nsIMsgFolder> msgFolder(do_QueryInterface(item));
-    if (!msgFolder) continue;
-
+  for (nsIMsgFolder* msgFolder : subFolders) {
     nsString folderName;
     rv = msgFolder->GetName(folderName);
     nsCOMPtr<nsIMsgFolder> newFolder;
     AddSubfolder(folderName, getter_AddRefs(newFolder));
     if (newFolder) {
       newFolder->SetPrettyName(folderName);
       bool changed = false;
       msgFolder->MatchOrChangeFilterDestination(
@@ -1504,29 +1495,24 @@ nsresult nsMsgLocalMailFolder::CopyFolde
   }
   return NS_OK;  // otherwise the front-end will say Exception::CopyFolder
 }
 
 nsresult  // copy the sub folders
 nsMsgLocalMailFolder::CopyAllSubFolders(nsIMsgFolder* srcFolder,
                                         nsIMsgWindow* msgWindow,
                                         nsIMsgCopyServiceListener* listener) {
-  nsCOMPtr<nsISimpleEnumerator> enumerator;
-  nsresult rv = srcFolder->GetSubFolders(getter_AddRefs(enumerator));
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  nsresult rv = srcFolder->GetSubFolders(subFolders);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  bool hasMore;
-  while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
-    nsCOMPtr<nsISupports> item;
-    enumerator->GetNext(getter_AddRefs(item));
-
-    nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(item));
-    if (folder) CopyFolderAcrossServer(folder, msgWindow, listener);
+  for (nsIMsgFolder* folder : subFolders) {
+    CopyFolderAcrossServer(folder, msgWindow, listener);
   }
-  return rv;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsMsgLocalMailFolder::CopyFolder(nsIMsgFolder* srcFolder, bool isMoveFolder,
                                  nsIMsgWindow* msgWindow,
                                  nsIMsgCopyServiceListener* listener) {
   NS_ENSURE_ARG_POINTER(srcFolder);
   // isMoveFolder == true when "this" and srcFolder are on same server
--- a/mailnews/local/src/nsLocalMailFolder.h
+++ b/mailnews/local/src/nsLocalMailFolder.h
@@ -101,17 +101,17 @@ class nsMsgLocalMailFolder : public nsMs
   NS_DECL_NSIJUNKMAILCLASSIFICATIONLISTENER
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIUrlListener methods
   NS_IMETHOD OnStartRunningUrl(nsIURI* aUrl) override;
   NS_IMETHOD OnStopRunningUrl(nsIURI* aUrl, nsresult aExitCode) override;
 
   // nsIMsgFolder methods:
-  NS_IMETHOD GetSubFolders(nsISimpleEnumerator** aResult) override;
+  NS_IMETHOD GetSubFolders(nsTArray<RefPtr<nsIMsgFolder>>& folders) override;
   NS_IMETHOD GetMsgDatabase(nsIMsgDatabase** aMsgDatabase) override;
 
   NS_IMETHOD OnAnnouncerGoingAway(nsIDBChangeAnnouncer* instigator) override;
   NS_IMETHOD UpdateFolder(nsIMsgWindow* aWindow) override;
 
   NS_IMETHOD CreateSubfolder(const nsAString& folderName,
                              nsIMsgWindow* msgWindow) override;
 
--- a/mailnews/local/src/nsMsgBrkMBoxStore.cpp
+++ b/mailnews/local/src/nsMsgBrkMBoxStore.cpp
@@ -464,34 +464,26 @@ NS_IMETHODIMP nsMsgBrkMBoxStore::CopyFol
   newMsgFolder->SetPrettyName(folderName);
   uint32_t flags;
   aSrcFolder->GetFlags(&flags);
   newMsgFolder->SetFlags(flags);
   bool changed = false;
   rv = aSrcFolder->MatchOrChangeFilterDestination(newMsgFolder, true, &changed);
   if (changed) aSrcFolder->AlertFilterChanged(aMsgWindow);
 
-  nsCOMPtr<nsISimpleEnumerator> enumerator;
-  rv = aSrcFolder->GetSubFolders(getter_AddRefs(enumerator));
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  rv = aSrcFolder->GetSubFolders(subFolders);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Copy subfolders to the new location
   nsresult copyStatus = NS_OK;
   nsCOMPtr<nsIMsgLocalMailFolder> localNewFolder(
       do_QueryInterface(newMsgFolder, &rv));
   if (NS_SUCCEEDED(rv)) {
-    bool hasMore;
-    while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore &&
-           NS_SUCCEEDED(copyStatus)) {
-      nsCOMPtr<nsISupports> item;
-      enumerator->GetNext(getter_AddRefs(item));
-
-      nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(item));
-      if (!folder) continue;
-
+    for (nsIMsgFolder* folder : subFolders) {
       copyStatus =
           localNewFolder->CopyFolderLocal(folder, false, aMsgWindow, aListener);
       // Test if the call succeeded, if not we have to stop recursive call
       if (NS_FAILED(copyStatus)) {
         // Copy failed we have to notify caller to handle the error and stop
         // moving the folders. In case this happens to the topmost level of
         // recursive call, then we just need to break from the while loop and
         // go to error handling code.
--- a/mailnews/local/src/nsMsgMaildirStore.cpp
+++ b/mailnews/local/src/nsMsgMaildirStore.cpp
@@ -466,34 +466,26 @@ NS_IMETHODIMP nsMsgMaildirStore::CopyFol
   newMsgFolder->SetPrettyName(folderName);
   uint32_t flags;
   aSrcFolder->GetFlags(&flags);
   newMsgFolder->SetFlags(flags);
   bool changed = false;
   rv = aSrcFolder->MatchOrChangeFilterDestination(newMsgFolder, true, &changed);
   if (changed) aSrcFolder->AlertFilterChanged(aMsgWindow);
 
-  nsCOMPtr<nsISimpleEnumerator> enumerator;
-  rv = aSrcFolder->GetSubFolders(getter_AddRefs(enumerator));
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  rv = aSrcFolder->GetSubFolders(subFolders);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Copy subfolders to the new location
   nsresult copyStatus = NS_OK;
   nsCOMPtr<nsIMsgLocalMailFolder> localNewFolder(
       do_QueryInterface(newMsgFolder, &rv));
   if (NS_SUCCEEDED(rv)) {
-    bool hasMore;
-    while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore &&
-           NS_SUCCEEDED(copyStatus)) {
-      nsCOMPtr<nsISupports> item;
-      enumerator->GetNext(getter_AddRefs(item));
-
-      nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(item));
-      if (!folder) continue;
-
+    for (nsIMsgFolder* folder : subFolders) {
       copyStatus =
           localNewFolder->CopyFolderLocal(folder, false, aMsgWindow, aListener);
       // Test if the call succeeded, if not we have to stop recursive call
       if (NS_FAILED(copyStatus)) {
         // Copy failed we have to notify caller to handle the error and stop
         // moving the folders. In case this happens to the topmost level of
         // recursive call, then we just need to break from the while loop and
         // go to error handling code.
--- a/mailnews/local/src/nsPop3IncomingServer.cpp
+++ b/mailnews/local/src/nsPop3IncomingServer.cpp
@@ -111,51 +111,46 @@ NS_IMETHODIMP nsPop3IncomingServer::GetD
         server->GetRootFolder(getter_AddRefs(hiddenRootFolder));
         localServer->GetRootFolder(getter_AddRefs(localFoldersRoot));
         if (hiddenRootFolder && localFoldersRoot) {
           // We're going to iterate over the folders in Local Folders-1,
           // though I suspect only the Inbox will have messages. I don't
           // think Sent Mail could end up here, but if any folders have
           // messages, might as well copy them to the real Local Folders
           // account.
-          nsCOMPtr<nsISimpleEnumerator> enumerator;
-          rv = hiddenRootFolder->GetSubFolders(getter_AddRefs(enumerator));
+          nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+          rv = hiddenRootFolder->GetSubFolders(subFolders);
           if (NS_SUCCEEDED(rv)) {
-            bool hasMore;
-            while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) &&
-                   hasMore) {
-              nsCOMPtr<nsISupports> item;
-              enumerator->GetNext(getter_AddRefs(item));
-              nsCOMPtr<nsIMsgFolder> subFolder(do_QueryInterface(item));
-              if (subFolder) {
-                nsCOMPtr<nsIMsgDatabase> subFolderDB;
-                subFolder->GetMsgDatabase(getter_AddRefs(subFolderDB));
-                if (subFolderDB) {
-                  // Copy any messages in this sub-folder of the hidden
-                  // account to the corresponding folder in Local Folders.
-                  nsTArray<nsMsgKey> keys;
-                  rv = subFolderDB->ListAllKeys(keys);
-                  if (NS_FAILED(rv)) {
-                    continue;  // Next subfolder.
-                  }
-                  nsTArray<RefPtr<nsIMsgDBHdr>> hdrsToCopy;
-                  MsgGetHeadersFromKeys2(subFolderDB, keys, hdrsToCopy);
-                  if (!hdrsToCopy.IsEmpty()) {
-                    // Look for a folder with the same name in Local Folders.
-                    nsCOMPtr<nsIMsgFolder> dest;
-                    nsString folderName;
-                    subFolder->GetName(folderName);
-                    localFoldersRoot->GetChildNamed(folderName,
-                                                    getter_AddRefs(dest));
-                    if (dest)
-                      dest->CopyMessages(subFolder, hdrsToCopy, false, nullptr,
-                                         nullptr, false, false);
-                    // Should we copy the folder if the dest doesn't exist?
-                  }
+            for (nsIMsgFolder* subFolder : subFolders) {
+              nsCOMPtr<nsIMsgDatabase> subFolderDB;
+              subFolder->GetMsgDatabase(getter_AddRefs(subFolderDB));
+              if (!subFolderDB) {
+                continue;
+              }
+              // Copy any messages in this sub-folder of the hidden
+              // account to the corresponding folder in Local Folders.
+              nsTArray<nsMsgKey> keys;
+              rv = subFolderDB->ListAllKeys(keys);
+              if (NS_FAILED(rv)) {
+                continue;  // Next subfolder.
+              }
+              nsTArray<RefPtr<nsIMsgDBHdr>> hdrsToCopy;
+              MsgGetHeadersFromKeys2(subFolderDB, keys, hdrsToCopy);
+              if (!hdrsToCopy.IsEmpty()) {
+                // Look for a folder with the same name in Local Folders.
+                nsCOMPtr<nsIMsgFolder> dest;
+                nsString folderName;
+                subFolder->GetName(folderName);
+                localFoldersRoot->GetChildNamed(folderName,
+                                                getter_AddRefs(dest));
+                if (dest) {
+                  dest->CopyMessages(subFolder, hdrsToCopy, false, nullptr,
+                                     nullptr, false, false);
                 }
+                // Should we copy the folder if the dest doesn't exist?
               }
             }
           }
         }
       }
       rv = acctMgr->FindAccountForServer(localServer,
                                          getter_AddRefs(localAccount));
       NS_ENSURE_SUCCESS(rv, rv);
--- a/mailnews/news/src/nsNewsFolder.cpp
+++ b/mailnews/news/src/nsNewsFolder.cpp
@@ -185,17 +185,17 @@ nsresult nsMsgNewsFolder::ParseFolder(ns
 nsresult nsMsgNewsFolder::AddDirectorySeparator(nsIFile* path) {
   // don't concat the full separator with .sbd
   return (mURI.Equals(kNewsRootURI))
              ? NS_OK
              : nsMsgDBFolder::AddDirectorySeparator(path);
 }
 
 NS_IMETHODIMP
-nsMsgNewsFolder::GetSubFolders(nsISimpleEnumerator** aResult) {
+nsMsgNewsFolder::GetSubFolders(nsTArray<RefPtr<nsIMsgFolder>>& folders) {
   if (!mInitialized) {
     // do this first, so we make sure to do it, even on failure.
     // see bug #70494
     mInitialized = true;
 
     nsCOMPtr<nsIFile> path;
     nsresult rv = GetFilePath(getter_AddRefs(path));
     if (NS_FAILED(rv)) return rv;
@@ -204,19 +204,17 @@ nsMsgNewsFolder::GetSubFolders(nsISimple
     if (NS_FAILED(rv)) return rv;
 
     // force ourselves to get initialized from cache
     // Don't care if it fails.  this will fail the first time after
     // migration, but we continue on.  see #66018
     (void)UpdateSummaryTotals(false);
   }
 
-  return aResult ? NS_NewArrayEnumerator(aResult, mSubFolders,
-                                         NS_GET_IID(nsIMsgFolder))
-                 : NS_ERROR_NULL_POINTER;
+  return nsMsgDBFolder::GetSubFolders(folders);
 }
 
 // Makes sure the database is open and exists.  If the database is valid then
 // returns NS_OK.  Otherwise returns a failure error value.
 nsresult nsMsgNewsFolder::GetDatabase() {
   nsresult rv;
   if (!mDatabase) {
     nsCOMPtr<nsIMsgDBService> msgDBService =
--- a/mailnews/news/src/nsNewsFolder.h
+++ b/mailnews/news/src/nsNewsFolder.h
@@ -24,17 +24,17 @@ class nsMsgNewsFolder : public nsMsgDBFo
   nsMsgNewsFolder(void);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIMSGNEWSFOLDER
 
   // nsIUrlListener method
   NS_IMETHOD OnStopRunningUrl(nsIURI* aUrl, nsresult aExitCode) override;
   // nsIMsgFolder methods:
-  NS_IMETHOD GetSubFolders(nsISimpleEnumerator** aResult) override;
+  NS_IMETHOD GetSubFolders(nsTArray<RefPtr<nsIMsgFolder>>& folders) override;
 
   NS_IMETHOD UpdateFolder(nsIMsgWindow* aWindow) override;
 
   NS_IMETHOD CreateSubfolder(const nsAString& folderName,
                              nsIMsgWindow* msgWindow) override;
 
   NS_IMETHOD DeleteStorage() override;
   NS_IMETHOD Rename(const nsAString& newName, nsIMsgWindow* msgWindow) override;
--- a/mailnews/news/src/nsNntpIncomingServer.cpp
+++ b/mailnews/news/src/nsNntpIncomingServer.cpp
@@ -295,17 +295,16 @@ nsNntpIncomingServer::WriteNewsrcFile() 
     rv = GetNewsrcFilePath(getter_AddRefs(newsrcFile));
     if (NS_FAILED(rv)) return rv;
 
     nsCOMPtr<nsIOutputStream> newsrcStream;
     nsresult rv = MsgNewBufferedFileOutputStream(getter_AddRefs(newsrcStream),
                                                  newsrcFile, -1, 00600);
     if (NS_FAILED(rv)) return rv;
 
-    nsCOMPtr<nsISimpleEnumerator> subFolders;
     nsCOMPtr<nsIMsgFolder> rootFolder;
     rv = GetRootFolder(getter_AddRefs(rootFolder));
     if (NS_FAILED(rv)) return rv;
 
     nsCOMPtr<nsIMsgNewsFolder> newsFolder = do_QueryInterface(rootFolder, &rv);
     if (NS_FAILED(rv)) return rv;
 
     uint32_t bytesWritten;
@@ -334,35 +333,28 @@ nsNntpIncomingServer::WriteNewsrcFile() 
 #endif /* DEBUG_NEWS */
     }
 #ifdef DEBUG_NEWS
     else {
       printf("no unsubscribed lines to write out\n");
     }
 #endif /* DEBUG_NEWS */
 
-    rv = rootFolder->GetSubFolders(getter_AddRefs(subFolders));
-    if (NS_FAILED(rv)) return rv;
-
-    bool moreFolders;
-
-    while (NS_SUCCEEDED(subFolders->HasMoreElements(&moreFolders)) &&
-           moreFolders) {
-      nsCOMPtr<nsISupports> child;
-      rv = subFolders->GetNext(getter_AddRefs(child));
-      if (NS_SUCCEEDED(rv) && child) {
-        newsFolder = do_QueryInterface(child, &rv);
-        if (NS_SUCCEEDED(rv) && newsFolder) {
-          nsCString newsrcLine;
-          rv = newsFolder->GetNewsrcLine(newsrcLine);
-          if (NS_SUCCEEDED(rv) && !newsrcLine.IsEmpty()) {
-            // write the line to the newsrc file
-            newsrcStream->Write(newsrcLine.get(), newsrcLine.Length(),
-                                &bytesWritten);
-          }
+    nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+    rv = rootFolder->GetSubFolders(subFolders);
+    NS_ENSURE_SUCCESS(rv, rv);
+    for (nsIMsgFolder* child : subFolders) {
+      newsFolder = do_QueryInterface(child, &rv);
+      if (NS_SUCCEEDED(rv) && newsFolder) {
+        nsCString newsrcLine;
+        rv = newsFolder->GetNewsrcLine(newsrcLine);
+        if (NS_SUCCEEDED(rv) && !newsrcLine.IsEmpty()) {
+          // write the line to the newsrc file
+          newsrcStream->Write(newsrcLine.get(), newsrcLine.Length(),
+                              &bytesWritten);
         }
       }
     }
 
     newsrcStream->Close();
 
     rv = SetNewsrcHasChanged(false);
     if (NS_FAILED(rv)) return rv;
@@ -633,27 +625,20 @@ nsNntpIncomingServer::PerformExpand(nsIM
   return NS_OK;
 }
 
 nsresult nsNntpIncomingServer::DownloadMail(nsIMsgWindow* aMsgWindow) {
   nsCOMPtr<nsIMsgFolder> rootFolder;
   nsresult rv = GetRootFolder(getter_AddRefs(rootFolder));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsISimpleEnumerator> groups;
-  rv = rootFolder->GetSubFolders(getter_AddRefs(groups));
+  nsTArray<RefPtr<nsIMsgFolder>> groups;
+  rv = rootFolder->GetSubFolders(groups);
   NS_ENSURE_SUCCESS(rv, rv);
-
-  bool hasNext;
-  while (NS_SUCCEEDED(rv = groups->HasMoreElements(&hasNext)) && hasNext) {
-    nsCOMPtr<nsISupports> nextGroup;
-    rv = groups->GetNext(getter_AddRefs(nextGroup));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsCOMPtr<nsIMsgFolder> group(do_QueryInterface(nextGroup));
+  for (nsIMsgFolder* group : groups) {
     rv = group->GetNewMessages(aMsgWindow, nullptr);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   return rv;
 }
 
 NS_IMETHODIMP
 nsNntpIncomingServer::DisplaySubscribedGroup(nsIMsgNewsFolder* aMsgFolder,
@@ -709,18 +694,18 @@ nsNntpIncomingServer::ContainsNewsgroup(
   NS_ENSURE_ARG_POINTER(containsGroup);
   NS_ENSURE_FALSE(aName.IsEmpty(), NS_ERROR_FAILURE);
 
   if (mSubscribedNewsgroups.Length() == 0) {
     // If this is empty, we may need to discover folders
     nsCOMPtr<nsIMsgFolder> rootFolder;
     GetRootFolder(getter_AddRefs(rootFolder));
     if (rootFolder) {
-      nsCOMPtr<nsISimpleEnumerator> subfolders;
-      rootFolder->GetSubFolders(getter_AddRefs(subfolders));
+      nsTArray<RefPtr<nsIMsgFolder>> dummy;
+      rootFolder->GetSubFolders(dummy);
     }
   }
   nsAutoCString unescapedName;
   MsgUnescapeString(aName, 0, unescapedName);
   *containsGroup = mSubscribedNewsgroups.Contains(aName);
   return NS_OK;
 }
 
@@ -1267,37 +1252,28 @@ nsNntpIncomingServer::ForgetPassword() {
   nsCOMPtr<nsIMsgNewsFolder> newsFolder = do_QueryInterface(rootFolder, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!newsFolder) return NS_ERROR_FAILURE;
 
   rv = newsFolder->ForgetAuthenticationCredentials();
   NS_ENSURE_SUCCESS(rv, rv);
 
   // clear password of all child folders
-  nsCOMPtr<nsISimpleEnumerator> subFolders;
-
-  rv = rootFolder->GetSubFolders(getter_AddRefs(subFolders));
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  rv = rootFolder->GetSubFolders(subFolders);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  bool moreFolders = false;
-
   nsresult return_rv = NS_OK;
-
-  while (NS_SUCCEEDED(subFolders->HasMoreElements(&moreFolders)) &&
-         moreFolders) {
-    nsCOMPtr<nsISupports> child;
-    rv = subFolders->GetNext(getter_AddRefs(child));
-    if (NS_SUCCEEDED(rv) && child) {
-      newsFolder = do_QueryInterface(child, &rv);
-      if (NS_SUCCEEDED(rv) && newsFolder) {
-        rv = newsFolder->ForgetAuthenticationCredentials();
-        if (NS_FAILED(rv)) return_rv = rv;
-      } else {
-        return_rv = NS_ERROR_FAILURE;
-      }
+  for (nsIMsgFolder* child : subFolders) {
+    newsFolder = do_QueryInterface(child, &rv);
+    if (NS_SUCCEEDED(rv) && newsFolder) {
+      rv = newsFolder->ForgetAuthenticationCredentials();
+      if (NS_FAILED(rv)) return_rv = rv;
+    } else {
+      return_rv = NS_ERROR_FAILURE;
     }
   }
 
   return return_rv;
 }
 
 NS_IMETHODIMP
 nsNntpIncomingServer::GetSupportsExtensions(bool* aSupportsExtensions) {
@@ -1916,38 +1892,31 @@ nsNntpIncomingServer::OnUserOrHostNameCh
   // article numbers
   //   in the rc file (this is because the old and new servers may maintain
   //   different numbers for the same articles if both servers handle the same
   //   groups).
   nsCOMPtr<nsIMsgFolder> serverFolder;
   rv = GetRootMsgFolder(getter_AddRefs(serverFolder));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsISimpleEnumerator> subFolders;
-  rv = serverFolder->GetSubFolders(getter_AddRefs(subFolders));
+  nsTArray<RefPtr<nsIMsgFolder>> subFolders;
+  rv = serverFolder->GetSubFolders(subFolders);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsTArray<nsString> groupList;
-  nsString folderName;
-
   // Prepare the group list
-  bool hasMore;
-  while (NS_SUCCEEDED(subFolders->HasMoreElements(&hasMore)) && hasMore) {
-    nsCOMPtr<nsISupports> item;
-    subFolders->GetNext(getter_AddRefs(item));
-    nsCOMPtr<nsIMsgFolder> newsgroupFolder(do_QueryInterface(item));
-    if (!newsgroupFolder) continue;
-
+  nsTArray<nsString> groupList(subFolders.Length());
+  for (nsIMsgFolder* newsgroupFolder : subFolders) {
+    nsString folderName;
     rv = newsgroupFolder->GetName(folderName);
     NS_ENSURE_SUCCESS(rv, rv);
     groupList.AppendElement(folderName);
   }
 
   // If nothing subscribed then we're done.
-  if (groupList.Length() == 0) return NS_OK;
+  if (groupList.IsEmpty()) return NS_OK;
 
   // Now unsubscribe & subscribe.
   uint32_t i;
   uint32_t cnt = groupList.Length();
   nsAutoCString cname;
   for (i = 0; i < cnt; i++) {
     // unsubscribe.
     rv = Unsubscribe(groupList[i].get());
--- a/suite/mailnews/content/SearchDialog.js
+++ b/suite/mailnews/content/SearchDialog.js
@@ -409,43 +409,33 @@ function onSearch()
     {
        dump("Search Exception\n");
     }
     // refresh the tree after the search starts, because initiating the
     // search will cause the datasource to clear itself
 }
 
 function AddSubFolders(folder) {
-  var subFolders = folder.subFolders;
-  while (subFolders.hasMoreElements())
-  {
-    var nextFolder =
-      subFolders.getNext().QueryInterface(Ci.nsIMsgFolder);
-
+  for (let nextFolder of folder.subFolders) {
     if (!(nextFolder.flags & Ci.nsMsgFolderFlags.Virtual))
     {
       if (!nextFolder.noSelect)
         gSearchSession.addScopeTerm(GetScopeForFolder(nextFolder), nextFolder);
 
       AddSubFolders(nextFolder);
     }
   }
 }
 
 function AddSubFoldersToURI(folder)
 {
   var returnString = "";
 
-  var subFolders = folder.subFolders;
-
-  while (subFolders.hasMoreElements())
+  for (let nextFolder of folder.subFolders) {
   {
-    var nextFolder =
-      subFolders.getNext().QueryInterface(Ci.nsIMsgFolder);
-
     if (!(nextFolder.flags & Ci.nsMsgFolderFlags.Virtual))
     {
       if (!nextFolder.noSelect && !nextFolder.isServer)
       {
         if (returnString.length > 0)
           returnString += '|';
         returnString += nextFolder.URI;
       }
--- a/suite/mailnews/content/folderPane.js
+++ b/suite/mailnews/content/folderPane.js
@@ -238,19 +238,19 @@ var gFolderTreeController = {
 
     if (!folder || !folder.getFlag(Ci.nsMsgFolderFlags.Junk))
       return;
 
     if (!this._checkConfirmationPrompt("emptyJunk"))
       return;
 
     // Delete any sub-folders this folder might have.
-    let iter = folder.subFolders;
-    while (iter.hasMoreElements())
-      folder.propagateDelete(iter.getNext(), true, msgWindow);
+    for (let f of folder.subFolders) {
+      folder.propagateDelete(f, true, msgWindow);
+    }
 
     // Now delete the messages.
     let messages = Array.from(fixIterator(folder.messages));
     folder.deleteMessages(messages, msgWindow, true, false, null, false);
   },
 
   /**
    * Compacts either particular folder/s, or selected folders.
--- a/suite/mailnews/content/mailContextMenus.js
+++ b/suite/mailnews/content/mailContextMenus.js
@@ -723,29 +723,24 @@ function OpenMessageByHeader(messageHead
   }
 }
 
 // search for message by message id in given folder and its subfolders
 // return message header if message was found
 function SearchForMessageIdInSubFolder(folder, messageId)
 {
   var messageHeader;
-  var subFolders = folder.subFolders;
 
   // search in folder
   if (!folder.isServer)
     messageHeader = CheckForMessageIdInFolder(folder, messageId);
 
   // search subfolders recursively
-  while (subFolders.hasMoreElements() && !messageHeader)
-  {
+  for (let currentFolder of folder.subFolders) {
     // search in current folder
-    var currentFolder =
-      subFolders.getNext().QueryInterface(Ci.nsIMsgFolder);
-
     messageHeader = CheckForMessageIdInFolder(currentFolder, messageId);
 
     // search in its subfolder
     if (!messageHeader && currentFolder.hasSubFolders)
       messageHeader = SearchForMessageIdInSubFolder(currentFolder, messageId);
   }
 
   return messageHeader;
--- a/suite/mailnews/content/msgViewNavigation.js
+++ b/suite/mailnews/content/msgViewNavigation.js
@@ -6,24 +6,17 @@
 /*  This file contains the js functions necessary to implement view navigation within the 3 pane. */
 
 const {allAccountsSorted} = ChromeUtils.import("resource:///modules/folderUtils.jsm");
 
 //NOTE: gMessengerBundle must be defined and set or this Overlay won't work
 
 function GetSubFoldersInFolderPaneOrder(folder)
 {
-  var subFolders = folder.subFolders;
-  var msgFolders = Array();
-
-  // get all the subfolders
-  while (subFolders.hasMoreElements()) {
-    msgFolders[msgFolders.length] =
-      subFolders.getNext().QueryInterface(Ci.nsIMsgFolder);
-  }
+  var msgFolders = folder.subFolders;
 
   function compareFolderSortKey(folder1, folder2) {
     return folder1.compareSortKeys(folder2);
   }
 
   // sort the subfolders
   msgFolders.sort(compareFolderSortKey);
   return msgFolders;