Bug 1614846 - remove nsIArray use in nsIMsgAccountManager (part one: accounts). r=mkmelin
authorBen Campbell <benc@thunderbird.net>
Sun, 16 Feb 2020 08:48:01 +1300
changeset 37516 1da9c365060718ffc88deb4d39b3930aeb02a1a7
parent 37515 7d7596b594c302f882acb50ebe5d98d971ceb1a2
child 37517 cd8871b0a49c89f2265cb1c039f1efe139052fb8
push id2566
push userclokep@gmail.com
push dateMon, 09 Mar 2020 19:20:31 +0000
treeherdercomm-beta@a352facfa0a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1614846
Bug 1614846 - remove nsIArray use in nsIMsgAccountManager (part one: accounts). r=mkmelin
calendar/base/modules/utils/calEmailUtils.jsm
calendar/base/modules/utils/calProviderUtils.jsm
mail/components/about-support/content/accounts.js
mail/components/cloudfile/test/browser/head.js
mail/components/compose/content/MsgComposeCommands.js
mail/components/extensions/parent/ext-accounts.js
mail/components/extensions/test/browser/head.js
mail/components/extensions/test/xpcshell/head.js
mail/components/im/content/imAccounts.js
mail/components/im/modules/chatHandler.jsm
mail/components/im/modules/index_im.jsm
mail/extensions/openpgp/content/modules/configure.jsm
mail/extensions/openpgp/content/modules/funcs.jsm
mail/extensions/openpgp/content/modules/keyUsability.jsm
mail/extensions/openpgp/content/modules/stdlib/misc.jsm
mail/test/browser/composition/browser_addressWidgets.js
mail/test/browser/folder-pane/browser_folderNamesInRecentMode.js
mail/test/browser/multiple-identities/browser_displayNames.js
mail/test/browser/shared-modules/NewMailAccountHelpers.jsm
mailnews/base/prefs/content/accountUtils.js
mailnews/base/prefs/content/am-server.js
mailnews/base/prefs/content/amUtils.js
mailnews/base/public/nsIMsgAccountManager.idl
mailnews/base/src/nsMsgAccountManager.cpp
mailnews/base/src/nsSpamSettings.cpp
mailnews/base/test/unit/test_nsIMsgFolder.js
mailnews/base/util/folderUtils.jsm
mailnews/compose/src/nsMsgSendLater.cpp
mailnews/db/gloda/modules/IndexMsg.jsm
mailnews/imap/src/nsAutoSyncManager.cpp
mailnews/import/becky/src/nsBeckyFilters.cpp
mailnews/import/test/unit/resources/import_helper.js
--- a/calendar/base/modules/utils/calEmailUtils.jsm
+++ b/calendar/base/modules/utils/calEmailUtils.jsm
@@ -48,19 +48,17 @@ var calemail = {
 
   /**
    * Iterates all email identities and calls the passed function with identity and account.
    * If the called function returns false, iteration is stopped.
    *
    * @param {Function} aFunc       The function to be called for each identity and account
    */
   iterateIdentities(aFunc) {
-    let accounts = MailServices.accounts.accounts;
-    for (let i = 0; i < accounts.length; ++i) {
-      let account = accounts.queryElementAt(i, Ci.nsIMsgAccount);
+    for (let account of MailServices.accounts.accounts) {
       let identities = account.identities;
       for (let j = 0; j < identities.length; ++j) {
         let identity = identities.queryElementAt(j, Ci.nsIMsgIdentity);
         if (!aFunc(identity, account)) {
           break;
         }
       }
     }
--- a/calendar/base/modules/utils/calProviderUtils.jsm
+++ b/calendar/base/modules/utils/calProviderUtils.jsm
@@ -1,15 +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 { MailServices } = ChromeUtils.import("resource:///modules/MailServices.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-var { fixIterator } = ChromeUtils.import("resource:///modules/iteratorUtils.jsm");
 
 ChromeUtils.defineModuleGetter(this, "cal", "resource:///modules/calendar/calUtils.jsm");
 
 /*
  * Helpers and base class for calendar providers
  */
 
 // NOTE: This module should not be loaded directly, it is available when
@@ -262,18 +261,17 @@ var calprovider = {
         }
         return null;
       };
 
       let foundAccount = MailServices.accounts.defaultAccount;
       let foundIdentity = findIdentity(foundAccount);
 
       if (!foundAccount || !foundIdentity) {
-        let accounts = MailServices.accounts.accounts;
-        for (let account of fixIterator(accounts, Ci.nsIMsgAccount)) {
+        for (let account of MailServices.accounts.accounts) {
           let identity = findIdentity(account);
 
           if (account && identity) {
             foundAccount = account;
             foundIdentity = identity;
             break;
           }
         }
--- a/mail/components/about-support/content/accounts.js
+++ b/mail/components/about-support/content/accounts.js
@@ -85,19 +85,18 @@ var AboutSupport = {
     return smtpDetails;
   },
 
   /**
    * Returns account details as an array of records.
    */
   getAccountDetails() {
     let accountDetails = [];
-    let accounts = MailServices.accounts.accounts;
 
-    for (let account of fixIterator(accounts, Ci.nsIMsgAccount)) {
+    for (let account of MailServices.accounts.accounts) {
       let server = account.incomingServer;
       accountDetails.push({
         key: account.key,
         name: server.prettyName,
         hostDetails:
           "(" +
           server.type +
           ") " +
--- a/mail/components/cloudfile/test/browser/head.js
+++ b/mail/components/cloudfile/test/browser/head.js
@@ -12,21 +12,21 @@ add_task(async function setup() {
   let rootFolder = gAccount.incomingServer.rootFolder;
 
   window.gFolderTreeView.selectFolder(rootFolder);
   await new Promise(resolve => executeSoon(resolve));
 });
 
 function createAccount() {
   registerCleanupFunction(() => {
-    [...MailServices.accounts.accounts.enumerate()].forEach(cleanUpAccount);
+    MailServices.accounts.accounts.forEach(cleanUpAccount);
   });
 
   MailServices.accounts.createLocalMailAccount();
-  let account = MailServices.accounts.accounts.enumerate().getNext();
+  let account = MailServices.accounts.accounts[0];
   info(`Created account ${account.toString()}`);
 
   return account;
 }
 
 function cleanUpAccount(account) {
   info(`Cleaning up account ${account.toString()}`);
   MailServices.accounts.removeAccount(account, true);
--- a/mail/components/compose/content/MsgComposeCommands.js
+++ b/mail/components/compose/content/MsgComposeCommands.js
@@ -6696,20 +6696,17 @@ function DetermineConvertibility() {
  *
  * @param {string} accountKey - Key of the account that is currently selected
  *   as the sending account.
  * @param {string} prevKey - Key of the account that was previously selected
  *   as the sending account.
  */
 function hideIrrelevantAddressingOptions(accountKey, prevKey) {
   let hideNews = true;
-  for (let account of fixIterator(
-    MailServices.accounts.accounts,
-    Ci.nsIMsgAccount
-  )) {
+  for (let account of MailServices.accounts.accounts) {
     if (account.incomingServer.type == "nntp") {
       hideNews = false;
     }
   }
   // If there is no News (NNTP) account existing then
   // hide the Newsgroup and Followup-To recipient type in all the menulists.
   for (let item of document.querySelectorAll(".news-label")) {
     item.collapsed = hideNews;
--- a/mail/components/extensions/parent/ext-accounts.js
+++ b/mail/components/extensions/parent/ext-accounts.js
@@ -44,20 +44,17 @@ function convertAccount(account) {
 }
 
 this.accounts = class extends ExtensionAPI {
   getAPI(context) {
     return {
       accounts: {
         async list() {
           let accounts = [];
-          for (let account of fixIterator(
-            MailServices.accounts.accounts,
-            Ci.nsIMsgAccount
-          )) {
+          for (let account of MailServices.accounts.accounts) {
             account = convertAccount(account);
             if (account) {
               accounts.push(account);
             }
           }
           return accounts;
         },
         async get(accountId) {
--- a/mail/components/extensions/test/browser/head.js
+++ b/mail/components/extensions/test/browser/head.js
@@ -28,21 +28,21 @@ registerCleanupFunction(() => {
 
   while (tabmail.tabInfo.length > 1) {
     tabmail.closeTab(tabmail.tabInfo[1]);
   }
 });
 
 function createAccount() {
   registerCleanupFunction(() => {
-    [...MailServices.accounts.accounts.enumerate()].forEach(cleanUpAccount);
+    MailServices.accounts.accounts.forEach(cleanUpAccount);
   });
 
   MailServices.accounts.createLocalMailAccount();
-  let account = MailServices.accounts.accounts.enumerate().getNext();
+  let account = MailServices.accounts.accounts[0];
   info(`Created account ${account.toString()}`);
 
   return account;
 }
 
 function cleanUpAccount(account) {
   info(`Cleaning up account ${account.toString()}`);
   MailServices.accounts.removeAccount(account, true);
--- a/mail/components/extensions/test/xpcshell/head.js
+++ b/mail/components/extensions/test/xpcshell/head.js
@@ -28,33 +28,30 @@ Services.prefs.deleteBranch("ldap_2.serv
 
 var createHttpServer = (...args) => {
   AddonTestUtils.maybeInit(this);
   return AddonTestUtils.createHttpServer(...args);
 };
 
 function createAccount() {
   MailServices.accounts.createLocalMailAccount();
-  let account = MailServices.accounts.accounts
-    .enumerate()
-    .getNext()
-    .QueryInterface(Ci.nsIMsgAccount);
+  let account = MailServices.accounts.accounts[0];
   account.incomingServer = MailServices.accounts.localFoldersServer;
   info(`Created account ${account.toString()}`);
 
   return account;
 }
 
 function cleanUpAccount(account) {
   info(`Cleaning up account ${account.toString()}`);
   MailServices.accounts.removeAccount(account, true);
 }
 
 registerCleanupFunction(() => {
-  [...MailServices.accounts.accounts.enumerate()].forEach(cleanUpAccount);
+  MailServices.accounts.accounts.forEach(cleanUpAccount);
 });
 
 function addIdentity(account, email = "xpcshell@localhost") {
   let identity = MailServices.accounts.createIdentity();
   identity.email = email;
   account.addIdentity(identity);
   if (!account.defaultIdentity) {
     account.defaultIdentity = identity;
--- a/mail/components/im/content/imAccounts.js
+++ b/mail/components/im/content/imAccounts.js
@@ -2,19 +2,16 @@
  * 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/. */
 
 /* globals MozElements */
 /* globals statusSelector */
 /* globals MsgAccountManager */
 
 var { Services } = ChromeUtils.import("resource:///modules/imServices.jsm");
-var { fixIterator } = ChromeUtils.import(
-  "resource:///modules/iteratorUtils.jsm"
-);
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 var { DownloadUtils } = ChromeUtils.import(
   "resource://gre/modules/DownloadUtils.jsm"
 );
 ChromeUtils.defineModuleGetter(
   this,
@@ -359,18 +356,17 @@ var gAccountManager = {
 
   new() {
     this.openDialog("chrome://messenger/content/chat/imAccountWizard.xhtml");
   },
   edit() {
     // Find the nsIIncomingServer for the current imIAccount.
     let server = null;
     let imAccountId = this.accountList.selectedItem.account.numericId;
-    let mgr = MailServices.accounts;
-    for (let account of fixIterator(mgr.accounts, Ci.nsIMsgAccount)) {
+    for (let account of MailServices.accounts.accounts) {
       let incomingServer = account.incomingServer;
       if (!incomingServer || incomingServer.type != "im") {
         continue;
       }
       if (incomingServer.wrappedJSObject.imAccount.numericId == imAccountId) {
         server = incomingServer;
         break;
       }
--- a/mail/components/im/modules/chatHandler.jsm
+++ b/mail/components/im/modules/chatHandler.jsm
@@ -1,18 +1,15 @@
 /* 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/. */
 
 const EXPORTED_SYMBOLS = ["allContacts", "onlineContacts", "ChatCore"];
 
 const { Services } = ChromeUtils.import("resource:///modules/imServices.jsm");
-const { fixIterator } = ChromeUtils.import(
-  "resource:///modules/iteratorUtils.jsm"
-);
 const { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
 var allContacts = {};
 var onlineContacts = {};
 
 var ChatCore = {
@@ -48,17 +45,17 @@ var ChatCore = {
           // not in nsMsgAccountManager. They have probably been lost if
           // the user has used an older version of Thunderbird on a
           // profile with IM accounts. See bug 736035.
           let accountsById = {};
           for (let account of Services.accounts.getAccounts()) {
             accountsById[account.numericId] = account;
           }
           let mgr = MailServices.accounts;
-          for (let account of fixIterator(mgr.accounts, Ci.nsIMsgAccount)) {
+          for (let account of mgr.accounts) {
             let incomingServer = account.incomingServer;
             if (!incomingServer || incomingServer.type != "im") {
               continue;
             }
             delete accountsById[
               incomingServer.wrappedJSObject.imAccount.numericId
             ];
           }
--- a/mail/components/im/modules/index_im.jsm
+++ b/mail/components/im/modules/index_im.jsm
@@ -10,19 +10,16 @@ const { Gloda } = ChromeUtils.import(
   "resource:///modules/gloda/GlodaPublic.jsm"
 );
 const { GlodaAccount } = ChromeUtils.import(
   "resource:///modules/gloda/GlodaDataModel.jsm"
 );
 const { GlodaIndexer, IndexingJob } = ChromeUtils.import(
   "resource:///modules/gloda/GlodaIndexer.jsm"
 );
-const { fixIterator } = ChromeUtils.import(
-  "resource:///modules/iteratorUtils.jsm"
-);
 const { Services } = ChromeUtils.import("resource:///modules/imServices.jsm");
 const { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 const { FileUtils } = ChromeUtils.import(
   "resource://gre/modules/FileUtils.jsm"
 );
 const { XPCOMUtils } = ChromeUtils.import(
@@ -98,18 +95,17 @@ GlodaIMConversation.prototype = {
     let [protocol, username] = this._path.split("/", 2);
 
     let cacheName = protocol + "/" + username;
     if (cacheName in gIMAccounts) {
       return gIMAccounts[cacheName];
     }
 
     // Find the nsIIncomingServer for the current imIAccount.
-    let mgr = MailServices.accounts;
-    for (let account of fixIterator(mgr.accounts, Ci.nsIMsgAccount)) {
+    for (let account of MailServices.accounts.accounts) {
       let incomingServer = account.incomingServer;
       if (!incomingServer || incomingServer.type != "im") {
         continue;
       }
       let imAccount = incomingServer.wrappedJSObject.imAccount;
       if (
         imAccount.protocol.normalizedName == protocol &&
         imAccount.normalizedName == username
--- a/mail/extensions/openpgp/content/modules/configure.jsm
+++ b/mail/extensions/openpgp/content/modules/configure.jsm
@@ -41,16 +41,19 @@ const { EnigmailStdlib } = ChromeUtils.i
   "chrome://openpgp/content/modules/stdlib.jsm"
 );
 const { EnigmailLazy } = ChromeUtils.import(
   "chrome://openpgp/content/modules/lazy.jsm"
 );
 const { EnigmailAutoSetup } = ChromeUtils.import(
   "chrome://openpgp/content/modules/autoSetup.jsm"
 );
+const { MailServices } = ChromeUtils.import(
+  "resource:///modules/MailServices.jsm"
+);
 
 /**
  * Upgrade sending prefs
  * (v1.6.x -> v1.7 )
  */
 function upgradePrefsSending() {
   EnigmailLog.DEBUG("enigmailCommon.jsm: upgradePrefsSending()\n");
 
@@ -144,23 +147,19 @@ function replaceKeyIdWithFpr() {
   }
 }
 
 /**
  * Change the default to PGP/MIME for all accounts, except nntp
  * (v1.8.x -> v1.9)
  */
 function defaultPgpMime() {
-  let accountManager = Cc[
-    "@mozilla.org/messenger/account-manager;1"
-  ].getService(Ci.nsIMsgAccountManager);
   let changedSomething = false;
 
-  for (let acct = 0; acct < accountManager.accounts.length; acct++) {
-    let ac = accountManager.accounts.queryElementAt(acct, Ci.nsIMsgAccount);
+  for (let ac of MailServices.accounts.accounts) {
     if (ac.incomingServer.type.search(/(pop3|imap|movemail)/) >= 0) {
       for (let i = 0; i < ac.identities.length; i++) {
         let id = ac.identities.queryElementAt(i, Ci.nsIMsgIdentity);
         if (
           id.getBoolAttribute("enablePgp") &&
           !id.getBoolAttribute("pgpMimeMode")
         ) {
           changedSomething = true;
@@ -179,22 +178,17 @@ function defaultPgpMime() {
 }
 
 /**
  * set the Autocrypt prefer-encrypt option to "mutual" for all existing
  * accounts
  */
 function setAutocryptForOldAccounts() {
   try {
-    let accountManager = Cc[
-      "@mozilla.org/messenger/account-manager;1"
-    ].getService(Ci.nsIMsgAccountManager);
-
-    for (let acct = 0; acct < accountManager.accounts.length; acct++) {
-      let ac = accountManager.accounts.queryElementAt(acct, Ci.nsIMsgAccount);
+    for (let ac of MailServices.accounts.accounts) {
       if (ac.incomingServer.type.search(/(pop3|imap|movemail)/) >= 0) {
         ac.incomingServer.setIntValue("acPreferEncrypt", 1);
       }
     }
   } catch (ex) {}
 }
 
 function setDefaultKeyServer() {
--- a/mail/extensions/openpgp/content/modules/funcs.jsm
+++ b/mail/extensions/openpgp/content/modules/funcs.jsm
@@ -17,16 +17,19 @@ const { EnigmailLog } = ChromeUtils.impo
   "chrome://openpgp/content/modules/log.jsm"
 );
 const { EnigmailPrefs } = ChromeUtils.import(
   "chrome://openpgp/content/modules/prefs.jsm"
 );
 const { EnigmailData } = ChromeUtils.import(
   "chrome://openpgp/content/modules/data.jsm"
 );
+const { MailServices } = ChromeUtils.import(
+  "resource:///modules/MailServices.jsm"
+);
 
 var gTxtConverter = null;
 
 var EnigmailFuncs = {
   /**
    * get a list of plain email addresses without name or surrounding <>
    * @param mailAddrs |string| - address-list encdoded in Unicode as specified in RFC 2822, 3.4
    *                             separated by , or ;
@@ -409,48 +412,37 @@ var EnigmailFuncs = {
     }
     return 0;
   },
 
   /**
    * Get the nsIMsgAccount associated with a given nsIMsgIdentity
    */
   getAccountForIdentity(identity) {
-    let accountManager = Cc[
-      "@mozilla.org/messenger/account-manager;1"
-    ].getService(Ci.nsIMsgAccountManager);
-
-    for (let acct = 0; acct < accountManager.accounts.length; acct++) {
-      let ac = accountManager.accounts.queryElementAt(acct, Ci.nsIMsgAccount);
-
+    for (let ac of MailServices.accounts.accounts) {
       for (let i = 0; i < ac.identities.length; i++) {
         let id = ac.identities.queryElementAt(i, Ci.nsIMsgIdentity);
         if (id.key === identity.key) {
           return ac;
         }
       }
     }
     return null;
   },
 
   /**
    * Get the default identity of the default account
    */
   getDefaultIdentity() {
-    let accountManager = Cc[
-      "@mozilla.org/messenger/account-manager;1"
-    ].getService(Ci.nsIMsgAccountManager);
-
     try {
       let ac;
-      if (accountManager.defaultAccount) {
-        ac = accountManager.defaultAccount;
+      if (MailServices.accounts.defaultAccount) {
+        ac = MailServices.accounts.defaultAccount;
       } else {
-        for (let i = 0; i < accountManager.accounts.length; i++) {
-          ac = accountManager.accounts.queryElementAt(i, Ci.nsIMsgAccount);
+        for (ac of MailServices.accounts.accounts) {
           if (
             ac.incomingServer.type === "imap" ||
             ac.incomingServer.type === "pop3"
           ) {
             break;
           }
         }
       }
--- a/mail/extensions/openpgp/content/modules/keyUsability.jsm
+++ b/mail/extensions/openpgp/content/modules/keyUsability.jsm
@@ -21,16 +21,19 @@ const { EnigmailCore } = ChromeUtils.imp
   "chrome://openpgp/content/modules/core.jsm"
 );
 const { EnigmailConstants } = ChromeUtils.import(
   "chrome://openpgp/content/modules/constants.jsm"
 );
 const { EnigmailLazy } = ChromeUtils.import(
   "chrome://openpgp/content/modules/lazy.jsm"
 );
+const { MailServices } = ChromeUtils.import(
+  "resource:///modules/MailServices.jsm"
+);
 
 const getDialog = EnigmailLazy.loader("enigmail/dialog.jsm", "EnigmailDialog");
 const getWindows = EnigmailLazy.loader(
   "enigmail/windows.jsm",
   "EnigmailWindows"
 );
 const getKeyRing = EnigmailLazy.loader(
   "enigmail/keyRing.jsm",
@@ -92,25 +95,20 @@ var EnigmailKeyUsability = {
   /**
    * Determine the configured key specifications for all identities
    * where Enigmail is enabled
    *
    * @return  Array of Strings - list of keyId and email addresses
    */
   getKeysSpecForIdentities() {
     EnigmailLog.DEBUG("keyUsability.jsm: getKeysSpecForIdentities()\n");
-    let accountManager = Cc[
-      "@mozilla.org/messenger/account-manager;1"
-    ].getService(Ci.nsIMsgAccountManager);
 
     let keySpecList = [];
 
-    for (let acct = 0; acct < accountManager.accounts.length; acct++) {
-      let ac = accountManager.accounts.queryElementAt(acct, Ci.nsIMsgAccount);
-
+    for (let ac of MailServices.accounts.accounts) {
       for (let i = 0; i < ac.identities.length; i++) {
         let id = ac.identities.queryElementAt(i, Ci.nsIMsgIdentity);
         if (id.getBoolAttribute("enablePgp")) {
           if (id.getIntAttribute("pgpKeyMode") === 1) {
             keySpecList.push(id.getCharAttribute("pgpkeyId"));
           } else {
             keySpecList.push(id.email);
           }
--- a/mail/extensions/openpgp/content/modules/stdlib/misc.jsm
+++ b/mail/extensions/openpgp/content/modules/stdlib/misc.jsm
@@ -177,20 +177,17 @@ function getDefaultIdentity() {
 /**
  * Returns a list of all identities in the form [{ boolean isDefault; nsIMsgIdentity identity }].
  * It is assured that there is exactly one default identity.
  * If only the default identity is needed, getDefaultIdentity() can be used.
  * @param aSkipNntpIdentities (default: true) Should we avoid including nntp identities in the list?
  */
 function getIdentities(aSkipNntpIdentities = true) {
   let identities = [];
-  for (let account of fixIterator(
-    MailServices.accounts.accounts,
-    Ci.nsIMsgAccount
-  )) {
+  for (let account of MailServices.accounts.accounts) {
     let server = account.incomingServer;
     if (
       aSkipNntpIdentities &&
       (!server || (server.type != "pop3" && server.type != "imap"))
     ) {
       continue;
     }
     for (let currentIdentity of fixIterator(
@@ -419,23 +416,17 @@ function combine(a1, a2) {
   return [...range(0, a1.length)].map(i => [a1[i], a2[i]]);
 }
 
 /**
  * Determine if at least one account / identity is configured
  * @return {Bool}
  */
 function hasConfiguredAccounts() {
-  let accountManager = Cc[
-    "@mozilla.org/messenger/account-manager;1"
-  ].getService(Ci.nsIMsgAccountManager);
-
-  for (let acct = 0; acct < accountManager.accounts.length; acct++) {
-    let ac = accountManager.accounts.queryElementAt(acct, Ci.nsIMsgAccount);
-
+  for (let ac of MailServices.accounts.accounts) {
     if (ac.incomingServer.type !== "none") {
       if (ac.defaultIdentity.email.length > 0) {
         return true;
       }
     }
   }
 
   return false;
--- a/mail/test/browser/composition/browser_addressWidgets.js
+++ b/mail/test/browser/composition/browser_addressWidgets.js
@@ -113,20 +113,17 @@ function remove_NNTP_account() {
 
 /**
  * Bug 399446 & bug 922614
  * Test that the allowed address types depend on the account type
  * we are sending from.
  */
 add_task(function test_address_types() {
   // Be sure there is no NNTP account yet.
-  for (let account of fixIterator(
-    MailServices.accounts.accounts,
-    Ci.nsIMsgAccount
-  )) {
+  for (let account of MailServices.accounts.accounts) {
     Assert.notEqual(
       account.incomingServer.type,
       "nntp",
       "There is a NNTP account existing unexpectedly"
     );
   }
 
   // Open compose window on the existing POP3 account.
--- a/mail/test/browser/folder-pane/browser_folderNamesInRecentMode.js
+++ b/mail/test/browser/folder-pane/browser_folderNamesInRecentMode.js
@@ -30,30 +30,27 @@ 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 fixIterator(
-    MailServices.accounts.accounts,
-    Ci.nsIMsgAccount
-  )) {
+  for (let acc of MailServices.accounts.accounts) {
     for (let fld of fixIterator(
       acc.incomingServer.rootFolder.subFolders,
       Ci.nsIMsgFolder
     )) {
       fld.setStringProperty("MRUTime", "0");
     }
   }
 
-  let acc1 = MailServices.accounts.accounts.queryElementAt(1, Ci.nsIMsgAccount);
-  let acc2 = MailServices.accounts.accounts.queryElementAt(0, Ci.nsIMsgAccount);
+  let acc1 = MailServices.accounts.accounts[1];
+  let acc2 = MailServices.accounts.accounts[0];
   let rootFolder1 = acc1.incomingServer.rootFolder;
   let rootFolder2 = acc2.incomingServer.rootFolder;
 
   // Create some test folders.
   rootFolder1.createSubfolder("uniqueName", null);
   rootFolder1.createSubfolder("duplicatedName", null);
   rootFolder2.createSubfolder("duplicatedName", null);
   let inbox2 = rootFolder2.getFolderWithFlags(Ci.nsMsgFolderFlags.Inbox);
--- a/mail/test/browser/multiple-identities/browser_displayNames.js
+++ b/mail/test/browser/multiple-identities/browser_displayNames.js
@@ -40,21 +40,17 @@ var collectedAddresses;
 
 add_task(function setupModule(module) {
   localAccount = MailServices.accounts.FindAccountForServer(
     MailServices.accounts.localFoldersServer
   );
 
   // We need to make sure we have only one identity:
   // 1) Delete all accounts except for Local Folders
-  for (let i = MailServices.accounts.accounts.length - 1; i >= 0; i--) {
-    let account = MailServices.accounts.accounts.queryElementAt(
-      i,
-      Ci.nsIMsgAccount
-    );
+  for (let account of MailServices.accounts.accounts) {
     if (account != localAccount) {
       MailServices.accounts.removeAccount(account);
     }
   }
 
   // 2) Delete all identities except for one
   for (let i = localAccount.identities.length - 1; i >= 0; i--) {
     let identity = localAccount.identities.queryElementAt(i, Ci.nsIMsgIdentity);
--- a/mail/test/browser/shared-modules/NewMailAccountHelpers.jsm
+++ b/mail/test/browser/shared-modules/NewMailAccountHelpers.jsm
@@ -27,19 +27,16 @@ var fdh = ChromeUtils.import(
   "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
 );
 var { input_value } = ChromeUtils.import(
   "resource://testing-common/mozmill/KeyboardHelpers.jsm"
 );
 
 var { Assert } = ChromeUtils.import("resource://testing-common/Assert.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-var { fixIterator } = ChromeUtils.import(
-  "resource:///modules/iteratorUtils.jsm"
-);
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
 var mc = fdh.mc;
 
 /* Wait until the list of providers is loaded and displayed.
  */
@@ -140,20 +137,17 @@ function wait_to_be_offline(w) {
 }
 
 /**
  * Remove an account with address aAddress from the current profile.
  *
  * @param aAddress the email address to try to remove.
  */
 function remove_email_account(aAddress) {
-  for (let account of fixIterator(
-    MailServices.accounts.accounts,
-    Ci.nsIMsgAccount
-  )) {
+  for (let account of MailServices.accounts.accounts) {
     if (account.defaultIdentity && account.defaultIdentity.email == aAddress) {
       MailServices.accounts.removeAccount(account);
       break;
     }
   }
 }
 
 /**
--- a/mailnews/base/prefs/content/accountUtils.js
+++ b/mailnews/base/prefs/content/accountUtils.js
@@ -16,21 +16,19 @@ var { MailServices } = ChromeUtils.impor
 );
 
 var gAnyValidIdentity = false; // If there are no valid identities for any account
 // returns the first account with an invalid server or identity
 
 var gNewAccountToLoad = null; // used to load new messages if we come from the mail3pane
 
 function getInvalidAccounts(accounts) {
-  let numAccounts = accounts.length;
   let invalidAccounts = [];
   let numIdentities = 0;
-  for (let i = 0; i < numAccounts; i++) {
-    let account = accounts.queryElementAt(i, Ci.nsIMsgAccount);
+  for (let account of accounts) {
     try {
       if (!account.incomingServer.valid) {
         invalidAccounts[invalidAccounts.length] = account;
         // skip to the next account
         continue;
       }
     } catch (ex) {
       // this account is busted, just keep going
--- a/mailnews/base/prefs/content/am-server.js
+++ b/mailnews/base/prefs/content/am-server.js
@@ -300,20 +300,17 @@ function onAdvanced() {
       // to that folder (moveOnSpam = true) then moving junk is disabled
       // (so that the user notices it and checks the settings).
       // This is the same sanitization as in am-junk.js, just applied to all POP accounts.
       let deferredURI =
         serverSettings.deferredToAccount &&
         MailServices.accounts.getAccount(serverSettings.deferredToAccount)
           .incomingServer.serverURI;
 
-      for (let account of fixIterator(
-        MailServices.accounts.accounts,
-        Ci.nsIMsgAccount
-      )) {
+      for (let account of MailServices.accounts.accounts) {
         let accountValues = parent.getValueArrayFor(account);
         let type = parent.getAccountValue(
           account,
           accountValues,
           "server",
           "type",
           null,
           false
--- a/mailnews/base/prefs/content/amUtils.js
+++ b/mailnews/base/prefs/content/amUtils.js
@@ -229,20 +229,17 @@ function openPrefsFromAccountManager(
 /**
  * Check if the given account name already exists in any account.
  *
  * @param aAccountName  The account name string to look for.
  * @param aAccountKey   Optional. The key of an account that is skipped when
  *                      searching the name. If unset, do not skip any account.
  */
 function accountNameExists(aAccountName, aAccountKey) {
-  for (let account of fixIterator(
-    MailServices.accounts.accounts,
-    Ci.nsIMsgAccount
-  )) {
+  for (let account of MailServices.accounts.accounts) {
     if (
       account.key != aAccountKey &&
       account.incomingServer &&
       aAccountName == account.incomingServer.prettyName
     ) {
       return true;
     }
   }
--- a/mailnews/base/public/nsIMsgAccountManager.idl
+++ b/mailnews/base/public/nsIMsgAccountManager.idl
@@ -80,17 +80,17 @@ interface nsIMsgAccountManager : nsISupp
    */
   attribute nsIMsgAccount defaultAccount;
 
   /**
    * Ordered list of all accounts, by the order they are in the prefs.
    * Accounts with hidden servers are not returned.
    * array of nsIMsgAccount
    */
-  readonly attribute nsIArray accounts;
+  readonly attribute Array<nsIMsgAccount> accounts;
 
   /* list of all identities in all accounts
    * array of nsIMsgIdentity
    */
   readonly attribute nsIArray allIdentities;
 
   /* list of all servers in all accounts, except for hidden and IM servers
    * array of nsIMsgIncomingServer
--- a/mailnews/base/src/nsMsgAccountManager.cpp
+++ b/mailnews/base/src/nsMsgAccountManager.cpp
@@ -824,37 +824,33 @@ NS_IMETHODIMP nsMsgAccountManager::GetFo
     m_msgFolderCache->Init(cacheFile);
   }
 
   NS_IF_ADDREF(*aFolderCache = m_msgFolderCache);
   return rv;
 }
 
 NS_IMETHODIMP
-nsMsgAccountManager::GetAccounts(nsIArray **_retval) {
+nsMsgAccountManager::GetAccounts(nsTArray<RefPtr<nsIMsgAccount>> &accounts) {
   nsresult rv = LoadAccounts();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIMutableArray> accounts(
-      do_CreateInstance(NS_ARRAY_CONTRACTID, &rv));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  for (uint32_t index = 0; index < m_accounts.Length(); index++) {
-    nsCOMPtr<nsIMsgAccount> existingAccount(m_accounts[index]);
+  accounts.Clear();
+  accounts.SetCapacity(m_accounts.Length());
+  for (auto existingAccount : m_accounts) {
     nsCOMPtr<nsIMsgIncomingServer> server;
     existingAccount->GetIncomingServer(getter_AddRefs(server));
     if (!server) continue;
     if (server) {
       bool hidden = false;
       server->GetHidden(&hidden);
       if (hidden) continue;
     }
-    accounts->AppendElement(existingAccount);
+    accounts.AppendElement(existingAccount);
   }
-  accounts.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsMsgAccountManager::GetAllIdentities(nsIArray **_retval) {
   nsresult rv = LoadAccounts();
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/mailnews/base/src/nsSpamSettings.cpp
+++ b/mailnews/base/src/nsSpamSettings.cpp
@@ -350,25 +350,24 @@ NS_IMETHODIMP nsSpamSettings::Initialize
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsAutoCString accountKey;
     if (account) account->GetKey(accountKey);
 
     // Loop through all accounts, adding emails from this account, as well as
     // from any accounts that defer to this account.
     mEmails.Clear();
-    nsCOMPtr<nsIArray> accounts;
-    rv = accountManager->GetAccounts(getter_AddRefs(accounts));
-    NS_ENSURE_SUCCESS(rv, rv);
-    uint32_t accountCount = 0;
+    nsTArray<RefPtr<nsIMsgAccount>> accounts;
     // No sense scanning accounts if we've nothing to match.
-    if (account && accounts) accounts->GetLength(&accountCount);
+    if (account) {
+      rv = accountManager->GetAccounts(accounts);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
 
-    for (uint32_t i = 0; i < accountCount; i++) {
-      nsCOMPtr<nsIMsgAccount> loopAccount(do_QueryElementAt(accounts, i));
+    for (auto loopAccount : accounts) {
       if (!loopAccount) continue;
       nsAutoCString loopAccountKey;
       loopAccount->GetKey(loopAccountKey);
       nsCOMPtr<nsIMsgIncomingServer> loopServer;
       loopAccount->GetIncomingServer(getter_AddRefs(loopServer));
       nsAutoCString deferredToAccountKey;
       if (loopServer)
         loopServer->GetCharValue("deferred_to_account", deferredToAccountKey);
--- a/mailnews/base/test/unit/test_nsIMsgFolder.js
+++ b/mailnews/base/test/unit/test_nsIMsgFolder.js
@@ -7,20 +7,17 @@ var { MailServices } = ChromeUtils.impor
   "resource:///modules/MailServices.jsm"
 );
 
 function run_test() {
   // Create a local mail account (we need this first)
   MailServices.accounts.createLocalMailAccount();
 
   // Get the account
-  let account = MailServices.accounts.accounts.queryElementAt(
-    0,
-    Ci.nsIMsgAccount
-  );
+  let account = MailServices.accounts.accounts[0];
 
   // Get the root folder
   var root = account.incomingServer.rootFolder;
 
   // Add a sub folder to ensure that we have some folders created
   root.createSubfolder("folder1", null);
 
   // Test - getChildNamed
--- a/mailnews/base/util/folderUtils.jsm
+++ b/mailnews/base/util/folderUtils.jsm
@@ -12,19 +12,16 @@ this.EXPORTED_SYMBOLS = [
   "allAccountsSorted",
   "getMostRecentFolders",
   "folderNameCompare",
 ];
 
 const { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
-const { fixIterator, toArray } = ChromeUtils.import(
-  "resource:///modules/iteratorUtils.jsm"
-);
 
 /**
  * Returns a string representation of a folder's "special" type.
  *
  * @param aFolder  the nsIMsgFolder whose special type should be returned
  */
 function getSpecialFolderString(aFolder) {
   let flags = aFolder.flags;
@@ -154,25 +151,22 @@ function compareAccounts(aAccount1, aAcc
 }
 
 /**
  * Returns a list of accounts sorted by server type.
  *
  * @param aExcludeIMAccounts  Remove IM accounts from the list?
  */
 function allAccountsSorted(aExcludeIMAccounts) {
-  // Get the account list, and add the proper items.
-  let accountList = toArray(
-    fixIterator(MailServices.accounts.accounts, Ci.nsIMsgAccount)
-  );
-
   // This is a HACK to work around bug 41133. If we have one of the
   // dummy "news" accounts there, that account won't have an
   // incomingServer attached to it, and everything will blow up.
-  accountList = accountList.filter(a => a.incomingServer);
+  let accountList = MailServices.accounts.accounts.filter(
+    a => a.incomingServer
+  );
 
   // Remove IM servers.
   if (aExcludeIMAccounts) {
     accountList = accountList.filter(a => a.incomingServer.type != "im");
   }
 
   return accountList.sort(compareAccounts);
 }
--- a/mailnews/compose/src/nsMsgSendLater.cpp
+++ b/mailnews/compose/src/nsMsgSendLater.cpp
@@ -610,23 +610,22 @@ nsMsgSendLater::HasUnsentMessages(nsIMsg
   NS_ENSURE_ARG_POINTER(aResult);
   *aResult = false;
   nsresult rv;
 
   nsCOMPtr<nsIMsgAccountManager> accountManager =
       do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIArray> accounts;
-  accountManager->GetAccounts(getter_AddRefs(accounts));
+  nsTArray<RefPtr<nsIMsgAccount>> accounts;
+  rv = accountManager->GetAccounts(accounts);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  uint32_t cnt = 0;
-  rv = accounts->GetLength(&cnt);
-  if (cnt == 0) return NS_OK;  // no account set up -> no unsent messages
+  if (accounts.IsEmpty())
+    return NS_OK;  // no account set up -> no unsent messages
 
   // XXX This code should be set up for multiple unsent folders, however we
   // don't support that at the moment, so for now just assume one folder.
   if (!mMessageFolder) {
     nsCOMPtr<nsIMsgFolder> folder;
     rv = GetUnsentMessagesFolder(nullptr, getter_AddRefs(folder));
     // There doesn't have to be a nsMsgQueueForLater flagged folder.
     if (NS_FAILED(rv) || !folder) return NS_OK;
--- a/mailnews/db/gloda/modules/IndexMsg.jsm
+++ b/mailnews/db/gloda/modules/IndexMsg.jsm
@@ -2009,20 +2009,17 @@ var GlodaMsgIndexer = {
    *  and have an accurate estimate of the number of folders that need to be
    *  indexed.  (We previously queued accounts rather than immediately
    *  walking their list of folders.)
    */
   indexEverything() {
     this._log.info("Queueing all accounts for indexing.");
 
     GlodaDatastore._beginTransaction();
-    for (let account of fixIterator(
-      MailServices.accounts.accounts,
-      Ci.nsIMsgAccount
-    )) {
+    for (let account of MailServices.accounts.accounts) {
       this.indexAccount(account);
     }
     GlodaDatastore._commitTransaction();
   },
 
   /**
    * Queue all of the folders belonging to an account for indexing.
    */
--- a/mailnews/imap/src/nsAutoSyncManager.cpp
+++ b/mailnews/imap/src/nsAutoSyncManager.cpp
@@ -650,25 +650,21 @@ nsresult nsAutoSyncManager::AutoUpdateFo
   nsresult rv;
 
   // iterate through each imap account and update offline folders automatically
 
   nsCOMPtr<nsIMsgAccountManager> accountManager =
       do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIArray> accounts;
-  rv = accountManager->GetAccounts(getter_AddRefs(accounts));
+  nsTArray<RefPtr<nsIMsgAccount>> accounts;
+  rv = accountManager->GetAccounts(accounts);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  uint32_t accountCount;
-  accounts->GetLength(&accountCount);
-
-  for (uint32_t i = 0; i < accountCount; ++i) {
-    nsCOMPtr<nsIMsgAccount> account(do_QueryElementAt(accounts, i, &rv));
+  for (auto account : accounts) {
     if (!account) continue;
 
     nsCOMPtr<nsIMsgIncomingServer> incomingServer;
     rv = account->GetIncomingServer(getter_AddRefs(incomingServer));
     if (!incomingServer) continue;
 
     nsCString type;
     rv = incomingServer->GetType(type);
--- a/mailnews/import/becky/src/nsBeckyFilters.cpp
+++ b/mailnews/import/becky/src/nsBeckyFilters.cpp
@@ -650,27 +650,22 @@ nsresult nsBeckyFilters::FindMessageFold
 nsresult nsBeckyFilters::GetMessageFolder(const nsAString &aName,
                                           nsIMsgFolder **_retval) {
   nsresult rv;
 
   nsCOMPtr<nsIMsgAccountManager> accountManager;
   accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIArray> accounts;
-  rv = accountManager->GetAccounts(getter_AddRefs(accounts));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  uint32_t accountCount;
-  rv = accounts->GetLength(&accountCount);
+  nsTArray<RefPtr<nsIMsgAccount>> accounts;
+  rv = accountManager->GetAccounts(accounts);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIMsgFolder> found;
-  for (uint32_t i = 0; i < accountCount; i++) {
-    nsCOMPtr<nsIMsgAccount> account(do_QueryElementAt(accounts, i));
+  for (auto account : accounts) {
     if (!account) continue;
 
     nsCOMPtr<nsIMsgIncomingServer> server;
     account->GetIncomingServer(getter_AddRefs(server));
     if (!server) continue;
     FindMessageFolderInServer(aName, server, getter_AddRefs(found));
     if (found) break;
   }
--- a/mailnews/import/test/unit/resources/import_helper.js
+++ b/mailnews/import/test/unit/resources/import_helper.js
@@ -468,20 +468,17 @@ SettingsImportHelper.prototype = {
     } else {
       Assert.equal(true, this.mInterface.AutoLocate({}, {}));
     }
     Assert.equal(true, this.mInterface.Import({}));
     this.checkResults();
   },
 
   _ensureNoAccounts() {
-    let accounts = MailServices.accounts.accounts;
-
-    for (let i = 0; i < accounts.length; i++) {
-      let account = accounts.queryElementAt(i, Ci.nsIMsgAccount);
+    for (let account of MailServices.accounts.accounts) {
       MailServices.accounts.removeAccount(account);
     }
   },
 
   _checkSmtpServer(expected, actual) {
     Assert.equal(expected.port, actual.port);
     Assert.equal(expected.username, actual.username);
     Assert.equal(expected.authMethod, actual.authMethod);
@@ -559,19 +556,17 @@ SettingsImportHelper.prototype = {
           account.incomingServer.username &&
         expectedAccount.incomingServer.hostName ==
           account.incomingServer.hostName
       );
     });
   },
 
   checkResults() {
-    let accounts = MailServices.accounts.accounts;
-    for (let i = 0; i < accounts.length - 1; i++) {
-      let actualAccount = accounts.queryElementAt(i, Ci.nsIMsgAccount);
+    for (let actualAccount of MailServices.accounts.accounts) {
       if (this._isLocalMailAccount(actualAccount)) {
         continue;
       }
       let expectedAccounts = this._findExpectedAccount(actualAccount);
       Assert.notEqual(null, expectedAccounts);
       Assert.equal(1, expectedAccounts.length);
       this._checkAccount(expectedAccounts[0], actualAccount);
     }