Bug 1652371 - Port bug 1649221 and bug 1649554. rs=bustage-fix CLOSED TREE
authorGeoff Lankow <geoff@darktrojan.net>
Mon, 13 Jul 2020 11:45:03 +1200
changeset 30102 18f27bc33168c576676908b2a9cdb34707fb89e2
parent 30101 46a5ff3fb44c60eba96b0a1197fdc2d3128a4bf2
child 30103 945a1e7f059e3af7d2c7fc36d49e52f3ecdaccd3
push id17697
push usergeoff@darktrojan.net
push dateSun, 12 Jul 2020 23:55:00 +0000
treeherdercomm-central@18f27bc33168 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbustage-fix
bugs1652371, 1649221, 1649554
Bug 1652371 - Port bug 1649221 and bug 1649554. rs=bustage-fix CLOSED TREE
calendar/base/backend/calBackendLoader.js
calendar/base/backend/icaljs/calDateTime.js
calendar/base/backend/icaljs/calDuration.js
calendar/base/backend/icaljs/calICALJSComponents.js
calendar/base/backend/icaljs/calICSService.js
calendar/base/backend/icaljs/calPeriod.js
calendar/base/backend/icaljs/calRecurrenceRule.js
calendar/base/content/agenda-listbox-utils.js
calendar/base/content/calendar-base-view.js
calendar/base/content/calendar-chrome-startup.js
calendar/base/content/calendar-dnd-listener.js
calendar/base/content/calendar-invitations-manager.js
calendar/base/content/calendar-management.js
calendar/base/content/calendar-statusbar.js
calendar/base/content/calendar-task-editing.js
calendar/base/content/calendar-task-tree.js
calendar/base/content/calendar-unifinder.js
calendar/base/content/calendar-views-utils.js
calendar/base/content/dialogs/calendar-invitations-dialog.js
calendar/base/content/dialogs/calendar-print-dialog.js
calendar/base/content/import-export.js
calendar/base/modules/calCalendarDeactivator.jsm
calendar/base/modules/calUtils.jsm
calendar/base/modules/utils/calAsyncUtils.jsm
calendar/base/modules/utils/calItipUtils.jsm
calendar/base/modules/utils/calProviderUtils.jsm
calendar/base/modules/utils/calViewUtils.jsm
calendar/base/src/CalAlarm.jsm
calendar/base/src/CalAlarmMonitor.jsm
calendar/base/src/CalAlarmService.jsm
calendar/base/src/CalAttachment.jsm
calendar/base/src/CalAttendee.jsm
calendar/base/src/CalCalendarManager.jsm
calendar/base/src/CalCalendarSearchService.jsm
calendar/base/src/CalDefaultACLManager.jsm
calendar/base/src/CalDeletedItems.jsm
calendar/base/src/CalEvent.jsm
calendar/base/src/CalFreeBusyService.jsm
calendar/base/src/CalIcsParser.jsm
calendar/base/src/CalIcsSerializer.jsm
calendar/base/src/CalItipItem.jsm
calendar/base/src/CalProtocolHandler.jsm
calendar/base/src/CalRecurrenceDate.jsm
calendar/base/src/CalRecurrenceInfo.jsm
calendar/base/src/CalRelation.jsm
calendar/base/src/CalSleepMonitor.jsm
calendar/base/src/CalStartupService.jsm
calendar/base/src/CalTimezoneService.jsm
calendar/base/src/CalTodo.jsm
calendar/base/src/CalTransactionManager.jsm
calendar/base/src/CalWeekInfoService.jsm
calendar/base/src/calCachedCalendar.js
calendar/base/src/calFilter.js
calendar/base/src/calItemBase.js
calendar/base/src/calTimezone.js
calendar/import-export/CalHtmlExport.jsm
calendar/import-export/CalIcsImportExport.jsm
calendar/import-export/CalListFormatter.jsm
calendar/import-export/CalMonthGridPrinter.jsm
calendar/import-export/CalOutlookCSVImportExport.jsm
calendar/import-export/CalWeekPrinter.jsm
calendar/itip/CalItipEmailTransport.jsm
calendar/lightning/components/CalItipProtocolHandler.jsm
calendar/lightning/components/CalMimeConverter.jsm
calendar/lightning/content/imip-bar.js
calendar/lightning/content/lightning-item-iframe.js
calendar/providers/caldav/CalDavCalendar.jsm
calendar/providers/caldav/modules/CalDavRequestHandlers.jsm
calendar/providers/composite/CalCompositeCalendar.jsm
calendar/providers/ics/CalICSCalendar.jsm
calendar/providers/memory/CalMemoryCalendar.jsm
calendar/providers/storage/CalStorageCalendar.jsm
calendar/resources/content/publish.js
calendar/test/browser/browser_calendarList.js
calendar/test/unit/test_alarmservice.js
calendar/test/unit/test_freebusy_service.js
calendar/test/unit/test_items.js
calendar/test/unit/test_search_service.js
chat/components/src/imAccounts.jsm
chat/components/src/imCommands.jsm
chat/components/src/imContacts.jsm
chat/components/src/imConversations.jsm
chat/components/src/imCore.jsm
chat/components/src/logger.jsm
chat/components/src/smileProtocolHandler.jsm
chat/content/chat-tooltip.js
chat/content/conversation-browser.js
chat/modules/imXPCOMUtils.jsm
chat/modules/jsProtoHelper.jsm
chat/protocols/twitter/twitter.jsm
mail/base/content/msgHdrView.js
mail/base/content/msgMail3PaneWindow.js
mail/base/content/specialTabs.js
mail/base/content/tabmail.js
mail/base/test/browser/browser_webSearchTelemetry.js
mail/base/test/unit/test_alertHook.js
mail/components/AboutRedirector.jsm
mail/components/MailGlue.jsm
mail/components/MessengerContentHandler.jsm
mail/components/activity/Activity.jsm
mail/components/activity/ActivityManager.jsm
mail/components/activity/ActivityManagerUI.jsm
mail/components/activity/content/activity-widgets.js
mail/components/activity/modules/alertHook.jsm
mail/components/activity/modules/sendLater.jsm
mail/components/addrbook/content/abTrees.js
mail/components/devtools/devtools-loader.jsm
mail/components/enterprisepolicies/Policies.jsm
mail/components/im/IMIncomingServer.jsm
mail/components/im/IMProtocolInfo.jsm
mail/components/im/content/chat-contact.js
mail/components/im/content/chat-conversation.js
mail/components/im/content/chat-imconv.js
mail/components/newmailaccount/content/uriListener.js
mail/components/preferences/cookies.js
mail/components/preferences/general.js
mail/components/preferences/passwordManager.js
mail/components/preferences/permissions.js
mail/components/preferences/test/browser/browser_cloudfile.js
mail/components/prompts/PromptCollection.jsm
mail/extensions/am-e2e/AME2E.jsm
mail/extensions/openpgp/content/modules/mimeVerify.jsm
mail/extensions/openpgp/content/modules/pgpmimeHandler.jsm
mail/extensions/openpgp/content/modules/protocolHandler.jsm
mail/extensions/openpgp/content/modules/stdlib/msgHdrUtils.jsm
mail/extensions/openpgp/content/modules/streams.jsm
mail/extensions/openpgp/content/modules/wksMimeHandler.jsm
mail/test/browser/notification/browser_notification.js
mail/test/browser/shared-modules/AttachmentHelpers.jsm
mail/test/browser/shared-modules/ContentTabHelpers.jsm
mail/test/browser/shared-modules/NewMailAccountHelpers.jsm
mail/test/browser/shared-modules/PromptHelpers.jsm
mailnews/addrbook/content/abDragDrop.js
mailnews/addrbook/content/abView.js
mailnews/addrbook/jsaddrbook/AddrBookCard.jsm
mailnews/addrbook/jsaddrbook/AddrBookDirectory.jsm
mailnews/addrbook/jsaddrbook/AddrBookMailingList.jsm
mailnews/addrbook/jsaddrbook/AddrBookManager.jsm
mailnews/addrbook/jsaddrbook/AddrBookUtils.jsm
mailnews/addrbook/jsaddrbook/CardDAVDirectory.jsm
mailnews/addrbook/jsaddrbook/VCardUtils.jsm
mailnews/addrbook/src/AbAutoCompleteMyDomain.jsm
mailnews/addrbook/src/AbAutoCompleteSearch.jsm
mailnews/addrbook/src/AbLDAPAttributeMap.jsm
mailnews/addrbook/src/AbLDAPAutoCompleteSearch.jsm
mailnews/addrbook/test/LDAPServer.jsm
mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch2.js
mailnews/base/search/src/MsgTraitService.jsm
mailnews/base/src/FolderLookupService.jsm
mailnews/base/src/MailNewsCommandLineHandler.jsm
mailnews/base/src/MailNotificationService.jsm
mailnews/base/src/MsgAsyncPrompter.jsm
mailnews/base/src/OAuth2Module.jsm
mailnews/base/test/unit/test_compactFailure.js
mailnews/base/test/unit/test_jsTreeSelection.js
mailnews/base/test/unit/test_nsMsgMailSession_Alerts.js
mailnews/base/test/unit/test_searchChaining.js
mailnews/base/util/JsTreeSelection.jsm
mailnews/base/util/OAuth2.jsm
mailnews/compose/src/SMTPProtocolHandler.jsm
mailnews/db/gloda/components/GlodaAutoComplete.jsm
mailnews/db/gloda/components/MimeMessageEmitter.jsm
mailnews/db/gloda/modules/MimeMessage.jsm
mailnews/extensions/dsn/src/DSNService.jsm
mailnews/extensions/mdn/src/MDNService.jsm
mailnews/extensions/newsblog/content/NewsBlog.jsm
mailnews/imap/test/unit/test_cacheParts.js
mailnews/imap/test/unit/test_chunkLastLF.js
mailnews/imap/test/unit/test_dod.js
mailnews/imap/test/unit/test_gmailOfflineMsgStore.js
mailnews/imap/test/unit/test_imapHdrChunking.js
mailnews/imap/test/unit/test_imapHdrStreaming.js
mailnews/imap/test/unit/test_imapStoreMsgOffline.js
mailnews/import/test/unit/resources/TestMailImporter.jsm
mailnews/import/test/unit/resources/mock_windows_reg_factory.js
mailnews/jsaccount/test/unit/resources/TestJaMsgProtocolInfoComponent.jsm
mailnews/jsaccount/test/unit/resources/testJaBaseIncomingServer.jsm
mailnews/jsaccount/test/unit/resources/testJaBaseIncomingServerComponent.js
mailnews/jsaccount/test/unit/resources/testJaBaseMsgFolder.jsm
mailnews/jsaccount/test/unit/resources/testJaBaseMsgFolderComponent.js
mailnews/jsaccount/test/unit/resources/testJaFooUrlComponent.js
mailnews/local/test/unit/test_over2GBMailboxes.js
mailnews/local/test/unit/test_pop3Download.js
mailnews/local/test/unit/test_streamHeaders.js
mailnews/mime/src/MimeJSComponents.jsm
mailnews/mime/src/mimeParser.jsm
mailnews/mime/test/unit/head_mime.js
mailnews/mime/test/unit/test_attachment_size.js
mailnews/mime/test/unit/test_badContentType.js
mailnews/mime/test/unit/test_hidden_attachments.js
mailnews/mime/test/unit/test_message_attachment.js
mailnews/mime/test/unit/test_mimeStreaming.js
mailnews/mime/test/unit/test_rfc822_body.js
mailnews/mime/test/unit/test_smime_decrypt.js
mailnews/mime/test/unit/test_text_attachment.js
mailnews/news/src/NewsAutoCompleteSearch.jsm
mailnews/news/test/unit/head_server_setup.js
mailnews/news/test/unit/test_bug540288.js
mailnews/news/test/unit/test_bug695309.js
mailnews/news/test/unit/test_getNewsMessage.js
mailnews/news/test/unit/test_internalUris.js
mailnews/test/resources/MockFactory.jsm
mailnews/test/resources/NetworkTestUtils.jsm
mailnews/test/resources/PromiseTestUtils.jsm
mailnews/test/resources/alertTestUtils.js
mailnews/test/resources/smimeUtils.jsm
--- a/calendar/base/backend/calBackendLoader.js
+++ b/calendar/base/backend/calBackendLoader.js
@@ -1,27 +1,27 @@
 /* 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 { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+var { ComponentUtils } = ChromeUtils.import("resource://gre/modules/ComponentUtils.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 function calBackendLoader() {
   this.wrappedJSObject = this;
   try {
     this.loadBackend();
   } catch (e) {
     dump(`### Error loading backend:${e.filename || e.fileName}:${e.lineNumber}: ${e}\n`);
   }
 }
 
 calBackendLoader.prototype = {
   classID: Components.ID("{0314c271-7168-40fa-802e-83c8c46a557e}"),
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
+  QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
 
   loaded: false,
 
   observe() {
     // Nothing to do here, just need the entry so this is instantiated.
   },
 
   loadBackend() {
@@ -72,9 +72,9 @@ function lazyFactoryFor(backendScope, cl
     },
     lockFactory(lock) {
       let realFactory = backendScope.NSGetFactory(classID);
       return realFactory.lockFactory(lock);
     },
   };
 }
 
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calBackendLoader]);
+this.NSGetFactory = ComponentUtils.generateNSGetFactory([calBackendLoader]);
--- a/calendar/base/backend/icaljs/calDateTime.js
+++ b/calendar/base/backend/icaljs/calDateTime.js
@@ -9,17 +9,17 @@ var { ICAL, unwrap, unwrapSetter } = Chr
 var UNIX_TIME_TO_PRTIME = 1000000;
 
 function calDateTime(innerObject) {
   this.wrappedJSObject = this;
   this.innerObject = innerObject || ICAL.Time.epochTime.clone();
 }
 
 calDateTime.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIDateTime]),
+  QueryInterface: ChromeUtils.generateQI(["calIDateTime"]),
   classID: Components.ID("{36783242-ec94-4d8a-9248-d2679edd55b9}"),
 
   isMutable: true,
   makeImmutable() {
     this.isMutable = false;
   },
   clone() {
     return new calDateTime(this.innerObject.clone());
--- a/calendar/base/backend/icaljs/calDuration.js
+++ b/calendar/base/backend/icaljs/calDuration.js
@@ -5,17 +5,17 @@
 var { ICAL, unwrap } = ChromeUtils.import("resource:///modules/calendar/Ical.jsm");
 
 function calDuration(innerObject) {
   this.innerObject = innerObject || new ICAL.Duration();
   this.wrappedJSObject = this;
 }
 
 calDuration.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIDuration]),
+  QueryInterface: ChromeUtils.generateQI(["calIDuration"]),
   classID: Components.ID("{7436f480-c6fc-4085-9655-330b1ee22288}"),
 
   get icalDuration() {
     return this.innerObject;
   },
   set icalDuration(val) {
     this.innerObject = val;
   },
--- a/calendar/base/backend/icaljs/calICALJSComponents.js
+++ b/calendar/base/backend/icaljs/calICALJSComponents.js
@@ -4,17 +4,17 @@
 
 /* import-globals-from ../../src/calTimezone.js */
 /* import-globals-from calDateTime.js */
 /* import-globals-from calDuration.js */
 /* import-globals-from calICSService.js */
 /* import-globals-from calPeriod.js */
 /* import-globals-from calRecurrenceRule.js */
 
-var { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+var { ComponentUtils } = ChromeUtils.import("resource://gre/modules/ComponentUtils.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 this.NSGetFactory = cid => {
   let scriptLoadOrder = [
     "resource:///components/calTimezone.js",
     "resource:///components/calDateTime.js",
     "resource:///components/calDuration.js",
     "resource:///components/calICSService.js",
@@ -31,11 +31,11 @@ this.NSGetFactory = cid => {
     calDuration,
     calIcalComponent,
     calIcalProperty,
     calICSService,
     calPeriod,
     calRecurrenceRule,
   ];
 
-  this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
+  this.NSGetFactory = ComponentUtils.generateNSGetFactory(components);
   return this.NSGetFactory(cid);
 };
--- a/calendar/base/backend/icaljs/calICSService.js
+++ b/calendar/base/backend/icaljs/calICSService.js
@@ -10,17 +10,17 @@ var { ICAL, unwrapSetter, unwrapSingle, 
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 function calIcalProperty(innerObject) {
   this.innerObject = innerObject || new ICAL.Property();
   this.wrappedJSObject = this;
 }
 
 calIcalProperty.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIIcalProperty]),
+  QueryInterface: ChromeUtils.generateQI(["calIIcalProperty"]),
   classID: Components.ID("{423ac3f0-f612-48b3-953f-47f7f8fd705b}"),
 
   get icalString() {
     return this.innerObject.toICALString() + ICAL.newLineChar;
   },
   get icalProperty() {
     return this.innerObject;
   },
@@ -226,17 +226,17 @@ calIcalProperty.prototype = {
 
 function calIcalComponent(innerObject) {
   this.innerObject = innerObject || new ICAL.Component();
   this.wrappedJSObject = this;
   this.mReferencedZones = {};
 }
 
 calIcalComponent.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIIcalComponent]),
+  QueryInterface: ChromeUtils.generateQI(["calIIcalComponent"]),
   classID: Components.ID("{51ac96fd-1279-4439-a85b-6947b37f4cea}"),
 
   clone() {
     return new calIcalComponent(new ICAL.Component(this.innerObject.toJSON()));
   },
 
   get parent() {
     return wrapGetter(calIcalComponent, this.innerObject.parent);
@@ -550,17 +550,17 @@ calIcalComponent.prototype = {
   },
 };
 
 function calICSService() {
   this.wrappedJSObject = this;
 }
 
 calICSService.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIICSService]),
+  QueryInterface: ChromeUtils.generateQI(["calIICSService"]),
   classID: Components.ID("{c61cb903-4408-41b3-bc22-da0b27efdfe1}"),
 
   parseICS(serialized, tzProvider) {
     // TODO ical.js doesn't support tz providers, but this is usually null
     // or our timezone service anyway.
     let comp = ICAL.parse(serialized);
     return new calIcalComponent(new ICAL.Component(comp));
   },
--- a/calendar/base/backend/icaljs/calPeriod.js
+++ b/calendar/base/backend/icaljs/calPeriod.js
@@ -9,17 +9,17 @@ var { ICAL, unwrapSetter, wrapGetter } =
 );
 
 function calPeriod(innerObject) {
   this.innerObject = innerObject || new ICAL.Period({});
   this.wrappedJSObject = this;
 }
 
 calPeriod.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIPeriod]),
+  QueryInterface: ChromeUtils.generateQI(["calIPeriod"]),
   classID: Components.ID("{394a281f-7299-45f7-8b1f-cce21258972f}"),
 
   isMutable: true,
   innerObject: null,
 
   get icalPeriod() {
     return this.innerObject;
   },
--- a/calendar/base/backend/icaljs/calRecurrenceRule.js
+++ b/calendar/base/backend/icaljs/calRecurrenceRule.js
@@ -12,17 +12,17 @@ var { cal } = ChromeUtils.import("resour
 function calRecurrenceRule(innerObject) {
   this.innerObject = innerObject || new ICAL.Recur();
   this.wrappedJSObject = this;
 }
 
 var calRecurrenceRuleInterfaces = [Ci.calIRecurrenceRule, Ci.calIRecurrenceItem];
 var calRecurrenceRuleClassID = Components.ID("{df19281a-5389-4146-b941-798cb93a7f0d}");
 calRecurrenceRule.prototype = {
-  QueryInterface: cal.generateQI(calRecurrenceRuleInterfaces),
+  QueryInterface: cal.generateQI(["calIRecurrenceRule", "calIRecurrenceItem"]),
   classID: calRecurrenceRuleClassID,
   classInfo: cal.generateCI({
     contractID: "@mozilla.org/calendar/recurrence-rule;1",
     classDescription: "Calendar Recurrence Rule",
     classID: calRecurrenceRuleClassID,
     interfaces: calRecurrenceRuleInterfaces,
   }),
 
--- a/calendar/base/content/agenda-listbox-utils.js
+++ b/calendar/base/content/agenda-listbox-utils.js
@@ -602,17 +602,17 @@ agendaListbox.setupContextMenu = functio
  *
  * @param aStart        (optional) The start date for the item query.
  * @param aEnd          (optional) The end date for the item query.
  * @param aCalendar     (optional) If specified, the single calendar from
  *                                   which the refresh will occur.
  */
 agendaListbox.refreshCalendarQuery = function(aStart, aEnd, aCalendar) {
   let refreshJob = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+    QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
     agendaListbox: this,
     calendar: null,
     calId: null,
     operation: null,
     cancelled: false,
 
     onOperationComplete(aOpCalendar, aStatus, aOperationType, aId, aDateTime) {
       if (this.agendaListbox.mPendingRefreshJobs.has(this.calId)) {
@@ -859,18 +859,18 @@ agendaListbox.calendarOpListener = { age
 /**
  * Calendar and composite observer, used to keep agenda listbox up to date.
  * @see calIObserver
  * @see calICompositeObserver
  */
 agendaListbox.calendarObserver = { agendaListbox };
 
 agendaListbox.calendarObserver.QueryInterface = cal.generateQI([
-  Ci.calIObserver,
-  Ci.calICompositeObserver,
+  "calIObserver",
+  "calICompositeObserver",
 ]);
 
 // calIObserver:
 agendaListbox.calendarObserver.onStartBatch = function() {
   this.needsRefresh = true;
 };
 
 agendaListbox.calendarObserver.onEndBatch = function() {
--- a/calendar/base/content/calendar-base-view.js
+++ b/calendar/base/content/calendar-base-view.js
@@ -21,19 +21,19 @@
   class CalendarViewObserver {
     /**
      * Constructor for CalendarViewObserver.
      *
      * @param {CalendarBaseView} calendarView    A calendar view.
      */
     constructor(calendarView) {
       this.QueryInterface = cal.generateQI([
-        Ci.calIObserver,
-        Ci.calIAlarmServiceObserver,
-        Ci.calICompositeObserver,
+        "calIObserver",
+        "calIAlarmServiceObserver",
+        "calICompositeObserver",
       ]);
 
       this.calView = calendarView.calICalendarView;
     }
 
     // calIObserver
 
     onStartBatch() {}
@@ -198,17 +198,17 @@
   class CalendarViewRefreshJob {
     /**
      * Constructor for CalendarViewRefreshJob.
      *
      * @param {CalendarBaseView} calendarView                   A calendar view.
      * @param {calICalendar|calICompositeCalendar} calendar     A calendar object.
      */
     constructor(calendarView, calendar) {
-      this.QueryInterface = ChromeUtils.generateQI([Ci.calIOperationListener]);
+      this.QueryInterface = ChromeUtils.generateQI(["calIOperationListener"]);
       this.calView = calendarView;
       this.calendar = calendar;
       this.calId = null;
       this.operation = null;
       this.cancelled = false;
     }
 
     onOperationComplete(opCalendar, status, operationType, id, dateTime) {
--- a/calendar/base/content/calendar-chrome-startup.js
+++ b/calendar/base/content/calendar-chrome-startup.js
@@ -198,17 +198,17 @@ function calObserveDisplayDeckChange(eve
 /**
  * TODO: The systemcolors pref observer really only needs to be set up once, so
  * ideally this code should go into a component. This should be taken care of when
  * there are more prefs that need to be observed on a global basis that don't fit
  * into the calendar manager.
  */
 var calendarWindowPrefs = {
   /** nsISupports QueryInterface */
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
+  QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
 
   /** Initialize the preference observers */
   init() {
     Services.prefs.addObserver("calendar.view.useSystemColors", this);
     Services.ww.registerNotification(this);
 
     // Trigger setting pref on all open windows
     this.observe(null, "nsPref:changed", "calendar.view.useSystemColors");
--- a/calendar/base/content/calendar-dnd-listener.js
+++ b/calendar/base/content/calendar-dnd-listener.js
@@ -601,17 +601,17 @@ calTaskButtonDNDObserver.prototype = {
  * @param {Object} aXULBox - The XUL box to invoke the drag session from.
  */
 function invokeEventDragSession(aItem, aXULBox) {
   let transfer = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
   transfer.init(null);
   transfer.addDataFlavor("text/calendar");
 
   let flavourProvider = {
-    QueryInterface: ChromeUtils.generateQI([Ci.nsIFlavorDataProvider]),
+    QueryInterface: ChromeUtils.generateQI(["nsIFlavorDataProvider"]),
 
     item: aItem,
     getFlavorData(aInTransferable, aInFlavor, aOutData) {
       if (
         aInFlavor == "application/vnd.x-moz-cal-event" ||
         aInFlavor == "application/vnd.x-moz-cal-task"
       ) {
         aOutData.value = aItem;
--- a/calendar/base/content/calendar-invitations-manager.js
+++ b/calendar/base/content/calendar-invitations-manager.js
@@ -63,17 +63,17 @@ function getInvitationsManager() {
 // == invitations link
 const FIRST_DELAY_STARTUP = 100;
 const FIRST_DELAY_RESCHEDULE = 100;
 const FIRST_DELAY_REGISTER = 10000;
 const FIRST_DELAY_UNREGISTER = 0;
 
 var gInvitationsOperationListener = {
   mCount: 0,
-  QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+  QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
 
   onOperationComplete(aCalendar, aStatus, aOperationType, aId, aDetail) {
     let invitationsBox = document.getElementById("calendar-invitations-panel");
     if (Components.isSuccessCode(aStatus)) {
       let value = cal.l10n.getLtnString("invitationsLink.label", [this.mCount]);
       document.getElementById("calendar-invitations-label").value = value;
       setElementValue(invitationsBox, this.mCount < 1 && "true", "hidden");
     } else {
@@ -86,17 +86,17 @@ var gInvitationsOperationListener = {
     if (Components.isSuccessCode(aStatus)) {
       this.mCount += aItems.length;
     }
   },
 };
 
 var gInvitationsCalendarManagerObserver = {
   mStoredThis: this,
-  QueryInterface: ChromeUtils.generateQI([Ci.calICalendarManagerObserver]),
+  QueryInterface: ChromeUtils.generateQI(["calICalendarManagerObserver"]),
 
   onCalendarRegistered(aCalendar) {
     this.mStoredThis.rescheduleInvitationsUpdate(FIRST_DELAY_REGISTER);
   },
 
   onCalendarUnregistering(aCalendar) {
     this.mStoredThis.rescheduleInvitationsUpdate(FIRST_DELAY_UNREGISTER);
   },
@@ -201,17 +201,17 @@ InvitationsManager.prototype = {
 
     gInvitationsRequestManager.cancelPendingRequests();
     this.updateStartDate();
     this.deleteAllItems();
 
     let cals = cal.getCalendarManager().getCalendars();
 
     let opListener = {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+      QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
       mCount: cals.length,
       mRequestManager: gInvitationsRequestManager,
       mInvitationsManager: this,
       mHandledItems: {},
 
       // calIOperationListener
       onOperationComplete(aCalendar, aStatus, aOperationType, aId, aDetail) {
         if (--this.mCount == 0) {
@@ -338,17 +338,17 @@ InvitationsManager.prototype = {
   processJobQueue(queue, jobQueueFinishedCallBack) {
     // TODO: undo/redo
     function operationListener(mgr, queueCallback, oldItem_) {
       this.mInvitationsManager = mgr;
       this.mJobQueueFinishedCallBack = queueCallback;
       this.mOldItem = oldItem_;
     }
     operationListener.prototype = {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+      QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
       onOperationComplete(aCalendar, aStatus, aOperationType, aId, aDetail) {
         if (
           Components.isSuccessCode(aStatus) &&
           aOperationType == Ci.calIOperationListener.MODIFY
         ) {
           cal.itip.checkAndSend(aOperationType, aDetail, this.mOldItem);
           this.mInvitationsManager.deleteItem(aDetail);
           this.mInvitationsManager.addItem(aDetail);
--- a/calendar/base/content/calendar-management.js
+++ b/calendar/base/content/calendar-management.js
@@ -323,17 +323,17 @@ function loadCalendarManager() {
     let item = calendarList.selectedItem;
     let calendarId = item.getAttribute("calendar-id");
     let calendar = calendarManager.getCalendarById(calendarId);
 
     compositeCalendar.defaultCalendar = calendar;
   });
 
   calendarList._calendarObserver = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calIObserver]),
+    QueryInterface: ChromeUtils.generateQI(["calIObserver"]),
 
     onStartBatch() {},
     onEndBatch() {},
     onLoad() {},
     onAddItem(item) {},
     onModifyItem(newItem, oldItem) {},
     onDeleteItem(deletedItem) {},
     onError(calendar, errNo, message) {},
@@ -374,17 +374,17 @@ function loadCalendarManager() {
       // Since the old value is not used directly in onPropertyChanged, but
       // should not be the same as the value, set it to a different value.
       this.onPropertyChanged(calendar, name, null, null);
     },
   };
   calendarManager.addCalendarObserver(calendarList._calendarObserver);
 
   calendarList._calendarManagerObserver = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calICalendarManagerObserver]),
+    QueryInterface: ChromeUtils.generateQI(["calICalendarManagerObserver"]),
 
     onCalendarRegistered(calendar) {
       let inComposite = calendar.getProperty("calendar-main-in-composite");
       if (inComposite === null) {
         compositeCalendar.addCalendar(calendar);
       }
       addCalendarItem(calendar);
       saveSortOrder();
@@ -635,17 +635,17 @@ function showOnlyCalendar(aCalendar) {
       composite.removeCalendar(calendar);
     }
   }
   composite.addCalendar(aCalendar);
   composite.endBatch();
 }
 
 var compositeObserver = {
-  QueryInterface: cal.generateQI([Ci.calIObserver, Ci.calICompositeObserver]),
+  QueryInterface: cal.generateQI(["calIObserver", "calICompositeObserver"]),
 
   onStartBatch() {},
   onEndBatch() {},
 
   onLoad() {
     calendarUpdateNewItemsCommand();
     document.commandDispatcher.updateCommands("calendar_commands");
   },
@@ -699,17 +699,17 @@ function openCalendarSubscriptionsDialog
     "chrome,titlebar,modal,resizable"
   );
 }
 
 /**
  * Calendar Offline Manager
  */
 var calendarOfflineManager = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
+  QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
 
   init() {
     if (this.initialized) {
       throw Components.Exception("", Cr.NS_ERROR_ALREADY_INITIALIZED);
     }
     Services.obs.addObserver(this, "network:offline-status-changed");
 
     this.updateOfflineUI(!this.isOnline());
--- a/calendar/base/content/calendar-statusbar.js
+++ b/calendar/base/content/calendar-statusbar.js
@@ -18,17 +18,17 @@ var gCalendarStatusFeedback = {
   mStatusBar: null,
   mStatusProgressPanel: null,
   mThrobber: null,
   mProgressMode: Ci.calIStatusObserver.NO_PROGRESS,
   mCurIndex: 0,
   mInitialized: false,
   mCalendars: {},
 
-  QueryInterface: ChromeUtils.generateQI([Ci.calIStatusObserver]),
+  QueryInterface: ChromeUtils.generateQI(["calIStatusObserver"]),
 
   initialize(aWindow) {
     if (!this.mInitialized) {
       this.mWindow = aWindow;
       this.mStatusText = this.mWindow.document.getElementById("statusText");
       this.mStatusBar = this.mWindow.document.getElementById("statusbar-icon");
       this.mStatusProgressPanel = this.mWindow.document.getElementById("statusbar-progresspanel");
       this.mThrobber = this.mWindow.document.getElementById("navigator-throbber");
--- a/calendar/base/content/calendar-task-editing.js
+++ b/calendar/base/content/calendar-task-editing.js
@@ -145,17 +145,17 @@ var taskEdit = {
 
   /**
    * Observer to watch for readonly, disabled and capability changes of the
    * observed calendar.
    *
    * @see calIObserver
    */
   calendarObserver: {
-    QueryInterface: ChromeUtils.generateQI([Ci.calIObserver]),
+    QueryInterface: ChromeUtils.generateQI(["calIObserver"]),
 
     // calIObserver:
     onStartBatch() {},
     onEndBatch() {},
     onLoad(aCalendar) {},
     onAddItem(aItem) {},
     onModifyItem(aNewItem, aOldItem) {},
     onDeleteItem(aDeletedItem) {},
@@ -190,17 +190,17 @@ var taskEdit = {
   /**
    * Observer to watch for changes to the selected calendar.
    *
    * XXX I think we don't need to implement calIObserver here.
    *
    * @see calICompositeObserver
    */
   compositeObserver: {
-    QueryInterface: cal.generateQI([Ci.calIObserver, Ci.calICompositeObserver]),
+    QueryInterface: cal.generateQI(["calIObserver", "calICompositeObserver"]),
 
     // calIObserver:
     onStartBatch() {},
     onEndBatch() {},
     onLoad(aCalendar) {},
     onAddItem(aItem) {},
     onModifyItem(aNewItem, aOldItem) {},
     onDeleteItem(aDeletedItem) {},
--- a/calendar/base/content/calendar-task-tree.js
+++ b/calendar/base/content/calendar-task-tree.js
@@ -18,17 +18,17 @@
   class TaskTreeObserver {
     /**
      * Creates and connects the new observer to a CalendarTaskTree and sets up Query Interface.
      *
      * @param {CalendarTaskTree} taskTree    The tree to observe.
      */
     constructor(taskTree) {
       this.tree = taskTree;
-      this.QueryInterface = cal.generateQI([Ci.calICompositeObserver, Ci.calIObserver]);
+      this.QueryInterface = cal.generateQI(["calICompositeObserver", "calIObserver"]);
     }
 
     // calIObserver Methods
 
     onStartBatch() {}
 
     onEndBatch() {}
 
@@ -446,17 +446,17 @@
      * @return {Object | false}    The task object related to the event or false if none found.
      */
     getTaskFromEvent(event) {
       return this.mTreeView.getItemFromEvent(event);
     }
 
     refreshFromCalendar(calendar) {
       let refreshJob = {
-        QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+        QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
         tree: this,
         calendar: null,
         items: null,
         operation: null,
 
         onOperationComplete(opCalendar, status, operationType, id, dateTime) {
           if (!this.tree.mTreeView.tree) {
             // Looks like we've been disconnected from the DOM, there's no point in continuing.
--- a/calendar/base/content/calendar-unifinder.js
+++ b/calendar/base/content/calendar-unifinder.js
@@ -60,17 +60,17 @@ function getCurrentUnifinderFilter() {
 /**
  * Observer for the calendar event data source. This keeps the unifinder
  * display up to date when the calendar event data is changed
  *
  * @see calIObserver
  * @see calICompositeObserver
  */
 var unifinderObserver = {
-  QueryInterface: cal.generateQI([Ci.calICompositeObserver, Ci.nsIObserver, Ci.calIObserver]),
+  QueryInterface: cal.generateQI(["calICompositeObserver", "nsIObserver", "calIObserver"]),
 
   // calIObserver:
   onStartBatch() {
     gUnifinderNeedsRefresh = true;
   },
 
   onEndBatch() {
     if (isUnifinderHidden()) {
@@ -380,17 +380,17 @@ function unifinderKeyPress(aEvent) {
       break;
   }
 }
 
 /**
  * Tree controller for unifinder search results
  */
 var unifinderTreeView = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsITreeView]),
+  QueryInterface: ChromeUtils.generateQI(["nsITreeView"]),
 
   // Provide a default tree that holds all the functions used here to avoid
   // cludgy if (this.tree) { this.tree.rowCountChanged(...); } constructs.
   tree: {
     rowCountChanged() {},
     beginUpdateBatch() {},
     endUpdateBatch() {},
     invalidate() {},
@@ -903,17 +903,17 @@ function addItemsFromSingleCalendarInter
 
 function addItemsFromCalendar(aCalendar, aAddItemsInternalFunc) {
   if (isUnifinderHidden()) {
     // If the unifinder is hidden, don't refresh the events to reduce needed
     // getItems calls.
     return;
   }
   let refreshListener = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+    QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
     mEventArray: [],
 
     onOperationComplete(aOpCalendar, aStatus, aOperationType, aId, aDateTime) {
       let refreshTreeInternalFunc = function() {
         aAddItemsInternalFunc(refreshListener.mEventArray);
       };
       setTimeout(refreshTreeInternalFunc, 0);
     },
--- a/calendar/base/content/calendar-views-utils.js
+++ b/calendar/base/content/calendar-views-utils.js
@@ -18,17 +18,17 @@ var { countOccurrences } = ChromeUtils.i
 );
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 /**
  * Controller for the views
  * @see calIcalendarViewController
  */
 var calendarViewController = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calICalendarViewController]),
+  QueryInterface: ChromeUtils.generateQI(["calICalendarViewController"]),
 
   /**
    * Creates a new event
    * @see calICalendarViewController
    */
   createNewEvent(calendar, startTime, endTime, forceAllday) {
     // if we're given both times, skip the dialog
     if (startTime && endTime && !startTime.isDate && !endTime.isDate) {
@@ -566,17 +566,17 @@ function editSelectedEvents() {
 }
 
 /**
  * Select all events from all calendars. Use with care.
  */
 function selectAllEvents() {
   let items = [];
   let listener = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+    QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
     onOperationComplete(calendar, status, operationType, id, detail) {
       currentView().setSelectedItems(items, false);
     },
     onGetResult(calendar, status, itemType, detail, itemsArg) {
       for (let item of itemsArg) {
         items.push(item);
       }
     },
--- a/calendar/base/content/dialogs/calendar-invitations-dialog.js
+++ b/calendar/base/content/dialogs/calendar-invitations-dialog.js
@@ -202,17 +202,17 @@ var { cal } = ChromeUtils.import("resour
 }
 
 /**
  * Sets up the invitations dialog from the window arguments, retrieves the
  * invitations from the invitations manager.
  */
 function onLoad() {
   let operationListener = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+    QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
     onOperationComplete(aCalendar, aStatus, aOperationType, aId, aDetail) {
       let updatingBox = document.getElementById("updating-box");
       updatingBox.setAttribute("hidden", "true");
       let richListBox = document.getElementById("invitations-listbox");
       if (richListBox.getRowCount() > 0) {
         richListBox.selectedIndex = 0;
       } else {
         let noInvitationsBox = document.getElementById("noinvitations-box");
--- a/calendar/base/content/dialogs/calendar-print-dialog.js
+++ b/calendar/base/content/dialogs/calendar-print-dialog.js
@@ -143,17 +143,17 @@ function getPrintSettings(receiverFunc) 
       break;
     }
   }
 
   // Some filters above might have filled the events list themselves. If not,
   // then fetch the items here.
   if (requiresFetch) {
     let listener = {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+      QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
       onOperationComplete(aCalendar, aStatus, aOperationType, aId, aDateTime) {
         receiverFunc(settings);
       },
       onGetResult(aCalendar, aStatus, aItemType, aDetail, aItems) {
         settings.eventList = settings.eventList.concat(aItems);
         if (!settings.printTasksWithNoDueDate) {
           let eventWithDueDate = [];
           for (let item of settings.eventList) {
--- a/calendar/base/content/import-export.js
+++ b/calendar/base/content/import-export.js
@@ -321,17 +321,17 @@ function saveEventsToFile(calendarEventA
  * Exports all the events and tasks in a calendar.  If aCalendar is not specified,
  * the user will be prompted with a list of calendars to choose which one to export.
  *
  * @param aCalendar     (optional) A specific calendar to export
  */
 function exportEntireCalendar(aCalendar) {
   let itemArray = [];
   let getListener = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+    QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
     onOperationComplete(aOpCalendar, aStatus, aOperationType, aId, aDetail) {
       saveEventsToFile(itemArray, aOpCalendar.name);
     },
     onGetResult(aOpCalendar, aStatus, aItemType, aDetail, aItems) {
       for (let item of aItems) {
         itemArray.push(item);
       }
     },
--- a/calendar/base/modules/calCalendarDeactivator.jsm
+++ b/calendar/base/modules/calCalendarDeactivator.jsm
@@ -22,17 +22,17 @@ const { cal } = ChromeUtils.import("reso
  *
  * @implements {calICalendarManagerObserver}
  * @implements {calIObserver}
  */
 var calendarDeactivator = {
   windows: new Set(),
   calendars: null,
   isCalendarActivated: null,
-  QueryInterface: cal.generateQI([Ci.calICalendarManagerObserver, Ci.calIObserver]),
+  QueryInterface: cal.generateQI(["calICalendarManagerObserver", "calIObserver"]),
 
   initializeDeactivator() {
     let manager = cal.getCalendarManager();
     this.calendars = new Set(manager.getCalendars());
     manager.addObserver(this);
     manager.addCalendarObserver(this);
     this.isCalendarActivated = this.checkCalendarsEnabled();
   },
--- a/calendar/base/modules/calUtils.jsm
+++ b/calendar/base/modules/calUtils.jsm
@@ -222,17 +222,17 @@ var cal = {
       },
       getScriptableHelper() {
         return null;
       },
       contractID: classInfo.contractID,
       classDescription: classInfo.classDescription,
       classID: classInfo.classID,
       flags: classInfo.flags,
-      QueryInterface: ChromeUtils.generateQI([Ci.nsIClassInfo]),
+      QueryInterface: ChromeUtils.generateQI(["nsIClassInfo"]),
     };
   },
 
   /**
    * Schedules execution of the passed function to the current thread's queue.
    */
   postPone(func) {
     if (this.threadingEnabled) {
--- a/calendar/base/modules/utils/calAsyncUtils.jsm
+++ b/calendar/base/modules/utils/calAsyncUtils.jsm
@@ -102,17 +102,17 @@ var calasync = {
    * See also promisifyCalendar, where the above can be replaced with:
    *   function promiseAddItem(aItem) {
    *     let calendar = cal.async.promisifyCalendar(aItem.calendar);
    *     return calendar.addItem(aItem);
    *   }
    */
   promiseOperationListener(deferred) {
     return {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+      QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
       items: [],
       itemStatus: Cr.NS_OK,
       onGetResult(aCalendar, aStatus, aItemType, aDetail, aItems) {
         this.itemStatus = aStatus;
         if (Components.isSuccessCode(aStatus)) {
           this.items = this.items.concat(aItems);
         } else {
           this.itemSuccess = aStatus;
--- a/calendar/base/modules/utils/calItipUtils.jsm
+++ b/calendar/base/modules/utils/calItipUtils.jsm
@@ -1523,17 +1523,17 @@ function sendMessage(aItem, aMethod, aRe
  *                                        recipients.
  */
 function ItipOpListener(aOpListener, aOldItem, aExtResponse = null) {
   this.mOpListener = aOpListener;
   this.mOldItem = aOldItem;
   this.mExtResponse = aExtResponse;
 }
 ItipOpListener.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+  QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
 
   mOpListener: null,
   mOldItem: null,
   mExtResponse: null,
 
   onOperationComplete(aCalendar, aStatus, aOperationType, aId, aDetail) {
     cal.ASSERT(Components.isSuccessCode(aStatus), "error on iTIP processing");
     if (Components.isSuccessCode(aStatus)) {
@@ -1605,17 +1605,17 @@ var ItipItemFinderFactory = {
  */
 function ItipItemFinder(aId, itipItem, optionsFunc) {
   this.mItipItem = itipItem;
   this.mOptionsFunc = optionsFunc;
   this.mSearchId = aId;
 }
 
 ItipItemFinder.prototype = {
-  QueryInterface: cal.generateQI([Ci.calIObserver, Ci.calIOperationListener]),
+  QueryInterface: cal.generateQI(["calIObserver", "calIOperationListener"]),
 
   mSearchId: null,
   mItipItem: null,
   mOptionsFunc: null,
   mFoundItems: null,
 
   findItem() {
     this.mFoundItems = [];
--- a/calendar/base/modules/utils/calProviderUtils.jsm
+++ b/calendar/base/modules/utils/calProviderUtils.jsm
@@ -245,17 +245,17 @@ var calprovider = {
    * @param aCalId         The calendar id to set up with.
    * @param aFreeBusyType  The type from calIFreeBusyInterval.
    * @param aStart         The start of the interval.
    * @param aEnd           The end of the interval.
    * @return               The fresh calIFreeBusyInterval.
    */
   FreeBusyInterval: class {
     QueryInterface() {
-      return ChromeUtils.generateQI([Ci.calIFreeBusyInterval]);
+      return ChromeUtils.generateQI(["calIFreeBusyInterval"]);
     }
 
     constructor(aCalId, aFreeBusyType, aStart, aEnd) {
       this.calId = aCalId;
       this.interval = Cc["@mozilla.org/calendar/period;1"].createInstance(Ci.calIPeriod);
       this.interval.start = aStart;
       this.interval.end = aEnd;
 
--- a/calendar/base/modules/utils/calViewUtils.jsm
+++ b/calendar/base/modules/utils/calViewUtils.jsm
@@ -348,17 +348,17 @@ var calview = {
 /**
  * Adds CSS variables for each calendar to registered windows for coloring
  * UI elements. Automatically tracks calendar creation, changes, and deletion.
  */
 calview.colorTracker = {
   calendars: null,
   categoryBranch: null,
   windows: new Set(),
-  QueryInterface: cal.generateQI([Ci.calICalendarManagerObserver, Ci.calIObserver]),
+  QueryInterface: cal.generateQI(["calICalendarManagerObserver", "calIObserver"]),
 
   // Deregistration is not required.
   registerWindow(aWindow) {
     if (this.calendars === null) {
       let manager = cal.getCalendarManager();
       this.calendars = new Set(manager.getCalendars());
       manager.addObserver(this);
       manager.addCalendarObserver(this);
--- a/calendar/base/src/CalAlarm.jsm
+++ b/calendar/base/src/CalAlarm.jsm
@@ -15,17 +15,17 @@ function CalAlarm() {
   this.wrappedJSObject = this;
   this.mProperties = new Map();
   this.mPropertyParams = {};
   this.mAttendees = [];
   this.mAttachments = [];
 }
 
 CalAlarm.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIAlarm]),
+  QueryInterface: ChromeUtils.generateQI(["calIAlarm"]),
   classID: Components.ID("{b8db7c7f-c168-4e11-becb-f26c1c4f5f8f}"),
 
   mProperties: null,
   mPropertyParams: null,
   mAction: null,
   mAbsoluteDate: null,
   mOffset: null,
   mDuration: null,
--- a/calendar/base/src/CalAlarmMonitor.jsm
+++ b/calendar/base/src/CalAlarmMonitor.jsm
@@ -35,17 +35,17 @@ CalAlarmMonitor.prototype = {
   // we call openWindow and when it appears via getMostRecentWindow.  If an
   // alarm is fired in that time-frame, it will actually end up in another window.
   mWindowOpening: null,
 
   // nsISound instance used for playing all sounds
   mSound: null,
 
   classID: calAlarmMonitorClassID,
-  QueryInterface: cal.generateQI(calAlarmMonitorInterfaces),
+  QueryInterface: cal.generateQI(["nsIObserver", "calIAlarmServiceObserver"]),
   classInfo: cal.generateCI({
     contractID: "@mozilla.org/calendar/alarm-monitor;1",
     classDescription: "Calendar Alarm Monitor",
     classID: calAlarmMonitorClassID,
     interfaces: calAlarmMonitorInterfaces,
     flags: Ci.nsIClassInfo.SINGLETON,
   }),
 
--- a/calendar/base/src/CalAlarmService.jsm
+++ b/calendar/base/src/CalAlarmService.jsm
@@ -28,17 +28,17 @@ function newTimerWithCallback(aCallback,
 function CalAlarmService() {
   this.wrappedJSObject = this;
 
   this.mLoadedCalendars = {};
   this.mTimerMap = {};
   this.mObservers = new cal.data.ListenerSet(Ci.calIAlarmServiceObserver);
 
   this.calendarObserver = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calIObserver]),
+    QueryInterface: ChromeUtils.generateQI(["calIObserver"]),
     alarmService: this,
 
     // calIObserver:
     onStartBatch() {},
     onEndBatch() {},
     onLoad(calendar) {
       // ignore any onLoad events until initial getItems() call of startup has finished:
       if (calendar && this.alarmService.mLoadedCalendars[calendar.id]) {
@@ -73,17 +73,17 @@ function CalAlarmService() {
       }
     },
     onPropertyDeleting(aCalendar, aName) {
       this.onPropertyChanged(aCalendar, aName);
     },
   };
 
   this.calendarManagerObserver = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calICalendarManagerObserver]),
+    QueryInterface: ChromeUtils.generateQI(["calICalendarManagerObserver"]),
     alarmService: this,
 
     onCalendarRegistered(aCalendar) {
       this.alarmService.observeCalendar(aCalendar);
       // initial refresh of alarms for new calendar:
       this.alarmService.initAlarms([aCalendar]);
     },
     onCalendarUnregistering(aCalendar) {
@@ -106,17 +106,17 @@ CalAlarmService.prototype = {
   mRangeEnd: null,
   mUpdateTimer: null,
   mStarted: false,
   mTimerMap: null,
   mObservers: null,
   mTimezone: null,
 
   classID: calAlarmServiceClassID,
-  QueryInterface: cal.generateQI(calAlarmServiceInterfaces),
+  QueryInterface: cal.generateQI(["calIAlarmService", "nsIObserver"]),
   classInfo: cal.generateCI({
     classID: calAlarmServiceClassID,
     contractID: "@mozilla.org/calendar/alarm-service;1",
     classDescription: "Calendar Alarm Service",
     interfaces: calAlarmServiceInterfaces,
     flags: Ci.nsIClassInfo.SINGLETON,
   }),
 
@@ -490,17 +490,17 @@ CalAlarmService.prototype = {
         }
         delete this.mTimerMap[calendar.id];
       }
     }
   },
 
   findAlarms(aCalendars, aStart, aUntil) {
     let getListener = {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+      QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
       alarmService: this,
       addRemovePromise: PromiseUtils.defer(),
       batchCount: 0,
       results: false,
       onOperationComplete(aCalendar, aStatus, aOperationType, aId, aDetail) {
         this.addRemovePromise.promise.then(
           aValue => {
             // calendar has been loaded, so until now, onLoad events can be ignored:
--- a/calendar/base/src/CalAttachment.jsm
+++ b/calendar/base/src/CalAttachment.jsm
@@ -8,17 +8,17 @@ var { Services } = ChromeUtils.import("r
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 function CalAttachment() {
   this.wrappedJSObject = this;
   this.mProperties = new Map();
 }
 
 CalAttachment.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIAttachment]),
+  QueryInterface: ChromeUtils.generateQI(["calIAttachment"]),
   classID: Components.ID("{5f76b352-ab75-4c2b-82c9-9206dbbf8571}"),
 
   mData: null,
   mHashId: null,
 
   get hashId() {
     if (!this.mHashId) {
       let cryptoHash = Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash);
--- a/calendar/base/src/CalAttendee.jsm
+++ b/calendar/base/src/CalAttendee.jsm
@@ -10,17 +10,17 @@ var { cal } = ChromeUtils.import("resour
 Services.scriptloader.loadSubScript("resource:///components/calItemBase.js");
 
 function CalAttendee() {
   this.wrappedJSObject = this;
   this.mProperties = new Map();
 }
 
 CalAttendee.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIAttendee]),
+  QueryInterface: ChromeUtils.generateQI(["calIAttendee"]),
   classID: Components.ID("{5c8dcaa3-170c-4a73-8142-d531156f664d}"),
 
   mImmutable: false,
   get isMutable() {
     return !this.mImmutable;
   },
 
   modify() {
--- a/calendar/base/src/CalCalendarManager.jsm
+++ b/calendar/base/src/CalCalendarManager.jsm
@@ -21,17 +21,17 @@ function CalCalendarManager() {
   this.mObservers = new cal.data.ListenerSet(Ci.calICalendarManagerObserver);
   this.mCalendarObservers = new cal.data.ListenerSet(Ci.calIObserver);
 }
 
 var calCalendarManagerClassID = Components.ID("{f42585e7-e736-4600-985d-9624c1c51992}");
 var calCalendarManagerInterfaces = [Ci.calICalendarManager, Ci.calIStartupService, Ci.nsIObserver];
 CalCalendarManager.prototype = {
   classID: calCalendarManagerClassID,
-  QueryInterface: cal.generateQI(calCalendarManagerInterfaces),
+  QueryInterface: cal.generateQI(["calICalendarManager", "calIStartupService", "nsIObserver"]),
   classInfo: cal.generateCI({
     classID: calCalendarManagerClassID,
     contractID: "@mozilla.org/calendar/manager;1",
     classDescription: "Calendar Manager",
     interfaces: calCalendarManagerInterfaces,
     flags: Ci.nsIClassInfo.SINGLETON,
   }),
 
@@ -504,17 +504,17 @@ function calMgrCalendarObserver(calendar
   this.calMgr = calMgr;
 }
 
 calMgrCalendarObserver.prototype = {
   calendar: null,
   storedReadOnly: null,
   calMgr: null,
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIWindowMediatorListener, Ci.calIObserver]),
+  QueryInterface: ChromeUtils.generateQI(["nsIWindowMediatorListener", "calIObserver"]),
 
   // calIObserver:
   onStartBatch() {
     return this.calMgr.notifyCalendarObservers("onStartBatch", arguments);
   },
   onEndBatch() {
     return this.calMgr.notifyCalendarObservers("onEndBatch", arguments);
   },
--- a/calendar/base/src/CalCalendarSearchService.jsm
+++ b/calendar/base/src/CalCalendarSearchService.jsm
@@ -54,17 +54,17 @@ var calCalendarSearchServiceClassID = Co
 var calCalendarSearchServiceInterfaces = [
   Ci.calICalendarSearchProvider,
   Ci.calICalendarSearchService,
 ];
 CalCalendarSearchService.prototype = {
   mProviders: null,
 
   classID: calCalendarSearchServiceClassID,
-  QueryInterface: cal.generateQI(calCalendarSearchServiceInterfaces),
+  QueryInterface: cal.generateQI(["calICalendarSearchProvider", "calICalendarSearchService"]),
   classInfo: cal.generateCI({
     classID: calCalendarSearchServiceClassID,
     contractID: "@mozilla.org/calendar/calendarsearch-service;1",
     classDescription: "Calendar Search Service",
     interfaces: calCalendarSearchServiceInterfaces,
     flags: Ci.nsIClassInfo.SINGLETON,
   }),
 
--- a/calendar/base/src/CalDefaultACLManager.jsm
+++ b/calendar/base/src/CalDefaultACLManager.jsm
@@ -6,17 +6,17 @@ var EXPORTED_SYMBOLS = ["CalDefaultACLMa
 
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 function CalDefaultACLManager() {
   this.mCalendarEntries = {};
 }
 
 CalDefaultACLManager.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calICalendarACLManager]),
+  QueryInterface: ChromeUtils.generateQI(["calICalendarACLManager"]),
   classID: Components.ID("{7463258c-6ef3-40a2-89a9-bb349596e927}"),
 
   mCalendarEntries: null,
 
   /* calICalendarACLManager */
   _getCalendarEntryCached(aCalendar) {
     let calUri = aCalendar.uri.spec;
     if (!(calUri in this.mCalendarEntries)) {
@@ -36,17 +36,17 @@ CalDefaultACLManager.prototype = {
 };
 
 function calDefaultCalendarACLEntry(aMgr, aCalendar) {
   this.mACLManager = aMgr;
   this.mCalendar = aCalendar;
 }
 
 calDefaultCalendarACLEntry.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calICalendarACLEntry]),
+  QueryInterface: ChromeUtils.generateQI(["calICalendarACLEntry"]),
 
   mACLManager: null,
 
   /* calICalendarACLCalendarEntry */
   get aclManager() {
     return this.mACLManager;
   },
 
@@ -81,17 +81,17 @@ calDefaultCalendarACLEntry.prototype = {
   refresh() {},
 };
 
 function calDefaultItemACLEntry(aCalendarEntry) {
   this.calendarEntry = aCalendarEntry;
 }
 
 calDefaultItemACLEntry.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIItemACLEntry]),
+  QueryInterface: ChromeUtils.generateQI(["calIItemACLEntry"]),
 
   /* calIItemACLEntry */
   calendarEntry: null,
   userCanModify: true,
   userCanRespond: true,
   userCanViewAll: true,
   userCanViewDateAndTime: true,
 };
--- a/calendar/base/src/CalDeletedItems.jsm
+++ b/calendar/base/src/CalDeletedItems.jsm
@@ -24,17 +24,17 @@ function CalDeletedItems() {
     handleCompletion() {},
   };
 }
 
 var calDeletedItemsClassID = Components.ID("{8e6799af-e7e9-4e6c-9a82-a2413e86d8c3}");
 var calDeletedItemsInterfaces = [Ci.calIDeletedItems, Ci.nsIObserver, Ci.calIObserver];
 CalDeletedItems.prototype = {
   classID: calDeletedItemsClassID,
-  QueryInterface: cal.generateQI(calDeletedItemsInterfaces),
+  QueryInterface: cal.generateQI(["calIDeletedItems", "nsIObserver", "calIObserver"]),
   classInfo: cal.generateCI({
     classID: calDeletedItemsClassID,
     contractID: "@mozilla.org/calendar/deleted-items-manager;1",
     classDescription: "Database containing information about deleted items",
     interfaces: calDeletedItemsInterfaces,
     flags: Ci.nsIClassInfo.SINGLETON,
   }),
 
--- a/calendar/base/src/CalEvent.jsm
+++ b/calendar/base/src/CalEvent.jsm
@@ -21,17 +21,17 @@ function CalEvent() {
   };
 }
 var calEventClassID = Components.ID("{974339d5-ab86-4491-aaaf-2b2ca177c12b}");
 var calEventInterfaces = [Ci.calIItemBase, Ci.calIEvent, Ci.calIInternalShallowCopy];
 CalEvent.prototype = {
   __proto__: calItemBase.prototype,
 
   classID: calEventClassID,
-  QueryInterface: cal.generateQI(calEventInterfaces),
+  QueryInterface: cal.generateQI(["calIItemBase", "calIEvent", "calIInternalShallowCopy"]),
   classInfo: cal.generateCI({
     classID: calEventClassID,
     contractID: "@mozilla.org/calendar/event;1",
     classDescription: "Calendar Event",
     interfaces: calEventInterfaces,
   }),
 
   cloneShallow(aNewParent) {
--- a/calendar/base/src/CalFreeBusyService.jsm
+++ b/calendar/base/src/CalFreeBusyService.jsm
@@ -10,17 +10,17 @@ function CalFreeBusyListener(numOperatio
   this.mFinalListener = finalListener;
   this.mNumOperations = numOperations;
 
   this.opGroup = new cal.data.OperationGroup(() => {
     this.notifyResult(null);
   });
 }
 CalFreeBusyListener.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIGenericOperationListener]),
+  QueryInterface: ChromeUtils.generateQI(["calIGenericOperationListener"]),
 
   mFinalListener: null,
   mNumOperations: 0,
   opGroup: null,
 
   notifyResult(result) {
     let listener = this.mFinalListener;
     if (listener) {
@@ -50,17 +50,17 @@ CalFreeBusyListener.prototype = {
   },
 };
 
 function CalFreeBusyService() {
   this.wrappedJSObject = this;
   this.mProviders = new Set();
 }
 CalFreeBusyService.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIFreeBusyProvider, Ci.calIFreeBusyService]),
+  QueryInterface: ChromeUtils.generateQI(["calIFreeBusyProvider", "calIFreeBusyService"]),
   classID: Components.ID("{29c56cd5-d36e-453a-acde-0083bd4fe6d3}"),
 
   mProviders: null,
 
   // calIFreeBusyProvider:
   getFreeBusyIntervals(aCalId, aRangeStart, aRangeEnd, aBusyTypes, aListener) {
     let groupListener = new CalFreeBusyListener(this.mProviders.size, aListener);
     if (this.mProviders.size == 0) {
--- a/calendar/base/src/CalIcsParser.jsm
+++ b/calendar/base/src/CalIcsParser.jsm
@@ -11,17 +11,17 @@ var { Services } = ChromeUtils.import("r
 function CalIcsParser() {
   this.wrappedJSObject = this;
   this.mItems = [];
   this.mParentlessItems = [];
   this.mComponents = [];
   this.mProperties = [];
 }
 CalIcsParser.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIIcsParser]),
+  QueryInterface: ChromeUtils.generateQI(["calIIcsParser"]),
   classID: Components.ID("{6fe88047-75b6-4874-80e8-5f5800f14984}"),
 
   processIcalComponent(rootComp, aAsyncParsing) {
     let calComp;
     // libical returns the vcalendar component if there is just one vcalendar.
     // If there are multiple vcalendars, it returns an xroot component, with
     // vcalendar children. We need to handle both cases.
     if (rootComp) {
--- a/calendar/base/src/CalIcsSerializer.jsm
+++ b/calendar/base/src/CalIcsSerializer.jsm
@@ -8,17 +8,17 @@ var { cal } = ChromeUtils.import("resour
 
 function CalIcsSerializer() {
   this.wrappedJSObject = this;
   this.mItems = [];
   this.mProperties = [];
   this.mComponents = [];
 }
 CalIcsSerializer.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIIcsSerializer]),
+  QueryInterface: ChromeUtils.generateQI(["calIIcsSerializer"]),
   classID: Components.ID("{207a6682-8ff1-4203-9160-729ec28c8766}"),
 
   addItems(aItems) {
     if (aItems.length > 0) {
       this.mItems = this.mItems.concat(aItems);
     }
   },
 
--- a/calendar/base/src/CalItipItem.jsm
+++ b/calendar/base/src/CalItipItem.jsm
@@ -6,17 +6,17 @@ var EXPORTED_SYMBOLS = ["CalItipItem"];
 
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 function CalItipItem() {
   this.wrappedJSObject = this;
   this.mCurrentItemIndex = 0;
 }
 CalItipItem.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIItipItem]),
+  QueryInterface: ChromeUtils.generateQI(["calIItipItem"]),
   classID: Components.ID("{f41392ab-dcad-4bad-818f-b3d1631c4d93}"),
 
   mIsInitialized: false,
 
   mSender: null,
   get sender() {
     return this.mSender;
   },
--- a/calendar/base/src/CalProtocolHandler.jsm
+++ b/calendar/base/src/CalProtocolHandler.jsm
@@ -70,22 +70,22 @@ calProtocolHandler.prototype = {
 
 /** Constructor for webcal: protocol handler */
 function CalProtocolHandlerWebcal() {
   calProtocolHandler.call(this, "webcal");
 }
 CalProtocolHandlerWebcal.prototype = {
   __proto__: calProtocolHandler.prototype,
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIProtocolHandler]),
+  QueryInterface: ChromeUtils.generateQI(["nsIProtocolHandler"]),
   classID: Components.ID("{1153c73a-39be-46aa-9ba9-656d188865ca}"),
 };
 
 /** Constructor for webcals: protocol handler */
 function CalProtocolHandlerWebcals() {
   calProtocolHandler.call(this, "webcals");
 }
 CalProtocolHandlerWebcals.prototype = {
   __proto__: calProtocolHandler.prototype,
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIProtocolHandler]),
+  QueryInterface: ChromeUtils.generateQI(["nsIProtocolHandler"]),
   classID: Components.ID("{bdf71224-365d-4493-856a-a7e74026f766}"),
 };
--- a/calendar/base/src/CalRecurrenceDate.jsm
+++ b/calendar/base/src/CalRecurrenceDate.jsm
@@ -14,17 +14,17 @@ var calRecurrenceDateClassID = Component
 var calRecurrenceDateInterfaces = [Ci.calIRecurrenceItem, Ci.calIRecurrenceDate];
 CalRecurrenceDate.prototype = {
   isMutable: true,
 
   mIsNegative: false,
   mDate: null,
 
   classID: calRecurrenceDateClassID,
-  QueryInterface: cal.generateQI(calRecurrenceDateInterfaces),
+  QueryInterface: cal.generateQI(["calIRecurrenceItem", "calIRecurrenceDate"]),
   classInfo: cal.generateCI({
     classID: calRecurrenceDateClassID,
     contractID: "@mozilla.org/calendar/recurrence-date;1",
     classDescription: "The date of an occurrence of a recurring item",
     interfaces: calRecurrenceDateInterfaces,
   }),
 
   makeImmutable() {
--- a/calendar/base/src/CalRecurrenceInfo.jsm
+++ b/calendar/base/src/CalRecurrenceInfo.jsm
@@ -19,17 +19,17 @@ function getRidKey(date) {
 
 function CalRecurrenceInfo() {
   this.wrappedJSObject = this;
   this.mRecurrenceItems = [];
   this.mExceptionMap = {};
 }
 
 CalRecurrenceInfo.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIRecurrenceInfo]),
+  QueryInterface: ChromeUtils.generateQI(["calIRecurrenceInfo"]),
   classID: Components.ID("{04027036-5884-4a30-b4af-f2cad79f6edf}"),
 
   mImmutable: false,
   mBaseItem: null,
   mEndDate: null,
   mRecurrenceItems: null,
   mPositiveRules: null,
   mNegativeRules: null,
--- a/calendar/base/src/CalRelation.jsm
+++ b/calendar/base/src/CalRelation.jsm
@@ -12,17 +12,17 @@ var { cal } = ChromeUtils.import("resour
  * @implements calIRelation
  * @constructor
  */
 function CalRelation() {
   this.wrappedJSObject = this;
   this.mProperties = new Map();
 }
 CalRelation.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIRelation]),
+  QueryInterface: ChromeUtils.generateQI(["calIRelation"]),
   classID: Components.ID("{76810fae-abad-4019-917a-08e95d5bbd68}"),
 
   mType: null,
   mId: null,
 
   /**
    * @see calIRelation
    */
--- a/calendar/base/src/CalSleepMonitor.jsm
+++ b/calendar/base/src/CalSleepMonitor.jsm
@@ -7,17 +7,17 @@ var EXPORTED_SYMBOLS = ["CalSleepMonitor
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 function CalSleepMonitor() {
   this.wrappedJSObject = this;
 }
 
 CalSleepMonitor.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
+  QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
   classID: Components.ID("9b987a8d-c2ef-4cb9-9602-1261b4b2f6fa"),
 
   interval: 60000,
   timer: null,
   expected: null,
   tolerance: 1000,
 
   callback() {
--- a/calendar/base/src/CalStartupService.jsm
+++ b/calendar/base/src/CalStartupService.jsm
@@ -27,17 +27,17 @@ function callOrderedServices(method, ser
 }
 
 function CalStartupService() {
   this.wrappedJSObject = this;
   this.setupObservers();
 }
 
 CalStartupService.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
+  QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
   classID: Components.ID("{2547331f-34c0-4a4b-b93c-b503538ba6d6}"),
 
   // Startup Service Methods
 
   /**
    * Sets up the needed observers for noticing startup/shutdown
    */
   setupObservers() {
--- a/calendar/base/src/CalTimezoneService.jsm
+++ b/calendar/base/src/CalTimezoneService.jsm
@@ -49,17 +49,21 @@ var calTimezoneServiceInterfaces = [
 ];
 CalTimezoneService.prototype = {
   mDefaultTimezone: null,
   mHasSetupObservers: false,
   mVersion: null,
   mZones: null,
 
   classID: calTimezoneServiceClassID,
-  QueryInterface: cal.generateQI(calTimezoneServiceInterfaces),
+  QueryInterface: cal.generateQI([
+    "calITimezoneService",
+    "calITimezoneProvider",
+    "calIStartupService",
+  ]),
   classInfo: cal.generateCI({
     classID: calTimezoneServiceClassID,
     contractID: "@mozilla.org/calendar/timezone-service;1",
     classDescription: "Calendar Timezone Service",
     interfaces: calTimezoneServiceInterfaces,
     flags: Ci.nsIClassInfo.SINGLETON,
   }),
 
--- a/calendar/base/src/CalTodo.jsm
+++ b/calendar/base/src/CalTodo.jsm
@@ -24,17 +24,17 @@ function CalTodo() {
 }
 
 var calTodoClassID = Components.ID("{7af51168-6abe-4a31-984d-6f8a3989212d}");
 var calTodoInterfaces = [Ci.calIItemBase, Ci.calITodo, Ci.calIInternalShallowCopy];
 CalTodo.prototype = {
   __proto__: calItemBase.prototype,
 
   classID: calTodoClassID,
-  QueryInterface: cal.generateQI(calTodoInterfaces),
+  QueryInterface: cal.generateQI(["calIItemBase", "calITodo", "calIInternalShallowCopy"]),
   classInfo: cal.generateCI({
     classID: calTodoClassID,
     contractID: "@mozilla.org/calendar/todo;1",
     classDescription: "Calendar Todo",
     interfaces: calTodoInterfaces,
   }),
 
   cloneShallow(aNewParent) {
--- a/calendar/base/src/CalTransactionManager.jsm
+++ b/calendar/base/src/CalTransactionManager.jsm
@@ -11,17 +11,17 @@ function CalTransactionManager() {
   if (!this.transactionManager) {
     this.transactionManager = Cc["@mozilla.org/transactionmanager;1"].createInstance(
       Ci.nsITransactionManager
     );
   }
 }
 
 CalTransactionManager.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calITransactionManager]),
+  QueryInterface: ChromeUtils.generateQI(["calITransactionManager"]),
   classID: Components.ID("{1d529847-d292-4222-b066-b8b17a794d62}"),
 
   transactionManager: null,
   createAndCommitTxn(aAction, aItem, aCalendar, aOldItem, aListener, aExtResponse) {
     let txn = new CalTransaction(aAction, aItem, aCalendar, aOldItem, aListener, aExtResponse);
     this.transactionManager.doTransaction(txn);
   },
 
@@ -76,17 +76,17 @@ function CalTransaction(aAction, aItem, 
   this.mItem = aItem;
   this.mCalendar = aCalendar;
   this.mOldItem = aOldItem;
   this.mListener = aListener;
   this.mExtResponse = aExtResponse;
 }
 
 var calTransactionClassID = Components.ID("{fcb54c82-2fb9-42cb-bf44-1e197a55e520}");
-var calTransactionInterfaces = [Ci.nsITransaction, Ci.calIOperationListener];
+var calTransactionInterfaces = ["nsITransaction", "calIOperationListener"];
 CalTransaction.prototype = {
   classID: calTransactionClassID,
   QueryInterface: ChromeUtils.generateQI(calTransactionInterfaces),
 
   mAction: null,
   mCalendar: null,
   mItem: null,
   mOldItem: null,
--- a/calendar/base/src/CalWeekInfoService.jsm
+++ b/calendar/base/src/CalWeekInfoService.jsm
@@ -5,17 +5,17 @@
 var EXPORTED_SYMBOLS = ["CalWeekInfoService"];
 
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 function CalWeekInfoService() {
   this.wrappedJSObject = this;
 }
 CalWeekInfoService.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIWeekInfoService]),
+  QueryInterface: ChromeUtils.generateQI(["calIWeekInfoService"]),
   classID: Components.ID("{6877bbdd-f336-46f5-98ce-fe86d0285cc1}"),
 
   // calIWeekInfoService:
   getWeekTitle(aDateTime) {
     /**
      * This implementation is based on the ISO 8601 standard.
      * ISO 8601 defines week one as the first week with at least 4
      * days, and defines Monday as the first day of the week.
--- a/calendar/base/src/calCachedCalendar.js
+++ b/calendar/base/src/calCachedCalendar.js
@@ -7,17 +7,17 @@ var EXPORTED_SYMBOLS = ["calCachedCalend
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var calICalendar = Ci.calICalendar;
 var cICL = Ci.calIChangeLog;
 var cIOL = Ci.calIOperationListener;
 
 var gNoOpListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+  QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
   onGetResult(calendar, status, itemType, detail, items) {},
 
   onOperationComplete(calendar, status, opType, id, detail) {},
 };
 
 /**
  * Returns true if the exception passed is one that should cause the cache
  * layer to retry the operation. This is usually a network error or other
@@ -48,17 +48,17 @@ function isUnavailableCode(result) {
   }
 }
 
 function calCachedCalendarObserverHelper(home, isCachedObserver) {
   this.home = home;
   this.isCachedObserver = isCachedObserver;
 }
 calCachedCalendarObserverHelper.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIObserver]),
+  QueryInterface: ChromeUtils.generateQI(["calIObserver"]),
   isCachedObserver: false,
 
   onStartBatch() {
     this.home.mObservers.notify("onStartBatch");
   },
 
   onEndBatch() {
     this.home.mObservers.notify("onEndBatch");
@@ -224,17 +224,17 @@ calCachedCalendar.prototype = {
       Cu.reportError(exc);
     }
   },
 
   getOfflineAddedItems(callbackFunc) {
     let self = this;
     self.offlineCachedItems = {};
     let getListener = {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+      QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
       onGetResult(aCalendar, aStatus, aItemType, aDetail, aItems) {
         for (let item of aItems) {
           self.offlineCachedItems[item.hashId] = item;
           self.offlineCachedItemFlags[item.hashId] = cICL.OFFLINE_FLAG_CREATED_RECORD;
         }
       },
 
       onOperationComplete(aCalendar, aStatus, aOpType, aId, aDetail) {
@@ -248,17 +248,17 @@ calCachedCalendar.prototype = {
       null,
       getListener
     );
   },
 
   getOfflineModifiedItems(callbackFunc) {
     let self = this;
     let getListener = {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+      QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
       onGetResult(aCalendar, aStatus, aItemType, aDetail, aItems) {
         for (let item of aItems) {
           self.offlineCachedItems[item.hashId] = item;
           self.offlineCachedItemFlags[item.hashId] = cICL.OFFLINE_FLAG_MODIFIED_RECORD;
         }
       },
 
       onOperationComplete(aCalendar, aStatus, aOpType, aId, aDetail) {
@@ -272,17 +272,17 @@ calCachedCalendar.prototype = {
       null,
       getListener
     );
   },
 
   getOfflineDeletedItems(callbackFunc) {
     let self = this;
     let getListener = {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+      QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
       onGetResult(aCalendar, aStatus, aItemType, aDetail, aItems) {
         for (let item of aItems) {
           self.offlineCachedItems[item.hashId] = item;
           self.offlineCachedItemFlags[item.hashId] = cICL.OFFLINE_FLAG_DELETED_RECORD;
         }
       },
 
       onOperationComplete(aCalendar, aStatus, aOpType, aId, aDetail) {
@@ -360,17 +360,17 @@ calCachedCalendar.prototype = {
         },
       };
       this.mPendingSync = this.mUncachedCalendar.replayChangesOn(opListener);
       return this.mPendingSync;
     }
 
     cal.LOG("[calCachedCalendar] Doing full sync for calendar " + this.uri.spec);
     let completeListener = {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+      QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
       modifiedTimes: {},
       hasRenewedCalendar: false,
       getsCompleted: 0,
       getsReceived: 0,
       opCompleted: false,
 
       onGetResult(aCalendar, aStatus, aItemType, aDetail, aItems) {
         if (Components.isSuccessCode(aStatus)) {
--- a/calendar/base/src/calFilter.js
+++ b/calendar/base/src/calFilter.js
@@ -879,17 +879,17 @@ calFilter.prototype = {
     }
     let props = this.mFilterProperties;
 
     // we use a local proxy listener for the calICalendar.getItems() call, and use it
     // to handle occurrence expansion and filter the results before forwarding them to
     // the listener passed in the aListener argument.
     let self = this;
     let listener = {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+      QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
       onOperationComplete: aListener.onOperationComplete.bind(aListener),
 
       onGetResult(aOpCalendar, aStatus, aOpItemType, aDetail, aItems) {
         let items;
         if (props.occurrences == props.FILTER_OCCURRENCES_PAST_AND_NEXT) {
           // with the FILTER_OCCURRENCES_PAST_AND_NEXT occurrence filter we will
           // get parent items returned here, so we need to let the getOccurrences
           // function handle occurrence expansion.
--- a/calendar/base/src/calItemBase.js
+++ b/calendar/base/src/calItemBase.js
@@ -49,17 +49,17 @@ calItemBase.prototype = {
     this.mProperties = new Map();
     this.mPropertyParams = {};
     this.mProperties.set("CREATED", cal.dtz.jsDateToDateTime(new Date()));
   },
 
   /**
    * @see nsISupports
    */
-  QueryInterface: ChromeUtils.generateQI([Ci.calIItemBase]),
+  QueryInterface: ChromeUtils.generateQI(["calIItemBase"]),
 
   /**
    * @see calIItemBase
    */
   get aclEntry() {
     let aclEntry = this.mACLEntry;
     let aclManager = this.calendar && this.calendar.superCalendar.aclManager;
 
@@ -457,28 +457,28 @@ calItemBase.prototype = {
   getParameterEnumerator(aPropName) {
     let propName = aPropName.toUpperCase();
     if (!(propName in this.mPropertyParams)) {
       throw new Error("Property " + aPropName + " not set");
     }
     let parameters = this.mPropertyParams[propName];
     return {
       // nsISimpleEnumerator
-      QueryInterface: ChromeUtils.generateQI([Ci.nsISimpleEnumerator]),
+      QueryInterface: ChromeUtils.generateQI(["nsISimpleEnumerator"]),
 
       mParamNames: Object.keys(parameters),
       hasMoreElements() {
         return this.mParamNames.length > 0;
       },
 
       getNext() {
         let paramName = this.mParamNames.pop();
         return {
           // nsIProperty
-          QueryInterface: ChromeUtils.generateQI([Ci.nsIProperty]),
+          QueryInterface: ChromeUtils.generateQI(["nsIProperty"]),
           name: paramName,
           value: parameters[paramName],
         };
       },
     };
   },
 
   // void getAttendees(out PRUint32 count,
--- a/calendar/base/src/calTimezone.js
+++ b/calendar/base/src/calTimezone.js
@@ -6,17 +6,17 @@ var { cal } = ChromeUtils.import("resour
 var { ICAL } = ChromeUtils.import("resource:///modules/calendar/Ical.jsm");
 
 function calICALJSTimezone(innerObject) {
   this.innerObject = innerObject || new ICAL.Timezone();
   this.wrappedJSObject = this;
 }
 
 calICALJSTimezone.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calITimezone]),
+  QueryInterface: ChromeUtils.generateQI(["calITimezone"]),
   classID: Components.ID("{6702eb17-a968-4b43-b562-0d0c5f8e9eb5}"),
 
   innerObject: null,
 
   get provider() {
     return cal.getTimezoneService();
   },
   get icalComponent() {
@@ -68,17 +68,17 @@ function calLibicalTimezone(tzid, compon
   this.tzid = tzid;
   this.mComponent = component;
   this.mUTC = false;
   this.isFloating = false;
   this.latitude = latitude;
   this.longitude = longitude;
 }
 calLibicalTimezone.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calITimezone]),
+  QueryInterface: ChromeUtils.generateQI(["calITimezone"]),
   classID: Components.ID("{6702eb17-a968-4b43-b562-0d0c5f8e9eb5}"),
 
   toString() {
     return this.icalComponent ? this.icalComponent.toString() : this.tzid;
   },
 
   get isUTC() {
     return this.mUTC;
--- a/calendar/import-export/CalHtmlExport.jsm
+++ b/calendar/import-export/CalHtmlExport.jsm
@@ -9,25 +9,25 @@ var { cal } = ChromeUtils.import("resour
 /**
  * HTML Export Plugin
  */
 function CalHtmlExporter() {
   this.wrappedJSObject = this;
 }
 
 CalHtmlExporter.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIExporter]),
+  QueryInterface: ChromeUtils.generateQI(["calIExporter"]),
   classID: Components.ID("{72d9ab35-9b1b-442a-8cd0-ae49f00b159b}"),
 
   getFileTypes() {
     let wildmat = "*.html; *.htm";
     let label = cal.l10n.getCalString("filterHtml", [wildmat]);
     return [
       {
-        QueryInterface: ChromeUtils.generateQI([Ci.calIFileType]),
+        QueryInterface: ChromeUtils.generateQI(["calIFileType"]),
         defaultExtension: "html",
         extensionFilter: wildmat,
         description: label,
       },
     ];
   },
 
   exportToStream(aStream, aItems, aTitle) {
--- a/calendar/import-export/CalIcsImportExport.jsm
+++ b/calendar/import-export/CalIcsImportExport.jsm
@@ -5,47 +5,47 @@
 var EXPORTED_SYMBOLS = ["CalIcsImporter", "CalIcsExporter"];
 
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 // Shared functions
 function getIcsFileTypes() {
   return [
     {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIFileType]),
+      QueryInterface: ChromeUtils.generateQI(["calIFileType"]),
       defaultExtension: "ics",
       extensionFilter: "*.ics",
       description: cal.l10n.getCalString("filterIcs", ["*.ics"]),
     },
   ];
 }
 
 function CalIcsImporter() {
   this.wrappedJSObject = this;
 }
 
 CalIcsImporter.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIImporter]),
+  QueryInterface: ChromeUtils.generateQI(["calIImporter"]),
   classID: Components.ID("{1e3e33dc-445a-49de-b2b6-15b2a050bb9d}"),
 
   getFileTypes: getIcsFileTypes,
 
   importFromStream(aStream) {
     let parser = Cc["@mozilla.org/calendar/ics-parser;1"].createInstance(Ci.calIIcsParser);
     parser.parseFromStream(aStream, null);
     return parser.getItems();
   },
 };
 
 function CalIcsExporter() {
   this.wrappedJSObject = this;
 }
 
 CalIcsExporter.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIExporter]),
+  QueryInterface: ChromeUtils.generateQI(["calIExporter"]),
   classID: Components.ID("{a6a524ce-adff-4a0f-bb7d-d1aaad4adc60}"),
 
   getFileTypes: getIcsFileTypes,
 
   exportToStream(aStream, aItems, aTitle) {
     let serializer = Cc["@mozilla.org/calendar/ics-serializer;1"].createInstance(
       Ci.calIIcsSerializer
     );
--- a/calendar/import-export/CalListFormatter.jsm
+++ b/calendar/import-export/CalListFormatter.jsm
@@ -9,17 +9,17 @@ var { cal } = ChromeUtils.import("resour
 /**
  * A thin wrapper around the html list exporter for the list print format.
  */
 function CalListFormatter() {
   this.wrappedJSObject = this;
 }
 
 CalListFormatter.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIPrintFormatter]),
+  QueryInterface: ChromeUtils.generateQI(["calIPrintFormatter"]),
   classID: Components.ID("{9ae04413-fee3-45b9-8bbb-1eb39a4cbd1b}"),
 
   get name() {
     return cal.l10n.getCalString("formatListName");
   },
 
   formatToHtml(aStream, aStart, aEnd, aItems, aTitle) {
     let htmlexporter = Cc["@mozilla.org/calendar/export;1?type=htmllist"].createInstance(
--- a/calendar/import-export/CalMonthGridPrinter.jsm
+++ b/calendar/import-export/CalMonthGridPrinter.jsm
@@ -10,17 +10,17 @@ var { cal } = ChromeUtils.import("resour
 /**
  * Prints a rough month-grid of events/tasks
  */
 function CalMonthPrinter() {
   this.wrappedJSObject = this;
 }
 
 CalMonthPrinter.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIPrintFormatter]),
+  QueryInterface: ChromeUtils.generateQI(["calIPrintFormatter"]),
   classID: Components.ID("{f42d5132-92c4-487b-b5c8-38bf292d74c1}"),
 
   get name() {
     return cal.l10n.getCalString("monthPrinterName");
   },
 
   formatToHtml(aStream, aStart, aEnd, aItems, aTitle) {
     let document = cal.xml.parseFile("chrome://calendar/content/printing/calMonthGridPrinter.html");
--- a/calendar/import-export/CalOutlookCSVImportExport.jsm
+++ b/calendar/import-export/CalOutlookCSVImportExport.jsm
@@ -88,17 +88,17 @@ function getOutlookCsvFileTypes() {
   ];
 }
 
 // Importer
 function CalOutlookCSVImporter() {
   this.wrappedJSObject = this;
 }
 CalOutlookCSVImporter.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIImporter]),
+  QueryInterface: ChromeUtils.generateQI(["calIImporter"]),
   classID: Components.ID("{64a5d17a-0497-48c5-b54f-72b15c9e9a14}"),
 
   getFileTypes: getOutlookCsvFileTypes,
 
   /**
    * Takes a text block of Outlook-exported Comma Separated Values and tries to
    * parse that into individual events.
    *
@@ -443,17 +443,17 @@ CalOutlookCSVImporter.prototype = {
   parseTextField(aTextField) {
     return aTextField ? aTextField.replace(/""/g, '"') : "";
   },
 };
 
 // Exporter
 function CalOutlookCSVExporter() {}
 CalOutlookCSVExporter.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIExporter]),
+  QueryInterface: ChromeUtils.generateQI(["calIExporter"]),
   classID: Components.ID("{48e6d3a6-b41b-4052-9ed2-40b27800bd4b}"),
 
   getFileTypes: getOutlookCsvFileTypes,
 
   exportToStream(aStream, aItems, aTitle) {
     // Helper functions
     function dateString(aDateTime) {
       return cal.dtz.dateTimeToJsDate(aDateTime).toLocaleString("en-US", localeEn.dateFormat);
--- a/calendar/import-export/CalWeekPrinter.jsm
+++ b/calendar/import-export/CalWeekPrinter.jsm
@@ -10,17 +10,17 @@ var { cal } = ChromeUtils.import("resour
 /**
  * Prints a two column view of a week of events, much like a paper day-planner
  */
 function CalWeekPrinter() {
   this.wrappedJSObject = this;
 }
 
 CalWeekPrinter.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIPrintFormatter]),
+  QueryInterface: ChromeUtils.generateQI(["calIPrintFormatter"]),
   classID: Components.ID("{2d6ec97b-9109-4b92-89c5-d4b4806619ce}"),
 
   get name() {
     return cal.l10n.getCalString("weekPrinterName");
   },
 
   formatToHtml(aStream, aStart, aEnd, aItems, aTitle) {
     let document = cal.xml.parseFile("chrome://calendar/content/printing/calWeekPrinter.html");
--- a/calendar/itip/CalItipEmailTransport.jsm
+++ b/calendar/itip/CalItipEmailTransport.jsm
@@ -9,17 +9,17 @@ var { cal } = ChromeUtils.import("resour
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { ltn } = ChromeUtils.import("resource:///modules/calendar/ltnInvitationUtils.jsm");
 
 function CalItipEmailTransport() {
   this.wrappedJSObject = this;
   this._initEmailTransport();
 }
 CalItipEmailTransport.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIItipTransport]),
+  QueryInterface: ChromeUtils.generateQI(["calIItipTransport"]),
   classID: Components.ID("{d4d7b59e-c9e0-4a7a-b5e8-5958f85515f0}"),
 
   mHasXpcomMail: false,
   mDefaultAccount: null,
   mDefaultIdentity: null,
   mDefaultSmtpServer: null,
 
   get scheme() {
--- a/calendar/lightning/components/CalItipProtocolHandler.jsm
+++ b/calendar/lightning/components/CalItipProtocolHandler.jsm
@@ -15,17 +15,17 @@ function NYI() {
 }
 
 function ItipChannel(URI, aLoadInfo) {
   this.wrappedJSObject = this;
   this.URI = this.originalURI = URI;
   this.loadInfo = aLoadInfo;
 }
 ItipChannel.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest]),
+  QueryInterface: ChromeUtils.generateQI(["nsIChannel", "nsIRequest"]),
   classID: Components.ID("{643e0328-36f6-411d-a107-16238dff9cd7}"),
 
   contentType: ITIP_HANDLER_MIMETYPE,
   loadAttributes: null,
   contentLength: 0,
   owner: null,
   loadGroup: null,
   notificationCallbacks: null,
@@ -49,33 +49,33 @@ ItipChannel.prototype = {
   suspend: NYI,
   resume: NYI,
 };
 
 function ItipProtocolHandler() {
   this.wrappedJSObject = this;
 }
 ItipProtocolHandler.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIProtocolHandler]),
+  QueryInterface: ChromeUtils.generateQI(["nsIProtocolHandler"]),
   classID: Components.ID("{6e957006-b4ce-11d9-b053-001124736B74}"),
 
   protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE | Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD,
   allowPort: () => false,
   isSecure: false,
   newChannel(URI, aLoadInfo) {
     dump("Creating new ItipChannel for " + URI + "\n");
     return new ItipChannel(URI, aLoadInfo);
   },
 };
 
 function ItipContentHandler() {
   this.wrappedJSObject = this;
 }
 ItipContentHandler.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIContentHandler]),
+  QueryInterface: ChromeUtils.generateQI(["nsIContentHandler"]),
   classID: Components.ID("{47c31f2b-b4de-11d9-bfe6-001124736B74}"),
 
   handleContent(contentType, windowTarget, request) {
     let channel = request.QueryInterface(Ci.nsIChannel);
     let uri = channel.URI.spec;
     if (!uri.startsWith(ITIP_HANDLER_PROTOCOL + ":")) {
       cal.ERROR("Unexpected iTIP uri: " + uri + "\n");
       throw NS_ERROR_WONT_HANDLE_CONTENT;
--- a/calendar/lightning/components/CalMimeConverter.jsm
+++ b/calendar/lightning/components/CalMimeConverter.jsm
@@ -8,17 +8,17 @@ var { Services } = ChromeUtils.import("r
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 var { ltn } = ChromeUtils.import("resource:///modules/calendar/ltnInvitationUtils.jsm");
 
 function CalMimeConverter() {
   this.wrappedJSObject = this;
 }
 
 CalMimeConverter.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsISimpleMimeConverter]),
+  QueryInterface: ChromeUtils.generateQI(["nsISimpleMimeConverter"]),
   classID: Components.ID("{c70acb08-464e-4e55-899d-b2c84c5409fa}"),
 
   uri: null,
 
   convertToHTML(contentType, data) {
     let parser = Cc["@mozilla.org/calendar/ics-parser;1"].createInstance(Ci.calIIcsParser);
     parser.parseString(data);
     let event = null;
--- a/calendar/lightning/content/imip-bar.js
+++ b/calendar/lightning/content/imip-bar.js
@@ -352,17 +352,17 @@ var ltnImipBar = {
           aParticipantStatus = "";
         }
         // hide the buttons now, to disable pressing them twice...
         if (aPartStat == aParticipantStatus) {
           ltnImipBar.resetButtons();
         }
 
         let opListener = {
-          QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+          QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
           onOperationComplete(aCalendar, aStatus, aOperationType, aId, aDetail) {
             if (Components.isSuccessCode(aStatus) && isDeclineCounter) {
               // TODO: move the DECLINECOUNTER stuff to actionFunc
               aItipItem.getItemList().forEach(aItem => {
                 // we can rely on the received itipItem to reply at this stage
                 // already, the checks have been done in cal.itip.processFoundItems
                 // when setting up the respective aActionFunc
                 let attendees = cal.itip.getAttendeesBySender(
--- a/calendar/lightning/content/lightning-item-iframe.js
+++ b/calendar/lightning/content/lightning-item-iframe.js
@@ -3255,17 +3255,17 @@ function onCommandSave(aIsClosing) {
   // When the call is complete, we need to set the new item, so that the
   // dialog is up to date.
 
   // XXX Do we want to disable the dialog or at least the save button until
   // the call is complete? This might help when the user tries to save twice
   // before the call is complete. In that case, we do need a progress bar and
   // the ability to cancel the operation though.
   let listener = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+    QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
     onOperationComplete(aCalendar, aStatus, aOpType, aId, aItem) {
       // Check if the current window has a calendarItem first, because in case of undo
       // window refers to the main window and we would get a 'calendarItem is undefined' warning.
       if (!aIsClosing && "calendarItem" in window) {
         // If we changed the calendar of the item, onOperationComplete will be called multiple
         // times. We need to make sure we're receiving the update on the right calendar.
         if (
           (!window.calendarItem.id || aId == window.calendarItem.id) &&
--- a/calendar/providers/caldav/CalDavCalendar.jsm
+++ b/calendar/providers/caldav/CalDavCalendar.jsm
@@ -72,17 +72,26 @@ var calDavCalendarInterfaces = [
   Ci.calISchedulingSupport,
   Ci.calICalendar,
   Ci.calIChangeLog,
   Ci.calICalDavCalendar,
 ];
 CalDavCalendar.prototype = {
   __proto__: cal.provider.BaseClass.prototype,
   classID: calDavCalendarClassID,
-  QueryInterface: cal.generateQI(calDavCalendarInterfaces),
+  QueryInterface: cal.generateQI([
+    "calICalendarProvider",
+    "nsIInterfaceRequestor",
+    "calIFreeBusyProvider",
+    "calIItipTransport",
+    "calISchedulingSupport",
+    "calICalendar",
+    "calIChangeLog",
+    "calICalDavCalendar",
+  ]),
   classInfo: cal.generateCI({
     classID: calDavCalendarClassID,
     contractID: "@mozilla.org/calendar/calendar;1?type=caldav",
     classDescription: "Calendar CalDAV back-end",
     interfaces: calDavCalendarInterfaces,
   }),
 
   // An array of components that are supported by the server. The default is
@@ -251,17 +260,17 @@ CalDavCalendar.prototype = {
   /**
    * Ensure that cached items have associated meta data, otherwise server side
    * changes may not be reflected
    */
   ensureMetaData() {
     let self = this;
     let refreshNeeded = false;
     let getMetaListener = {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+      QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
       onGetResult(aCalendar, aStatus, aItemType, aDetail, aItems) {
         for (let item of aItems) {
           if (!(item.id in self.mItemInfoCache)) {
             let path = self.getItemLocationPath(item);
             cal.LOG("Adding meta-data for cached item " + item.id);
             self.mItemInfoCache[item.id] = {
               etag: null,
               isNew: false,
@@ -1173,17 +1182,17 @@ CalDavCalendar.prototype = {
       if (this.isCached && aChangeLogListener) {
         aChangeLogListener.onResult({ status }, status);
       }
     };
 
     if (!this.mACLEntry) {
       let self = this;
       let opListener = {
-        QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+        QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
         onGetResult(calendar, status, itemType, detail, items) {
           cal.ASSERT(false, "unexpected!");
         },
         onOperationComplete(opCalendar, opStatus, opType, opId, opDetail) {
           self.mACLEntry = opDetail;
           self.fillACLProperties();
           self.safeRefresh(aChangeLogListener);
         },
@@ -2119,17 +2128,17 @@ CalDavCalendar.prototype = {
   //
 
   processItipReply(aItem, aPath) {
     // modify partstat for in-calendar item
     // delete item from inbox
     let self = this;
 
     let getItemListener = {};
-    getItemListener.QueryInterface = ChromeUtils.generateQI([Ci.calIOperationListener]);
+    getItemListener.QueryInterface = ChromeUtils.generateQI(["calIOperationListener"]);
     getItemListener.onOperationComplete = function(
       aCalendar,
       aStatus,
       aOperationType,
       aId,
       aDetail
     ) {};
     getItemListener.onGetResult = function(aCalendar, aStatus, aItemType, aDetail, aItems) {
@@ -2152,17 +2161,17 @@ CalDavCalendar.prototype = {
         newItem,
         itemToUpdate.parentItem /* related to bug 396182 */,
         modListener,
         true
       );
     };
 
     let modListener = {};
-    modListener.QueryInterface = ChromeUtils.generateQI([Ci.calIOperationListener]);
+    modListener.QueryInterface = ChromeUtils.generateQI(["calIOperationListener"]);
     modListener.onOperationComplete = function(
       aCalendar,
       aStatus,
       aOperationType,
       aItemId,
       aDetail
     ) {
       cal.LOG(`CalDAV: status ${aStatus} while processing iTIP REPLY for ${self.name}`);
--- a/calendar/providers/caldav/modules/CalDavRequestHandlers.jsm
+++ b/calendar/providers/caldav/modules/CalDavRequestHandlers.jsm
@@ -49,20 +49,20 @@ CalDavEtagsHandler.prototype = {
   baseUri: null,
   changeLogListener: null,
   logXML: "",
 
   itemsReported: null,
   itemsNeedFetching: null,
 
   QueryInterface: cal.generateQI([
-    Ci.nsISAXContentHandler,
-    Ci.nsISAXErrorHandler,
-    Ci.nsIRequestObserver,
-    Ci.nsIStreamListener,
+    "nsISAXContentHandler",
+    "nsISAXErrorHandler",
+    "nsIRequestObserver",
+    "nsIStreamListener",
   ]),
 
   /**
    * @see nsIRequestObserver
    */
   onStartRequest(request) {
     let httpchannel = request.QueryInterface(Ci.nsIHttpChannel);
 
@@ -311,20 +311,20 @@ CalDavWebDavSyncHandler.prototype = {
   isInPropStat: false,
   changeCount: 0,
   unhandledErrors: 0,
   itemsReported: null,
   itemsNeedFetching: null,
   additionalSyncNeeded: false,
 
   QueryInterface: cal.generateQI([
-    Ci.nsISAXContentHandler,
-    Ci.nsISAXErrorHandler,
-    Ci.nsIRequestObserver,
-    Ci.nsIStreamListener,
+    "nsISAXContentHandler",
+    "nsISAXErrorHandler",
+    "nsIRequestObserver",
+    "nsIStreamListener",
   ]),
 
   doWebDAVSync() {
     if (this.calendar.mDisabled) {
       // check if maybe our calendar has become available
       this.calendar.checkDavResourceType(this.changeLogListener);
       return;
     }
@@ -717,20 +717,20 @@ CalDavMultigetSyncHandler.prototype = {
   changeLogListener: null,
   logXML: null,
   unhandledErrors: 0,
   itemsNeedFetching: null,
   additionalSyncNeeded: false,
   timer: null,
 
   QueryInterface: cal.generateQI([
-    Ci.nsISAXContentHandler,
-    Ci.nsISAXErrorHandler,
-    Ci.nsIRequestObserver,
-    Ci.nsIStreamListener,
+    "nsISAXContentHandler",
+    "nsISAXErrorHandler",
+    "nsIRequestObserver",
+    "nsIStreamListener",
   ]),
 
   doMultiGet() {
     if (this.calendar.mDisabled) {
       // check if maybe our calendar has become available
       this.calendar.checkDavResourceType(this.changeLogListener);
       return;
     }
--- a/calendar/providers/composite/CalCompositeCalendar.jsm
+++ b/calendar/providers/composite/CalCompositeCalendar.jsm
@@ -14,17 +14,17 @@ var calIOperationListener = Ci.calIOpera
 function calCompositeCalendarObserverHelper(compCalendar) {
   this.compCalendar = compCalendar;
   this.pendingLoads = {};
 }
 
 calCompositeCalendarObserverHelper.prototype = {
   pendingLoads: null,
 
-  QueryInterface: ChromeUtils.generateQI([Ci.calIObserver]),
+  QueryInterface: ChromeUtils.generateQI(["calIObserver"]),
 
   onStartBatch() {
     this.compCalendar.mObservers.notify("onStartBatch");
   },
 
   onEndBatch() {
     this.compCalendar.mObservers.notify("onEndBatch");
   },
@@ -75,19 +75,19 @@ function CalCompositeCalendar() {
   this.mCompositeObservers = new cal.data.ObserverSet(Ci.calICompositeObserver);
   this.mObservers = new cal.data.ObserverSet(Ci.calIObserver);
   this.mDefaultCalendar = null;
   this.mStatusObserver = null;
 }
 
 var calCompositeCalendarClassID = Components.ID("{aeff788d-63b0-4996-91fb-40a7654c6224}");
 var calCompositeCalendarInterfaces = [
-  Ci.calICalendarProvider,
-  Ci.calICalendar,
-  Ci.calICompositeCalendar,
+  "calICalendarProvider",
+  "calICalendar",
+  "calICompositeCalendar",
 ];
 CalCompositeCalendar.prototype = {
   classID: calCompositeCalendarClassID,
   QueryInterface: ChromeUtils.generateQI(calCompositeCalendarInterfaces),
 
   //
   // calICalendarProvider interface
   //
@@ -426,17 +426,17 @@ function calCompositeGetListenerHelper(a
   this.wrappedJSObject = this;
   this.mCompositeCalendar = aCompositeCalendar;
   this.mNumQueries = aCompositeCalendar.enabledCalendars.length;
   this.mRealListener = aRealListener;
   this.mMaxItems = aMaxItems;
 }
 
 calCompositeGetListenerHelper.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+  QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
 
   mNumQueries: 0,
   mRealListener: null,
   mOpGroup: null,
   mReceivedCompletes: 0,
   mFinished: false,
   mMaxItems: 0,
   mItemsReceived: 0,
--- a/calendar/providers/ics/CalICSCalendar.jsm
+++ b/calendar/providers/ics/CalICSCalendar.jsm
@@ -43,17 +43,25 @@ var calICSCalendarInterfaces = [
   Ci.nsIStreamListener,
   Ci.nsIStreamLoaderObserver,
   Ci.nsIChannelEventSink,
   Ci.nsIInterfaceRequestor,
 ];
 CalICSCalendar.prototype = {
   __proto__: cal.provider.BaseClass.prototype,
   classID: calICSCalendarClassID,
-  QueryInterface: cal.generateQI(calICSCalendarInterfaces),
+  QueryInterface: cal.generateQI([
+    "calICalendarProvider",
+    "calICalendar",
+    "calISchedulingSupport",
+    "nsIStreamListener",
+    "nsIStreamLoaderObserver",
+    "nsIChannelEventSink",
+    "nsIInterfaceRequestor",
+  ]),
   classInfo: cal.generateCI({
     classID: calICSCalendarClassID,
     contractID: "@mozilla.org/calendar/calendar;1?type=ics",
     classDescription: "Calendar ICS provider",
     interfaces: calICSCalendarInterfaces,
   }),
 
   mObserver: null,
--- a/calendar/providers/memory/CalMemoryCalendar.jsm
+++ b/calendar/providers/memory/CalMemoryCalendar.jsm
@@ -18,17 +18,23 @@ var calMemoryCalendarInterfaces = [
   Ci.calISchedulingSupport,
   Ci.calIOfflineStorage,
   Ci.calISyncWriteCalendar,
   Ci.calICalendarProvider,
 ];
 CalMemoryCalendar.prototype = {
   __proto__: cal.provider.BaseClass.prototype,
   classID: calMemoryCalendarClassID,
-  QueryInterface: cal.generateQI(calMemoryCalendarInterfaces),
+  QueryInterface: cal.generateQI([
+    "calICalendar",
+    "calISchedulingSupport",
+    "calIOfflineStorage",
+    "calISyncWriteCalendar",
+    "calICalendarProvider",
+  ]),
   classInfo: cal.generateCI({
     classID: calMemoryCalendarClassID,
     contractID: "@mozilla.org/calendar/calendar;1?type=memory",
     classDescription: "Calendar Memory Provider",
     interfaces: calMemoryCalendarInterfaces,
   }),
 
   mItems: null,
--- a/calendar/providers/storage/CalStorageCalendar.jsm
+++ b/calendar/providers/storage/CalStorageCalendar.jsm
@@ -28,17 +28,23 @@ var calStorageCalendarInterfaces = [
   Ci.calICalendarProvider,
   Ci.calIOfflineStorage,
   Ci.calISchedulingSupport,
   Ci.calISyncWriteCalendar,
 ];
 CalStorageCalendar.prototype = {
   __proto__: cal.provider.BaseClass.prototype,
   classID: calStorageCalendarClassID,
-  QueryInterface: cal.generateQI(calStorageCalendarInterfaces),
+  QueryInterface: cal.generateQI([
+    "calICalendar",
+    "calICalendarProvider",
+    "calIOfflineStorage",
+    "calISchedulingSupport",
+    "calISyncWriteCalendar",
+  ]),
   classInfo: cal.generateCI({
     classID: calStorageCalendarClassID,
     contractID: "@mozilla.org/calendar/calendar;1?type=storage",
     classDescription: "Calendar Storage Provider",
     interfaces: calStorageCalendarInterfaces,
   }),
 
   //
@@ -905,17 +911,17 @@ CalStorageCalendar.prototype = {
       aItem.id,
       aItem
     );
   },
 
   modifyOfflineItem(aItem, aListener) {
     let self = this;
     let opListener = {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+      QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
       onGetResult(calendar, status, itemType, detail, items) {},
       async onOperationComplete(calendar, status, opType, id, oldOfflineJournalFlag) {
         let newOfflineJournalFlag = cICL.OFFLINE_FLAG_MODIFIED_RECORD;
         if (
           oldOfflineJournalFlag == cICL.OFFLINE_FLAG_CREATED_RECORD ||
           oldOfflineJournalFlag == cICL.OFFLINE_FLAG_DELETED_RECORD
         ) {
           // Do nothing since a flag of "created" or "deleted" exists
@@ -932,17 +938,17 @@ CalStorageCalendar.prototype = {
       },
     };
     this.getItemOfflineFlag(aItem, opListener);
   },
 
   deleteOfflineItem(aItem, aListener) {
     let self = this;
     let opListener = {
-      QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+      QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
       onGetResult(calendar, status, itemType, detail, items) {},
       async onOperationComplete(calendar, status, opType, id, oldOfflineJournalFlag) {
         if (oldOfflineJournalFlag) {
           // Delete item if flag is c
           if (oldOfflineJournalFlag == cICL.OFFLINE_FLAG_CREATED_RECORD) {
             await self.deleteItemById(aItem.id);
           } else if (oldOfflineJournalFlag == cICL.OFFLINE_FLAG_MODIFIED_RECORD) {
             await self.setOfflineJournalFlag(aItem, cICL.OFFLINE_FLAG_DELETED_RECORD);
--- a/calendar/resources/content/publish.js
+++ b/calendar/resources/content/publish.js
@@ -101,17 +101,17 @@ function publishEntireCalendar(aCalendar
  * presses the OK button in the publish dialog.
  */
 function publishEntireCalendarDialogResponse(CalendarPublishObject, aProgressDialog) {
   // store the selected remote ics path as a calendar preference
   CalendarPublishObject.calendar.setProperty("remote-ics-path", CalendarPublishObject.remotePath);
 
   let itemArray = [];
   let getListener = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calIOperationListener]),
+    QueryInterface: ChromeUtils.generateQI(["calIOperationListener"]),
     onOperationComplete(aCalendar, aStatus, aOperationType, aId, aDetail) {
       publishItemArray(itemArray, CalendarPublishObject.remotePath, aProgressDialog);
     },
     onGetResult(aCalendar, aStatus, aItemType, aDetail, aItems) {
       if (!Components.isSuccessCode(aStatus)) {
         return;
       }
       if (aItems.length) {
--- a/calendar/test/browser/browser_calendarList.js
+++ b/calendar/test/browser/browser_calendarList.js
@@ -40,17 +40,17 @@ async function withModalDialog(trigger, 
   });
   let triggerPromise = trigger();
   return Promise.all([callbackPromise, triggerPromise]);
 }
 
 async function withMockPromptService(response, callback) {
   let realPrompt = Services.prompt;
   Services.prompt = {
-    QueryInterface: ChromeUtils.generateQI([Ci.nsIPromptService]),
+    QueryInterface: ChromeUtils.generateQI(["nsIPromptService"]),
     confirmEx: (unused1, unused2, text) => {
       info(text);
       return response;
     },
   };
   await callback();
   Services.prompt = realPrompt;
 }
--- a/calendar/test/unit/test_alarmservice.js
+++ b/calendar/test/unit/test_alarmservice.js
@@ -8,17 +8,17 @@ var EXPECT_NONE = 0;
 var EXPECT_FIRED = 1;
 var EXPECT_TIMER = 2;
 
 function do_check_xor(a, b, aMessage) {
   return ok((a && !b) || (!a && b), aMessage);
 }
 
 var alarmObserver = {
-  QueryInterface: ChromeUtils.generateQI([Ci.calIAlarmServiceObserver]),
+  QueryInterface: ChromeUtils.generateQI(["calIAlarmServiceObserver"]),
 
   service: null,
   firedMap: {},
   expectedMap: {},
   pendingOps: {},
 
   onAlarm(aItem, aAlarm) {
     this.firedMap[aItem.hashId] = this.firedMap[aItem.hashId] || {};
--- a/calendar/test/unit/test_freebusy_service.js
+++ b/calendar/test/unit/test_freebusy_service.js
@@ -132,17 +132,17 @@ function test_failure() {
     listener
   );
 }
 
 function test_cancel() {
   _clearProviders();
 
   let provider = {
-    QueryInterface: cal.generateQI([Ci.calIFreeBusyProvider, Ci.calIOperation]),
+    QueryInterface: cal.generateQI(["calIFreeBusyProvider", "calIOperation"]),
     getFreeBusyIntervals(aCalId, aStart, aEnd, aTypes, aListener) {
       Services.tm.currentThread.dispatch(
         {
           run() {
             dump("Cancelling freebusy query...");
             operation.cancel();
           },
         },
--- a/calendar/test/unit/test_items.js
+++ b/calendar/test/unit/test_items.js
@@ -14,17 +14,17 @@ function really_run_test() {
   test_attachment();
   test_lastack();
   test_categories();
   test_alarm();
 }
 
 function test_aclmanager() {
   let mockCalendar = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calICalendar]),
+    QueryInterface: ChromeUtils.generateQI(["calICalendar"]),
 
     get superCalendar() {
       return this;
     },
     get aclManager() {
       return this;
     },
 
@@ -32,17 +32,17 @@ function test_aclmanager() {
       if (item.id == "withentry") {
         return itemEntry;
       }
       return null;
     },
   };
 
   let itemEntry = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calIItemACLEntry]),
+    QueryInterface: ChromeUtils.generateQI(["calIItemACLEntry"]),
     userCanModify: true,
     userCanRespond: false,
     userCanViewAll: true,
     userCanViewDateAndTime: false,
   };
 
   let event = cal.createEvent();
   event.id = "withentry";
@@ -69,17 +69,17 @@ function test_aclmanager() {
   equal(event.aclEntry, null);
 }
 
 function test_calendar() {
   let event = cal.createEvent();
   let parentEntry = cal.createEvent();
 
   let mockCalendar = {
-    QueryInterface: ChromeUtils.generateQI([Ci.calICalendar]),
+    QueryInterface: ChromeUtils.generateQI(["calICalendar"]),
     id: "one",
   };
 
   parentEntry.calendar = mockCalendar;
   event.parentItem = parentEntry;
 
   notEqual(event.calendar, null);
   equal(event.calendar.id, "one");
--- a/calendar/test/unit/test_search_service.js
+++ b/calendar/test/unit/test_search_service.js
@@ -88,17 +88,17 @@ function test_failure() {
   search.searchForCalendars("str", HINT_EXACT_MATCH, 0, listener);
   ok(listener.called);
 }
 
 function test_cancel() {
   search.getProviders().forEach(search.removeProvider, search);
 
   let provider = {
-    QueryInterface: cal.generateQI([Ci.calICalendarSearchProvider, Ci.calIOperation]),
+    QueryInterface: cal.generateQI(["calICalendarSearchProvider", "calIOperation"]),
     searchForCalendars(aStr, aHint, aMax, aListener) {
       Services.tm.currentThread.dispatch(
         {
           run() {
             dump("Cancelling search...");
             operation.cancel();
           },
         },
--- a/chat/components/src/imAccounts.jsm
+++ b/chat/components/src/imAccounts.jsm
@@ -1291,11 +1291,11 @@ AccountsService.prototype = {
     /* Update the account list pref. */
     let list = this._accountList;
     this._accountList = list
       .split(",")
       .filter(k => k.trim() != aAccountId)
       .join(",");
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.imIAccountsService]),
+  QueryInterface: ChromeUtils.generateQI(["imIAccountsService"]),
   classDescription: "Accounts",
 };
--- a/chat/components/src/imCommands.jsm
+++ b/chat/components/src/imCommands.jsm
@@ -280,11 +280,11 @@ CommandsService.prototype = {
     // them in order until one succeeds.
     if (!cmdArray.some(aCmd => aCmd.run(args, aConversation, aReturnedConv))) {
       // If they all failed, print help message.
       this.executeCommand("/help " + name, aConversation);
     }
     return true;
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.imICommandsService]),
+  QueryInterface: ChromeUtils.generateQI(["imICommandsService"]),
   classDescription: "Commands",
 };
--- a/chat/components/src/imContacts.jsm
+++ b/chat/components/src/imContacts.jsm
@@ -196,17 +196,17 @@ TagsService.prototype = {
   showTag(aTag) {
     otherContactsTag.showTag(aTag);
   },
   get otherContactsTag() {
     otherContactsTag._initContacts();
     return otherContactsTag;
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.imITagsService]),
+  QueryInterface: ChromeUtils.generateQI(["imITagsService"]),
   classDescription: "Tags",
 };
 
 // TODO move into the tagsService
 var Tags = [];
 var TagsById = {};
 
 function Tag(aId, aName) {
@@ -1793,11 +1793,11 @@ ContactsService.prototype = {
     try {
       statement.params.accountId = aId;
       statement.execute();
     } finally {
       statement.finalize();
     }
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.imIContactsService]),
+  QueryInterface: ChromeUtils.generateQI(["imIContactsService"]),
   classDescription: "Contacts",
 };
--- a/chat/components/src/imConversations.jsm
+++ b/chat/components/src/imConversations.jsm
@@ -855,11 +855,11 @@ ConversationsService.prototype = {
         conv.isChat == aIsChat
       ) {
         return conv;
       }
     }
     return null;
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.imIConversationsService]),
+  QueryInterface: ChromeUtils.generateQI(["imIConversationsService"]),
   classDescription: "Conversations",
 };
--- a/chat/components/src/imCore.jsm
+++ b/chat/components/src/imCore.jsm
@@ -406,11 +406,11 @@ CoreService.prototype = {
       Cu.reportError("Could not initialize protocol " + aPrplId + ": " + e);
       return null;
     }
 
     this._protos[aPrplId] = proto;
     return proto;
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.imICoreService]),
+  QueryInterface: ChromeUtils.generateQI(["imICoreService"]),
   classDescription: "Core",
 };
--- a/chat/components/src/logger.jsm
+++ b/chat/components/src/logger.jsm
@@ -561,17 +561,17 @@ LogConversation.prototype = {
       _conv: this,
       _messages: this._messages,
       hasMoreElements() {
         return this._index < this._messages.length;
       },
       getNext() {
         return new LogMessage(this._messages[this._index++], this._conv);
       },
-      QueryInterface: ChromeUtils.generateQI([Ci.nsISimpleEnumerator]),
+      QueryInterface: ChromeUtils.generateQI(["nsISimpleEnumerator"]),
       *[Symbol.iterator]() {
         while (this.hasMoreElements()) {
           yield this.getNext();
         }
       },
     };
     return enumerator;
   },
@@ -773,17 +773,17 @@ DailyLogEnumerator.prototype = {
   _index: 0,
   hasMoreElements() {
     return this._index < this._days.length;
   },
   getNext() {
     let dayID = this._days[this._index++];
     return new Log(this._entries[dayID]);
   },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsISimpleEnumerator]),
+  QueryInterface: ChromeUtils.generateQI(["nsISimpleEnumerator"]),
   *[Symbol.iterator]() {
     while (this.hasMoreElements()) {
       yield this.getNext();
     }
   },
 };
 
 function LogEnumerator(aEntries) {
@@ -794,17 +794,17 @@ LogEnumerator.prototype = {
   _entries: [],
   hasMoreElements() {
     return this._entries.length > 0;
   },
   getNext() {
     // Create and return a log from the first entry.
     return new Log(this._entries.shift().path);
   },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsISimpleEnumerator]),
+  QueryInterface: ChromeUtils.generateQI(["nsISimpleEnumerator"]),
   *[Symbol.iterator]() {
     while (this.hasMoreElements()) {
       yield this.getNext();
     }
   },
 };
 
 function Logger() {}
@@ -1124,11 +1124,11 @@ Logger.prototype = {
           nameText + " is now " + status
         );
         break;
       default:
         throw new Error("Unexpected notification " + aTopic);
     }
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver, Ci.imILogger]),
+  QueryInterface: ChromeUtils.generateQI(["nsIObserver", "imILogger"]),
   classDescription: "Logger",
 };
--- a/chat/components/src/smileProtocolHandler.jsm
+++ b/chat/components/src/smileProtocolHandler.jsm
@@ -27,11 +27,11 @@ smileProtocolHandler.prototype = {
     let channel = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
     channel.originalURI = aURI;
     return channel;
   },
   allowPort(aPort, aScheme) {
     return false;
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIProtocolHandler]),
+  QueryInterface: ChromeUtils.generateQI(["nsIProtocolHandler"]),
   classDescription: "Smile Protocol Handler",
 };
--- a/chat/content/chat-tooltip.js
+++ b/chat/content/chat-tooltip.js
@@ -51,18 +51,18 @@
             data == this.observedUserInfo
           ) {
             this.updateTooltipInfo(
               subject.QueryInterface(Ci.nsISimpleEnumerator)
             );
           }
         },
         QueryInterface: ChromeUtils.generateQI([
-          Ci.nsIObserver,
-          Ci.nsISupportsWeakReference,
+          "nsIObserver",
+          "nsISupportsWeakReference",
         ]),
       };
 
       this.addEventListener("popupshowing", event => {
         if (!this._onPopupShowing()) {
           event.preventDefault();
         }
       });
--- a/chat/content/conversation-browser.js
+++ b/chat/content/conversation-browser.js
@@ -107,18 +107,18 @@
           curTotal,
           maxTotal
         ) {},
         onLocationChange(aprogress, request, location) {},
         onStatusChange(progress, request, status, message) {},
         onSecurityChange(progress, request, state) {},
         onContentBlockingEvent(progress, request, event) {},
         QueryInterface: ChromeUtils.generateQI([
-          Ci.nsIWebProgressListener,
-          Ci.nsISupportsWeakReference,
+          "nsIWebProgressListener",
+          "nsISupportsWeakReference",
         ]),
       };
 
       // Make sure to load URLs externally.
       this.addEventListener("click", event => {
         // Right click should open the context menu.
         if (event.button == 2) {
           return;
@@ -256,17 +256,17 @@
             return;
           }
 
           Cc["@mozilla.org/widget/clipboardhelper;1"]
             .getService(Ci.nsIClipboardHelper)
             .copyString(serializeSelection(selection));
         },
         onEvent(command) {},
-        QueryInterface: ChromeUtils.generateQI([Ci.nsIController]),
+        QueryInterface: ChromeUtils.generateQI(["nsIController"]),
       };
 
       // @implements {nsISelectionListener}
       this.chatSelectionListener = {
         notifySelectionChanged(document, selection, reason) {
           if (
             !(
               reason & Ci.nsISelectionListener.MOUSEUP_REASON ||
@@ -280,17 +280,17 @@
 
           Cc["@mozilla.org/widget/clipboardhelper;1"]
             .getService(Ci.nsIClipboardHelper)
             .copyStringToClipboard(
               serializeSelection(selection),
               Ci.nsIClipboard.kSelectionClipboard
             );
         },
-        QueryInterface: ChromeUtils.generateQI([Ci.nsISelectionListener]),
+        QueryInterface: ChromeUtils.generateQI(["nsISelectionListener"]),
       };
     }
 
     init(conversation) {
       // Magic Copy may be initialized if the convbrowser is already
       // displaying a conversation.
       this.uninitMagicCopy();
 
--- a/chat/modules/imXPCOMUtils.jsm
+++ b/chat/modules/imXPCOMUtils.jsm
@@ -262,22 +262,22 @@ nsSimpleEnumerator.prototype = {
   },
   getNext() {
     if (!this.hasMoreElements()) {
       throw Components.Exception("", Cr.NS_ERROR_NOT_AVAILABLE);
     }
 
     return this._items[this._nextIndex++];
   },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsISimpleEnumerator]),
+  QueryInterface: ChromeUtils.generateQI(["nsISimpleEnumerator"]),
   [Symbol.iterator]() {
     return this._items.values();
   },
 };
 
 var EmptyEnumerator = {
   hasMoreElements: () => false,
   getNext() {
     throw Components.Exception("", Cr.NS_ERROR_NOT_AVAILABLE);
   },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsISimpleEnumerator]),
+  QueryInterface: ChromeUtils.generateQI(["nsISimpleEnumerator"]),
   *[Symbol.iterator]() {},
 };
--- a/chat/modules/jsProtoHelper.jsm
+++ b/chat/modules/jsProtoHelper.jsm
@@ -216,17 +216,17 @@ var GenericAccountPrototype = {
           this,
           "buddy-authorization-request-canceled"
         );
         this._remove();
       },
       _remove() {
         this._account.removeBuddyRequest(this);
       },
-      QueryInterface: ChromeUtils.generateQI([Ci.prplIBuddyRequest]),
+      QueryInterface: ChromeUtils.generateQI(["prplIBuddyRequest"]),
     };
     this._pendingBuddyRequests.push(buddyRequest);
     Services.obs.notifyObservers(buddyRequest, "buddy-authorization-request");
   },
   removeBuddyRequest(aRequest) {
     if (!this._pendingBuddyRequests) {
       return;
     }
@@ -1188,17 +1188,17 @@ var GenericProtocolPrototype = {
       return;
     }
 
     this.commands.forEach(function(command) {
       if (!command.hasOwnProperty("name") || !command.hasOwnProperty("run")) {
         throw new Error("Every command must have a name and a run function.");
       }
       if (!("QueryInterface" in command)) {
-        command.QueryInterface = ChromeUtils.generateQI([Ci.imICommand]);
+        command.QueryInterface = ChromeUtils.generateQI(["imICommand"]);
       }
       if (!command.hasOwnProperty("usageContext")) {
         command.usageContext = Ci.imICommand.CMD_CONTEXT_ALL;
       }
       if (!command.hasOwnProperty("priority")) {
         command.priority = Ci.imICommand.CMD_PRIORITY_PRPL;
       }
       Services.cmd.registerCommand(command, this.id);
--- a/chat/protocols/twitter/twitter.jsm
+++ b/chat/protocols/twitter/twitter.jsm
@@ -1165,18 +1165,18 @@ Account.prototype = {
       },
       loaded(aWindow, aWebProgress) {
         if (!this._active) {
           return;
         }
 
         this._listener = {
           QueryInterface: ChromeUtils.generateQI([
-            Ci.nsIWebProgressListener,
-            Ci.nsISupportsWeakReference,
+            "nsIWebProgressListener",
+            "nsISupportsWeakReference",
           ]),
           _cleanUp() {
             this.webProgress.removeProgressListener(this);
             this.window.close();
             delete this.window;
           },
           _checkForRedirect(aURL) {
             if (!aURL.startsWith(this._parent.completionURI)) {
@@ -1203,17 +1203,17 @@ Account.prototype = {
           webProgress: aWebProgress,
           _parent: this.account,
         };
         aWebProgress.addProgressListener(
           this._listener,
           Ci.nsIWebProgress.NOTIFY_ALL
         );
       },
-      QueryInterface: ChromeUtils.generateQI([Ci.prplIRequestBrowser]),
+      QueryInterface: ChromeUtils.generateQI(["prplIRequestBrowser"]),
     };
     Services.obs.notifyObservers(this._browserRequest, "browser-request");
   },
   finishAuthorizationRequest() {
     // Clean up the cookies, so that several twitter OAuth dialogs can work
     // during the same session (bug 954308).
     for (let cookie of Services.cookies.getCookiesFromHost("twitter.com", {})) {
       Services.cookies.remove(
--- a/mail/base/content/msgHdrView.js
+++ b/mail/base/content/msgHdrView.js
@@ -419,17 +419,17 @@ function OnAddressBookDataChanged(aActio
   });
 }
 
 /**
  * The messageHeaderSink is the class that gets notified of a message's headers
  * as we display the message through our mime converter.
  */
 var messageHeaderSink = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgHeaderSink]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgHeaderSink"]),
   onStartHeaders() {
     this.mSaveHdr = null;
     // Every time we start to redisplay a message, check the view all headers
     // pref...
     var showAllHeadersPref = Services.prefs.getIntPref("mail.show_headers");
     if (showAllHeadersPref == 2) {
       gViewAllHeaders = true;
     } else {
--- a/mail/base/content/msgMail3PaneWindow.js
+++ b/mail/base/content/msgMail3PaneWindow.js
@@ -1685,17 +1685,17 @@ function ThreadPaneOnDragStart(aEvent) {
 
   aEvent.dataTransfer.effectAllowed = "copyMove";
   aEvent.dataTransfer.addElement(aEvent.originalTarget);
 }
 
 function messageFlavorDataProvider() {}
 
 messageFlavorDataProvider.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIFlavorDataProvider]),
+  QueryInterface: ChromeUtils.generateQI(["nsIFlavorDataProvider"]),
 
   getFlavorData(aTransferable, aFlavor, aData) {
     if (aFlavor !== "application/x-moz-file-promise") {
       return;
     }
     let fileUriPrimitive = {};
     aTransferable.getTransferData(
       "application/x-moz-file-promise-url",
--- a/mail/base/content/specialTabs.js
+++ b/mail/base/content/specialTabs.js
@@ -261,19 +261,19 @@ tabProgressListener.prototype = {
         aWebProgress,
         aURI,
         aDelay,
         aSameURI
       );
     }
   },
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIWebProgressListener,
-    Ci.nsIWebProgressListener2,
-    Ci.nsISupportsWeakReference,
+    "nsIWebProgressListener",
+    "nsIWebProgressListener2",
+    "nsISupportsWeakReference",
   ]),
 };
 
 var DOMLinkHandler = {
   handleEvent(event) {
     switch (event.type) {
       case "DOMLinkAdded":
         this.onLinkAdded(event);
--- a/mail/base/content/tabmail.js
+++ b/mail/base/content/tabmail.js
@@ -576,17 +576,17 @@
           let onEventFunc = tab.mode.onEvent || tab.mode.tabType.onEvent;
           if (onEventFunc) {
             return onEventFunc.call(tab.mode.tabType, aEvent, tab);
           }
 
           return false;
         },
 
-        QueryInterface: ChromeUtils.generateQI([Ci.nsIController]),
+        QueryInterface: ChromeUtils.generateQI(["nsIController"]),
       };
 
       window.controllers.insertControllerAt(0, this.tabController);
       this._restoringTabState = null;
     }
 
     set selectedTab(val) {
       this.switchToTab(val);
--- a/mail/base/test/browser/browser_webSearchTelemetry.js
+++ b/mail/base/test/browser/browser_webSearchTelemetry.js
@@ -12,17 +12,17 @@ let { TelemetryTestUtils } = ChromeUtils
 );
 let { MockRegistrar } = ChromeUtils.import(
   "resource://testing-common/MockRegistrar.jsm"
 );
 
 /** @implements {nsIExternalProtocolService} */
 let mockExternalProtocolService = {
   loadURI(aURI, aWindowContext) {},
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIExternalProtocolService]),
+  QueryInterface: ChromeUtils.generateQI(["nsIExternalProtocolService"]),
 };
 
 let mockExternalProtocolServiceCID = MockRegistrar.register(
   "@mozilla.org/uriloader/external-protocol-service;1",
   mockExternalProtocolService
 );
 
 registerCleanupFunction(() => {
--- a/mail/base/test/unit/test_alertHook.js
+++ b/mail/base/test/unit/test_alertHook.js
@@ -16,17 +16,17 @@ var { MockFactory } = ChromeUtils.import
 );
 alertHook.init();
 
 // Replace the alerts service with our own. This will let us check if we're
 // prompting or not.
 var gAlertShown = false;
 
 var mockAlertsService = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIAlertsService]),
+  QueryInterface: ChromeUtils.generateQI(["nsIAlertsService"]),
 
   showAlertNotification(
     imageUrl,
     title,
     text,
     textClickable,
     cookie,
     alertListener,
--- a/mail/components/AboutRedirector.jsm
+++ b/mail/components/AboutRedirector.jsm
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var EXPORTED_SYMBOLS = ["AboutRedirector"];
 
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 function AboutRedirector() {}
 AboutRedirector.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIAboutModule]),
+  QueryInterface: ChromeUtils.generateQI(["nsIAboutModule"]),
 
   // Each entry in the map has the key as the part after the "about:" and the
   // value as a record with url and flags entries. Note that each addition here
   // should be coupled with a corresponding addition in mailComponents.manifest.
   _redirMap: {
     newserror: {
       url: "chrome://messenger/content/newsError.xhtml",
       flags: Ci.nsIAboutModule.ALLOW_SCRIPT,
--- a/mail/components/MailGlue.jsm
+++ b/mail/components/MailGlue.jsm
@@ -326,10 +326,10 @@ MailGlue.prototype = {
         "chrome,dialog=no,all",
         { type: "contentTab", tabParams }
       );
       linkHandled.data = true;
     }
   },
 
   // for XPCOM
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
+  QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
 };
--- a/mail/components/MessengerContentHandler.jsm
+++ b/mail/components/MessengerContentHandler.jsm
@@ -97,18 +97,18 @@ function openURI(uri) {
       Services.startup.enterLastWindowClosingSurvivalArea();
     },
 
     onStopRequest(aRequest, aStatusCode) {
       Services.startup.exitLastWindowClosingSurvivalArea();
     },
 
     QueryInterface: ChromeUtils.generateQI([
-      Ci.nsIRequestObserver,
-      Ci.nsISupportsWeakReference,
+      "nsIRequestObserver",
+      "nsISupportsWeakReference",
     ]),
   };
 
   loadgroup.groupObserver = loadlistener;
 
   var listener = {
     doContent(ctype, preferred, request, handler) {
       var newHandler = Cc[
@@ -142,19 +142,19 @@ function openURI(uri) {
   };
   loader.openURI(channel, true, listener);
 }
 
 function MailDefaultHandler() {}
 
 MailDefaultHandler.prototype = {
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsICommandLineHandler,
-    Ci.nsICommandLineValidator,
-    Ci.nsIFactory,
+    "nsICommandLineHandler",
+    "nsICommandLineValidator",
+    "nsIFactory",
   ]),
 
   /* nsICommandLineHandler */
 
   /* eslint-disable complexity */
   handle(cmdLine) {
     var uri;
 
@@ -580,12 +580,12 @@ MailDefaultHandler.prototype = {
 function MessengerContentHandler() {
   if (!gMessengerContentHandler) {
     gMessengerContentHandler = this;
   }
   return gMessengerContentHandler;
 }
 
 MessengerContentHandler.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIModule, Ci.nsIContentHandler]),
+  QueryInterface: ChromeUtils.generateQI(["nsIModule", "nsIContentHandler"]),
 };
 
 var gMessengerContentHandler = new MailDefaultHandler();
--- a/mail/components/activity/Activity.jsm
+++ b/mail/components/activity/Activity.jsm
@@ -226,20 +226,17 @@ ActivityProcess.prototype = {
 
     // let the listeners know about the change
     this.log.debug("Notifying onHandlerChanged listeners");
     for (let value of this._listeners) {
       value.onHandlerChanged(this);
     }
   },
 
-  QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIActivityProcess,
-    Ci.nsIActivity,
-  ]),
+  QueryInterface: ChromeUtils.generateQI(["nsIActivityProcess", "nsIActivity"]),
 };
 
 function ActivityEvent() {
   Activity.call(this);
   this.bindingName = "activity-event-richlistitem";
   this.groupingStyle = Ci.nsIActivity.GROUPING_STYLE_STANDALONE;
 }
 
@@ -273,17 +270,17 @@ ActivityEvent.prototype = {
 
     // let the listeners know about the change
     this.log.debug("Notifying onHandlerChanged listeners");
     for (let value of this._listeners) {
       value.onHandlerChanged(this);
     }
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIActivityEvent, Ci.nsIActivity]),
+  QueryInterface: ChromeUtils.generateQI(["nsIActivityEvent", "nsIActivity"]),
 };
 
 function ActivityWarning() {
   Activity.call(this);
   this.bindingName = "activity-warning-richlistitem";
   this.groupingStyle = Ci.nsIActivity.GROUPING_STYLE_BYCONTEXT;
 }
 
@@ -314,13 +311,10 @@ ActivityWarning.prototype = {
       value.onHandlerChanged(this);
     }
   },
 
   get time() {
     return this._time;
   },
 
-  QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIActivityWarning,
-    Ci.nsIActivity,
-  ]),
+  QueryInterface: ChromeUtils.generateQI(["nsIActivityWarning", "nsIActivity"]),
 };
--- a/mail/components/activity/ActivityManager.jsm
+++ b/mail/components/activity/ActivityManager.jsm
@@ -146,10 +146,10 @@ ActivityManager.prototype = {
     this.log.info("removeListener\n");
     for (let i = 0; i < this._listeners.length; i++) {
       if (this._listeners[i] == aListener) {
         this._listeners.splice(i, 1);
       }
     }
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIActivityManager]),
+  QueryInterface: ChromeUtils.generateQI(["nsIActivityManager"]),
 };
--- a/mail/components/activity/ActivityManagerUI.jsm
+++ b/mail/components/activity/ActivityManagerUI.jsm
@@ -40,10 +40,10 @@ ActivityManagerUI.prototype = {
   get visible() {
     return null != this.recentWindow;
   },
 
   get recentWindow() {
     return Services.wm.getMostRecentWindow("Activity:Manager");
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIActivityManagerUI]),
+  QueryInterface: ChromeUtils.generateQI(["nsIActivityManagerUI"]),
 };
--- a/mail/components/activity/content/activity-widgets.js
+++ b/mail/components/activity/content/activity-widgets.js
@@ -129,17 +129,17 @@
       }
       this.setAttribute("is", "activity-event-richlistitem");
 
       this.activityListener = {
         onHandlerChanged: activity => {
           // update handler button's visibility
           this.setVisibility(".undo", this.canUndo);
         },
-        QueryInterface: ChromeUtils.generateQI([Ci.nsIActivityListener]),
+        QueryInterface: ChromeUtils.generateQI(["nsIActivityListener"]),
       };
 
       this._activity.addListener(this.activityListener);
       this.appendChild(
         MozXULElement.parseXULToFragment(
           `
           <hbox flex="1">
             <vbox pack="center" class="eventIconBox">
@@ -469,17 +469,17 @@
           if (hidePauseBut) {
             this.setVisibility(".pause", !hidePauseBut);
             this.setVisibility(".resume", !hideResumeBut);
           } else {
             this.setVisibility(".pause", this.paused);
             this.setVisibility(".resume", !this.paused);
           }
         },
-        QueryInterface: ChromeUtils.generateQI([Ci.nsIActivityListener]),
+        QueryInterface: ChromeUtils.generateQI(["nsIActivityListener"]),
       };
 
       this._activity.addListener(this.activityListener);
 
       this.setAttribute("class", "activityitem");
 
       this.displayText = this._activity.displayText;
       // make sure that custom element reflects the latest state of the process
@@ -589,17 +589,17 @@
       }
       this.setAttribute("is", "activity-warning-richlistitem");
 
       this.activityListener = {
         onHandlerChanged: activity => {
           // update handler button's visibility
           this.setVisibility(".recover", this.canRecover);
         },
-        QueryInterface: ChromeUtils.generateQI([Ci.nsIActivityListener]),
+        QueryInterface: ChromeUtils.generateQI(["nsIActivityListener"]),
       };
 
       this._activity.addListener(this.activityListener);
 
       this.appendChild(
         MozXULElement.parseXULToFragment(
           `
           <hbox flex="1">
--- a/mail/components/activity/modules/alertHook.jsm
+++ b/mail/components/activity/modules/alertHook.jsm
@@ -35,17 +35,17 @@ var alertHook = {
 
   get brandShortName() {
     delete this.brandShortName;
     return (this.brandShortName = Services.strings
       .createBundle("chrome://branding/locale/brand.properties")
       .GetStringFromName("brandShortName"));
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgUserFeedbackListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgUserFeedbackListener"]),
 
   onAlert(aMessage, aUrl) {
     // Create a new warning.
     let warning = new nsActWarning(aMessage, this.activityMgr, "");
 
     if (aUrl && aUrl.server && aUrl.server.prettyName) {
       warning.groupingStyle = Ci.nsIActivity.GROUPING_STYLE_BYCONTEXT;
       warning.contextType = "incomingServer";
--- a/mail/components/activity/modules/sendLater.jsm
+++ b/mail/components/activity/modules/sendLater.jsm
@@ -28,18 +28,18 @@ const { Log4Moz } = ChromeUtils.import("
  * This really, really, sucks. Due to mailnews widespread use of
  * nsIMsgStatusFeedback we're bound to the UI to get any sensible feedback of
  * mail sending operations. The current send later code can't hook into the
  * progress listener easily to get the state of messages being sent, so we'll
  * just have to do it here.
  */
 var sendMsgProgressListener = {
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIMsgStatusFeedback,
-    Ci.nsISupportsWeakReference,
+    "nsIMsgStatusFeedback",
+    "nsISupportsWeakReference",
   ]),
 
   showStatusString(aStatusText) {
     sendLaterModule.onMsgStatus(aStatusText);
   },
 
   startMeteors() {},
 
@@ -72,17 +72,17 @@ var sendLaterModule = {
 
   get bundle() {
     delete this.bundle;
     return (this.bundle = Services.strings.createBundle(
       "chrome://messenger/locale/activity.properties"
     ));
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgSendLaterListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgSendLaterListener"]),
 
   _displayTextForHeader(aLocaleStringBase, aSubject) {
     return aSubject
       ? this.bundle.formatStringFromName(aLocaleStringBase + "WithSubject", [
           aSubject,
         ])
       : this.bundle.GetStringFromName(aLocaleStringBase);
   },
--- a/mail/components/addrbook/content/abTrees.js
+++ b/mail/components/addrbook/content/abTrees.js
@@ -169,17 +169,17 @@ abDirTreeItem.prototype = {
 };
 
 /**
  * Our actual implementation of nsITreeView.
  */
 function directoryTreeView() {}
 directoryTreeView.prototype = {
   __proto__: new PROTO_TREE_VIEW(),
-  QueryInterface: ChromeUtils.generateQI([Ci.nsITreeView, Ci.nsIAbListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsITreeView", "nsIAbListener"]),
 
   hasRemoteAB: false,
 
   init(aTree, aJSONFile) {
     if (aJSONFile) {
       // Parse our persistent-open-state json file
       let data = IOUtils.loadFileToString(aJSONFile);
       if (data) {
@@ -299,17 +299,17 @@ directoryTreeView.prototype = {
    *       this function.
    */
   _rebuild() {
     var oldCount = this._rowMap.length;
     this._rowMap = [];
 
     // Make an entry for All Address Books.
     let rootAB = {
-      QueryInterface: ChromeUtils.generateQI([Ci.nsIAbDirectory]),
+      QueryInterface: ChromeUtils.generateQI(["nsIAbDirectory"]),
 
       dirName: gAddressBookBundle.getString("allAddressBooks"),
       isMailList: false,
       isRemote: false,
       isSecure: false,
       URI: kAllDirectoryRoot + "?",
 
       get childNodes() {
--- a/mail/components/devtools/devtools-loader.jsm
+++ b/mail/components/devtools/devtools-loader.jsm
@@ -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/. */
 
 "use strict";
 
 function DevToolsStartup() {}
 
 DevToolsStartup.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsICommandLineHandler]),
+  QueryInterface: ChromeUtils.generateQI(["nsICommandLineHandler"]),
 
   helpInfo: "",
   handle(cmdLine) {
     this.initialize();
 
     // We want to overwrite the -devtools flag and open the toolbox instead
     let devtoolsFlag = cmdLine.handleFlag("devtools", false);
     if (devtoolsFlag) {
--- a/mail/components/enterprisepolicies/Policies.jsm
+++ b/mail/components/enterprisepolicies/Policies.jsm
@@ -951,17 +951,17 @@ let ChromeURLBlockPolicy = {
     return Ci.nsIContentPolicy.ACCEPT;
   },
   shouldProcess(contentLocation, loadInfo, mimeTypeGuess) {
     return Ci.nsIContentPolicy.ACCEPT;
   },
   classDescription: "Policy Engine Content Policy",
   contractID: "@mozilla-org/policy-engine-content-policy-service;1",
   classID: Components.ID("{ba7b9118-cabc-4845-8b26-4215d2a59ed7}"),
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIContentPolicy]),
+  QueryInterface: ChromeUtils.generateQI(["nsIContentPolicy"]),
   createInstance(outer, iid) {
     return this.QueryInterface(iid);
   },
 };
 
 function blockAllChromeURLs() {
   let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
   registrar.registerFactory(
--- a/mail/components/im/IMIncomingServer.jsm
+++ b/mail/components/im/IMIncomingServer.jsm
@@ -276,17 +276,17 @@ IMIncomingServer.prototype = {
   // using the initialize method, but we can't just use a null value
   // because that would crash nsMsgPurgeService::PerformPurge which
   // only verifies the nsresult return value of the spamSettings
   // getter before accessing the level property.
   get spamSettings() {
     return {
       level: 0,
       initialize(aServer) {},
-      QueryInterface: ChromeUtils.generateQI([Ci.nsISpamSettings]),
+      QueryInterface: ChromeUtils.generateQI(["nsISpamSettings"]),
     };
   },
 
   // nsMsgDBFolder.cpp crashes in HandleAutoCompactEvent if this doesn't exist:
   msgStore: {
     supportsCompaction: false,
   },
 
@@ -325,24 +325,24 @@ IMIncomingServer.prototype = {
       getFolderWithFlags: aFlags => null,
       getFoldersWithFlags: aFlags => [],
       get subFolders() {
         return EmptyEnumerator;
       },
       getStringProperty: aPropertyName => "",
       getNumUnread: aDeep => 0,
       Shutdown() {},
-      QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgFolder]),
+      QueryInterface: ChromeUtils.generateQI(["nsIMsgFolder"]),
     });
   },
 
   get sortOrder() {
     return 300000000;
   },
 
   get protocolInfo() {
     return Cc["@mozilla.org/messenger/protocol/info;1?type=im"].getService(
       Ci.nsIMsgProtocolInfo
     );
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgIncomingServer]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgIncomingServer"]),
 };
--- a/mail/components/im/IMProtocolInfo.jsm
+++ b/mail/components/im/IMProtocolInfo.jsm
@@ -42,10 +42,10 @@ IMProtocolInfo.prototype = {
   },
   get showComposeMsgLink() {
     return false;
   },
   get foldersCreatedAsync() {
     return false;
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgProtocolInfo]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgProtocolInfo"]),
 };
--- a/mail/components/im/content/chat-contact.js
+++ b/mail/components/im/content/chat-contact.js
@@ -69,17 +69,17 @@
       });
 
       this.parentNode.addEventListener("mousedown", event => {
         event.preventDefault();
       });
 
       // @implements {nsIObserver}
       this.observer = {
-        QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
+        QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
         observe: function(subject, topic, data) {
           if (
             topic == "contact-preferred-buddy-changed" ||
             topic == "contact-display-name-changed" ||
             topic == "contact-status-changed"
           ) {
             this.update();
           }
--- a/mail/components/im/content/chat-conversation.js
+++ b/mail/components/im/content/chat-conversation.js
@@ -137,18 +137,18 @@
             case "chat-update-topic":
               if (this._isConversationSelected) {
                 this.updateTopic();
               }
               break;
           }
         },
         QueryInterface: ChromeUtils.generateQI([
-          Ci.nsIObserver,
-          Ci.nsISupportsWeakReference,
+          "nsIObserver",
+          "nsISupportsWeakReference",
         ]),
       };
     }
 
     connectedCallback() {
       if (this.hasChildNodes() || this.delayConnectedCallback()) {
         return;
       }
--- a/mail/components/im/content/chat-imconv.js
+++ b/mail/components/im/content/chat-imconv.js
@@ -94,17 +94,17 @@
           this.convView.switchingToPanel();
         } else {
           this.convView.switchingAwayFromPanel(true);
         }
       }).observe(this, { attributes: true, attributeFilter: ["selected"] });
 
       // @implements {nsIObserver}
       this.observer = {
-        QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
+        QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
         observe: function(subject, topic, data) {
           if (
             topic == "target-prpl-conversation-changed" ||
             topic == "unread-message-count-changed" ||
             topic == "update-conv-title" ||
             topic == "update-buddy-status" ||
             topic == "update-buddy-status" ||
             topic == "update-conv-chatleft" ||
--- a/mail/components/newmailaccount/content/uriListener.js
+++ b/mail/components/newmailaccount/content/uriListener.js
@@ -108,17 +108,17 @@ httpRequestObserver.prototype = {
         "Could not find an associated window " +
           "for an HTTP request. Error: " +
           e
       );
     }
     return null;
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
+  QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
 };
 
 /**
  * TracingListener is an nsITracableChannel implementation that copies
  * an incoming stream of data from a request.  The data flows through this
  * nsITracableChannel transparently to the original listener. Once the
  * response data is fully downloaded, an attempt is made to parse it
  * as XML, and derive email account data from it.
@@ -264,12 +264,12 @@ TracingListener.prototype = {
       aRequest,
       storageStream.newInputStream(0),
       aOffset,
       aCount
     );
   },
 
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIStreamListener,
-    Ci.nsIRequestObserver,
+    "nsIStreamListener",
+    "nsIRequestObserver",
   ]),
 };
--- a/mail/components/preferences/cookies.js
+++ b/mail/components/preferences/cookies.js
@@ -185,17 +185,17 @@ var gCookiesWindow = {
     var oldRowCount = this._rowCount;
     this._view._rowCount += rowCountImpact;
     this._tree.rowCountChanged(oldRowCount - 1, rowCountImpact);
 
     document.getElementById("removeAllCookies").disabled = this._view._filtered;
   },
 
   _view: {
-    QueryInterface: ChromeUtils.generateQI([Ci.nsITreeView]),
+    QueryInterface: ChromeUtils.generateQI(["nsITreeView"]),
     _filtered: false,
     _filterSet: [],
     _filterValue: "",
     _rowCount: 0,
     _cacheValid: 0,
     _cacheItems: [],
     get rowCount() {
       return this._rowCount;
--- a/mail/components/preferences/general.js
+++ b/mail/components/preferences/general.js
@@ -1319,18 +1319,18 @@ var gGeneralPane = {
         }
         actualSizeLabel.value = prefStrBundle.getFormattedString(
           "actualDiskCacheSize",
           size
         );
       },
 
       QueryInterface: ChromeUtils.generateQI([
-        Ci.nsICacheStorageConsumptionObserver,
-        Ci.nsISupportsWeakReference,
+        "nsICacheStorageConsumptionObserver",
+        "nsISupportsWeakReference",
       ]),
     };
 
     actualSizeLabel.value = prefStrBundle.getString(
       "actualDiskCacheSizeCalculated"
     );
 
     try {
@@ -2226,17 +2226,17 @@ var gGeneralPane = {
   destroy() {
     window.removeEventListener("unload", this);
 
     Services.obs.removeObserver(this, AUTO_UPDATE_CHANGED_TOPIC);
   },
 
   // nsISupports
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
+  QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
 
   // nsIObserver
 
   async observe(aSubject, aTopic, aData) {
     if (aTopic == AUTO_UPDATE_CHANGED_TOPIC) {
       if (aData != "true" && aData != "false") {
         throw new Error("Invalid preference value for app.update.auto");
       }
--- a/mail/components/preferences/passwordManager.js
+++ b/mail/components/preferences/passwordManager.js
@@ -143,17 +143,17 @@ function Shutdown() {
 }
 
 function setFilter(aFilterString) {
   filterField.value = aFilterString;
   FilterPasswords();
 }
 
 let signonsTreeView = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsITreeView]),
+  QueryInterface: ChromeUtils.generateQI(["nsITreeView"]),
   _filterSet: [],
   _lastSelectedRanges: [],
   selection: null,
 
   rowCount: 0,
   setTree(tree) {},
   getImageSrc(row, column) {
     if (column.element.getAttribute("id") !== "providerCol") {
--- a/mail/components/preferences/permissions.js
+++ b/mail/components/preferences/permissions.js
@@ -32,17 +32,17 @@ var gPermissionManager = {
   _type: "",
   _permissions: [],
   _permissionsToAdd: new Map(),
   _permissionsToDelete: new Map(),
   _tree: null,
   _observerRemoved: false,
 
   _view: {
-    QueryInterface: ChromeUtils.generateQI([Ci.nsITreeView]),
+    QueryInterface: ChromeUtils.generateQI(["nsITreeView"]),
     _rowCount: 0,
     get rowCount() {
       return this._rowCount;
     },
     getCellText(aRow, aColumn) {
       if (aColumn.id == "siteCol") {
         return gPermissionManager._permissions[aRow].origin.replace(
           MAILURI_BASE,
--- a/mail/components/preferences/test/browser/browser_cloudfile.js
+++ b/mail/components/preferences/test/browser/browser_cloudfile.js
@@ -59,34 +59,34 @@ let provider = {
 
 /** @implements {nsIPromptService} */
 let mockPromptService = {
   confirmCount: 0,
   confirm() {
     this.confirmCount++;
     return true;
   },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIPromptService]),
+  QueryInterface: ChromeUtils.generateQI(["nsIPromptService"]),
 };
 /** @implements {nsIExternalProtocolService} */
 let mockExternalProtocolService = {
   _loadedURLs: [],
   externalProtocolHandlerExists(aProtocolScheme) {},
   getApplicationDescription(aScheme) {},
   getProtocolHandlerInfo(aProtocolScheme) {},
   getProtocolHandlerInfoFromOS(aProtocolScheme, aFound) {},
   isExposedProtocol(aProtocolScheme) {},
   loadURI(aURI, aWindowContext) {
     this._loadedURLs.push(aURI.spec);
   },
   setProtocolHandlerDefaults(aHandlerInfo, aOSHandlerExists) {},
   urlLoaded(aURL) {
     return this._loadedURLs.includes(aURL);
   },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIExternalProtocolService]),
+  QueryInterface: ChromeUtils.generateQI(["nsIExternalProtocolService"]),
 };
 
 let mockPromptServiceCID = MockRegistrar.register(
   "@mozilla.org/embedcomp/prompt-service;1",
   mockPromptService
 );
 let mockExternalProtocolServiceCID = MockRegistrar.register(
   "@mozilla.org/uriloader/external-protocol-service;1",
--- a/mail/components/prompts/PromptCollection.jsm
+++ b/mail/components/prompts/PromptCollection.jsm
@@ -76,10 +76,10 @@ XPCOMUtils.defineLazyGetter(
     return bundle;
   }
 );
 
 PromptCollection.prototype.classID = Components.ID(
   "{7913837c-9623-11ea-bb37-0242ac130002}"
 );
 PromptCollection.prototype.QueryInterface = ChromeUtils.generateQI([
-  Ci.nsIPromptCollection,
+  "nsIPromptCollection",
 ]);
--- a/mail/extensions/am-e2e/AME2E.jsm
+++ b/mail/extensions/am-e2e/AME2E.jsm
@@ -15,10 +15,10 @@ E2EService.prototype = {
     return (
       server.type != "nntp" &&
       server.type != "rss" &&
       server.type != "im" &&
       server.type != "none"
     );
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgAccountManagerExtension]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgAccountManagerExtension"]),
 };
--- a/mail/extensions/openpgp/content/modules/mimeVerify.jsm
+++ b/mail/extensions/openpgp/content/modules/mimeVerify.jsm
@@ -145,17 +145,17 @@ MimeVerify.prototype = {
   msgUriSpec: null,
   statusDisplayed: false,
   window: null,
   inStream: null,
   sigFile: null,
   sigData: "",
   mimePartNumber: "",
 
-  QueryInterface: EnigmailCompat.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: EnigmailCompat.generateQI(["nsIStreamListener"]),
 
   startStreaming(window, msgWindow, msgUriSpec) {
     LOCAL_DEBUG("mimeVerify.jsm: startStreaming\n");
 
     this.msgWindow = msgWindow;
     this.msgUriSpec = msgUriSpec;
     this.window = window;
     var messenger = Cc["@mozilla.org/messenger;1"].getService(Ci.nsIMessenger);
--- a/mail/extensions/openpgp/content/modules/pgpmimeHandler.jsm
+++ b/mail/extensions/openpgp/content/modules/pgpmimeHandler.jsm
@@ -156,17 +156,17 @@ UnknownProtoHandler.prototype = {
 function PgpMimeHandler() {
   EnigmailLog.DEBUG("pgpmimeHandler.js: PgpMimeHandler()\n"); // always log this one
 }
 
 PgpMimeHandler.prototype = {
   classDescription: "Enigmail JS Decryption Handler",
   classID: PGPMIME_JS_DECRYPTOR_CID,
   contractID: PGPMIME_JS_DECRYPTOR_CONTRACTID,
-  QueryInterface: EnigmailCompat.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: EnigmailCompat.generateQI(["nsIStreamListener"]),
   inStream: Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
     Ci.nsIScriptableInputStream
   ),
 
   onStartRequest(request, ctxt) {
     let mimeSvc = request.QueryInterface(Ci.nsIPgpMimeProxy);
     let ct = mimeSvc.contentType;
 
--- a/mail/extensions/openpgp/content/modules/protocolHandler.jsm
+++ b/mail/extensions/openpgp/content/modules/protocolHandler.jsm
@@ -53,17 +53,17 @@ EnigmailProtocolHandler.prototype = {
   defaultPort: -1,
   protocolFlags:
     nsIProtocolHandler.URI_INHERITS_SECURITY_CONTEXT |
     nsIProtocolHandler.URI_LOADABLE_BY_ANYONE |
     nsIProtocolHandler.URI_NORELATIVE |
     nsIProtocolHandler.URI_NOAUTH |
     nsIProtocolHandler.URI_OPENING_EXECUTES_SCRIPT,
 
-  QueryInterface: EnigmailCompat.generateQI([nsIProtocolHandler]),
+  QueryInterface: EnigmailCompat.generateQI(["nsIProtocolHandler"]),
 
   newURI(aSpec, originCharset, aBaseURI) {
     EnigmailLog.DEBUG(
       "protocolHandler.jsm: EnigmailProtocolHandler.newURI: aSpec='" +
         aSpec +
         "'\n"
     );
 
--- a/mail/extensions/openpgp/content/modules/stdlib/msgHdrUtils.jsm
+++ b/mail/extensions/openpgp/content/modules/stdlib/msgHdrUtils.jsm
@@ -369,18 +369,18 @@ HeaderHandler.prototype = {
  * that has been read.
  */
 function createStreamListener(k) {
   return {
     _data: "",
     _stream: null,
 
     QueryInterface: ChromeUtils.generateQI([
-      Ci.nsIStreamListener,
-      Ci.nsIRequestObserver,
+      "nsIStreamListener",
+      "nsIRequestObserver",
     ]),
 
     // nsIRequestObserver
     onStartRequest(aRequest) {},
     onStopRequest(aRequest, aStatusCode) {
       try {
         k(this._data);
       } catch (e) {
@@ -482,17 +482,17 @@ function msgHdrsModifyRaw(aMsgHdrs, aTra
     let { msgHdr, tempFile } = obj;
 
     EnigmailCompat.copyFileToMailFolder(
       tempFile,
       msgHdr.folder,
       msgHdr.flags,
       msgHdr.getStringProperty("keywords"),
       {
-        QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgCopyServiceListener]),
+        QueryInterface: ChromeUtils.generateQI(["nsIMsgCopyServiceListener"]),
 
         OnStartCopy() {},
         OnProgress(aProgress, aProgressMax) {},
         SetMessageKey(aKey) {},
         GetMessageId(aMessageId) {},
         OnStopCopy(aStatus) {
           if (NS_SUCCEEDED(aStatus)) {
             dump("msgHdrModifyRaw: copied successfully\n");
--- a/mail/extensions/openpgp/content/modules/streams.jsm
+++ b/mail/extensions/openpgp/content/modules/streams.jsm
@@ -55,18 +55,18 @@ var EnigmailStreams = {
 
     let listener = {
       data: "",
       inStream: Cc["@mozilla.org/binaryinputstream;1"].createInstance(
         Ci.nsIBinaryInputStream
       ),
       _onStopCallback: onStopCallback,
       QueryInterface: EnigmailCompat.generateQI([
-        Ci.nsIStreamListener,
-        Ci.nsIRequestObserver,
+        "nsIStreamListener",
+        "nsIRequestObserver",
       ]),
 
       onStartRequest(channel) {
         // EnigmailLog.DEBUG("enigmailCommon.jsm: stringListener.onStartRequest\n");
       },
 
       onStopRequest(channel, status) {
         // EnigmailLog.DEBUG("enigmailCommon.jsm: stringListener.onStopRequest: "+ctxt+"\n");
--- a/mail/extensions/openpgp/content/modules/wksMimeHandler.jsm
+++ b/mail/extensions/openpgp/content/modules/wksMimeHandler.jsm
@@ -70,17 +70,17 @@ function PgpWkdHandler(protocol) {
 
 // PgpWkdHandler implementation
 PgpWkdHandler.prototype = {
   data: "",
   mimePartNumber: "",
   uri: null,
   backgroundJob: false,
 
-  QueryInterface: EnigmailCompat.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: EnigmailCompat.generateQI(["nsIStreamListener"]),
 
   onStartRequest(request, ctxt) {
     EnigmailLog.DEBUG("wksMimeHandler.jsm: onStartRequest\n"); // always log this one
 
     this.mimeSvc = request.QueryInterface(Ci.nsIPgpMimeProxy);
     if ("messageURI" in this.mimeSvc) {
       this.uri = this.mimeSvc.messageURI;
     } else {
--- a/mail/test/browser/notification/browser_notification.js
+++ b/mail/test/browser/notification/browser_notification.js
@@ -37,17 +37,17 @@ var gTotalOpenTime;
 
 // Used by make_gradually_newer_sets_in_folders
 var gMsgMinutes = 9000;
 
 // We'll use this mock alerts service to capture notification events
 var gMockAlertsService = {
   _doFail: false,
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIAlertsService]),
+  QueryInterface: ChromeUtils.generateQI(["nsIAlertsService"]),
 
   showAlertNotification(
     imageUrl,
     title,
     text,
     textClickable,
     cookie,
     alertListener,
--- a/mail/test/browser/shared-modules/AttachmentHelpers.jsm
+++ b/mail/test/browser/shared-modules/AttachmentHelpers.jsm
@@ -25,17 +25,17 @@ var gMockFilePickReg = new MockObjectRep
   MockFilePickerConstructor
 );
 
 function MockFilePickerConstructor() {
   return gMockFilePicker;
 }
 
 var gMockFilePicker = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIFilePicker]),
+  QueryInterface: ChromeUtils.generateQI(["nsIFilePicker"]),
   defaultExtension: "",
   filterIndex: null,
   displayDirectory: null,
   returnFiles: [],
   addToRecentDocs: false,
 
   get defaultString() {
     throw Components.Exception("", Cr.NS_ERROR_FAILURE);
@@ -51,17 +51,17 @@ var gMockFilePicker = {
     }
     return null;
   },
 
   get files() {
     let self = this;
     return {
       index: 0,
-      QueryInterface: ChromeUtils.generateQI([Ci.nsISimpleEnumerator]),
+      QueryInterface: ChromeUtils.generateQI(["nsISimpleEnumerator"]),
       hasMoreElements() {
         return this.index < self.returnFiles.length;
       },
       getNext() {
         return self.returnFiles[this.index++];
       },
       [Symbol.iterator]() {
         return self.returnFiles.values();
--- a/mail/test/browser/shared-modules/ContentTabHelpers.jsm
+++ b/mail/test/browser/shared-modules/ContentTabHelpers.jsm
@@ -61,17 +61,17 @@ var gMockExtProtSvcReg = new MockObjectR
 );
 
 /**
  * gMockExtProtocolSvc allows us to capture (most if not all) attempts to
  * open links in the default browser.
  */
 var gMockExtProtSvc = {
   _loadedURLs: [],
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIExternalProtocolService]),
+  QueryInterface: ChromeUtils.generateQI(["nsIExternalProtocolService"]),
 
   externalProtocolHandlerExists(aProtocolScheme) {},
 
   getApplicationDescription(aScheme) {},
 
   getProtocolHandlerInfo(aProtocolScheme) {},
 
   getProtocolHandlerInfoFromOS(aProtocolScheme, aFound) {},
--- a/mail/test/browser/shared-modules/NewMailAccountHelpers.jsm
+++ b/mail/test/browser/shared-modules/NewMailAccountHelpers.jsm
@@ -164,17 +164,17 @@ function type_in_search_name(aController
 
   input_value(aController, aName);
 }
 
 /* A listener for the Error Console, which allows us to ensure that certain
  * messages appear in the console.
  */
 var gConsoleListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIConsoleListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIConsoleListener"]),
   _msg: null,
   _sawMsg: false,
 
   observe(aMsg) {
     if (!this._msg) {
       return;
     }
 
--- a/mail/test/browser/shared-modules/PromptHelpers.jsm
+++ b/mail/test/browser/shared-modules/PromptHelpers.jsm
@@ -28,26 +28,26 @@ var gMockAuthPromptReg = new MockObjectR
   MockAuthPromptFactoryConstructor
 );
 
 function MockAuthPromptFactoryConstructor() {
   return gMockAuthPromptFactory;
 }
 
 var gMockAuthPromptFactory = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIPromptFactory]),
+  QueryInterface: ChromeUtils.generateQI(["nsIPromptFactory"]),
   getPrompt(aParent, aIID, aResult) {
     return gMockAuthPrompt.QueryInterface(aIID);
   },
 };
 
 var gMockAuthPrompt = {
   password: "",
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIAuthPrompt]),
+  QueryInterface: ChromeUtils.generateQI(["nsIAuthPrompt"]),
 
   prompt(aTitle, aText, aRealm, aSave, aDefaultText) {
     throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
   },
 
   promptUsernameAndPassword(aTitle, aText, aRealm, aSave, aUser, aPwd) {
     throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
   },
@@ -55,17 +55,17 @@ var gMockAuthPrompt = {
   promptPassword(aTitle, aText, aRealm, aSave, aPwd) {
     aPwd.value = this.password;
     return true;
   },
 };
 
 var gMockPromptService = {
   _registered: false,
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIPromptService]),
+  QueryInterface: ChromeUtils.generateQI(["nsIPromptService"]),
   _will_return: null,
   _inout_value: null,
   _promptState: null,
   _origFactory: null,
   _promptCb: null,
 
   alert(aParent, aDialogTitle, aText) {
     this._promptState = {
--- a/mailnews/addrbook/content/abDragDrop.js
+++ b/mailnews/addrbook/content/abDragDrop.js
@@ -15,17 +15,17 @@ var { MailServices } = ChromeUtils.impor
 );
 
 // Returns the load context for the current window
 function getLoadContext() {
   return window.docShell.QueryInterface(Ci.nsILoadContext);
 }
 
 var abFlavorDataProvider = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIFlavorDataProvider]),
+  QueryInterface: ChromeUtils.generateQI(["nsIFlavorDataProvider"]),
 
   getFlavorData(aTransferable, aFlavor, aData) {
     if (aFlavor == "application/x-moz-file-promise") {
       var primitive = {};
       aTransferable.getTransferData("text/vcard", primitive);
       var vCard = primitive.value.QueryInterface(Ci.nsISupportsString).data;
       aTransferable.getTransferData(
         "application/x-moz-file-promise-dest-filename",
--- a/mailnews/addrbook/content/abView.js
+++ b/mailnews/addrbook/content/abView.js
@@ -24,20 +24,20 @@ function ABView(directory, searchQuery, 
     if (this.listener) {
       this.listener.onCountChanged(this.rowCount);
     }
   }
   this.sortBy(sortColumn, sortDirection);
 }
 ABView.prototype = {
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsITreeView,
-    Ci.nsIAbDirSearchListener,
-    Ci.nsIObserver,
-    Ci.nsISupportsWeakReference,
+    "nsITreeView",
+    "nsIAbDirSearchListener",
+    "nsIObserver",
+    "nsISupportsWeakReference",
   ]),
 
   directory: null,
   listener: null,
   _notifications: [
     "addrbook-directory-invalidated",
     "addrbook-contact-created",
     "addrbook-contact-deleted",
--- a/mailnews/addrbook/jsaddrbook/AddrBookCard.jsm
+++ b/mailnews/addrbook/jsaddrbook/AddrBookCard.jsm
@@ -26,17 +26,17 @@ function AddrBookCard() {
   this._properties = new Map([
     ["PreferMailFormat", Ci.nsIAbPreferMailFormat.unknown],
     ["PopularityIndex", 0],
     ["LastModifiedDate", 0],
   ]);
 }
 
 AddrBookCard.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIAbCard]),
+  QueryInterface: ChromeUtils.generateQI(["nsIAbCard"]),
   classID: Components.ID("{1143991d-31cd-4ea6-9c97-c587d990d724}"),
 
   /* nsIAbCard */
 
   get uuid() {
     return MailServices.ab.generateUUID(this._directoryId, this._localId);
   },
   generateName(generateFormat, bundle) {
@@ -108,25 +108,25 @@ AddrBookCard.prototype = {
         let [name, value] = entries.shift();
         return {
           get name() {
             return name;
           },
           get value() {
             return value;
           },
-          QueryInterface: ChromeUtils.generateQI([Ci.nsIProperty]),
+          QueryInterface: ChromeUtils.generateQI(["nsIProperty"]),
         };
       },
       *[Symbol.iterator]() {
         while (this.hasMoreElements()) {
           yield this.getNext();
         }
       },
-      QueryInterface: ChromeUtils.generateQI([Ci.nsISimpleEnumerator]),
+      QueryInterface: ChromeUtils.generateQI(["nsISimpleEnumerator"]),
     };
     return enumerator;
   },
   get firstName() {
     return this.getProperty("FirstName", "");
   },
   set firstName(value) {
     this.setProperty("FirstName", value);
--- a/mailnews/addrbook/jsaddrbook/AddrBookDirectory.jsm
+++ b/mailnews/addrbook/jsaddrbook/AddrBookDirectory.jsm
@@ -1097,13 +1097,13 @@ class AddrBookDirectory {
     );
   }
 
   static forFile(fileName) {
     return directories.get(fileName);
   }
 }
 AddrBookDirectory.prototype.QueryInterface = ChromeUtils.generateQI([
-  Ci.nsIAbDirectory,
+  "nsIAbDirectory",
 ]);
 AddrBookDirectory.prototype.classID = Components.ID(
   "{e96ee804-0bd3-472f-81a6-8a9d65277ad3}"
 );
--- a/mailnews/addrbook/jsaddrbook/AddrBookMailingList.jsm
+++ b/mailnews/addrbook/jsaddrbook/AddrBookMailingList.jsm
@@ -39,17 +39,17 @@ function AddrBookMailingList(
   this._name = name;
   this._nickName = nickName;
   this._description = description;
 }
 AddrBookMailingList.prototype = {
   get asDirectory() {
     let self = this;
     return {
-      QueryInterface: ChromeUtils.generateQI([Ci.nsIAbDirectory]),
+      QueryInterface: ChromeUtils.generateQI(["nsIAbDirectory"]),
       classID: Components.ID("{e96ee804-0bd3-472f-81a6-8a9d65277ad3}"),
 
       get propertiesChromeURI() {
         return "chrome://messenger/content/addressbook/abAddressBookNameDialog.xhtml";
       },
       get UID() {
         return self._uid;
       },
@@ -205,17 +205,17 @@ AddrBookMailingList.prototype = {
           self._parent.UID
         );
       },
     };
   },
   get asCard() {
     let self = this;
     return {
-      QueryInterface: ChromeUtils.generateQI([Ci.nsIAbCard]),
+      QueryInterface: ChromeUtils.generateQI(["nsIAbCard"]),
       classID: Components.ID("{1143991d-31cd-4ea6-9c97-c587d990d724}"),
 
       get UID() {
         return self._uid;
       },
       get uuid() {
         return MailServices.ab.generateUUID(self._parent.uuid, self._localId);
       },
--- a/mailnews/addrbook/jsaddrbook/AddrBookManager.jsm
+++ b/mailnews/addrbook/jsaddrbook/AddrBookManager.jsm
@@ -162,17 +162,17 @@ function ensureInitialized() {
 Services.obs.addObserver(() => {
   // Clear the store. The next call to ensureInitialized will recreate it.
   store = null;
 }, "addrbook-reload");
 
 /** @implements nsIAbManager */
 function AddrBookManager() {}
 AddrBookManager.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIAbManager]),
+  QueryInterface: ChromeUtils.generateQI(["nsIAbManager"]),
   classID: Components.ID("{224d3ef9-d81c-4d94-8826-a79a5835af93}"),
 
   get directories() {
     ensureInitialized();
     let dirs = [...store.values()];
     dirs.sort((a, b) => {
       let aPosition = a.getIntValue("position", 0);
       let bPosition = b.getIntValue("position", 0);
--- a/mailnews/addrbook/jsaddrbook/AddrBookUtils.jsm
+++ b/mailnews/addrbook/jsaddrbook/AddrBookUtils.jsm
@@ -38,17 +38,17 @@ SimpleEnumerator.prototype = {
     return this._position < this._elements.length;
   },
   getNext() {
     if (this.hasMoreElements()) {
       return this._elements[this._position++];
     }
     throw Components.Exception("", Cr.NS_ERROR_NOT_AVAILABLE);
   },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsISimpleEnumerator]),
+  QueryInterface: ChromeUtils.generateQI(["nsISimpleEnumerator"]),
   *[Symbol.iterator]() {
     while (this.hasMoreElements()) {
       yield this.getNext();
     }
   },
 };
 
 function newUID() {
--- a/mailnews/addrbook/jsaddrbook/CardDAVDirectory.jsm
+++ b/mailnews/addrbook/jsaddrbook/CardDAVDirectory.jsm
@@ -597,23 +597,23 @@ function xmlEncode(string) {
     .replace(/&/g, "&amp;")
     .replace(/"/g, "&quot;")
     .replace(/</g, "&lt;")
     .replace(/>/g, "&gt;");
 }
 
 let notificationCallbacks = {
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIInterfaceRequestor,
-    Ci.nsIAuthPrompt2,
-    Ci.nsIChannelEventSink,
+    "nsIInterfaceRequestor",
+    "nsIAuthPrompt2",
+    "nsIChannelEventSink",
   ]),
   getInterface: ChromeUtils.generateQI([
-    Ci.nsIAuthPrompt2,
-    Ci.nsIChannelEventSink,
+    "nsIAuthPrompt2",
+    "nsIChannelEventSink",
   ]),
   promptAuth(channel, level, authInfo) {
     if (authInfo.flags & Ci.nsIAuthInformation.PREVIOUS_FAILED) {
       return false;
     }
     let logins = Services.logins.findLogins(channel.URI.prePath, null, "");
     for (let l of logins) {
       authInfo.username = l.username;
--- a/mailnews/addrbook/jsaddrbook/VCardUtils.jsm
+++ b/mailnews/addrbook/jsaddrbook/VCardUtils.jsm
@@ -238,30 +238,30 @@ var VCardUtils = {
 
     vProps.push(["uid", {}, "text", abCard.UID]);
     return ICAL.stringify(["vcard", vProps]);
   },
 };
 
 function VCardService() {}
 VCardService.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgVCardService]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgVCardService"]),
   classID: Components.ID("{e2e0f615-bc5a-4441-a16b-a26e75949376}"),
 
   escapedVCardToAbCard(vCard) {
     return VCardUtils.vCardToAbCard(decodeURIComponent(vCard));
   },
   abCardToEscapedVCard(abCard) {
     return encodeURIComponent(VCardUtils.abCardToVCard(abCard));
   },
 };
 
 function VCardMimeConverter() {}
 VCardMimeConverter.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsISimpleMimeConverter]),
+  QueryInterface: ChromeUtils.generateQI(["nsISimpleMimeConverter"]),
   classID: Components.ID("{dafab386-bd4c-4238-bb48-228fbc98ba29}"),
 
   uri: null,
   convertToHTML(contentType, data) {
     function escapeHTML(template, ...parts) {
       let arr = [];
       for (let i = 0; i < parts.length; i++) {
         arr.push(template[i]);
--- a/mailnews/addrbook/src/AbAutoCompleteMyDomain.jsm
+++ b/mailnews/addrbook/src/AbAutoCompleteMyDomain.jsm
@@ -6,17 +6,17 @@ var EXPORTED_SYMBOLS = ["AbAutoCompleteM
 
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
 function AbAutoCompleteMyDomain() {}
 
 AbAutoCompleteMyDomain.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIAutoCompleteSearch]),
+  QueryInterface: ChromeUtils.generateQI(["nsIAutoCompleteSearch"]),
 
   cachedIdKey: "",
   cachedIdentity: null,
 
   applicableHeaders: new Set(["addr_to", "addr_cc", "addr_bcc", "addr_reply"]),
 
   startSearch(aString, aSearchParam, aResult, aListener) {
     let params = aSearchParam ? JSON.parse(aSearchParam) : {};
--- a/mailnews/addrbook/src/AbAutoCompleteSearch.jsm
+++ b/mailnews/addrbook/src/AbAutoCompleteSearch.jsm
@@ -81,17 +81,20 @@ nsAbAutoCompleteResult.prototype = {
   },
 
   getEmailToUse(aIndex) {
     return this._searchResults[aIndex].emailToUse;
   },
 
   // nsISupports
 
-  QueryInterface: ChromeUtils.generateQI([ACR, nsIAbAutoCompleteResult]),
+  QueryInterface: ChromeUtils.generateQI([
+    "nsIAutoCompleteResult",
+    "nsIAbAutoCompleteResult",
+  ]),
 };
 
 function AbAutoCompleteSearch() {}
 
 AbAutoCompleteSearch.prototype = {
   // This is set from a preference,
   // 0 = no comment column, 1 = name of address book this card came from
   // Other numbers currently unused (hence default to zero)
@@ -493,10 +496,10 @@ AbAutoCompleteSearch.prototype = {
 
     aListener.onSearchResult(this, result);
   },
 
   stopSearch() {},
 
   // nsISupports
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIAutoCompleteSearch]),
+  QueryInterface: ChromeUtils.generateQI(["nsIAutoCompleteSearch"]),
 };
--- a/mailnews/addrbook/src/AbLDAPAttributeMap.jsm
+++ b/mailnews/addrbook/src/AbLDAPAttributeMap.jsm
@@ -174,17 +174,17 @@ AbLDAPAttributeMap.prototype = {
         }
 
         // remember that we've seen it now
         attrsSeen.push(attr);
       }
     }
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIAbLDAPAttributeMap]),
+  QueryInterface: ChromeUtils.generateQI(["nsIAbLDAPAttributeMap"]),
 };
 
 function AbLDAPAttributeMapService() {}
 
 AbLDAPAttributeMapService.prototype = {
   mAttrMaps: {},
 
   getMapForPrefBranch(aPrefBranchName) {
@@ -200,10 +200,10 @@ AbLDAPAttributeMapService.prototype = {
 
     // cache
     this.mAttrMaps[aPrefBranchName] = attrMap;
 
     // and return
     return attrMap;
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIAbLDAPAttributeMapService]),
+  QueryInterface: ChromeUtils.generateQI(["nsIAbLDAPAttributeMapService"]),
 };
--- a/mailnews/addrbook/src/AbLDAPAutoCompleteSearch.jsm
+++ b/mailnews/addrbook/src/AbLDAPAutoCompleteSearch.jsm
@@ -6,17 +6,16 @@
 var EXPORTED_SYMBOLS = ["AbLDAPAutoCompleteSearch"];
 
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
 var ACR = Ci.nsIAutoCompleteResult;
-var nsIAbAutoCompleteResult = Ci.nsIAbAutoCompleteResult;
 var nsIAbDirectoryQueryResultListener = Ci.nsIAbDirectoryQueryResultListener;
 
 // nsAbLDAPAutoCompleteResult
 // Derived from nsIAbAutoCompleteResult, provides a LDAP specific result
 // implementation.
 
 function nsAbLDAPAutoCompleteResult(aSearchString) {
   // Can't create this in the prototype as we'd get the same array for
@@ -71,17 +70,20 @@ nsAbLDAPAutoCompleteResult.prototype = {
   // nsIAbAutoCompleteResult
 
   getCardAt(aIndex) {
     return this._searchResults[aIndex].card;
   },
 
   // nsISupports
 
-  QueryInterface: ChromeUtils.generateQI([ACR, nsIAbAutoCompleteResult]),
+  QueryInterface: ChromeUtils.generateQI([
+    "nsIAutoCompleteResult",
+    "nsIAbAutoCompleteResult",
+  ]),
 };
 
 function AbLDAPAutoCompleteSearch() {
   Services.obs.addObserver(this, "quit-application");
   this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
 }
 
 AbLDAPAutoCompleteSearch.prototype = {
@@ -345,13 +347,13 @@ AbLDAPAutoCompleteSearch.prototype = {
     }
     this._listener.onSearchResult(this, this._result);
     */
   },
 
   // nsISupports
 
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIObserver,
-    Ci.nsIAutoCompleteSearch,
-    Ci.nsIAbDirSearchListener,
+    "nsIObserver",
+    "nsIAutoCompleteSearch",
+    "nsIAbDirSearchListener",
   ]),
 };
--- a/mailnews/addrbook/test/LDAPServer.jsm
+++ b/mailnews/addrbook/test/LDAPServer.jsm
@@ -21,18 +21,18 @@ const { Services } = ChromeUtils.import(
 var LDAPServer = {
   BindRequest: 0x60,
   UnbindRequest: 0x42,
   SearchRequest: 0x63,
 
   serverSocket: null,
 
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIInputStreamCallback,
-    Ci.nsIServerSocketListener,
+    "nsIInputStreamCallback",
+    "nsIServerSocketListener",
   ]),
 
   /**
    * Start listening on an OS-selected port. The port number can be found at
    * LDAPServer.port.
    */
   open() {
     this.serverSocket = Cc[
--- a/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch2.js
+++ b/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch2.js
@@ -73,17 +73,20 @@ nsAbAutoCompleteResult.prototype = {
 
   getEmailToUse: function getEmailToUse(aIndex) {
     // For this test we can just use the primary email here.
     return this._searchResults[aIndex].card.primaryEmail;
   },
 
   // nsISupports
 
-  QueryInterface: ChromeUtils.generateQI([ACR, nsIAbAutoCompleteResult]),
+  QueryInterface: ChromeUtils.generateQI([
+    "nsIAutoCompleteResult",
+    "nsIAbAutoCompleteResult",
+  ]),
 };
 
 function createCard(chars, popularity) {
   var card = Cc["@mozilla.org/addressbook/cardproperty;1"].createInstance(
     Ci.nsIAbCard
   );
 
   card.firstName = "firstName".slice(0, chars);
--- a/mailnews/base/search/src/MsgTraitService.jsm
+++ b/mailnews/base/search/src/MsgTraitService.jsm
@@ -21,17 +21,17 @@ function _registerTrait(aId, aIndex) {
   trait.index = aIndex;
   _traits[aId] = trait;
 }
 
 function MsgTraitService() {}
 
 MsgTraitService.prototype = {
   // Component setup
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgTraitService]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgTraitService"]),
 
   // nsIMsgTraitService implementation
 
   get lastIndex() {
     return _lastIndex;
   },
 
   registerTrait(aId) {
--- a/mailnews/base/src/FolderLookupService.jsm
+++ b/mailnews/base/src/FolderLookupService.jsm
@@ -22,17 +22,17 @@ function FolderLookupService() {
   if (gCreated) {
     throw Components.Exception("", Cr.NS_ERROR_ALREADY_INITIALIZED);
   }
   this._map = new Map();
   gCreated = true;
 }
 
 FolderLookupService.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIFolderLookupService]),
+  QueryInterface: ChromeUtils.generateQI(["nsIFolderLookupService"]),
 
   /**
    * Fetch the folder corresponding to the given URI.
    * Will only return folders which already exist and have a parent. If this
    * not the case then null is returned.
    *
    * @param {String} uri - URI of folder to get.
    * @returns {nsIMsgFolder|null}
--- a/mailnews/base/src/MailNewsCommandLineHandler.jsm
+++ b/mailnews/base/src/MailNewsCommandLineHandler.jsm
@@ -150,13 +150,13 @@ MailNewsCommandLineHandler.prototype = {
     if (outer != null) {
       throw Components.Exception("", Cr.NS_ERROR_NO_AGGREGATION);
     }
 
     return this.QueryInterface(iid);
   },
 
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsICommandLineHandler,
-    Ci.nsIFactory,
-    Ci.nsIModule,
+    "nsICommandLineHandler",
+    "nsIFactory",
+    "nsIModule",
   ]),
 };
--- a/mailnews/base/src/MailNotificationService.jsm
+++ b/mailnews/base/src/MailNotificationService.jsm
@@ -52,19 +52,19 @@ function NewMailNotificationService() {
   );
 
   // Listen for mail-startup-done to do the rest of our setup after folders are initialized
   Services.obs.addObserver(this, "mail-startup-done");
 }
 
 NewMailNotificationService.prototype = {
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIObserver,
-    Ci.nsIFolderListener,
-    Ci.mozINewMailNotificationService,
+    "nsIObserver",
+    "nsIFolderListener",
+    "mozINewMailNotificationService",
   ]),
 
   _mUnreadCount: 0,
   _mNewCount: 0,
   _listeners: null,
   _log: null,
 
   get countNew() {
--- a/mailnews/base/src/MsgAsyncPrompter.jsm
+++ b/mailnews/base/src/MsgAsyncPrompter.jsm
@@ -89,17 +89,17 @@ function MsgAsyncPrompter() {
   this._log = Log4Moz.getConfiguredLogger(
     "msgAsyncPrompter",
     Log4Moz.Level.Warn,
     Log4Moz.Level.Warn
   );
 }
 
 MsgAsyncPrompter.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgAsyncPrompter]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgAsyncPrompter"]),
 
   _pendingPrompts: null,
   _asyncPromptInProgress: 0,
   _log: null,
 
   queueAsyncAuthPrompt(aKey, aJumpQueue, aCaller) {
     if (aKey in this._pendingPrompts) {
       this._log.debug(
--- a/mailnews/base/src/OAuth2Module.jsm
+++ b/mailnews/base/src/OAuth2Module.jsm
@@ -17,17 +17,17 @@ var { Services } = ChromeUtils.import("r
  * bearer token it can use to authenticate in SASL steps.
  * It also takes care of persising the refreshToken for later usage.
  *
  * @implements {msgIOAuth2Module}
  */
 function OAuth2Module() {}
 OAuth2Module.prototype = {
   // XPCOM registration stuff
-  QueryInterface: ChromeUtils.generateQI([Ci.msgIOAuth2Module]),
+  QueryInterface: ChromeUtils.generateQI(["msgIOAuth2Module"]),
 
   initFromSmtp(aServer) {
     return this._initPrefs(
       "mail.smtpserver." + aServer.key + ".",
       aServer.username,
       aServer.hostname
     );
   },
--- a/mailnews/base/test/unit/test_compactFailure.js
+++ b/mailnews/base/test/unit/test_compactFailure.js
@@ -22,25 +22,25 @@ var gUuid;
 
 // Allow certain xpcom errors.
 logHelperAllowedErrors.push("NS_ERROR_FILE_IS_LOCKED");
 logHelperAllowedErrors.push("NS_ERROR_FILE_TARGET_DOES_NOT_EXIST");
 
 function LockedFileOutputStream() {}
 
 LockedFileOutputStream.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIFileOutputStream]),
+  QueryInterface: ChromeUtils.generateQI(["nsIFileOutputStream"]),
 
   init(file, ioFlags, perm, behaviorFlags) {
     throw Components.Exception("", Cr.NS_ERROR_FILE_IS_LOCKED);
   },
 };
 
 var MsgDBServiceFailure = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgDBService]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgDBService"]),
 
   openMailDBFromFile(file, folder, create, leaveInvalidDB) {
     if (folder.name == "ShouldFail") {
       throw Components.Exception("", Cr.NS_ERROR_FILE_TARGET_DOES_NOT_EXIST);
     }
     return this._genuine.openMailDBFromFile(
       file,
       folder,
--- a/mailnews/base/test/unit/test_jsTreeSelection.js
+++ b/mailnews/base/test/unit/test_jsTreeSelection.js
@@ -4,17 +4,17 @@
 
 const { JSTreeSelection } = ChromeUtils.import(
   "resource:///modules/JsTreeSelection.jsm"
 );
 
 var fakeView = {
   rowCount: 101,
   selectionChanged() {},
-  QueryInterface: ChromeUtils.generateQI([Ci.nsITreeView]),
+  QueryInterface: ChromeUtils.generateQI(["nsITreeView"]),
 };
 
 var sel = new JSTreeSelection(null);
 sel.view = fakeView;
 
 function bad_ranges(aMsg, aExpected) {
   let s = "\x1b[1;31m!!! BAD RANGES: " + aMsg + "\n";
   s += "Selection ranges: " + sel._ranges.length + ":";
--- a/mailnews/base/test/unit/test_nsMsgMailSession_Alerts.js
+++ b/mailnews/base/test/unit/test_nsMsgMailSession_Alerts.js
@@ -29,27 +29,27 @@ function alert(aDialogTitle, aText) {
   gText = aText;
 }
 
 var msgWindow = {
   get promptDialog() {
     return alertUtilsPrompts;
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgWindow]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgWindow"]),
 };
 
 var msgUrl = {
   _msgWindow: null,
 
   get msgWindow() {
     return this._msgWindow;
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgMailNewsUrl]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgMailNewsUrl"]),
 };
 
 function alertListener() {}
 
 alertListener.prototype = {
   mReturn: false,
   mMessage: null,
   mMsgWindow: null,
--- a/mailnews/base/test/unit/test_searchChaining.js
+++ b/mailnews/base/test/unit/test_searchChaining.js
@@ -65,17 +65,17 @@ async function searchTest() {
   // After the search completes, there still seem to be active URLs, so we
   //   have to wait before we are done and clear.
   await PromiseTestUtils.promiseDelay(1000);
 }
 
 // nsIMsgSearchNotify implementation
 var searchListener = {
   numTotalMessages: 0,
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgSearchNotify]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgSearchNotify"]),
   onNewSearch() {
     this.numTotalMessages = 0;
   },
   onSearchHit(dbHdr, folder) {
     this.numTotalMessages++;
   },
   onSearchDone(status) {
     Assert.equal(this.numTotalMessages, 1);
--- a/mailnews/base/util/JsTreeSelection.jsm
+++ b/mailnews/base/util/JsTreeSelection.jsm
@@ -665,17 +665,17 @@ JSTreeSelection.prototype = {
   },
 
   currentColumn: null,
 
   get shiftSelectPivot() {
     return this._shiftSelectPivot != null ? this._shiftSelectPivot : -1;
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsITreeSelection]),
+  QueryInterface: ChromeUtils.generateQI(["nsITreeSelection"]),
 
   /*
    * Functions after this aren't part of the nsITreeSelection interface.
    */
 
   /**
    * Duplicate this selection on another nsITreeSelection. This is useful
    * when you would like to discard this selection for a real tree selection.
--- a/mailnews/base/util/OAuth2.jsm
+++ b/mailnews/base/util/OAuth2.jsm
@@ -129,18 +129,18 @@ OAuth2.prototype = {
         }
 
         this._listener = {
           window: aWindow,
           webProgress: aWebProgress,
           _parent: this.account,
 
           QueryInterface: ChromeUtils.generateQI([
-            Ci.nsIWebProgressListener,
-            Ci.nsISupportsWeakReference,
+            "nsIWebProgressListener",
+            "nsISupportsWeakReference",
           ]),
 
           _cleanUp() {
             this.webProgress.removeProgressListener(this);
             this.window.close();
             delete this.window;
           },
 
--- a/mailnews/compose/src/SMTPProtocolHandler.jsm
+++ b/mailnews/compose/src/SMTPProtocolHandler.jsm
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var EXPORTED_SYMBOLS = ["SMTPProtocolHandler", "SMTPSProtocolHandler"];
 
 var nsIProtocolHandler = Ci.nsIProtocolHandler;
 
 function makeProtocolHandler(aProtocol, aDefaultPort, aClassID) {
   return {
-    QueryInterface: ChromeUtils.generateQI([nsIProtocolHandler]),
+    QueryInterface: ChromeUtils.generateQI(["nsIProtocolHandler"]),
 
     scheme: aProtocol,
     defaultPort: aDefaultPort,
     protocolFlags:
       nsIProtocolHandler.URI_NORELATIVE |
       nsIProtocolHandler.URI_DANGEROUS_TO_LOAD |
       nsIProtocolHandler.URI_NON_PERSISTABLE |
       nsIProtocolHandler.ALLOWS_PROXY |
--- a/mailnews/db/gloda/components/GlodaAutoComplete.jsm
+++ b/mailnews/db/gloda/components/GlodaAutoComplete.jsm
@@ -539,17 +539,17 @@ function GlodaAutoComplete() {
     this.completers.push(new ContactTagCompleter()); // not async.
     this.completers.push(new MessageTagCompleter()); // not async.
   } catch (e) {
     logException(e);
   }
 }
 
 GlodaAutoComplete.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIAutoCompleteSearch]),
+  QueryInterface: ChromeUtils.generateQI(["nsIAutoCompleteSearch"]),
 
   startSearch(aString, aParam, aResult, aListener) {
     try {
       let result = new nsAutoCompleteGlodaResult(aListener, this, aString);
       // save this for hacky access to the search.  I somewhat suspect we simply
       //  should not be using the formal autocomplete mechanism at all.
       // Used in glodacomplete.xml.
       this.curResult = result;
--- a/mailnews/db/gloda/components/MimeMessageEmitter.jsm
+++ b/mailnews/db/gloda/components/MimeMessageEmitter.jsm
@@ -63,17 +63,17 @@ function MimeMessageEmitter() {
   this._state = kStateUnknown;
 
   this._writeBody = false;
 }
 
 var deathToNewlines = /\n/g;
 
 MimeMessageEmitter.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMimeEmitter]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMimeEmitter"]),
 
   initialize(aUrl, aChannel, aFormat) {
     this._url = aUrl;
     this._curPart = new this._mimeMsg.MimeMessage();
     // the partName is intentionally ""!  not a place-holder!
     this._curPart.partName = "";
     this._curAttachment = "";
     this._partMap[""] = this._curPart;
--- a/mailnews/db/gloda/modules/MimeMessage.jsm
+++ b/mailnews/db/gloda/modules/MimeMessage.jsm
@@ -67,17 +67,17 @@ function CallbackStreamListener(aMsgHdr,
   } else {
     this._callbacksThis = [aCallbackThis];
     this._callbacks = [aCallback];
   }
   activeStreamListeners[hdrURI] = this;
 }
 
 CallbackStreamListener.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
 
   // nsIRequestObserver part
   onStartRequest(aRequest) {
     this._request = aRequest;
   },
   onStopRequest(aRequest, aStatusCode) {
     let msgURI = this._msgHdr.folder.getUriForMsg(this._msgHdr);
     delete activeStreamListeners[msgURI];
--- a/mailnews/extensions/dsn/src/DSNService.jsm
+++ b/mailnews/extensions/dsn/src/DSNService.jsm
@@ -12,10 +12,10 @@ DSNService.prototype = {
   chromePackageName: "messenger",
   showPanel(server) {
     // don't show the panel for news, rss, or local accounts
     return (
       server.type != "nntp" && server.type != "rss" && server.type != "none"
     );
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgAccountManagerExtension]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgAccountManagerExtension"]),
 };
--- a/mailnews/extensions/mdn/src/MDNService.jsm
+++ b/mailnews/extensions/mdn/src/MDNService.jsm
@@ -15,10 +15,10 @@ MDNService.prototype = {
     return (
       server.type != "nntp" &&
       server.type != "rss" &&
       server.type != "im" &&
       server.type != "none"
     );
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgAccountManagerExtension]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgAccountManagerExtension"]),
 };
--- a/mailnews/extensions/newsblog/content/NewsBlog.jsm
+++ b/mailnews/extensions/newsblog/content/NewsBlog.jsm
@@ -14,19 +14,19 @@ FeedDownloader.prototype = {
   },
   subscribeToFeed(aUrl, aFolder, aMsgWindow) {
     FeedUtils.subscribeToFeed(aUrl, aFolder, aMsgWindow);
   },
   updateSubscriptionsDS(aFolder, aOrigFolder, aAction) {
     FeedUtils.updateSubscriptionsDS(aFolder, aOrigFolder, aAction);
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsINewsBlogFeedDownloader]),
+  QueryInterface: ChromeUtils.generateQI(["nsINewsBlogFeedDownloader"]),
 };
 
 function FeedAcctMgrExtension() {}
 FeedAcctMgrExtension.prototype = {
   name: "newsblog",
   chromePackageName: "messenger-newsblog",
   showPanel: server => false,
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgAccountManagerExtension]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgAccountManagerExtension"]),
 };
--- a/mailnews/imap/test/unit/test_cacheParts.js
+++ b/mailnews/imap/test/unit/test_cacheParts.js
@@ -26,18 +26,18 @@ var gMsgURL2;
 var gMsgPartURL2;
 var gUidValidity;
 
 // We use this as a display consumer
 var streamListener = {
   _data: "",
 
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIStreamListener,
-    Ci.nsIRequestObserver,
+    "nsIStreamListener",
+    "nsIRequestObserver",
   ]),
 
   // nsIRequestObserver
   onStartRequest(aRequest) {},
   onStopRequest(aRequest, aStatusCode) {
     Assert.equal(aStatusCode, Cr.NS_OK);
   },
 
--- a/mailnews/imap/test/unit/test_chunkLastLF.js
+++ b/mailnews/imap/test/unit/test_chunkLastLF.js
@@ -117,17 +117,17 @@ function* endTest() {
   while (thread.hasPendingEvents()) {
     thread.processNextEvent(true);
   }
 
   yield true;
 }
 
 var gStreamListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
   _stream: null,
   _data: null,
   onStartRequest(aRequest) {
     this._data = "";
     this._stream = null;
   },
   onStopRequest(aRequest, aStatusCode) {
     async_driver();
--- a/mailnews/imap/test/unit/test_dod.js
+++ b/mailnews/imap/test/unit/test_dod.js
@@ -109,17 +109,17 @@ function* streamMessages() {
         Assert.ok(buf.includes(marker));
       } catch (e) {}
     }
   }
   yield true;
 }
 
 var gStreamListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
   _stream: null,
   _data: null,
   onStartRequest(aRequest) {
     this._data = "";
     this._stream = null;
   },
   onStopRequest(aRequest, aStatusCode) {
     async_driver();
--- a/mailnews/imap/test/unit/test_gmailOfflineMsgStore.js
+++ b/mailnews/imap/test/unit/test_gmailOfflineMsgStore.js
@@ -250,18 +250,18 @@ asyncUrlListener.callback = function(aUr
   Assert.equal(aExitCode, 0);
 };
 
 // We use this as a display consumer
 var streamListener = {
   _data: "",
 
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIStreamListener,
-    Ci.nsIRequestObserver,
+    "nsIStreamListener",
+    "nsIRequestObserver",
   ]),
 
   // nsIRequestObserver
   onStartRequest(aRequest) {},
   onStopRequest(aRequest, aStatusCode) {
     Assert.equal(aStatusCode, 0);
   },
 
@@ -273,17 +273,17 @@ var streamListener = {
 
     scriptStream.init(aInputStream);
 
     scriptStream.read(aCount);
   },
 };
 
 var gStreamListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
   _stream: null,
   _data: null,
   onStartRequest(aRequest) {
     this._data = "";
   },
   onStopRequest(aRequest, aStatusCode) {
     async_driver();
     this._stream = null;
--- a/mailnews/imap/test/unit/test_imapHdrChunking.js
+++ b/mailnews/imap/test/unit/test_imapHdrChunking.js
@@ -22,18 +22,18 @@ var { MailServices } = ChromeUtils.impor
 // IMAP pump
 
 setupIMAPPump();
 
 // Dummy message window so we can say the inbox is open in a window.
 var dummyMsgWindow = {
   openFolder: IMAPPump.inbox,
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIMsgWindow,
-    Ci.nsISupportsWeakReference,
+    "nsIMsgWindow",
+    "nsISupportsWeakReference",
   ]),
 };
 
 var gFolderListener = {
   _gotNewMailBiff: false,
   OnItemIntPropertyChanged(aItem, aProperty, aOldValue, aNewValue) {
     if (
       aProperty == "BiffState" &&
--- a/mailnews/imap/test/unit/test_imapHdrStreaming.js
+++ b/mailnews/imap/test/unit/test_imapHdrStreaming.js
@@ -25,18 +25,18 @@ var gMsgFile1 = do_get_file("../../../da
 var gMsgId1 = "200806061706.m56H6RWT004933@mrapp54.mozilla.org";
 
 // We use this as a display consumer
 var streamListener = {
   _data: "",
   _stream: null,
 
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIStreamListener,
-    Ci.nsIRequestObserver,
+    "nsIStreamListener",
+    "nsIRequestObserver",
   ]),
 
   // nsIRequestObserver
   onStartRequest(aRequest) {},
   onStopRequest(aRequest, aStatusCode) {
     Assert.equal(aStatusCode, 0);
     Assert.ok(this._data.includes("Content-Type"));
     async_driver();
--- a/mailnews/imap/test/unit/test_imapStoreMsgOffline.js
+++ b/mailnews/imap/test/unit/test_imapStoreMsgOffline.js
@@ -33,18 +33,18 @@ var gFirstNewMsg;
 var gFirstMsgSize;
 var gImapInboxOfflineStoreSize;
 
 // We use this as a display consumer
 var streamListener = {
   _data: "",
 
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIStreamListener,
-    Ci.nsIRequestObserver,
+    "nsIStreamListener",
+    "nsIRequestObserver",
   ]),
 
   // nsIRequestObserver
   onStartRequest(aRequest) {},
   onStopRequest(aRequest, aStatusCode) {
     Assert.equal(aStatusCode, 0);
   },
 
@@ -240,17 +240,17 @@ var tests = [
   function checkOfflineStoreSize() {
     dump("checking offline store size\n");
     Assert.ok(IMAPPump.inbox.filePath.fileSize <= gImapInboxOfflineStoreSize);
   },
   teardown,
 ];
 
 var gStreamListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
   _stream: null,
   _data: null,
   onStartRequest(aRequest) {
     this._data = "";
   },
   onStopRequest(aRequest, aStatusCode) {
     async_driver();
   },
--- a/mailnews/import/test/unit/resources/TestMailImporter.jsm
+++ b/mailnews/import/test/unit/resources/TestMailImporter.jsm
@@ -1,19 +1,16 @@
 var EXPORTED_SYMBOLS = ["TestMailImpoter"];
 
 function TestMailImpoter() {}
 
 TestMailImpoter.prototype = {
   classID: Components.ID("{a81438ef-aca1-41a5-9b3a-3ccfbbe4f5e1}"),
 
-  QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIImportModule,
-    Ci.nsIImportMail,
-  ]),
+  QueryInterface: ChromeUtils.generateQI(["nsIImportModule", "nsIImportMail"]),
 
   contractID: "@mozilla.org/import/test;1",
 
   _xpcom_categories: [
     {
       category: "mailnewsimport",
       entry: "{a81438ef-aca1-41a5-9b3a-3ccfbbe4f5e1}",
       value: "mail",
--- a/mailnews/import/test/unit/resources/mock_windows_reg_factory.js
+++ b/mailnews/import/test/unit/resources/mock_windows_reg_factory.js
@@ -4,17 +4,17 @@ const { MockFactory } = ChromeUtils.impo
 
 var gUuid;
 
 function MockWindowsRegKey(registryData) {
   this._registryData = registryData;
 }
 
 MockWindowsRegKey.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIWindowsRegKey]),
+  QueryInterface: ChromeUtils.generateQI(["nsIWindowsRegKey"]),
 
   open(aRootKey, aRelPath, aMode) {
     if (!this._registryData[aRelPath]) {
       throw Components.Exception("", Cr.NS_ERROR_FAILURE);
     }
     this._keyPath = aRelPath;
   },
 
--- a/mailnews/jsaccount/test/unit/resources/TestJaMsgProtocolInfoComponent.jsm
+++ b/mailnews/jsaccount/test/unit/resources/TestJaMsgProtocolInfoComponent.jsm
@@ -68,10 +68,10 @@ TestJaMsgProtocolInfo.prototype = {
   },
   get showComposeMsgLink() {
     return false;
   },
   get foldersCreatedAsync() {
     return false;
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgProtocolInfo]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgProtocolInfo"]),
 };
--- a/mailnews/jsaccount/test/unit/resources/testJaBaseIncomingServer.jsm
+++ b/mailnews/jsaccount/test/unit/resources/testJaBaseIncomingServer.jsm
@@ -20,17 +20,17 @@ const JaBaseIncomingServerProperties = {
   baseContractID: "@mozilla.org/jacppincomingserverdelegator;1",
   baseInterfaces: [
     Ci.nsISupports,
     Ci.nsIMsgIncomingServer,
     Ci.nsIInterfaceRequestor,
     Ci.msgIOverride,
     Ci.nsISupportsWeakReference,
   ],
-  delegateInterfaces: [Ci.nsIMsgIncomingServer],
+  delegateInterfaces: ["nsIMsgIncomingServer"],
   contractID: "@mozilla.org/messenger/server;1?type=testja",
   classID: Components.ID("{0eec03cd-da67-4949-ab2d-5fa4bdc68135}"),
 };
 
 function JaBaseIncomingServer(aDelegator, aBaseInterfaces) {
   dump("JaBaseIncomingServer\n");
   // Typical boilerplate to include in all implementations.
 
--- a/mailnews/jsaccount/test/unit/resources/testJaBaseIncomingServerComponent.js
+++ b/mailnews/jsaccount/test/unit/resources/testJaBaseIncomingServerComponent.js
@@ -1,18 +1,18 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // This file is the component definition for a demo base implementation of a
 // javascript IncomingServer.
 
-var { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
+var { ComponentUtils } = ChromeUtils.import(
+  "resource://gre/modules/ComponentUtils.jsm"
 );
 const { JSAccountUtils } = ChromeUtils.import(
   "resource:///modules/jsaccount/JSAccountUtils.jsm"
 );
 var {
   JaBaseIncomingServerProperties,
   JaBaseIncomingServer,
 } = ChromeUtils.import(
@@ -29,11 +29,11 @@ function JaBaseIncomingServerConstructor
 JaBaseIncomingServerConstructor.prototype = {
   classID: JaBaseIncomingServerProperties.classID,
   _xpcom_factory: JSAccountUtils.jaFactory(
     JaBaseIncomingServerProperties,
     JaBaseIncomingServer
   ),
 };
 
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([
+this.NSGetFactory = ComponentUtils.generateNSGetFactory([
   JaBaseIncomingServerConstructor,
 ]);
--- a/mailnews/jsaccount/test/unit/resources/testJaBaseMsgFolder.jsm
+++ b/mailnews/jsaccount/test/unit/resources/testJaBaseMsgFolder.jsm
@@ -20,17 +20,17 @@ const JaBaseMsgFolderProperties = {
     Ci.nsIMsgFolder,
     Ci.nsIDBChangeListener,
     Ci.nsIUrlListener,
     Ci.nsIJunkMailClassificationListener,
     Ci.nsIMsgTraitClassificationListener,
     Ci.nsIInterfaceRequestor,
     Ci.msgIOverride,
   ],
-  delegateInterfaces: [Ci.nsIMsgFolder],
+  delegateInterfaces: ["nsIMsgFolder"],
   contractID: "@mozilla.org/mail/folder-factory;1?name=testja",
   classID: Components.ID("{8508ddeb-3eab-4877-a420-297518f62371}"),
 };
 
 function JaBaseMsgFolder(aDelegator, aBaseInterfaces) {
   // Typical boilerplate to include in all implementations.
 
   // Object delegating method calls to the appropriate XPCOM object.
--- a/mailnews/jsaccount/test/unit/resources/testJaBaseMsgFolderComponent.js
+++ b/mailnews/jsaccount/test/unit/resources/testJaBaseMsgFolderComponent.js
@@ -1,18 +1,18 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // This file is the component definition for a demo base implementation of a
 // javascript msgFolder.
 
-var { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
+var { ComponentUtils } = ChromeUtils.import(
+  "resource://gre/modules/ComponentUtils.jsm"
 );
 const { JSAccountUtils } = ChromeUtils.import(
   "resource:///modules/jsaccount/JSAccountUtils.jsm"
 );
 var { JaBaseMsgFolderProperties, JaBaseMsgFolder } = ChromeUtils.import(
   "resource://testing-common/mailnews/testJaBaseMsgFolder.jsm"
 );
 
@@ -23,11 +23,11 @@ function JaBaseMsgFolderConstructor() {}
 JaBaseMsgFolderConstructor.prototype = {
   classID: JaBaseMsgFolderProperties.classID,
   _xpcom_factory: JSAccountUtils.jaFactory(
     JaBaseMsgFolderProperties,
     JaBaseMsgFolder
   ),
 };
 
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([
+this.NSGetFactory = ComponentUtils.generateNSGetFactory([
   JaBaseMsgFolderConstructor,
 ]);
--- a/mailnews/jsaccount/test/unit/resources/testJaFooUrlComponent.js
+++ b/mailnews/jsaccount/test/unit/resources/testJaFooUrlComponent.js
@@ -2,18 +2,18 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
   One of the goals of JsAccount is to be able to incrementally extend a base
   implementation, possibly adding a new interface. This code demonstrates
   a mailnews URL extended for a hypthetical account type "foo".
 **/
 
-var { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
+var { ComponentUtils } = ChromeUtils.import(
+  "resource://gre/modules/ComponentUtils.jsm"
 );
 const { JSAccountUtils } = ChromeUtils.import(
   "resource:///modules/jsaccount/JSAccountUtils.jsm"
 );
 const { JaBaseUrl, JaBaseUrlProperties } = ChromeUtils.import(
   "resource:///modules/jsaccount/JaBaseUrl.jsm"
 );
 
@@ -91,9 +91,9 @@ FooUrl.prototype = {
   // readonly attribute boolean isAttachment;
   get isAttachment() {
     // We look to see if the URL has an attachment query
     let query = this.QueryInterface(Ci.nsIURL).query;
     return query && query.includes(ATTACHMENT_QUERY);
   },
 };
 
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FooUrlConstructor]);
+this.NSGetFactory = ComponentUtils.generateNSGetFactory([FooUrlConstructor]);
--- a/mailnews/local/test/unit/test_over2GBMailboxes.js
+++ b/mailnews/local/test/unit/test_over2GBMailboxes.js
@@ -119,17 +119,17 @@ function accessOver2GBMsg() {
   );
   let msghdr = getMessageHdr();
   let msgURI = msghdr.folder.getUriForMsg(msghdr);
   let msgServ = messenger.messageServiceFromURI(msgURI);
   msgServ.streamMessage(msgURI, gStreamListener, null, null, false, "", true);
 }
 
 var gStreamListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
   _stream: null,
   _data: null,
   onStartRequest(aRequest) {
     this._data = "";
   },
   onStopRequest(aRequest, aStatusCode) {
     let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
       Ci.nsIFileInputStream
--- a/mailnews/local/test/unit/test_pop3Download.js
+++ b/mailnews/local/test/unit/test_pop3Download.js
@@ -51,17 +51,17 @@ function streamNextMessage() {
   );
   let msghdr = gMsgHdrs[gHdrIndex];
   let msgURI = msghdr.folder.getUriForMsg(msghdr);
   let msgServ = messenger.messageServiceFromURI(msgURI);
   msgServ.streamMessage(msgURI, gStreamListener, null, null, false, "", true);
 }
 
 var gStreamListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
   _stream: null,
   _data: null,
   onStartRequest(aRequest) {
     this._stream = null;
     this._data = "";
   },
   onStopRequest(aRequest, aStatusCode) {
     // check that the streamed message starts with "From "
--- a/mailnews/local/test/unit/test_streamHeaders.js
+++ b/mailnews/local/test/unit/test_streamHeaders.js
@@ -104,18 +104,18 @@ function badStreaming() {
  * that has been read.
  */
 function createStreamListener(k) {
   return {
     _data: "",
     _stream: null,
 
     QueryInterface: ChromeUtils.generateQI([
-      Ci.nsIStreamListener,
-      Ci.nsIRequestObserver,
+      "nsIStreamListener",
+      "nsIRequestObserver",
     ]),
 
     // nsIRequestObserver
     onStartRequest(aRequest) {},
     onStopRequest(aRequest, aStatusCode) {
       k(this._data);
     },
 
--- a/mailnews/mime/src/MimeJSComponents.jsm
+++ b/mailnews/mime/src/MimeJSComponents.jsm
@@ -20,17 +20,17 @@ function HeaderHandler() {
   this.deliverEOF = function() {};
 }
 
 function StringEnumerator(iterator) {
   this._iterator = iterator;
   this._next = undefined;
 }
 StringEnumerator.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIUTF8StringEnumerator]),
+  QueryInterface: ChromeUtils.generateQI(["nsIUTF8StringEnumerator"]),
   [Symbol.iterator]() {
     return this._iterator;
   },
   _setNext() {
     if (this._next !== undefined) {
       return;
     }
     this._next = this._iterator.next();
@@ -144,18 +144,18 @@ MimeStructuredHeaders.prototype = {
   },
 };
 
 function MimeHeaders() {}
 MimeHeaders.prototype = {
   __proto__: MimeStructuredHeaders.prototype,
   classDescription: "Mime headers implementation",
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIMimeHeaders,
-    Ci.msgIStructuredHeaders,
+    "nsIMimeHeaders",
+    "msgIStructuredHeaders",
   ]),
 
   initialize(allHeaders) {
     this._headers = MimeParser.extractHeaders(allHeaders);
   },
 
   extractHeader(header, getAll) {
     if (!this._headers) {
@@ -179,18 +179,18 @@ MimeHeaders.prototype = {
 };
 
 function MimeWritableStructuredHeaders() {
   this._headers = new Map();
 }
 MimeWritableStructuredHeaders.prototype = {
   __proto__: MimeStructuredHeaders.prototype,
   QueryInterface: ChromeUtils.generateQI([
-    Ci.msgIStructuredHeaders,
-    Ci.msgIWritableStructuredHeaders,
+    "msgIStructuredHeaders",
+    "msgIWritableStructuredHeaders",
   ]),
 
   setHeader(aHeaderName, aValue) {
     this._headers.set(aHeaderName.toLowerCase(), aValue);
   },
 
   deleteHeader(aHeaderName) {
     this._headers.delete(aHeaderName.toLowerCase());
@@ -276,17 +276,17 @@ function fixArray(addresses, preserveGro
   if (count) {
     count.value = outputArray.length;
   }
   return outputArray;
 }
 
 function MimeAddressParser() {}
 MimeAddressParser.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgHeaderParser]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgHeaderParser"]),
 
   parseEncodedHeader(aHeader, aCharset, aPreserveGroups) {
     aHeader = aHeader || "";
     let value = MimeParser.parseHeaderField(
       aHeader,
       MimeParser.HEADER_ADDRESS | MimeParser.HEADER_OPTION_ALL_I18N,
       aCharset
     );
@@ -461,17 +461,17 @@ MimeAddressParser.prototype = {
   makeMimeAddress(aName, aEmail) {
     let object = this.makeMailboxObject(aName, aEmail);
     return this.makeMimeHeader([object]);
   },
 };
 
 function MimeConverter() {}
 MimeConverter.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMimeConverter]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMimeConverter"]),
 
   encodeMimePartIIStr_UTF8(aHeader, aStructured, aFieldNameLen, aLineLength) {
     // Compute the encoding options. The way our API is structured in this
     // method is really horrendous and does not align with the way that JSMime
     // handles it. Instead, we'll need to create a fake header to take into
     // account the aFieldNameLen parameter.
     let fakeHeader = "-".repeat(aFieldNameLen);
     let options = {
--- a/mailnews/mime/src/mimeParser.jsm
+++ b/mailnews/mime/src/mimeParser.jsm
@@ -117,18 +117,18 @@ var MimeParser = {
         var scriptIn = Cc[
           "@mozilla.org/scriptableinputstream;1"
         ].createInstance(Ci.nsIScriptableInputStream);
         scriptIn.init(aStream);
         // Use readBytes instead of read to handle embedded NULs properly.
         this._parser.deliverData(scriptIn.readBytes(aCount));
       },
       QueryInterface: ChromeUtils.generateQI([
-        Ci.nsIStreamListener,
-        Ci.nsIRequestObserver,
+        "nsIStreamListener",
+        "nsIRequestObserver",
       ]),
     };
     setDefaultParserOptions(opts);
     StreamListener._parser = new jsmime.MimeParser(emitter, opts);
     return StreamListener;
   },
 
   /**
--- a/mailnews/mime/test/unit/head_mime.js
+++ b/mailnews/mime/test/unit/head_mime.js
@@ -78,17 +78,17 @@ function apply_mime_conversion(msgUri, h
     onEndMsgDownload(url) {},
     securityInfo: null,
     onMsgHasRemoteContent(aMsgHdr, aContentURI) {},
     dummyMsgHeader: new DummyMsgHeader(),
     get properties() {
       return null;
     },
     resetProperties() {},
-    QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgHeaderSink]),
+    QueryInterface: ChromeUtils.generateQI(["nsIMsgHeaderSink"]),
   };
 
   // Copy the descriptors from headerSink to stubHeaderSink.
   let fullHeaderSink = Object.create(headerSink);
   for (let name of Object.getOwnPropertyNames(stubHeaderSink)) {
     if (!(name in headerSink)) {
       Object.defineProperty(
         fullHeaderSink,
--- a/mailnews/mime/test/unit/test_attachment_size.js
+++ b/mailnews/mime/test/unit/test_attachment_size.js
@@ -239,17 +239,17 @@ var messages = [
         disposition: 'attachment; name="file.mp3"',
       },
     ],
     size: 123456789,
   },
 ];
 
 var gStreamListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
 
   // nsIRequestObserver part
   onStartRequest(aRequest) {
     // We reset the size here because we know that we only expect one attachment
     //  per test email. In the case of the attached .eml with nested
     //  attachments, this allows us to properly discard the nested attachment
     //  sizes.
     // msgHdrViewOverlay.js has a stack of attachment infos that properly
--- a/mailnews/mime/test/unit/test_badContentType.js
+++ b/mailnews/mime/test/unit/test_badContentType.js
@@ -55,17 +55,17 @@ var messages = [
         format: "",
       },
     ],
     testContentType: "application/pdf",
   },
 ];
 
 var gStreamListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
 
   // nsIRequestObserver part
   onStartRequest(aRequest) {
     // We reset the size here because we know that we only expect one attachment
     //  per test email
     // msgHdrViewOverlay.js has a stack of attachment infos that properly
     //  handles this.
     gMessageHeaderSink.size = null;
--- a/mailnews/mime/test/unit/test_hidden_attachments.js
+++ b/mailnews/mime/test/unit/test_hidden_attachments.js
@@ -130,17 +130,17 @@ var messages = [
         format: "",
         shouldShow: true,
       },
     ],
   },
 ];
 
 var gStreamListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
 
   // nsIRequestObserver part
   onStartRequest(aRequest) {},
   onStopRequest(aRequest, aStatusCode) {
     let expectedAttachments = this.allAttachments
       .filter(i => i.shouldShow)
       .map(i => i.filename);
     Assert.equal(
--- a/mailnews/mime/test/unit/test_message_attachment.js
+++ b/mailnews/mime/test/unit/test_message_attachment.js
@@ -87,17 +87,17 @@ var messages = [
         subject: "=?UTF-8?B?dGVzdFN1YmplY3Q=?=", // This string is 'testSubject'.
         charset: "UTF-8",
       }),
     ]),
   },
 ];
 
 var gStreamListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
 
   index: 0, // The index of the message we're currently looking at.
 
   // nsIRequestObserver part
   onStartRequest(aRequest) {
     this.contents = "";
     this.stream = null;
   },
--- a/mailnews/mime/test/unit/test_mimeStreaming.js
+++ b/mailnews/mime/test/unit/test_mimeStreaming.js
@@ -49,17 +49,17 @@ function streamMsg(msgHdr) {
     true, // have them create the converter
     // additional uri payload, note that "header=" is prepended automatically
     "filter",
     true
   );
 }
 
 var gStreamListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
   _stream: null,
   // nsIRequestObserver part
   onStartRequest(aRequest) {},
   onStopRequest(aRequest, aStatusCode) {
     doNextTest();
   },
 
   /* okay, our onDataAvailable should actually never be called.  the stream
--- a/mailnews/mime/test/unit/test_rfc822_body.js
+++ b/mailnews/mime/test/unit/test_rfc822_body.js
@@ -41,17 +41,17 @@ var messages = [
       ],
     }),
     attachmentCount: inline => (inline ? 2 : 1),
   },
 ];
 
 var gStreamListener = {
   stream: null,
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
 
   // nsIRequestObserver part
   onStartRequest(aRequest) {},
   onStopRequest(aRequest, aStatusCode) {
     Assert.equal(
       gMessageHeaderSink.attachmentCount,
       this.expectedAttachmentCount
     );
--- a/mailnews/mime/test/unit/test_smime_decrypt.js
+++ b/mailnews/mime/test/unit/test_smime_decrypt.js
@@ -181,17 +181,17 @@ let smimeHeaderSink = {
         this._results.push(this.resultEnc);
         if (this.resultSig != null) {
           this._results.push(this.resultSig);
         }
       }
       this._deferred.resolve(this._results);
     }
   },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgSMIMEHeaderSink]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgSMIMEHeaderSink"]),
 };
 
 /**
  * Note on FILENAMES taken from the NSS test suite:
  * - env: CMS enveloped (encrypted)
  * - dsig: CMS detached signature (with multipart MIME)
  * - sig: CMS opaque signature (content embedded inside signature)
  * - bad: message text does not match signature
--- a/mailnews/mime/test/unit/test_text_attachment.js
+++ b/mailnews/mime/test/unit/test_text_attachment.js
@@ -35,17 +35,17 @@ var messages = [
         filename: "test.txt",
         format: "",
       },
     ],
   },
 ];
 
 var gStreamListener = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
 
   _str: "",
   // nsIRequestObserver part
   onStartRequest(aRequest) {
     this.str = "";
     this._stream = null;
   },
   onStopRequest(aRequest, aStatusCode) {
--- a/mailnews/news/src/NewsAutoCompleteSearch.jsm
+++ b/mailnews/news/src/NewsAutoCompleteSearch.jsm
@@ -56,17 +56,17 @@ NewsAutoCompleteResult.prototype = {
   getFinalCompleteValueAt(aIndex) {
     return this.getValueAt(aIndex);
   },
 
   removeValueAt(aRowIndex, aRemoveFromDB) {},
 
   // nsISupports
 
-  QueryInterface: ChromeUtils.generateQI([kACR]),
+  QueryInterface: ChromeUtils.generateQI(["nsIAutoCompleteResult"]),
 };
 
 function NewsAutoCompleteSearch() {}
 
 NewsAutoCompleteSearch.prototype = {
   // For component registration
   classDescription: "Newsgroup Autocomplete",
 
@@ -125,10 +125,10 @@ NewsAutoCompleteSearch.prototype = {
     }
     aListener.onSearchResult(this, result);
   },
 
   stopSearch() {},
 
   // nsISupports
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIAutoCompleteSearch]),
+  QueryInterface: ChromeUtils.generateQI(["nsIAutoCompleteSearch"]),
 };
--- a/mailnews/news/test/unit/head_server_setup.js
+++ b/mailnews/news/test/unit/head_server_setup.js
@@ -236,18 +236,18 @@ function make_article(file) {
   return new newsArticle(post);
 }
 
 var articleTextListener = {
   data: "",
   finished: false,
 
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIStreamListener,
-    Ci.nsIRequestObserver,
+    "nsIStreamListener",
+    "nsIRequestObserver",
   ]),
 
   // nsIRequestObserver
   onStartRequest(aRequest) {},
   onStopRequest(aRequest, aStatusCode) {
     Assert.equal(aStatusCode, 0);
 
     // Reduce any \r\n to just \n so we can do a good comparison on any
--- a/mailnews/news/test/unit/test_bug540288.js
+++ b/mailnews/news/test/unit/test_bug540288.js
@@ -6,18 +6,18 @@ var daemon = setupNNTPDaemon();
 
 var server;
 var localserver;
 
 var streamListener = {
   _data: "",
 
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIStreamListener,
-    Ci.nsIRequestObserver,
+    "nsIStreamListener",
+    "nsIRequestObserver",
   ]),
 
   // nsIRequestObserver
   onStartRequest(aRequest) {},
   onStopRequest(aRequest, aStatusCode) {
     Assert.equal(aStatusCode, 0);
 
     // Reduce any \r\n to just \n so we can do a good comparison on any
--- a/mailnews/news/test/unit/test_bug695309.js
+++ b/mailnews/news/test/unit/test_bug695309.js
@@ -76,17 +76,17 @@ add_task(async function trigger_bug() {
   // present, be overwritten with one from the load queue that causes the
   // confusion. It then loads it again, and should (before the patch that fixes
   // this) read the 200 logon instead of the 211 group.
   let testFolder = localserver.rootFolder.getChildNamed("test.filter");
   let asyncUrlListener = new PromiseTestUtils.PromiseUrlListener();
   let promiseFolderEvent = function(folder, event) {
     return new Promise((resolve, reject) => {
       let folderListener = {
-        QueryInterface: ChromeUtils.generateQI([Ci.nsIFolderListener]),
+        QueryInterface: ChromeUtils.generateQI(["nsIFolderListener"]),
         OnItemEvent(aEventFolder, aEvent) {
           if (
             aEvent == "FolderLoaded" &&
             aEventFolder.prettyName == "test.subscribe.simple"
           ) {
             aEventFolder.getNewMessages(null, asyncUrlListener);
             return;
           }
--- a/mailnews/news/test/unit/test_getNewsMessage.js
+++ b/mailnews/news/test/unit/test_getNewsMessage.js
@@ -15,18 +15,18 @@ var daemon = setupNNTPDaemon();
 
 var server;
 var localserver;
 
 var streamListener = {
   _data: "",
 
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIStreamListener,
-    Ci.nsIRequestObserver,
+    "nsIStreamListener",
+    "nsIRequestObserver",
   ]),
 
   // nsIRequestObserver
   onStartRequest(aRequest) {},
   onStopRequest(aRequest, aStatusCode) {
     Assert.equal(aStatusCode, 0);
 
     // Reduce any \r\n to just \n so we can do a good comparison on any
--- a/mailnews/news/test/unit/test_internalUris.js
+++ b/mailnews/news/test/unit/test_internalUris.js
@@ -22,18 +22,18 @@ var dummyMsgWindow = {
       },
       showProgress() {},
     };
   },
   get promptDialog() {
     return alertUtilsPrompts;
   },
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIMsgWindow,
-    Ci.nsISupportsWeakReference,
+    "nsIMsgWindow",
+    "nsISupportsWeakReference",
   ]),
 };
 var daemon, localserver, server;
 
 var tests = [
   test_newMsgs,
   test_cancel,
   test_fetchMessage,
@@ -107,18 +107,18 @@ function* test_fetchMessage() {
   var statuscode = -1;
   let streamlistener = {
     onDataAvailable() {},
     onStartRequest() {},
     onStopRequest(aRequest, aStatus) {
       statuscode = aStatus;
     },
     QueryInterface: ChromeUtils.generateQI([
-      Ci.nsIStreamListener,
-      Ci.nsIRequestObserver,
+      "nsIStreamListener",
+      "nsIRequestObserver",
     ]),
   };
   let folder = localserver.rootFolder.getChildNamed("test.filter");
   MailServices.nntp.fetchMessage(
     folder,
     2,
     null,
     streamlistener,
@@ -251,18 +251,18 @@ function* test_escapedName() {
   var statuscode = -1;
   let streamlistener = {
     onDataAvailable() {},
     onStartRequest() {},
     onStopRequest(aRequest, aStatus) {
       statuscode = aStatus;
     },
     QueryInterface: ChromeUtils.generateQI([
-      Ci.nsIStreamListener,
-      Ci.nsIRequestObserver,
+      "nsIStreamListener",
+      "nsIRequestObserver",
     ]),
   };
   MailServices.nntp.fetchMessage(
     folder,
     1,
     null,
     streamlistener,
     asyncUrlListener
--- a/mailnews/test/resources/MockFactory.jsm
+++ b/mailnews/test/resources/MockFactory.jsm
@@ -54,17 +54,17 @@ var MockFactory = {
           let genuine = originalFactory.createInstance(outer, iid);
           wrappedMock._genuine = genuine;
         } catch (ex) {
           dump(ex);
         }
 
         return wrappedMock.QueryInterface(iid);
       },
-      QueryInterface: ChromeUtils.generateQI([Ci.nsIFactory]),
+      QueryInterface: ChromeUtils.generateQI(["nsIFactory"]),
     };
 
     Components.manager
       .QueryInterface(Ci.nsIComponentRegistrar)
       .registerFactory(
         Components.ID(uuid),
         "A Mock for " + contractID,
         contractID,
--- a/mailnews/test/resources/NetworkTestUtils.jsm
+++ b/mailnews/test/resources/NetworkTestUtils.jsm
@@ -47,17 +47,17 @@ function SocksClient(client_in, client_o
   this.client_in = client_in;
   this.client_out = client_out;
   this.inbuf = [];
   this.state = STATE_WAIT_GREETING;
   this.waitRead(this.client_in);
 }
 SocksClient.prototype = {
   // ... implement nsIInputStreamCallback ...
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIInputStreamCallback]),
+  QueryInterface: ChromeUtils.generateQI(["nsIInputStreamCallback"]),
   onInputStreamReady(input) {
     var len = input.available();
     var bin = new BinaryInputStream(input);
     var data = bin.readByteArray(len);
     this.inbuf = this.inbuf.concat(data);
 
     switch (this.state) {
       case STATE_WAIT_GREETING:
@@ -191,17 +191,17 @@ SocksClient.prototype = {
 function SocksTestServer() {
   this.listener = ServerSocket(-1, true, -1);
   dump("Starting SOCKS server on " + this.listener.port + "\n");
   this.port = this.listener.port;
   this.listener.asyncListen(this);
   this.client_connections = [];
 }
 SocksTestServer.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIServerSocketListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIServerSocketListener"]),
 
   onSocketAccepted(socket, trans) {
     var input = trans.openInputStream(0, 0, 0);
     var output = trans.openOutputStream(0, 0, 0);
     var client = new SocksClient(input, output);
     this.client_connections.push(client);
   },
 
@@ -253,17 +253,17 @@ var NetworkTestUtils = {
       Services.prefs.setCharPref("network.proxy.autoconfig_url", pac);
       */
 
       // Until then, we'll serve the actual proxy via a proxy filter.
       let pps = Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(
         Ci.nsIProtocolProxyService
       );
       let filter = {
-        QueryInterface: ChromeUtils.generateQI([Ci.nsIProtocolProxyFilter]),
+        QueryInterface: ChromeUtils.generateQI(["nsIProtocolProxyFilter"]),
         applyFilter(aURI, aProxyInfo, aCallback) {
           if (aURI.host != "localhost" && aURI.host != "127.0.0.1") {
             aCallback.onProxyFilterResult(
               pps.newProxyInfo(
                 "socks",
                 "localhost",
                 gSocksServer.port,
                 "",
--- a/mailnews/test/resources/PromiseTestUtils.jsm
+++ b/mailnews/test/resources/PromiseTestUtils.jsm
@@ -26,17 +26,17 @@ PromiseTestUtils.PromiseUrlListener = fu
   this.wrapped = aWrapped;
   this._promise = new Promise((resolve, reject) => {
     this._resolve = resolve;
     this._reject = reject;
   });
 };
 
 PromiseTestUtils.PromiseUrlListener.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIUrlListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIUrlListener"]),
 
   OnStartRunningUrl(aUrl) {
     if (this.wrapped && this.wrapped.OnStartRunningUrl) {
       this.wrapped.OnStartRunningUrl(aUrl);
     }
   },
   OnStopRunningUrl(aUrl, aExitCode) {
     if (this.wrapped && this.wrapped.OnStopRunningUrl) {
@@ -64,17 +64,17 @@ PromiseTestUtils.PromiseCopyListener = f
   this._promise = new Promise((resolve, reject) => {
     this._resolve = resolve;
     this._reject = reject;
   });
   this._result = { messageKeys: [], messageIds: [] };
 };
 
 PromiseTestUtils.PromiseCopyListener.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgCopyServiceListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgCopyServiceListener"]),
   OnStartCopy() {
     if (this.wrapped && this.wrapped.OnStartCopy) {
       this.wrapped.OnStartCopy();
     }
   },
   OnProgress(aProgress, aProgressMax) {
     if (this.wrapped && this.wrapped.OnProgress) {
       this.wrapped.OnProgress(aProgress, aProgressMax);
@@ -122,17 +122,17 @@ PromiseTestUtils.PromiseStreamListener =
     this._resolve = resolve;
     this._reject = reject;
   });
   this._data = null;
   this._stream = null;
 };
 
 PromiseTestUtils.PromiseStreamListener.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
 
   onStartRequest(aRequest) {
     if (this.wrapped && this.wrapped.onStartRequest) {
       this.wrapped.onStartRequest(aRequest);
     }
     this._data = "";
     this._stream = null;
   },
@@ -172,17 +172,17 @@ PromiseTestUtils.PromiseStreamListener.p
  * @param folder   nsIMsgFolder to listen to
  * @param event    string event name to listen for. Example event is
  *                 "DeleteOrMoveMsgCompleted".
  * @return         promise that resolves when the event occurs
  */
 PromiseTestUtils.promiseFolderEvent = function(folder, event) {
   return new Promise((resolve, reject) => {
     let folderListener = {
-      QueryInterface: ChromeUtils.generateQI([Ci.nsIFolderListener]),
+      QueryInterface: ChromeUtils.generateQI(["nsIFolderListener"]),
       OnItemEvent(aEventFolder, aEvent) {
         if (folder === aEventFolder && event == aEvent) {
           MailServices.mailSession.RemoveFolderListener(folderListener);
           resolve();
         }
       },
     };
     MailServices.mailSession.AddFolderListener(
@@ -283,17 +283,17 @@ PromiseTestUtils.PromiseSearchNotify = f
   this.wrapped = aWrapped;
   this._promise = new Promise((resolve, reject) => {
     this._resolve = resolve;
     this._reject = reject;
   });
 };
 
 PromiseTestUtils.PromiseSearchNotify.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIMsgSearchNotify]),
+  QueryInterface: ChromeUtils.generateQI(["nsIMsgSearchNotify"]),
   onSearchHit(aHeader, aFolder) {
     if (this.wrapped && this.wrapped.onSearchHit) {
       this.wrapped.onSearchHit(aHeader, aFolder);
     }
   },
   onSearchDone(aResult) {
     this._searchSession.unregisterListener(this);
     if (this.wrapped && this.wrapped.onSearchDone) {
--- a/mailnews/test/resources/alertTestUtils.js
+++ b/mailnews/test/resources/alertTestUtils.js
@@ -164,17 +164,17 @@ var alertUtilsPrompts = {
       // eslint-disable-next-line no-undef
       return select(aDialogTitle, aText, aCount, aSelectList, aOutSelection);
     }
 
     do_throw("select unexpectedly called: " + aText + "\n");
     return false;
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIPrompt]),
+  QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]),
 };
 
 var alertUtilsPromptService = {
   alert(aParent, aDialogTitle, aText) {
     if (typeof alertPS == "function") {
       // eslint-disable-next-line no-undef
       alertPS(aParent, aDialogTitle, aText);
       return;
@@ -338,33 +338,33 @@ var alertUtilsPromptService = {
   createInstance(outer, iid) {
     if (outer != null) {
       throw Components.Exception("", Cr.NS_ERROR_NO_AGGREGATION);
     }
     return this.QueryInterface(iid);
   },
 
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIPromptService,
-    Ci.nsIPromptService2,
+    "nsIPromptService",
+    "nsIPromptService2",
   ]),
 };
 
 var alertUtilsWindowWatcher = {
   getNewPrompter(aParent) {
     return alertUtilsPrompts;
   },
 
   getNewAuthPrompter(aParent) {
     return Cc["@mozilla.org/login-manager/authprompter;1"].getService(
       Ci.nsIAuthPrompt
     );
   },
 
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIWindowWatcher]),
+  QueryInterface: ChromeUtils.generateQI(["nsIWindowWatcher"]),
 };
 
 function registerAlertTestUtils() {
   MockRegistrar.register(
     "@mozilla.org/embedcomp/window-watcher;1",
     alertUtilsWindowWatcher
   );
   MockRegistrar.register(
--- a/mailnews/test/resources/smimeUtils.jsm
+++ b/mailnews/test/resources/smimeUtils.jsm
@@ -23,17 +23,17 @@ const gCertDialogs = {
   },
   getPKCS12FilePassword: (ctx, password) => {
     password.value = "";
     return true;
   },
   viewCert: (ctx, cert) => {
     throw new Error("Not implemented");
   },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsICertificateDialogs]),
+  QueryInterface: ChromeUtils.generateQI(["nsICertificateDialogs"]),
 };
 
 var SmimeUtils = {
   ensureNSS() {
     // Ensure NSS is initialized.
     Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports);
 
     // Set up the internal key token so that subsequent code doesn't fail. If