Bug 1562313 - Convert most calendar JavaScript components (not calBackendLoader) to static registration. r=pmorris DONTBUILD
authorKhushil Mistry <khushil324@gmail.com>
Tue, 25 Feb 2020 12:48:44 +0200
changeset 37431 5958d77c395b5ec1df97b100215eeabd796e8924
parent 37430 3e7f62e8f741bdd3e09a656cb9c1321a26141fb4
child 37432 560479c08fef0a1657c7d7ceea382a469ff909c1
push id2566
push userclokep@gmail.com
push dateMon, 09 Mar 2020 19:20:31 +0000
treeherdercomm-beta@a352facfa0a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspmorris
bugs1562313
Bug 1562313 - Convert most calendar JavaScript components (not calBackendLoader) to static registration. r=pmorris DONTBUILD
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/CalDateTimeFormatter.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/calAlarm.js
calendar/base/src/calAlarmMonitor.js
calendar/base/src/calAlarmService.js
calendar/base/src/calAttachment.js
calendar/base/src/calAttendee.js
calendar/base/src/calCachedCalendar.js
calendar/base/src/calCalendarManager.js
calendar/base/src/calCalendarSearchService.js
calendar/base/src/calDateTimeFormatter.js
calendar/base/src/calDefaultACLManager.js
calendar/base/src/calDefaultACLManager.manifest
calendar/base/src/calDeletedItems.js
calendar/base/src/calEvent.js
calendar/base/src/calFreeBusyService.js
calendar/base/src/calIcsParser.js
calendar/base/src/calIcsSerializer.js
calendar/base/src/calItemBase.js
calendar/base/src/calItemModule.js
calendar/base/src/calItemModule.manifest
calendar/base/src/calItipItem.js
calendar/base/src/calProtocolHandler.js
calendar/base/src/calRecurrenceDate.js
calendar/base/src/calRecurrenceInfo.js
calendar/base/src/calRelation.js
calendar/base/src/calSleepMonitor.js
calendar/base/src/calSleepMonitor.manifest
calendar/base/src/calStartupService.js
calendar/base/src/calTimezoneService.js
calendar/base/src/calTimezoneService.manifest
calendar/base/src/calTodo.js
calendar/base/src/calTransactionManager.js
calendar/base/src/calWeekInfoService.js
calendar/base/src/components.conf
calendar/base/src/moz.build
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/import-export/calHtmlExport.js
calendar/import-export/calIcsImportExport.js
calendar/import-export/calImportExportModule.js
calendar/import-export/calImportExportModule.manifest
calendar/import-export/calListFormatter.js
calendar/import-export/calMonthGridPrinter.js
calendar/import-export/calOutlookCSVImportExport.js
calendar/import-export/calWeekPrinter.js
calendar/import-export/components.conf
calendar/import-export/moz.build
calendar/itip/CalItipEmailTransport.jsm
calendar/itip/calItipEmailTransport.js
calendar/itip/calItipEmailTransport.manifest
calendar/itip/components.conf
calendar/itip/moz.build
calendar/lightning/components/CalItipProtocolHandler.jsm
calendar/lightning/components/CalMimeConverter.jsm
calendar/lightning/components/calItipProtocolHandler.js
calendar/lightning/components/calItipProtocolHandler.manifest
calendar/lightning/components/components.conf
calendar/lightning/components/lightningTextCalendarConverter.js
calendar/lightning/components/lightningTextCalendarConverter.manifest
calendar/lightning/components/moz.build
calendar/providers/caldav/CalDavCalendar.jsm
calendar/providers/caldav/calDavCalendar.js
calendar/providers/caldav/calDavCalendar.manifest
calendar/providers/caldav/components.conf
calendar/providers/caldav/moz.build
calendar/providers/composite/CalCompositeCalendar.jsm
calendar/providers/composite/calCompositeCalendar.js
calendar/providers/composite/calCompositeCalendar.manifest
calendar/providers/composite/components.conf
calendar/providers/composite/moz.build
calendar/providers/ics/CalICSCalendar.jsm
calendar/providers/ics/calICSCalendar.js
calendar/providers/ics/calICSCalendar.manifest
calendar/providers/ics/components.conf
calendar/providers/ics/moz.build
calendar/providers/memory/CalMemoryCalendar.jsm
calendar/providers/memory/calMemoryCalendar.js
calendar/providers/memory/calMemoryCalendar.manifest
calendar/providers/memory/components.conf
calendar/providers/memory/moz.build
calendar/providers/storage/CalStorageCalendar.jsm
calendar/providers/storage/calStorageCalendar.js
calendar/providers/storage/calStorageCalendar.manifest
calendar/providers/storage/components.conf
calendar/providers/storage/moz.build
calendar/test/unit/test_imip.js
mail/installer/package-manifest.in
rename from calendar/base/src/calAlarm.js
rename to calendar/base/src/CalAlarm.jsm
--- a/calendar/base/src/calAlarm.js
+++ b/calendar/base/src/CalAlarm.jsm
@@ -1,28 +1,30 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalAlarm"];
+
 var { PluralForm } = ChromeUtils.import("resource://gre/modules/PluralForm.jsm");
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 var ALARM_RELATED_ABSOLUTE = Ci.calIAlarm.ALARM_RELATED_ABSOLUTE;
 var ALARM_RELATED_START = Ci.calIAlarm.ALARM_RELATED_START;
 var ALARM_RELATED_END = Ci.calIAlarm.ALARM_RELATED_END;
 
-function calAlarm() {
+function CalAlarm() {
   this.wrappedJSObject = this;
   this.mProperties = new Map();
   this.mPropertyParams = {};
   this.mAttendees = [];
   this.mAttachments = [];
 }
 
-calAlarm.prototype = {
+CalAlarm.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIAlarm]),
   classID: Components.ID("{b8db7c7f-c168-4e11-becb-f26c1c4f5f8f}"),
 
   mProperties: null,
   mPropertyParams: null,
   mAction: null,
   mAbsoluteDate: null,
   mOffset: null,
@@ -68,17 +70,17 @@ calAlarm.prototype = {
         propval.makeImmutable();
       }
     }
 
     this.mImmutable = true;
   },
 
   clone() {
-    let cloned = new calAlarm();
+    let cloned = new CalAlarm();
 
     cloned.mImmutable = false;
 
     const simpleMembers = ["mAction", "mSummary", "mDescription", "mRelated", "mRepeat"];
 
     const arrayMembers = ["mAttendees", "mAttachments"];
 
     const objectMembers = ["mAbsoluteDate", "mOffset", "mDuration", "mLastAck"];
rename from calendar/base/src/calAlarmMonitor.js
rename to calendar/base/src/CalAlarmMonitor.jsm
--- a/calendar/base/src/calAlarmMonitor.js
+++ b/calendar/base/src/CalAlarmMonitor.jsm
@@ -1,37 +1,39 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalAlarmMonitor"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 function peekAlarmWindow() {
   return Services.wm.getMostRecentWindow("Calendar:AlarmWindow");
 }
 
 /**
  * The alarm monitor takes care of playing the alarm sound and opening one copy
  * of the calendar-alarm-dialog. Both depend on their respective prefs to be
  * set. This monitor is only used for DISPLAY type alarms.
  */
-function calAlarmMonitor() {
+function CalAlarmMonitor() {
   this.wrappedJSObject = this;
   this.mAlarms = [];
 
   this.mSound = Cc["@mozilla.org/sound;1"].createInstance(Ci.nsISound);
 
   Services.obs.addObserver(this, "alarm-service-startup");
   Services.obs.addObserver(this, "alarm-service-shutdown");
 }
 
 var calAlarmMonitorClassID = Components.ID("{4b7ae030-ed79-11d9-8cd6-0800200c9a66}");
 var calAlarmMonitorInterfaces = [Ci.nsIObserver, Ci.calIAlarmServiceObserver];
-calAlarmMonitor.prototype = {
+CalAlarmMonitor.prototype = {
   mAlarms: null,
 
   // This is a work-around for the fact that there is a delay between when
   // 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
rename from calendar/base/src/calAlarmService.js
rename to calendar/base/src/CalAlarmService.jsm
--- a/calendar/base/src/calAlarmService.js
+++ b/calendar/base/src/CalAlarmService.jsm
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalAlarmService"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { PromiseUtils } = ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
 
 var kHoursBetweenUpdates = 6;
 
 function nowUTC() {
   return cal.dtz.jsDateToDateTime(new Date()).getInTimezone(cal.dtz.UTC);
@@ -18,17 +20,17 @@ function newTimerWithCallback(aCallback,
   timer.initWithCallback(
     aCallback,
     aDelay,
     aRepeating ? timer.TYPE_REPEATING_PRECISE : timer.TYPE_ONE_SHOT
   );
   return timer;
 }
 
-function calAlarmService() {
+function CalAlarmService() {
   this.wrappedJSObject = this;
 
   this.mLoadedCalendars = {};
   this.mTimerMap = {};
   this.mObservers = new cal.data.ListenerSet(Ci.calIAlarmServiceObserver);
 
   this.calendarObserver = {
     QueryInterface: ChromeUtils.generateQI([Ci.calIObserver]),
@@ -94,17 +96,17 @@ function calAlarmService() {
       this.alarmService.unobserveCalendar(aCalendar);
       delete this.alarmService.mLoadedCalendars[aCalendar.id];
     },
   };
 }
 
 var calAlarmServiceClassID = Components.ID("{7a9200dd-6a64-4fff-a798-c5802186e2cc}");
 var calAlarmServiceInterfaces = [Ci.calIAlarmService, Ci.nsIObserver];
-calAlarmService.prototype = {
+CalAlarmService.prototype = {
   mRangeStart: null,
   mRangeEnd: null,
   mUpdateTimer: null,
   mStarted: false,
   mTimerMap: null,
   mObservers: null,
   mTimezone: null,
 
rename from calendar/base/src/calAttachment.js
rename to calendar/base/src/CalAttachment.jsm
--- a/calendar/base/src/calAttachment.js
+++ b/calendar/base/src/CalAttachment.jsm
@@ -1,24 +1,23 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalAttachment"];
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
-//
-// calAttachment.js
-//
-function calAttachment() {
+function CalAttachment() {
   this.wrappedJSObject = this;
   this.mProperties = new Map();
 }
 
-calAttachment.prototype = {
+CalAttachment.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIAttachment]),
   classID: Components.ID("{5f76b352-ab75-4c2b-82c9-9206dbbf8571}"),
 
   mData: null,
   mHashId: null,
 
   get hashId() {
     if (!this.mHashId) {
@@ -146,17 +145,17 @@ calAttachment.prototype = {
     return this.mProperties.delete(aName);
   },
 
   deleteParameter(aName) {
     this.mProperties.delete(aName);
   },
 
   clone() {
-    let newAttachment = new calAttachment();
+    let newAttachment = new CalAttachment();
     newAttachment.mData = this.mData;
     newAttachment.mHashId = this.mHashId;
     for (let [name, value] of this.mProperties.entries()) {
       newAttachment.mProperties.set(name, value);
     }
     return newAttachment;
   },
 
rename from calendar/base/src/calAttendee.js
rename to calendar/base/src/CalAttendee.jsm
--- a/calendar/base/src/calAttendee.js
+++ b/calendar/base/src/CalAttendee.jsm
@@ -1,20 +1,25 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalAttendee"];
+
+var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
-function calAttendee() {
+Services.scriptloader.loadSubScript("resource:///components/calItemBase.js");
+
+function CalAttendee() {
   this.wrappedJSObject = this;
   this.mProperties = new Map();
 }
 
-calAttendee.prototype = {
+CalAttendee.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIAttendee]),
   classID: Components.ID("{5c8dcaa3-170c-4a73-8142-d531156f664d}"),
 
   mImmutable: false,
   get isMutable() {
     return !this.mImmutable;
   },
 
@@ -24,17 +29,17 @@ calAttendee.prototype = {
     }
   },
 
   makeImmutable() {
     this.mImmutable = true;
   },
 
   clone() {
-    let a = new calAttendee();
+    let a = new CalAttendee();
 
     if (this.mIsOrganizer) {
       a.isOrganizer = true;
     }
 
     const allProps = ["id", "commonName", "rsvp", "role", "participationStatus", "userType"];
     for (let prop of allProps) {
       a[prop] = this[prop];
@@ -188,14 +193,14 @@ calAttendee.prototype = {
     }
 
     return stringRep;
   },
 };
 
 var makeMemberAttr;
 if (makeMemberAttr) {
-  makeMemberAttr(calAttendee, "mCommonName", null, "commonName");
-  makeMemberAttr(calAttendee, "mRsvp", null, "rsvp");
-  makeMemberAttr(calAttendee, "mRole", null, "role");
-  makeMemberAttr(calAttendee, "mParticipationStatus", "NEEDS-ACTION", "participationStatus");
-  makeMemberAttr(calAttendee, "mUserType", "INDIVIDUAL", "userType");
+  makeMemberAttr(CalAttendee, "mCommonName", null, "commonName");
+  makeMemberAttr(CalAttendee, "mRsvp", null, "rsvp");
+  makeMemberAttr(CalAttendee, "mRole", null, "role");
+  makeMemberAttr(CalAttendee, "mParticipationStatus", "NEEDS-ACTION", "participationStatus");
+  makeMemberAttr(CalAttendee, "mUserType", "INDIVIDUAL", "userType");
 }
rename from calendar/base/src/calCalendarManager.js
rename to calendar/base/src/CalCalendarManager.jsm
--- a/calendar/base/src/calCalendarManager.js
+++ b/calendar/base/src/CalCalendarManager.jsm
@@ -1,32 +1,35 @@
 /* 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/. */
 
-/* import-globals-from calItemModule.js */
+/* import-globals-from calCachedCalendar.js */
+
+var EXPORTED_SYMBOLS = ["CalCalendarManager"];
 
 var { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { Preferences } = ChromeUtils.import("resource://gre/modules/Preferences.jsm");
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
+var { calCachedCalendar } = ChromeUtils.import("resource:///components/calCachedCalendar.js");
 
 var REGISTRY_BRANCH = "calendar.registry.";
 var MAX_INT = Math.pow(2, 31) - 1;
 var MIN_INT = -MAX_INT;
 
-function calCalendarManager() {
+function CalCalendarManager() {
   this.wrappedJSObject = this;
   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 = {
+CalCalendarManager.prototype = {
   classID: calCalendarManagerClassID,
   QueryInterface: cal.generateQI(calCalendarManagerInterfaces),
   classInfo: cal.generateCI({
     classID: calCalendarManagerClassID,
     contractID: "@mozilla.org/calendar/manager;1",
     classDescription: "Calendar Manager",
     interfaces: calCalendarManagerInterfaces,
     flags: Ci.nsIClassInfo.SINGLETON,
@@ -263,17 +266,17 @@ calCalendarManager.prototype = {
   },
 
   registerCalendar(calendar) {
     this.assureCache();
 
     // If the calendar is already registered, bail out
     cal.ASSERT(
       !calendar.id || !(calendar.id in this.mCache),
-      "[calCalendarManager::registerCalendar] calendar already registered!",
+      "[CalCalendarManager::registerCalendar] calendar already registered!",
       true
     );
 
     if (!calendar.id) {
       calendar.id = cal.getUUID();
     }
 
     Services.prefs.setStringPref(getPrefBranchFor(calendar.id) + "type", calendar.type);
rename from calendar/base/src/calCalendarSearchService.js
rename to calendar/base/src/CalCalendarSearchService.jsm
--- a/calendar/base/src/calCalendarSearchService.js
+++ b/calendar/base/src/CalCalendarSearchService.jsm
@@ -1,24 +1,26 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalCalendarSearchService"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
-function calCalendarSearchListener(numOperations, finalListener) {
+function CalCalendarSearchListener(numOperations, finalListener) {
   this.mFinalListener = finalListener;
   this.mNumOperations = numOperations;
   this.mResults = [];
 
   this.opGroup = new cal.data.OperationGroup(() => {
     this.notifyResult(null);
   });
 }
-calCalendarSearchListener.prototype = {
+CalCalendarSearchListener.prototype = {
   mFinalListener: null,
   mNumOperations: 0,
   opGroup: null,
 
   notifyResult(result) {
     let listener = this.mFinalListener;
     if (listener) {
       if (!this.opGroup.isPending) {
@@ -39,41 +41,41 @@ calCalendarSearchListener.prototype = {
       }
       if (aResult) {
         this.notifyResult(aResult);
       }
     }
   },
 };
 
-function calCalendarSearchService() {
+function CalCalendarSearchService() {
   this.wrappedJSObject = this;
   this.mProviders = new Set();
 }
 var calCalendarSearchServiceClassID = Components.ID("{f5f743cd-8997-428e-bc1b-644e73f61203}");
 var calCalendarSearchServiceInterfaces = [
   Ci.calICalendarSearchProvider,
   Ci.calICalendarSearchService,
 ];
-calCalendarSearchService.prototype = {
+CalCalendarSearchService.prototype = {
   mProviders: null,
 
   classID: calCalendarSearchServiceClassID,
   QueryInterface: cal.generateQI(calCalendarSearchServiceInterfaces),
   classInfo: cal.generateCI({
     classID: calCalendarSearchServiceClassID,
     contractID: "@mozilla.org/calendar/calendarsearch-service;1",
     classDescription: "Calendar Search Service",
     interfaces: calCalendarSearchServiceInterfaces,
     flags: Ci.nsIClassInfo.SINGLETON,
   }),
 
   // calICalendarSearchProvider:
   searchForCalendars(aString, aHints, aMaxResults, aListener) {
-    let groupListener = new calCalendarSearchListener(this.mProviders.size, aListener);
+    let groupListener = new CalCalendarSearchListener(this.mProviders.size, aListener);
     for (let provider of this.mProviders.values()) {
       try {
         groupListener.opGroup.add(
           provider.searchForCalendars(aString, aHints, aMaxResults, groupListener)
         );
       } catch (exc) {
         Cu.reportError(exc);
         groupListener.onResult(null, []); // dummy to adopt mNumOperations
rename from calendar/base/src/calDateTimeFormatter.js
rename to calendar/base/src/CalDateTimeFormatter.jsm
--- a/calendar/base/src/calDateTimeFormatter.js
+++ b/calendar/base/src/CalDateTimeFormatter.jsm
@@ -1,22 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalDateTimeFormatter"];
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
-function calDateTimeFormatter() {
+function CalDateTimeFormatter() {
   this.wrappedJSObject = this;
   this.mDateStringBundle = Services.strings.createBundle(
     "chrome://calendar/locale/dateFormat.properties"
   );
 }
-calDateTimeFormatter.prototype = {
+CalDateTimeFormatter.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIDateTimeFormatter]),
   classID: Components.ID("{4123da9a-f047-42da-a7d0-cc4175b9f36a}"),
 
   formatDate(aDate) {
     // Format the date using user's format preference (long or short)
     let format = Services.prefs.getIntPref("calendar.date.format", 0);
     return format == 0 ? this.formatDateLong(aDate) : this.formatDateShort(aDate);
   },
rename from calendar/base/src/calDefaultACLManager.js
rename to calendar/base/src/CalDefaultACLManager.jsm
--- a/calendar/base/src/calDefaultACLManager.js
+++ b/calendar/base/src/CalDefaultACLManager.jsm
@@ -1,21 +1,21 @@
 /* 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 EXPORTED_SYMBOLS = ["CalDefaultACLManager"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
-/* calDefaultACLManager */
-function calDefaultACLManager() {
+function CalDefaultACLManager() {
   this.mCalendarEntries = {};
 }
 
-calDefaultACLManager.prototype = {
+CalDefaultACLManager.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calICalendarACLManager]),
   classID: Components.ID("{7463258c-6ef3-40a2-89a9-bb349596e927}"),
 
   mCalendarEntries: null,
 
   /* calICalendarACLManager */
   _getCalendarEntryCached(aCalendar) {
     let calUri = aCalendar.uri.spec;
@@ -90,11 +90,8 @@ calDefaultItemACLEntry.prototype = {
 
   /* calIItemACLEntry */
   calendarEntry: null,
   userCanModify: true,
   userCanRespond: true,
   userCanViewAll: true,
   userCanViewDateAndTime: true,
 };
-
-/** Module Registration */
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calDefaultACLManager]);
rename from calendar/base/src/calDeletedItems.js
rename to calendar/base/src/CalDeletedItems.jsm
--- a/calendar/base/src/calDeletedItems.js
+++ b/calendar/base/src/CalDeletedItems.jsm
@@ -1,36 +1,38 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalDeletedItems"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { FileUtils } = ChromeUtils.import("resource://gre/modules/FileUtils.jsm");
 
 /**
  * Handles remembering deleted items.
  *
  * This is (currently) not a real trashcan. Only ids and time deleted is stored.
  * Note also that the code doesn't strictly check the calendar of the item,
  * except when a calendar id is passed to getDeletedDate.
  */
-function calDeletedItems() {
+function CalDeletedItems() {
   this.wrappedJSObject = this;
 
   this.completedNotifier = {
     handleResult() {},
     handleError() {},
     handleCompletion() {},
   };
 }
 
 var calDeletedItemsClassID = Components.ID("{8e6799af-e7e9-4e6c-9a82-a2413e86d8c3}");
 var calDeletedItemsInterfaces = [Ci.calIDeletedItems, Ci.nsIObserver, Ci.calIObserver];
-calDeletedItems.prototype = {
+CalDeletedItems.prototype = {
   classID: calDeletedItemsClassID,
   QueryInterface: cal.generateQI(calDeletedItemsInterfaces),
   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,
rename from calendar/base/src/calEvent.js
rename to calendar/base/src/CalEvent.jsm
--- a/calendar/base/src/calEvent.js
+++ b/calendar/base/src/CalEvent.jsm
@@ -1,52 +1,54 @@
 /* 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/. */
 
-/* import-globals-from calItemModule.js */
+/* import-globals-from calItemBase.js */
+
+var EXPORTED_SYMBOLS = ["CalEvent"];
 
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
+var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-//
-// constructor
-//
-function calEvent() {
+Services.scriptloader.loadSubScript("resource:///components/calItemBase.js");
+
+function CalEvent() {
   this.initItemBase();
 
   this.eventPromotedProps = {
     DTSTART: true,
     DTEND: true,
     __proto__: this.itemBasePromotedProps,
   };
 }
 var calEventClassID = Components.ID("{974339d5-ab86-4491-aaaf-2b2ca177c12b}");
 var calEventInterfaces = [Ci.calIItemBase, Ci.calIEvent, Ci.calIInternalShallowCopy];
-calEvent.prototype = {
+CalEvent.prototype = {
   __proto__: calItemBase.prototype,
 
   classID: calEventClassID,
   QueryInterface: cal.generateQI(calEventInterfaces),
   classInfo: cal.generateCI({
     classID: calEventClassID,
     contractID: "@mozilla.org/calendar/event;1",
     classDescription: "Calendar Event",
     interfaces: calEventInterfaces,
   }),
 
   cloneShallow(aNewParent) {
-    let cloned = new calEvent();
+    let cloned = new CalEvent();
     this.cloneItemBaseInto(cloned, aNewParent);
     return cloned;
   },
 
   createProxy(aRecurrenceId) {
     cal.ASSERT(!this.mIsProxy, "Tried to create a proxy for an existing proxy!", true);
 
-    let proxy = new calEvent();
+    let proxy = new CalEvent();
 
     // override proxy's DTSTART/DTEND/RECURRENCE-ID
     // before master is set (and item might get immutable):
     let endDate = aRecurrenceId.clone();
     endDate.addDuration(this.duration);
     proxy.endDate = endDate;
     proxy.startDate = aRecurrenceId;
 
rename from calendar/base/src/calFreeBusyService.js
rename to calendar/base/src/CalFreeBusyService.jsm
--- a/calendar/base/src/calFreeBusyService.js
+++ b/calendar/base/src/CalFreeBusyService.jsm
@@ -1,23 +1,25 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalFreeBusyService"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
-function calFreeBusyListener(numOperations, finalListener) {
+function CalFreeBusyListener(numOperations, finalListener) {
   this.mFinalListener = finalListener;
   this.mNumOperations = numOperations;
 
   this.opGroup = new cal.data.OperationGroup(() => {
     this.notifyResult(null);
   });
 }
-calFreeBusyListener.prototype = {
+CalFreeBusyListener.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIGenericOperationListener]),
 
   mFinalListener: null,
   mNumOperations: 0,
   opGroup: null,
 
   notifyResult(result) {
     let listener = this.mFinalListener;
@@ -43,29 +45,29 @@ calFreeBusyListener.prototype = {
         this.notifyResult(aResult);
       } else {
         this.notifyResult([]);
       }
     }
   },
 };
 
-function calFreeBusyService() {
+function CalFreeBusyService() {
   this.wrappedJSObject = this;
   this.mProviders = new Set();
 }
-calFreeBusyService.prototype = {
+CalFreeBusyService.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIFreeBusyProvider, Ci.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);
+    let groupListener = new CalFreeBusyListener(this.mProviders.size, aListener);
     for (let provider of this.mProviders.values()) {
       let operation = provider.getFreeBusyIntervals(
         aCalId,
         aRangeStart,
         aRangeEnd,
         aBusyTypes,
         groupListener
       );
rename from calendar/base/src/calIcsParser.js
rename to calendar/base/src/CalIcsParser.jsm
--- a/calendar/base/src/calIcsParser.js
+++ b/calendar/base/src/CalIcsParser.jsm
@@ -1,24 +1,26 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalIcsParser"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 var { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-function calIcsParser() {
+function CalIcsParser() {
   this.wrappedJSObject = this;
   this.mItems = [];
   this.mParentlessItems = [];
   this.mComponents = [];
   this.mProperties = [];
 }
-calIcsParser.prototype = {
+CalIcsParser.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.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.
rename from calendar/base/src/calIcsSerializer.js
rename to calendar/base/src/CalIcsSerializer.jsm
--- a/calendar/base/src/calIcsSerializer.js
+++ b/calendar/base/src/CalIcsSerializer.jsm
@@ -1,21 +1,23 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalIcsSerializer"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
-function calIcsSerializer() {
+function CalIcsSerializer() {
   this.wrappedJSObject = this;
   this.mItems = [];
   this.mProperties = [];
   this.mComponents = [];
 }
-calIcsSerializer.prototype = {
+CalIcsSerializer.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIIcsSerializer]),
   classID: Components.ID("{207a6682-8ff1-4203-9160-729ec28c8766}"),
 
   addItems(aItems) {
     if (aItems.length > 0) {
       this.mItems = this.mItems.concat(aItems);
     }
   },
rename from calendar/base/src/calItipItem.js
rename to calendar/base/src/CalItipItem.jsm
--- a/calendar/base/src/calItipItem.js
+++ b/calendar/base/src/CalItipItem.jsm
@@ -1,22 +1,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalItipItem"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
-/**
- * Constructor of calItipItem object
- */
-function calItipItem() {
+function CalItipItem() {
   this.wrappedJSObject = this;
   this.mCurrentItemIndex = 0;
 }
-calItipItem.prototype = {
+CalItipItem.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIItipItem]),
   classID: Components.ID("{f41392ab-dcad-4bad-818f-b3d1631c4d93}"),
 
   mIsInitialized: false,
 
   mSender: null,
   get sender() {
     return this.mSender;
@@ -158,17 +157,17 @@ calItipItem.prototype = {
         break;
       }
     }
 
     this.mIsInitialized = true;
   },
 
   clone() {
-    let newItem = new calItipItem();
+    let newItem = new CalItipItem();
     newItem.mItemList = this.mItemList.map(item => item.clone());
     newItem.mReceivedMethod = this.mReceivedMethod;
     newItem.mResponseMethod = this.mResponseMethod;
     newItem.mAutoResponse = this.mAutoResponse;
     newItem.mTargetCalendar = this.mTargetCalendar;
     newItem.mIdentity = this.mIdentity;
     newItem.mLocalStatus = this.mLocalStatus;
     newItem.mSender = this.mSender;
rename from calendar/base/src/calProtocolHandler.js
rename to calendar/base/src/CalProtocolHandler.jsm
--- a/calendar/base/src/calProtocolHandler.js
+++ b/calendar/base/src/CalProtocolHandler.jsm
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalProtocolHandlerWebcal", "CalProtocolHandlerWebcals"];
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 /**
  * Generic webcal constructor
  *
  * @param scheme        The scheme to init for (webcal, webcals)
  */
 function calProtocolHandler(scheme) {
@@ -62,28 +64,28 @@ calProtocolHandler.prototype = {
 
   // We are not overriding any special ports
   allowPort(aPort, aScheme) {
     return false;
   },
 };
 
 /** Constructor for webcal: protocol handler */
-function calProtocolHandlerWebcal() {
+function CalProtocolHandlerWebcal() {
   calProtocolHandler.call(this, "webcal");
 }
-calProtocolHandlerWebcal.prototype = {
+CalProtocolHandlerWebcal.prototype = {
   __proto__: calProtocolHandler.prototype,
 
   QueryInterface: ChromeUtils.generateQI([Ci.nsIProtocolHandler]),
   classID: Components.ID("{1153c73a-39be-46aa-9ba9-656d188865ca}"),
 };
 
 /** Constructor for webcals: protocol handler */
-function calProtocolHandlerWebcals() {
+function CalProtocolHandlerWebcals() {
   calProtocolHandler.call(this, "webcals");
 }
-calProtocolHandlerWebcals.prototype = {
+CalProtocolHandlerWebcals.prototype = {
   __proto__: calProtocolHandler.prototype,
 
   QueryInterface: ChromeUtils.generateQI([Ci.nsIProtocolHandler]),
   classID: Components.ID("{bdf71224-365d-4493-856a-a7e74026f766}"),
 };
rename from calendar/base/src/calRecurrenceDate.js
rename to calendar/base/src/CalRecurrenceDate.jsm
--- a/calendar/base/src/calRecurrenceDate.js
+++ b/calendar/base/src/CalRecurrenceDate.jsm
@@ -1,21 +1,23 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalRecurrenceDate"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
-function calRecurrenceDate() {
+function CalRecurrenceDate() {
   this.wrappedJSObject = this;
 }
 
 var calRecurrenceDateClassID = Components.ID("{806b6423-3aaa-4b26-afa3-de60563e9cec}");
 var calRecurrenceDateInterfaces = [Ci.calIRecurrenceItem, Ci.calIRecurrenceDate];
-calRecurrenceDate.prototype = {
+CalRecurrenceDate.prototype = {
   isMutable: true,
 
   mIsNegative: false,
   mDate: null,
 
   classID: calRecurrenceDateClassID,
   QueryInterface: cal.generateQI(calRecurrenceDateInterfaces),
   classInfo: cal.generateCI({
@@ -31,17 +33,17 @@ calRecurrenceDate.prototype = {
 
   ensureMutable() {
     if (!this.isMutable) {
       throw Cr.NS_ERROR_OBJECT_IS_IMMUTABLE;
     }
   },
 
   clone() {
-    let other = new calRecurrenceDate();
+    let other = new CalRecurrenceDate();
     other.mDate = this.mDate ? this.mDate.clone() : null;
     other.mIsNegative = this.mIsNegative;
     return other;
   },
 
   get isNegative() {
     return this.mIsNegative;
   },
rename from calendar/base/src/calRecurrenceInfo.js
rename to calendar/base/src/CalRecurrenceInfo.jsm
--- a/calendar/base/src/calRecurrenceInfo.js
+++ b/calendar/base/src/CalRecurrenceInfo.jsm
@@ -1,32 +1,34 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalRecurrenceInfo"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 function getRidKey(date) {
   if (!date) {
     return null;
   }
   let timezone = date.timezone;
   if (!timezone.isUTC && !timezone.isFloating) {
     date = date.getInTimezone(cal.dtz.UTC);
   }
   return date.icalString;
 }
 
-function calRecurrenceInfo() {
+function CalRecurrenceInfo() {
   this.wrappedJSObject = this;
   this.mRecurrenceItems = [];
   this.mExceptionMap = {};
 }
 
-calRecurrenceInfo.prototype = {
+CalRecurrenceInfo.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIRecurrenceInfo]),
   classID: Components.ID("{04027036-5884-4a30-b4af-f2cad79f6edf}"),
 
   mImmutable: false,
   mBaseItem: null,
   mEndDate: null,
   mRecurrenceItems: null,
   mPositiveRules: null,
@@ -83,17 +85,17 @@ calRecurrenceInfo.prototype = {
         item.makeImmutable();
       }
     }
 
     this.mImmutable = true;
   },
 
   clone() {
-    let cloned = new calRecurrenceInfo();
+    let cloned = new CalRecurrenceInfo();
     cloned.mBaseItem = this.mBaseItem;
 
     let clonedItems = [];
     for (let ritem of this.mRecurrenceItems) {
       clonedItems.push(ritem.clone());
     }
     cloned.mRecurrenceItems = clonedItems;
 
rename from calendar/base/src/calRelation.js
rename to calendar/base/src/CalRelation.jsm
--- a/calendar/base/src/calRelation.js
+++ b/calendar/base/src/CalRelation.jsm
@@ -1,25 +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 EXPORTED_SYMBOLS = ["CalRelation"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 /**
  * calRelation prototype definition
  *
  * @implements calIRelation
  * @constructor
  */
-function calRelation() {
+function CalRelation() {
   this.wrappedJSObject = this;
   this.mProperties = new Map();
 }
-calRelation.prototype = {
+CalRelation.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIRelation]),
   classID: Components.ID("{76810fae-abad-4019-917a-08e95d5bbd68}"),
 
   mType: null,
   mId: null,
 
   /**
    * @see calIRelation
@@ -105,17 +107,17 @@ calRelation.prototype = {
     return this.mProperties.set(aName, aValue);
   },
 
   deleteParameter(aName) {
     return this.mProperties.delete(aName);
   },
 
   clone() {
-    let newRelation = new calRelation();
+    let newRelation = new CalRelation();
     newRelation.mId = this.mId;
     newRelation.mType = this.mType;
     for (let [name, value] of this.mProperties.entries()) {
       newRelation.mProperties.set(name, value);
     }
     return newRelation;
   },
 };
rename from calendar/base/src/calSleepMonitor.js
rename to calendar/base/src/CalSleepMonitor.jsm
--- a/calendar/base/src/calSleepMonitor.js
+++ b/calendar/base/src/CalSleepMonitor.jsm
@@ -1,33 +1,34 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalSleepMonitor"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-var { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
-function calSleepMonitor() {
+function CalSleepMonitor() {
   this.wrappedJSObject = this;
 }
 
-calSleepMonitor.prototype = {
+CalSleepMonitor.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
   classID: Components.ID("9b987a8d-c2ef-4cb9-9602-1261b4b2f6fa"),
 
   interval: 60000,
   timer: null,
   expected: null,
   tolerance: 1000,
 
   callback() {
     let now = Date.now();
     if (now - this.expected > this.tolerance) {
-      cal.LOG("[calSleepMonitor] Sleep cycle detected, notifying observers.");
+      cal.LOG("[CalSleepMonitor] Sleep cycle detected, notifying observers.");
       Services.obs.notifyObservers(null, "wake_notification");
     }
     this.expected = now + this.interval;
   },
   start() {
     this.stop();
     this.expected = Date.now() + this.interval;
     this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
@@ -41,26 +42,24 @@ calSleepMonitor.prototype = {
     if (this.timer) {
       this.timer.cancel();
       this.timer = null;
     }
   },
 
   // nsIObserver:
   observe(aSubject, aTopic, aData) {
-    // calSleepMonitor is not used on Windows or OSX.
+    // CalSleepMonitor is not used on Windows or OSX.
     if (Services.appinfo.OS == "WINNT" || Services.appinfo.OS == "Darwin") {
       return;
     }
 
     if (aTopic == "profile-after-change") {
-      cal.LOG("[calSleepMonitor] Starting sleep monitor.");
+      cal.LOG("[CalSleepMonitor] Starting sleep monitor.");
       this.start();
 
       Services.obs.addObserver(this, "quit-application");
     } else if (aTopic == "quit-application") {
-      cal.LOG("[calSleepMonitor] Stopping sleep monitor.");
+      cal.LOG("[CalSleepMonitor] Stopping sleep monitor.");
       this.stop();
     }
   },
 };
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calSleepMonitor]);
rename from calendar/base/src/calStartupService.js
rename to calendar/base/src/CalStartupService.jsm
--- a/calendar/base/src/calStartupService.js
+++ b/calendar/base/src/CalStartupService.jsm
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalStartupService"];
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { FileSource, L10nRegistry } = ChromeUtils.import("resource://gre/modules/L10nRegistry.jsm");
 
 /**
  * Helper function to asynchronously call a certain method on the objects passed
  * in 'services' in order (i.e wait until the first completes before calling the
  * second
  *
@@ -19,22 +21,22 @@ function callOrderedServices(method, ser
     service[method]({
       onResult() {
         callOrderedServices(method, services);
       },
     });
   }
 }
 
-function calStartupService() {
+function CalStartupService() {
   this.wrappedJSObject = this;
   this.setupObservers();
 }
 
-calStartupService.prototype = {
+CalStartupService.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
   classID: Components.ID("{2547331f-34c0-4a4b-b93c-b503538ba6d6}"),
 
   // Startup Service Methods
 
   /**
    * Sets up the needed observers for noticing startup/shutdown
    */
rename from calendar/base/src/calTimezoneService.js
rename to calendar/base/src/CalTimezoneService.jsm
--- a/calendar/base/src/calTimezoneService.js
+++ b/calendar/base/src/CalTimezoneService.jsm
@@ -1,21 +1,24 @@
 /* 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/. */
 
 /* import-globals-from calTimezone.js */
 
+var EXPORTED_SYMBOLS = ["CalTimezoneService"];
+
 var { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-var { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 var { ICAL, unwrapSingle } = ChromeUtils.import("resource:///modules/calendar/Ical.jsm");
 
+Services.scriptloader.loadSubScript("resource:///components/calTimezone.js");
+
 function calStringEnumerator(stringArray) {
   this.mIndex = 0;
   this.mStringArray = stringArray;
 }
 calStringEnumerator.prototype = {
   // nsIUTF8StringEnumerator:
   [Symbol.iterator]() {
     return this.mStringArray.values();
@@ -26,30 +29,30 @@ calStringEnumerator.prototype = {
   getNext() {
     if (!this.hasMore()) {
       throw Cr.NS_ERROR_UNEXPECTED;
     }
     return this.mStringArray[this.mIndex++];
   },
 };
 
-function calTimezoneService() {
+function CalTimezoneService() {
   this.wrappedJSObject = this;
 
   this.mZones = new Map();
 
   ICAL.TimezoneService = this.wrappedJSObject;
 }
 var calTimezoneServiceClassID = Components.ID("{e736f2bd-7640-4715-ab35-887dc866c587}");
 var calTimezoneServiceInterfaces = [
   Ci.calITimezoneService,
   Ci.calITimezoneProvider,
   Ci.calIStartupService,
 ];
-calTimezoneService.prototype = {
+CalTimezoneService.prototype = {
   mDefaultTimezone: null,
   mHasSetupObservers: false,
   mVersion: null,
   mZones: null,
 
   classID: calTimezoneServiceClassID,
   QueryInterface: cal.generateQI(calTimezoneServiceInterfaces),
   classInfo: cal.generateCI({
@@ -68,17 +71,17 @@ calTimezoneService.prototype = {
     return id ? unwrapSingle(ICAL.Timezone, this.getTimezone(id)) : null;
   },
   remove() {},
   register() {},
 
   // calIStartupService:
   startup(aCompleteListener) {
     function fetchJSON(aURL) {
-      cal.LOG("[calTimezoneService] Loading " + aURL);
+      cal.LOG("[CalTimezoneService] Loading " + aURL);
 
       return new Promise((resolve, reject) => {
         let uri = Services.io.newURI(aURL);
         let channel = Services.io.newChannelFromURI(
           uri,
           null,
           Services.scriptSecurityManager.getSystemPrincipal(),
           null,
@@ -114,17 +117,17 @@ calTimezoneService.prototype = {
         for (let tzid of Object.keys(tzData.zones)) {
           let data = tzData.zones[tzid];
           if (typeof data == "object" && data !== null) {
             this.mZones.set(tzid, data);
           }
         }
 
         this.mVersion = tzData.version;
-        cal.LOG("[calTimezoneService] Timezones version " + this.version + " loaded");
+        cal.LOG("[CalTimezoneService] Timezones version " + this.version + " loaded");
 
         let bundleURL = "chrome://calendar/locale/timezones.properties";
         this.stringBundle = ICAL.Timezone.cal_tz_bundle = Services.strings.createBundle(bundleURL);
 
         // Make sure UTC and floating are cached by calling their getters
         this.UTC; // eslint-disable-line no-unused-expressions
         this.floating; // eslint-disable-line no-unused-expressions
       })
@@ -843,14 +846,8 @@ function guessSystemTimezone() {
   } catch (ex) {
     // don't abort if error occurs warning user
     Cu.reportError(ex);
   }
 
   // return the guessed timezone
   return probableTZId;
 }
-
-this.NSGetFactory = cid => {
-  Services.scriptloader.loadSubScript("resource:///components/calTimezone.js", this);
-  this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calTimezoneService]);
-  return this.NSGetFactory(cid);
-};
rename from calendar/base/src/calTodo.js
rename to calendar/base/src/CalTodo.jsm
--- a/calendar/base/src/calTodo.js
+++ b/calendar/base/src/CalTodo.jsm
@@ -1,55 +1,57 @@
 /* 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/. */
 
-/* import-globals-from calItemModule.js */
+/* import-globals-from calItemBase.js */
+
+var EXPORTED_SYMBOLS = ["CalTodo"];
 
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
+var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-//
-// constructor
-//
-function calTodo() {
+Services.scriptloader.loadSubScript("resource:///components/calItemBase.js");
+
+function CalTodo() {
   this.initItemBase();
 
   this.todoPromotedProps = {
     DTSTART: true,
     DTEND: true,
     DUE: true,
     COMPLETED: true,
     __proto__: this.itemBasePromotedProps,
   };
 }
 
 var calTodoClassID = Components.ID("{7af51168-6abe-4a31-984d-6f8a3989212d}");
 var calTodoInterfaces = [Ci.calIItemBase, Ci.calITodo, Ci.calIInternalShallowCopy];
-calTodo.prototype = {
+CalTodo.prototype = {
   __proto__: calItemBase.prototype,
 
   classID: calTodoClassID,
   QueryInterface: cal.generateQI(calTodoInterfaces),
   classInfo: cal.generateCI({
     classID: calTodoClassID,
     contractID: "@mozilla.org/calendar/todo;1",
     classDescription: "Calendar Todo",
     interfaces: calTodoInterfaces,
   }),
 
   cloneShallow(aNewParent) {
-    let cloned = new calTodo();
+    let cloned = new CalTodo();
     this.cloneItemBaseInto(cloned, aNewParent);
     return cloned;
   },
 
   createProxy(aRecurrenceId) {
     cal.ASSERT(!this.mIsProxy, "Tried to create a proxy for an existing proxy!", true);
 
-    let proxy = new calTodo();
+    let proxy = new CalTodo();
 
     // override proxy's DTSTART/DUE/RECURRENCE-ID
     // before master is set (and item might get immutable):
     let duration = this.duration;
     if (duration) {
       let dueDate = aRecurrenceId.clone();
       dueDate.addDuration(duration);
       proxy.dueDate = dueDate;
@@ -239,11 +241,11 @@ calTodo.prototype = {
     return (this.mDueDate = value);
   },
 };
 
 // var decl to prevent spurious error messages when loaded as component
 
 var makeMemberAttr;
 if (makeMemberAttr) {
-  makeMemberAttr(calTodo, "COMPLETED", null, "completedDate", true);
-  makeMemberAttr(calTodo, "PERCENT-COMPLETE", 0, "percentComplete", true);
+  makeMemberAttr(CalTodo, "COMPLETED", null, "completedDate", true);
+  makeMemberAttr(CalTodo, "PERCENT-COMPLETE", 0, "percentComplete", true);
 }
rename from calendar/base/src/calTransactionManager.js
rename to calendar/base/src/CalTransactionManager.jsm
--- a/calendar/base/src/calTransactionManager.js
+++ b/calendar/base/src/CalTransactionManager.jsm
@@ -1,30 +1,32 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalTransactionManager", "CalTransaction"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
-function calTransactionManager() {
+function CalTransactionManager() {
   this.wrappedJSObject = this;
   if (!this.transactionManager) {
     this.transactionManager = Cc["@mozilla.org/transactionmanager;1"].createInstance(
       Ci.nsITransactionManager
     );
   }
 }
 
-calTransactionManager.prototype = {
+CalTransactionManager.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.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);
+    let txn = new CalTransaction(aAction, aItem, aCalendar, aOldItem, aListener, aExtResponse);
     this.transactionManager.doTransaction(txn);
   },
 
   beginBatch() {
     this.transactionManager.beginBatch(null);
   },
 
   endBatch() {
@@ -63,29 +65,29 @@ calTransactionManager.prototype = {
   canRedo() {
     return (
       this.transactionManager.numberOfRedoItems > 0 &&
       this.checkWritable(this.transactionManager.peekRedoStack())
     );
   },
 };
 
-function calTransaction(aAction, aItem, aCalendar, aOldItem, aListener, aExtResponse) {
+function CalTransaction(aAction, aItem, aCalendar, aOldItem, aListener, aExtResponse) {
   this.wrappedJSObject = this;
   this.mAction = aAction;
   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];
-calTransaction.prototype = {
+CalTransaction.prototype = {
   classID: calTransactionClassID,
   QueryInterface: ChromeUtils.generateQI(calTransactionInterfaces),
 
   mAction: null,
   mCalendar: null,
   mItem: null,
   mOldItem: null,
   mOldCalendar: null,
rename from calendar/base/src/calWeekInfoService.js
rename to calendar/base/src/CalWeekInfoService.jsm
--- a/calendar/base/src/calWeekInfoService.js
+++ b/calendar/base/src/CalWeekInfoService.jsm
@@ -1,18 +1,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalWeekInfoService"];
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-function calWeekInfoService() {
+function CalWeekInfoService() {
   this.wrappedJSObject = this;
 }
-calWeekInfoService.prototype = {
+CalWeekInfoService.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.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
--- a/calendar/base/src/calCachedCalendar.js
+++ b/calendar/base/src/calCachedCalendar.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["calCachedCalendar"];
+
 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 = {
deleted file mode 100644
--- a/calendar/base/src/calDefaultACLManager.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {7463258c-6ef3-40a2-89a9-bb349596e927} calDefaultACLManager.js
-contract @mozilla.org/calendar/acl-manager;1?type=default {7463258c-6ef3-40a2-89a9-bb349596e927}
--- a/calendar/base/src/calItemBase.js
+++ b/calendar/base/src/calItemBase.js
@@ -1,15 +1,16 @@
 /* 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/. */
 
-/* import-globals-from calItemModule.js */
-
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
+var { CalAttendee } = ChromeUtils.import("resource:///modules/CalAttendee.jsm");
+var { CalRelation } = ChromeUtils.import("resource:///modules/CalRelation.jsm");
+var { CalAttachment } = ChromeUtils.import("resource:///modules/CalAttachment.jsm");
 
 /**
  * calItemBase prototype definition
  *
  * @implements calIItemBase
  * @constructor
  */
 function calItemBase() {
@@ -796,39 +797,39 @@ calItemBase.prototype = {
     this.mIsProxy = false;
     this.mProperties = new Map();
     this.mPropertyParams = {};
 
     this.mapPropsFromICS(icalcomp, this.icsBasePropMap);
 
     this.mAttendees = []; // don't inherit anything from parent
     for (let attprop of cal.iterate.icalProperty(icalcomp, "ATTENDEE")) {
-      let att = new calAttendee();
+      let att = new CalAttendee();
       att.icalProperty = attprop;
       this.addAttendee(att);
     }
 
     this.mAttachments = []; // don't inherit anything from parent
     for (let attprop of cal.iterate.icalProperty(icalcomp, "ATTACH")) {
-      let att = new calAttachment();
+      let att = new CalAttachment();
       att.icalProperty = attprop;
       this.addAttachment(att);
     }
 
     this.mRelations = []; // don't inherit anything from parent
     for (let relprop of cal.iterate.icalProperty(icalcomp, "RELATED-TO")) {
-      let rel = new calRelation();
+      let rel = new CalRelation();
       rel.icalProperty = relprop;
       this.addRelation(rel);
     }
 
     let org = null;
     let orgprop = icalcomp.getFirstProperty("ORGANIZER");
     if (orgprop) {
-      org = new calAttendee();
+      org = new CalAttendee();
       org.icalProperty = orgprop;
       org.isOrganizer = true;
     }
     this.mOrganizer = org;
 
     this.mCategories = [];
     for (let catprop of cal.iterate.icalProperty(icalcomp, "CATEGORIES")) {
       this.mCategories.push(catprop.value);
deleted file mode 100644
--- a/calendar/base/src/calItemModule.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/* 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/. */
-
-/* import-globals-from calItemBase.js */
-/* import-globals-from calCachedCalendar.js */
-/* import-globals-from calAlarm.js */
-/* import-globals-from calAlarmMonitor.js */
-/* import-globals-from calAlarmService.js */
-/* import-globals-from calAttendee.js */
-/* import-globals-from calAttachment.js */
-/* import-globals-from calCalendarManager.js */
-/* import-globals-from calCalendarSearchService.js */
-/* import-globals-from calDateTimeFormatter.js */
-/* import-globals-from calDeletedItems.js */
-/* import-globals-from calEvent.js */
-/* import-globals-from calFreeBusyService.js */
-/* import-globals-from calIcsParser.js */
-/* import-globals-from calIcsSerializer.js */
-/* import-globals-from calItipItem.js */
-/* import-globals-from calProtocolHandler.js */
-/* import-globals-from calRecurrenceDate.js */
-/* import-globals-from calRecurrenceInfo.js */
-/* import-globals-from calRelation.js */
-/* import-globals-from calStartupService.js */
-/* import-globals-from calTransactionManager.js */
-/* import-globals-from calTodo.js */
-/* import-globals-from calWeekInfoService.js */
-
-var { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-this._NSGetFactory = cid => {
-  let scriptLoadOrder = [
-    "resource:///components/calItemBase.js",
-    "resource:///components/calCachedCalendar.js",
-
-    "resource:///components/calAlarm.js",
-    "resource:///components/calAlarmMonitor.js",
-    "resource:///components/calAlarmService.js",
-    "resource:///components/calAttendee.js",
-    "resource:///components/calAttachment.js",
-    "resource:///components/calCalendarManager.js",
-    "resource:///components/calCalendarSearchService.js",
-    "resource:///components/calDateTimeFormatter.js",
-    "resource:///components/calDeletedItems.js",
-    "resource:///components/calEvent.js",
-    "resource:///components/calFreeBusyService.js",
-    "resource:///components/calIcsParser.js",
-    "resource:///components/calIcsSerializer.js",
-    "resource:///components/calItipItem.js",
-    "resource:///components/calProtocolHandler.js",
-    "resource:///components/calRecurrenceDate.js",
-    "resource:///components/calRecurrenceInfo.js",
-    "resource:///components/calRelation.js",
-    "resource:///components/calStartupService.js",
-    "resource:///components/calTransactionManager.js",
-    "resource:///components/calTodo.js",
-    "resource:///components/calWeekInfoService.js",
-  ];
-
-  for (let script of scriptLoadOrder) {
-    Services.scriptloader.loadSubScript(script, this);
-  }
-
-  let components = [
-    calAlarm,
-    calAlarmMonitor,
-    calAlarmService,
-    calAttendee,
-    calAttachment,
-    calCalendarManager,
-    calCalendarSearchService,
-    calDateTimeFormatter,
-    calDeletedItems,
-    calEvent,
-    calFreeBusyService,
-    calIcsParser,
-    calIcsSerializer,
-    calItipItem,
-    calProtocolHandlerWebcal,
-    calProtocolHandlerWebcals,
-    calRecurrenceDate,
-    calRecurrenceInfo,
-    calRelation,
-    calStartupService,
-    calTransaction,
-    calTransactionManager,
-    calTodo,
-    calWeekInfoService,
-  ];
-
-  this._NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
-  return this._NSGetFactory(cid);
-};
-
-// This version of NSGetFactory is used every time, even if it is replaced. Instead, we use a shim
-// calling an internal function. The internal function is replaced after the first run.
-this.NSGetFactory = cid => {
-  return this._NSGetFactory(cid);
-};
deleted file mode 100644
--- a/calendar/base/src/calItemModule.manifest
+++ /dev/null
@@ -1,73 +0,0 @@
-component {b8db7c7f-c168-4e11-becb-f26c1c4f5f8f} calItemModule.js
-contract @mozilla.org/calendar/alarm;1 {b8db7c7f-c168-4e11-becb-f26c1c4f5f8f}
-
-component {7a9200dd-6a64-4fff-a798-c5802186e2cc} calItemModule.js
-contract @mozilla.org/calendar/alarm-service;1 {7a9200dd-6a64-4fff-a798-c5802186e2cc}
-
-component {4b7ae030-ed79-11d9-8cd6-0800200c9a66} calItemModule.js
-contract @mozilla.org/calendar/alarm-monitor;1 {4b7ae030-ed79-11d9-8cd6-0800200c9a66}
-
-component {5c8dcaa3-170c-4a73-8142-d531156f664d} calItemModule.js
-contract @mozilla.org/calendar/attendee;1 {5c8dcaa3-170c-4a73-8142-d531156f664d}
-
-component {5f76b352-ab75-4c2b-82c9-9206dbbf8571} calItemModule.js
-contract @mozilla.org/calendar/attachment;1 {5f76b352-ab75-4c2b-82c9-9206dbbf8571}
-
-component {f42585e7-e736-4600-985d-9624c1c51992} calItemModule.js
-contract @mozilla.org/calendar/manager;1 {f42585e7-e736-4600-985d-9624c1c51992}
-
-component {f5f743cd-8997-428e-bc1b-644e73f61203} calItemModule.js
-contract @mozilla.org/calendar/calendarsearch-service;1 {f5f743cd-8997-428e-bc1b-644e73f61203}
-
-component {4123da9a-f047-42da-a7d0-cc4175b9f36a} calItemModule.js
-contract @mozilla.org/calendar/datetime-formatter;1 {4123da9a-f047-42da-a7d0-cc4175b9f36a}
-
-component {8e6799af-e7e9-4e6c-9a82-a2413e86d8c3} calItemModule.js
-contract @mozilla.org/calendar/deleted-items-manager;1 {8e6799af-e7e9-4e6c-9a82-a2413e86d8c3}
-category profile-after-change deleted-items-manager @mozilla.org/calendar/deleted-items-manager;1
-
-component {974339d5-ab86-4491-aaaf-2b2ca177c12b} calItemModule.js
-contract @mozilla.org/calendar/event;1 {974339d5-ab86-4491-aaaf-2b2ca177c12b}
-
-component {29c56cd5-d36e-453a-acde-0083bd4fe6d3} calItemModule.js
-contract @mozilla.org/calendar/freebusy-service;1 {29c56cd5-d36e-453a-acde-0083bd4fe6d3}
-
-component {6fe88047-75b6-4874-80e8-5f5800f14984} calItemModule.js
-contract @mozilla.org/calendar/ics-parser;1 {6fe88047-75b6-4874-80e8-5f5800f14984}
-
-component {207a6682-8ff1-4203-9160-729ec28c8766} calItemModule.js
-contract @mozilla.org/calendar/ics-serializer;1 {207a6682-8ff1-4203-9160-729ec28c8766}
-
-component {f41392ab-dcad-4bad-818f-b3d1631c4d93} calItemModule.js
-contract @mozilla.org/calendar/itip-item;1 {f41392ab-dcad-4bad-818f-b3d1631c4d93}
-
-component {1153c73a-39be-46aa-9ba9-656d188865ca} calItemModule.js
-contract @mozilla.org/network/protocol;1?name=webcal {1153c73a-39be-46aa-9ba9-656d188865ca}
-
-component {bdf71224-365d-4493-856a-a7e74026f766} calItemModule.js
-contract @mozilla.org/network/protocol;1?name=webcals {bdf71224-365d-4493-856a-a7e74026f766}
-
-component {806b6423-3aaa-4b26-afa3-de60563e9cec} calItemModule.js
-contract @mozilla.org/calendar/recurrence-date;1 {806b6423-3aaa-4b26-afa3-de60563e9cec}
-
-component {04027036-5884-4a30-b4af-f2cad79f6edf} calItemModule.js
-contract @mozilla.org/calendar/recurrence-info;1 {04027036-5884-4a30-b4af-f2cad79f6edf}
-
-component {76810fae-abad-4019-917a-08e95d5bbd68} calItemModule.js
-contract @mozilla.org/calendar/relation;1 {76810fae-abad-4019-917a-08e95d5bbd68}
-
-component {2547331f-34c0-4a4b-b93c-b503538ba6d6} calItemModule.js
-contract @mozilla.org/calendar/startup-service;1 {2547331f-34c0-4a4b-b93c-b503538ba6d6}
-category profile-after-change calendar-startup-service @mozilla.org/calendar/startup-service;1
-
-component {fcb54c82-2fb9-42cb-bf44-1e197a55e520} calItemModule.js
-contract @mozilla.org/calendar/transaction;1 {fcb54c82-2fb9-42cb-bf44-1e197a55e520}
-
-component {1d529847-d292-4222-b066-b8b17a794d62} calItemModule.js
-contract @mozilla.org/calendar/transactionmanager;1 {1d529847-d292-4222-b066-b8b17a794d62}
-
-component {7af51168-6abe-4a31-984d-6f8a3989212d} calItemModule.js
-contract @mozilla.org/calendar/todo;1 {7af51168-6abe-4a31-984d-6f8a3989212d}
-
-component {6877bbdd-f336-46f5-98ce-fe86d0285cc1} calItemModule.js
-contract @mozilla.org/calendar/weekinfo-service;1 {6877bbdd-f336-46f5-98ce-fe86d0285cc1}
deleted file mode 100644
--- a/calendar/base/src/calSleepMonitor.manifest
+++ /dev/null
@@ -1,3 +0,0 @@
-component {9b987a8d-c2ef-4cb9-9602-1261b4b2f6fa} calSleepMonitor.js
-contract @mozilla.org/calendar/sleep-monitor;1 {9b987a8d-c2ef-4cb9-9602-1261b4b2f6fa}
-category profile-after-change calSleepMonitor @mozilla.org/calendar/sleep-monitor;1
deleted file mode 100644
--- a/calendar/base/src/calTimezoneService.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {e736f2bd-7640-4715-ab35-887dc866c587} calTimezoneService.js
-contract @mozilla.org/calendar/timezone-service;1 {e736f2bd-7640-4715-ab35-887dc866c587}
new file mode 100644
--- /dev/null
+++ b/calendar/base/src/components.conf
@@ -0,0 +1,173 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/
+
+Classes = [
+  {
+    'cid': '{9b987a8d-c2ef-4cb9-9602-1261b4b2f6fa}',
+    'contract_ids': ['@mozilla.org/calendar/sleep-monitor;1'],
+    'jsm': 'resource:///modules/CalSleepMonitor.jsm',
+    'constructor': 'CalSleepMonitor',
+    'categories': {'profile-after-change': 'CalSleepMonitor'},
+  },
+  {
+    'cid': '{7463258c-6ef3-40a2-89a9-bb349596e927}',
+    'contract_ids': ['@mozilla.org/calendar/acl-manager;1?type=default'],
+    'jsm': 'resource:///modules/CalDefaultACLManager.jsm',
+    'constructor': 'CalDefaultACLManager',
+  },
+  {
+    'cid': '{e736f2bd-7640-4715-ab35-887dc866c587}',
+    'contract_ids': ['@mozilla.org/calendar/timezone-service;1'],
+    'jsm': 'resource:///modules/CalTimezoneService.jsm',
+    'constructor': 'CalTimezoneService',
+  },
+  {
+    'cid': '{b8db7c7f-c168-4e11-becb-f26c1c4f5f8f}',
+    'contract_ids': ['@mozilla.org/calendar/alarm;1'],
+    'jsm': 'resource:///modules/CalAlarm.jsm',
+    'constructor': 'CalAlarm',
+  },
+  {
+    'cid': '{4b7ae030-ed79-11d9-8cd6-0800200c9a66}',
+    'contract_ids': ['@mozilla.org/calendar/alarm-monitor;1'],
+    'jsm': 'resource:///modules/CalAlarmMonitor.jsm',
+    'constructor': 'CalAlarmMonitor',
+  },
+  {
+    'cid': '{7a9200dd-6a64-4fff-a798-c5802186e2cc}',
+    'contract_ids': ['@mozilla.org/calendar/alarm-service;1'],
+    'jsm': 'resource:///modules/CalAlarmService.jsm',
+    'constructor': 'CalAlarmService',
+  },
+  {
+    'cid': '{5f76b352-ab75-4c2b-82c9-9206dbbf8571}',
+    'contract_ids': ['@mozilla.org/calendar/attachment;1'],
+    'jsm': 'resource:///modules/CalAttachment.jsm',
+    'constructor': 'CalAttachment',
+  },
+  {
+    'cid': '{5c8dcaa3-170c-4a73-8142-d531156f664d}',
+    'contract_ids': ['@mozilla.org/calendar/attendee;1'],
+    'jsm': 'resource:///modules/CalAttendee.jsm',
+    'constructor': 'CalAttendee',
+  },
+  {
+    'cid': '{f42585e7-e736-4600-985d-9624c1c51992}',
+    'contract_ids': ['@mozilla.org/calendar/manager;1'],
+    'jsm': 'resource:///modules/CalCalendarManager.jsm',
+    'constructor': 'CalCalendarManager',
+  },
+  {
+    'cid': '{f5f743cd-8997-428e-bc1b-644e73f61203}',
+    'contract_ids': ['@mozilla.org/calendar/calendarsearch-service;1'],
+    'jsm': 'resource:///modules/CalCalendarSearchService.jsm',
+    'constructor': 'CalCalendarSearchService',
+  },
+  {
+    'cid': '{4123da9a-f047-42da-a7d0-cc4175b9f36a}',
+    'contract_ids': ['@mozilla.org/calendar/datetime-formatter;1'],
+    'jsm': 'resource:///modules/CalDateTimeFormatter.jsm',
+    'constructor': 'CalDateTimeFormatter',
+  },
+  {
+    'cid': '{8e6799af-e7e9-4e6c-9a82-a2413e86d8c3}',
+    'contract_ids': ['@mozilla.org/calendar/deleted-items-manager;1'],
+    'jsm': 'resource:///modules/CalDeletedItems.jsm',
+    'constructor': 'CalDeletedItems',
+    'categories': {'profile-after-change': 'deleted-items-manager'},
+  },
+  {
+    'cid': '{974339d5-ab86-4491-aaaf-2b2ca177c12b}',
+    'contract_ids': ['@mozilla.org/calendar/event;1'],
+    'jsm': 'resource:///modules/CalEvent.jsm',
+    'constructor': 'CalEvent',
+  },
+  {
+    'cid': '{29c56cd5-d36e-453a-acde-0083bd4fe6d3}',
+    'contract_ids': ['@mozilla.org/calendar/freebusy-service;1'],
+    'jsm': 'resource:///modules/CalFreeBusyService.jsm',
+    'constructor': 'CalFreeBusyService',
+  },
+  {
+    'cid': '{6fe88047-75b6-4874-80e8-5f5800f14984}',
+    'contract_ids': ['@mozilla.org/calendar/ics-parser;1'],
+    'jsm': 'resource:///modules/CalIcsParser.jsm',
+    'constructor': 'CalIcsParser',
+  },
+  {
+    'cid': '{207a6682-8ff1-4203-9160-729ec28c8766}',
+    'contract_ids': ['@mozilla.org/calendar/ics-serializer;1'],
+    'jsm': 'resource:///modules/CalIcsSerializer.jsm',
+    'constructor': 'CalIcsSerializer',
+  },
+  {
+    'cid': '{f41392ab-dcad-4bad-818f-b3d1631c4d93}',
+    'contract_ids': ['@mozilla.org/calendar/itip-item;1'],
+    'jsm': 'resource:///modules/CalItipItem.jsm',
+    'constructor': 'CalItipItem',
+  },
+  {
+    'cid': '{1153c73a-39be-46aa-9ba9-656d188865ca}',
+    'contract_ids': ['@mozilla.org/network/protocol;1?name=webcal'],
+    'jsm': 'resource:///modules/CalProtocolHandler.jsm',
+    'constructor': 'CalProtocolHandlerWebcal',
+  },
+  {
+    'cid': '{bdf71224-365d-4493-856a-a7e74026f766}',
+    'contract_ids': ['@mozilla.org/network/protocol;1?name=webcals'],
+    'jsm': 'resource:///modules/CalProtocolHandler.jsm',
+    'constructor': 'CalProtocolHandlerWebcals',
+  },
+  {
+    'cid': '{806b6423-3aaa-4b26-afa3-de60563e9cec}',
+    'contract_ids': ['@mozilla.org/calendar/recurrence-date;1'],
+    'jsm': 'resource:///modules/CalRecurrenceDate.jsm',
+    'constructor': 'CalRecurrenceDate',
+  },
+  {
+    'cid': '{04027036-5884-4a30-b4af-f2cad79f6edf}',
+    'contract_ids': ['@mozilla.org/calendar/recurrence-info;1'],
+    'jsm': 'resource:///modules/CalRecurrenceInfo.jsm',
+    'constructor': 'CalRecurrenceInfo',
+  },
+  {
+    'cid': '{76810fae-abad-4019-917a-08e95d5bbd68}',
+    'contract_ids': ['@mozilla.org/calendar/relation;1'],
+    'jsm': 'resource:///modules/CalRelation.jsm',
+    'constructor': 'CalRelation',
+  },
+  {
+    'cid': '{fcb54c82-2fb9-42cb-bf44-1e197a55e520}',
+    'contract_ids': ['@mozilla.org/calendar/transaction;1'],
+    'jsm': 'resource:///modules/CalTransactionManager.jsm',
+    'constructor': 'CalTransaction',
+  },
+  {
+    'cid': '{1d529847-d292-4222-b066-b8b17a794d62}',
+    'contract_ids': ['@mozilla.org/calendar/transactionmanager;1'],
+    'jsm': 'resource:///modules/CalTransactionManager.jsm',
+    'constructor': 'CalTransactionManager',
+  },
+  {
+    'cid': '{7af51168-6abe-4a31-984d-6f8a3989212d}',
+    'contract_ids': ['@mozilla.org/calendar/todo;1'],
+    'jsm': 'resource:///modules/CalTodo.jsm',
+    'constructor': 'CalTodo',
+  },
+  {
+    'cid': '{6877bbdd-f336-46f5-98ce-fe86d0285cc1}',
+    'contract_ids': ['@mozilla.org/calendar/weekinfo-service;1'],
+    'jsm': 'resource:///modules/CalWeekInfoService.jsm',
+    'constructor': 'CalWeekInfoService',
+  },
+  {
+    'cid': '{2547331f-34c0-4a4b-b93c-b503538ba6d6}',
+    'contract_ids': ['@mozilla.org/calendar/startup-service;1'],
+    'jsm': 'resource:///modules/CalStartupService.jsm',
+    'constructor': 'CalStartupService',
+    'categories': {'profile-after-change': 'calendar-startup-service'},
+  },
+]
--- a/calendar/base/src/moz.build
+++ b/calendar/base/src/moz.build
@@ -4,55 +4,54 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'calInternalInterfaces.idl',
 ]
 
 XPIDL_MODULE = 'calbaseinternal'
 
-EXTRA_COMPONENTS += [
-    'calDefaultACLManager.js',
-    'calDefaultACLManager.manifest',
-    'calItemModule.js',
-    'calItemModule.manifest',
-    'calSleepMonitor.js',
-    'calSleepMonitor.manifest',
-    'calTimezoneService.js',
-    'calTimezoneService.manifest',
+EXTRA_JS_MODULES += [
+    'CalAlarm.jsm',
+    'CalAlarmMonitor.jsm',
+    'CalAlarmService.jsm',
+    'CalAttachment.jsm',
+    'CalAttendee.jsm',
+    'CalCalendarManager.jsm',
+    'CalCalendarSearchService.jsm',
+    'CalDateTimeFormatter.jsm',
+    'CalDefaultACLManager.jsm',
+    'CalDeletedItems.jsm',
+    'CalEvent.jsm',
+    'CalFreeBusyService.jsm',
+    'CalIcsParser.jsm',
+    'CalIcsSerializer.jsm',
+    'CalItipItem.jsm',
+    'CalProtocolHandler.jsm',
+    'CalRecurrenceDate.jsm',
+    'CalRecurrenceInfo.jsm',
+    'CalRelation.jsm',
+    'CalSleepMonitor.jsm',
+    'CalStartupService.jsm',
+    'CalTimezoneService.jsm',
+    'CalTodo.jsm',
+    'CalTransactionManager.jsm',
+    'CalWeekInfoService.jsm',
+]
+
+XPCOM_MANIFESTS += [
+    'components.conf',
 ]
 
 # These files go in components so they can be packaged correctly.
 FINAL_TARGET_FILES.components += [
-    'calAlarm.js',
-    'calAlarmMonitor.js',
-    'calAlarmService.js',
-    'calAttachment.js',
-    'calAttendee.js',
     'calCachedCalendar.js',
-    'calCalendarManager.js',
-    'calCalendarSearchService.js',
-    'calDateTimeFormatter.js',
-    'calDeletedItems.js',
-    'calEvent.js',
     'calFilter.js',
-    'calFreeBusyService.js',
-    'calIcsParser.js',
-    'calIcsSerializer.js',
     'calItemBase.js',
-    'calItipItem.js',
-    'calProtocolHandler.js',
-    'calRecurrenceDate.js',
-    'calRecurrenceInfo.js',
-    'calRelation.js',
-    'calStartupService.js',
     'calTimezone.js',
-    'calTodo.js',
-    'calTransactionManager.js',
-    'calWeekInfoService.js',
 ]
 
 with Files('**'):
     BUG_COMPONENT = ('Calendar', 'Internal Components')
 
 with Files('calAlarm*'):
     BUG_COMPONENT = ('Calendar', 'Alarms')
 
rename from calendar/import-export/calHtmlExport.js
rename to calendar/import-export/CalHtmlExport.jsm
--- a/calendar/import-export/calHtmlExport.js
+++ b/calendar/import-export/CalHtmlExport.jsm
@@ -1,22 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalHtmlExporter"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 /**
  * HTML Export Plugin
  */
-function calHtmlExporter() {
+function CalHtmlExporter() {
   this.wrappedJSObject = this;
 }
 
-calHtmlExporter.prototype = {
+CalHtmlExporter.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIExporter]),
   classID: Components.ID("{72d9ab35-9b1b-442a-8cd0-ae49f00b159b}"),
 
   getFileTypes() {
     let wildmat = "*.html; *.htm";
     let label = cal.l10n.getCalString("filterHtml", [wildmat]);
     return [
       {
rename from calendar/import-export/calIcsImportExport.js
rename to calendar/import-export/CalIcsImportExport.jsm
--- a/calendar/import-export/calIcsImportExport.js
+++ b/calendar/import-export/CalIcsImportExport.jsm
@@ -1,54 +1,50 @@
 /* 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 { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
+var EXPORTED_SYMBOLS = ["CalIcsImporter", "CalIcsExporter"];
 
-/**
- * ICS Import and Export Plugin
- */
+var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 // Shared functions
 function getIcsFileTypes() {
   return [
     {
       QueryInterface: ChromeUtils.generateQI([Ci.calIFileType]),
       defaultExtension: "ics",
       extensionFilter: "*.ics",
       description: cal.l10n.getCalString("filterIcs", ["*.ics"]),
     },
   ];
 }
 
-// Importer
-function calIcsImporter() {
+function CalIcsImporter() {
   this.wrappedJSObject = this;
 }
 
-calIcsImporter.prototype = {
+CalIcsImporter.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.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();
   },
 };
 
-// Exporter
-function calIcsExporter() {
+function CalIcsExporter() {
   this.wrappedJSObject = this;
 }
 
-calIcsExporter.prototype = {
+CalIcsExporter.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.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
rename from calendar/import-export/calListFormatter.js
rename to calendar/import-export/CalListFormatter.jsm
--- a/calendar/import-export/calListFormatter.js
+++ b/calendar/import-export/CalListFormatter.jsm
@@ -1,22 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalListFormatter"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 /**
  * A thin wrapper around the html list exporter for the list print format.
  */
-function calListFormatter() {
+function CalListFormatter() {
   this.wrappedJSObject = this;
 }
 
-calListFormatter.prototype = {
+CalListFormatter.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIPrintFormatter]),
   classID: Components.ID("{9ae04413-fee3-45b9-8bbb-1eb39a4cbd1b}"),
 
   get name() {
     return cal.l10n.getCalString("formatListName");
   },
 
   formatToHtml(aStream, aStart, aEnd, aItems, aTitle) {
rename from calendar/import-export/calMonthGridPrinter.js
rename to calendar/import-export/CalMonthGridPrinter.jsm
--- a/calendar/import-export/calMonthGridPrinter.js
+++ b/calendar/import-export/CalMonthGridPrinter.jsm
@@ -1,23 +1,25 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalMonthPrinter"];
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 /**
  * Prints a rough month-grid of events/tasks
  */
-function calMonthPrinter() {
+function CalMonthPrinter() {
   this.wrappedJSObject = this;
 }
 
-calMonthPrinter.prototype = {
+CalMonthPrinter.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIPrintFormatter]),
   classID: Components.ID("{f42d5132-92c4-487b-b5c8-38bf292d74c1}"),
 
   get name() {
     return cal.l10n.getCalString("monthPrinterName");
   },
 
   formatToHtml(aStream, aStart, aEnd, aItems, aTitle) {
rename from calendar/import-export/calOutlookCSVImportExport.js
rename to calendar/import-export/CalOutlookCSVImportExport.jsm
--- a/calendar/import-export/calOutlookCSVImportExport.js
+++ b/calendar/import-export/CalOutlookCSVImportExport.jsm
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalOutlookCSVImporter", "CalOutlookCSVExporter"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var localeEn = {
   headTitle: "Subject",
   headStartDate: "Start Date",
   headStartTime: "Start Time",
   headEndDate: "End Date",
@@ -82,20 +84,20 @@ function getOutlookCsvFileTypes() {
       defaultExtension: "csv",
       extensionFilter: wildmat,
       description: label,
     },
   ];
 }
 
 // Importer
-function calOutlookCSVImporter() {
+function CalOutlookCSVImporter() {
   this.wrappedJSObject = this;
 }
-calOutlookCSVImporter.prototype = {
+CalOutlookCSVImporter.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.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.
@@ -439,18 +441,18 @@ calOutlookCSVImporter.prototype = {
   },
 
   parseTextField(aTextField) {
     return aTextField ? aTextField.replace(/""/g, '"') : "";
   },
 };
 
 // Exporter
-function calOutlookCSVExporter() {}
-calOutlookCSVExporter.prototype = {
+function CalOutlookCSVExporter() {}
+CalOutlookCSVExporter.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIExporter]),
   classID: Components.ID("{48e6d3a6-b41b-4052-9ed2-40b27800bd4b}"),
 
   getFileTypes: getOutlookCsvFileTypes,
 
   exportToStream(aStream, aItems, aTitle) {
     // Helper functions
     function dateString(aDateTime) {
rename from calendar/import-export/calWeekPrinter.js
rename to calendar/import-export/CalWeekPrinter.jsm
--- a/calendar/import-export/calWeekPrinter.js
+++ b/calendar/import-export/CalWeekPrinter.jsm
@@ -1,23 +1,25 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalWeekPrinter"];
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 /**
  * Prints a two column view of a week of events, much like a paper day-planner
  */
-function calWeekPrinter() {
+function CalWeekPrinter() {
   this.wrappedJSObject = this;
 }
 
-calWeekPrinter.prototype = {
+CalWeekPrinter.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIPrintFormatter]),
   classID: Components.ID("{2d6ec97b-9109-4b92-89c5-d4b4806619ce}"),
 
   get name() {
     return cal.l10n.getCalString("weekPrinterName");
   },
 
   formatToHtml(aStream, aStart, aEnd, aItems, aTitle) {
deleted file mode 100644
--- a/calendar/import-export/calImportExportModule.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* 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/. */
-
-/* import-globals-from calIcsImportExport.js */
-/* import-globals-from calHtmlExport.js */
-/* import-globals-from calOutlookCSVImportExport.js */
-/* import-globals-from calListFormatter.js */
-/* import-globals-from calMonthGridPrinter.js */
-/* import-globals-from calWeekPrinter.js */
-
-var { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-this.NSGetFactory = cid => {
-  let scriptLoadOrder = [
-    "resource:///components/calIcsImportExport.js",
-    "resource:///components/calHtmlExport.js",
-    "resource:///components/calOutlookCSVImportExport.js",
-
-    "resource:///components/calListFormatter.js",
-    "resource:///components/calMonthGridPrinter.js",
-    "resource:///components/calWeekPrinter.js",
-  ];
-
-  for (let script of scriptLoadOrder) {
-    Services.scriptloader.loadSubScript(script, this);
-  }
-
-  let components = [
-    calIcsImporter,
-    calIcsExporter,
-    calHtmlExporter,
-    calOutlookCSVImporter,
-    calOutlookCSVExporter,
-    calListFormatter,
-    calMonthPrinter,
-    calWeekPrinter,
-  ];
-
-  this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
-  return this.NSGetFactory(cid);
-};
deleted file mode 100644
--- a/calendar/import-export/calImportExportModule.manifest
+++ /dev/null
@@ -1,31 +0,0 @@
-component {1e3e33dc-445a-49de-b2b6-15b2a050bb9d} calImportExportModule.js
-contract @mozilla.org/calendar/import;1?type=ics {1e3e33dc-445a-49de-b2b6-15b2a050bb9d}
-category cal-importers cal-ics-importer @mozilla.org/calendar/import;1?type=ics
-
-component {a6a524ce-adff-4a0f-bb7d-d1aaad4adc60} calImportExportModule.js
-contract @mozilla.org/calendar/export;1?type=ics {a6a524ce-adff-4a0f-bb7d-d1aaad4adc60}
-category cal-exporters cal-ics-exporter @mozilla.org/calendar/export;1?type=ics
-
-component {72d9ab35-9b1b-442a-8cd0-ae49f00b159b} calImportExportModule.js
-contract @mozilla.org/calendar/export;1?type=htmllist {72d9ab35-9b1b-442a-8cd0-ae49f00b159b}
-category cal-exporters cal-html-list-exporter @mozilla.org/calendar/export;1?type=htmllist
-
-component {9ae04413-fee3-45b9-8bbb-1eb39a4cbd1b} calImportExportModule.js
-contract @mozilla.org/calendar/printformatter;1?type=list {9ae04413-fee3-45b9-8bbb-1eb39a4cbd1b}
-category cal-print-formatters cal-list-printformatter @mozilla.org/calendar/printformatter;1?type=list
-
-component {f42d5132-92c4-487b-b5c8-38bf292d74c1} calImportExportModule.js
-contract @mozilla.org/calendar/printformatter;1?type=monthgrid {f42d5132-92c4-487b-b5c8-38bf292d74c1}
-category cal-print-formatters cal-month-printer @mozilla.org/calendar/printformatter;1?type=monthgrid
-
-component {2d6ec97b-9109-4b92-89c5-d4b4806619ce} calImportExportModule.js
-contract @mozilla.org/calendar/printformatter;1?type=weekplan {2d6ec97b-9109-4b92-89c5-d4b4806619ce}
-category cal-print-formatters cal-week-planner-printer @mozilla.org/calendar/printformatter;1?type=weekplan
-
-component {64a5d17a-0497-48c5-b54f-72b15c9e9a14} calImportExportModule.js
-contract @mozilla.org/calendar/import;1?type=csv {64a5d17a-0497-48c5-b54f-72b15c9e9a14}
-category cal-importers cal-outlookcsv-importer @mozilla.org/calendar/import;1?type=csv
-
-component {48e6d3a6-b41b-4052-9ed2-40b27800bd4b} calImportExportModule.js
-contract @mozilla.org/calendar/export;1?type=csv {48e6d3a6-b41b-4052-9ed2-40b27800bd4b}
-category cal-exporters cal-outlookcsv-exporter @mozilla.org/calendar/export;1?type=csv
new file mode 100644
--- /dev/null
+++ b/calendar/import-export/components.conf
@@ -0,0 +1,64 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/
+
+Classes = [
+  {
+    'cid': '{1e3e33dc-445a-49de-b2b6-15b2a050bb9d}',
+    'contract_ids': ['@mozilla.org/calendar/import;1?type=ics'],
+    'jsm': 'resource:///modules/CalIcsImportExport.jsm',
+    'constructor': 'CalIcsImporter',
+    'categories': {'cal-importers': 'cal-ics-importer'},
+  },
+  {
+    'cid': '{a6a524ce-adff-4a0f-bb7d-d1aaad4adc60}',
+    'contract_ids': ['@mozilla.org/calendar/export;1?type=ics'],
+    'jsm': 'resource:///modules/CalIcsImportExport.jsm',
+    'constructor': 'CalIcsExporter',
+    'categories': {'cal-exporters': 'cal-ics-exporter'},
+  },
+  {
+    'cid': '{64a5d17a-0497-48c5-b54f-72b15c9e9a14}',
+    'contract_ids': [' @mozilla.org/calendar/import;1?type=csv'],
+    'jsm': 'resource:///modules/CalOutlookCSVImportExport.jsm',
+    'constructor': 'CalOutlookCSVImporter',
+    'categories': {'cal-importers': 'cal-outlookcsv-importer'},
+  },
+  {
+    'cid': '{48e6d3a6-b41b-4052-9ed2-40b27800bd4b}',
+    'contract_ids': ['@mozilla.org/calendar/export;1?type=csv'],
+    'jsm': 'resource:///modules/CalOutlookCSVImportExport.jsm',
+    'constructor': 'CalOutlookCSVExporter',
+    'categories': {'cal-exporters': 'cal-outlookcsv-exporter'},
+  },
+  {
+    'cid': '{72d9ab35-9b1b-442a-8cd0-ae49f00b159b}',
+    'contract_ids': ['@mozilla.org/calendar/export;1?type=htmllist'],
+    'jsm': 'resource:///modules/CalHtmlExport.jsm',
+    'constructor': 'CalHtmlExporter',
+    'categories': {'cal-exporters': 'cal-html-list-exporter'},
+  },
+  {
+    'cid': '{2d6ec97b-9109-4b92-89c5-d4b4806619ce}',
+    'contract_ids': ['@mozilla.org/calendar/printformatter;1?type=weekplan'],
+    'jsm': 'resource:///modules/CalWeekPrinter.jsm',
+    'constructor': 'CalWeekPrinter',
+    'categories': {'cal-print-formatters': 'cal-week-planner-printer'},
+  },
+  {
+    'cid': '{9ae04413-fee3-45b9-8bbb-1eb39a4cbd1b}',
+    'contract_ids': ['@mozilla.org/calendar/printformatter;1?type=list'],
+    'jsm': 'resource:///modules/CalListFormatter.jsm',
+    'constructor': 'CalListFormatter',
+    'categories': {'cal-print-formatters': 'cal-list-printformatter'},
+  },
+  {
+    'cid': '{f42d5132-92c4-487b-b5c8-38bf292d74c1}',
+    'contract_ids': ['@mozilla.org/calendar/printformatter;1?type=monthgrid'],
+    'jsm': 'resource:///modules/CalMonthGridPrinter.jsm',
+    'constructor': 'CalMonthPrinter',
+    'categories': {'cal-print-formatters': 'cal-month-printer'},
+  },
+]
--- a/calendar/import-export/moz.build
+++ b/calendar/import-export/moz.build
@@ -1,27 +1,25 @@
 # vim: set filetype=python:
 # 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/.
 
-EXTRA_COMPONENTS += [
-    'calImportExportModule.js',
-    'calImportExportModule.manifest',
-]
-
 JAR_MANIFESTS += ['jar.mn']
 
-# These files go in components so they can be packaged correctly.
-FINAL_TARGET_FILES.components += [
-    'calHtmlExport.js',
-    'calIcsImportExport.js',
-    'calListFormatter.js',
-    'calMonthGridPrinter.js',
-    'calOutlookCSVImportExport.js',
-    'calWeekPrinter.js',
+EXTRA_JS_MODULES += [
+    'CalHtmlExport.jsm',
+    'CalIcsImportExport.jsm',
+    'CalListFormatter.jsm',
+    'CalMonthGridPrinter.jsm',
+    'CalOutlookCSVImportExport.jsm',
+    'CalWeekPrinter.jsm',
+]
+
+XPCOM_MANIFESTS += [
+    'components.conf',
 ]
 
 with Files('**'):
     BUG_COMPONENT = ('Calendar', 'Import and Export')
 
 with Files('*Print*'):
     BUG_COMPONENT = ('Calendar', 'Printing')
rename from calendar/itip/calItipEmailTransport.js
rename to calendar/itip/CalItipEmailTransport.jsm
--- a/calendar/itip/calItipEmailTransport.js
+++ b/calendar/itip/CalItipEmailTransport.jsm
@@ -1,26 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+var EXPORTED_SYMBOLS = ["CalItipEmailTransport"];
+
 var { MailServices } = ChromeUtils.import("resource:///modules/MailServices.jsm");
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-var { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 var { ltn } = ChromeUtils.import("resource:///modules/calendar/ltnInvitationUtils.jsm");
 
-/**
- * Constructor of calItipEmailTransport object
- */
-function calItipEmailTransport() {
+function CalItipEmailTransport() {
   this.wrappedJSObject = this;
   this._initEmailTransport();
 }
-calItipEmailTransport.prototype = {
+CalItipEmailTransport.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.calIItipTransport]),
   classID: Components.ID("{d4d7b59e-c9e0-4a7a-b5e8-5958f85515f0}"),
 
   mHasXpcomMail: false,
   mDefaultAccount: null,
   mDefaultIdentity: null,
   mDefaultSmtpServer: null,
 
@@ -392,10 +390,8 @@ calItipEmailTransport.prototype = {
       cal.LOG("_createTempImipFile path: " + tempFile.path);
       return tempFile;
     } catch (exc) {
       cal.ASSERT(false, exc);
       return null;
     }
   },
 };
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calItipEmailTransport]);
deleted file mode 100644
--- a/calendar/itip/calItipEmailTransport.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {d4d7b59e-c9e0-4a7a-b5e8-5958f85515f0} calItipEmailTransport.js
-contract @mozilla.org/calendar/itip-transport;1?type=email {d4d7b59e-c9e0-4a7a-b5e8-5958f85515f0}
new file mode 100644
--- /dev/null
+++ b/calendar/itip/components.conf
@@ -0,0 +1,14 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/
+
+Classes = [
+  {
+    'cid': '{d4d7b59e-c9e0-4a7a-b5e8-5958f85515f0}',
+    'contract_ids': ['@mozilla.org/calendar/itip-transport;1?type=email'],
+    'jsm': 'resource:///modules/CalItipEmailTransport.jsm',
+    'constructor': 'CalItipEmailTransport',
+  },
+]
--- a/calendar/itip/moz.build
+++ b/calendar/itip/moz.build
@@ -1,12 +1,15 @@
 # vim: set filetype=python:
 # 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/.
 
-EXTRA_COMPONENTS += [
-    'calItipEmailTransport.js',
-    'calItipEmailTransport.manifest',
+EXTRA_JS_MODULES += [
+    'CalItipEmailTransport.jsm',
+]
+
+XPCOM_MANIFESTS += [
+    'components.conf',
 ]
 
 with Files('**'):
     BUG_COMPONENT = ('Calendar', 'E-mail based Scheduling (iTIP/iMIP)')
rename from calendar/lightning/components/calItipProtocolHandler.js
rename to calendar/lightning/components/CalItipProtocolHandler.jsm
--- a/calendar/lightning/components/calItipProtocolHandler.js
+++ b/calendar/lightning/components/CalItipProtocolHandler.jsm
@@ -1,13 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-var { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+var EXPORTED_SYMBOLS = ["ItipChannel", "ItipProtocolHandler", "ItipContentHandler"];
+
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 var ITIP_HANDLER_MIMETYPE = "application/x-itip-internal";
 var ITIP_HANDLER_PROTOCOL = "moz-cal-handle-itip";
 var NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
 
 function NYI() {
   throw Cr.NS_ERROR_NOT_IMPLEMENTED;
@@ -98,11 +99,8 @@ ItipContentHandler.prototype = {
         event.id +
         ")\n"
     );
     let calMgr = cal.getCalendarManager();
     let cals = calMgr.getCalendars();
     cals[0].addItem(event, null);
   },
 };
-
-var components = [ItipChannel, ItipProtocolHandler, ItipContentHandler];
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
rename from calendar/lightning/components/lightningTextCalendarConverter.js
rename to calendar/lightning/components/CalMimeConverter.jsm
--- a/calendar/lightning/components/lightningTextCalendarConverter.js
+++ b/calendar/lightning/components/CalMimeConverter.jsm
@@ -1,22 +1,23 @@
 /* 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 EXPORTED_SYMBOLS = ["CalMimeConverter"];
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 var { ltn } = ChromeUtils.import("resource:///modules/calendar/ltnInvitationUtils.jsm");
 
-function ltnMimeConverter() {
+function CalMimeConverter() {
   this.wrappedJSObject = this;
 }
 
-ltnMimeConverter.prototype = {
+CalMimeConverter.prototype = {
   QueryInterface: ChromeUtils.generateQI([Ci.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);
@@ -70,10 +71,8 @@ ltnMimeConverter.prototype = {
       sinkProps.setPropertyAsAUTF8String("msgOverlay", msgOverlay);
 
       // Notify the observer that the itipItem is available
       Services.obs.notifyObservers(null, "onItipItemCreation");
     }
     return msgOverlay;
   },
 };
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ltnMimeConverter]);
deleted file mode 100644
--- a/calendar/lightning/components/calItipProtocolHandler.manifest
+++ /dev/null
@@ -1,8 +0,0 @@
-component {643e0328-36f6-411d-a107-16238dff9cd7} calItipProtocolHandler.js
-contract @mozilla.org/calendar/itip-channel;1 {643e0328-36f6-411d-a107-16238dff9cd7}
-
-component {6e957006-b4ce-11d9-b053-001124736B74} calItipProtocolHandler.js
-contract @mozilla.org/network/protocol;1?name=moz-cal-handle-itip {6e957006-b4ce-11d9-b053-001124736B74}
-
-component {47c31f2b-b4de-11d9-bfe6-001124736B74} calItipProtocolHandler.js
-contract @mozilla.org/uriloader/content-handler;1?type=application/x-itip-internal {47c31f2b-b4de-11d9-bfe6-001124736B74}
new file mode 100644
--- /dev/null
+++ b/calendar/lightning/components/components.conf
@@ -0,0 +1,33 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/
+
+Classes = [
+  {
+    'cid': '{643e0328-36f6-411d-a107-16238dff9cd7}',
+    'contract_ids': ['@mozilla.org/calendar/itip-channel;1'],
+    'jsm': 'resource:///modules/CalItipProtocolHandler.jsm',
+    'constructor': 'ItipChannel',
+  },
+  {
+    'cid': '{6e957006-b4ce-11d9-b053-001124736B74}',
+    'contract_ids': ['@mozilla.org/network/protocol;1?name=moz-cal-handle-itip'],
+    'jsm': 'resource:///modules/CalItipProtocolHandler.jsm',
+    'constructor': 'ItipProtocolHandler',
+  },
+  {
+    'cid': '{47c31f2b-b4de-11d9-bfe6-001124736B74}',
+    'contract_ids': ['@mozilla.org/uriloader/content-handler;1?type=application/x-itip-internal'],
+    'jsm': 'resource:///modules/CalItipEmailTransport.jsm',
+    'constructor': 'ItipContentHandler',
+  },
+  {
+    'cid': '{c70acb08-464e-4e55-899d-b2c84c5409fa}',
+    'contract_ids': ['@mozilla.org/lightning/mime-converter;1'],
+    'jsm': 'resource:///modules/CalMimeConverter.jsm',
+    'constructor': 'CalMimeConverter',
+    'categories': {'simple-mime-converters': 'text/calendar'},
+  },
+]
\ No newline at end of file
deleted file mode 100644
--- a/calendar/lightning/components/lightningTextCalendarConverter.manifest
+++ /dev/null
@@ -1,3 +0,0 @@
-component {c70acb08-464e-4e55-899d-b2c84c5409fa} lightningTextCalendarConverter.js
-contract @mozilla.org/lightning/mime-converter;1 {c70acb08-464e-4e55-899d-b2c84c5409fa}
-category simple-mime-converters text/calendar @mozilla.org/lightning/mime-converter;1
--- a/calendar/lightning/components/moz.build
+++ b/calendar/lightning/components/moz.build
@@ -1,12 +1,14 @@
 # vim: set filetype=python:
 # 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/.
 
-EXTRA_COMPONENTS += [
-    'calItipProtocolHandler.js',
-    'calItipProtocolHandler.manifest',
-    'lightningTextCalendarConverter.js',
-    'lightningTextCalendarConverter.manifest',
+EXTRA_JS_MODULES += [
+    'CalItipProtocolHandler.jsm',
+    'CalMimeConverter.jsm',
 ]
 
+XPCOM_MANIFESTS += [
+    'components.conf',
+]
+
rename from calendar/providers/caldav/calDavCalendar.js
rename to calendar/providers/caldav/CalDavCalendar.jsm
--- a/calendar/providers/caldav/calDavCalendar.js
+++ b/calendar/providers/caldav/CalDavCalendar.jsm
@@ -1,26 +1,25 @@
 /* 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/. */
 
 /* import-globals-from calDavRequestHandlers.js */
 /* globals OAUTH_BASE_URI, OAUTH_SCOPE, OAUTH_CLIENT_ID, OAUTH_HASH */
 
-var { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+var EXPORTED_SYMBOLS = ["CalDavCalendar"];
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { setTimeout } = ChromeUtils.import("resource://gre/modules/Timer.jsm");
 
 var { OAuth2 } = ChromeUtils.import("resource:///modules/OAuth2.jsm");
 
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
-//
-// calDavCalendar.js
-//
+Services.scriptloader.loadSubScript("resource:///components/calDavRequestHandlers.js");
 
 var xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>\n';
 
 var davNS = "DAV:";
 var caldavNS = "urn:ietf:params:xml:ns:caldav";
 var calservNS = "http://calendarserver.org/ns/";
 var MIME_TEXT_CALENDAR = "text/calendar; charset=utf-8";
 var MIME_TEXT_XML = "text/xml; charset=utf-8";
@@ -41,17 +40,17 @@ function caldavNSResolver(prefix) {
 
 function caldavXPath(aNode, aExpr, aType) {
   return cal.xml.evalXPath(aNode, aExpr, caldavNSResolver, aType);
 }
 function caldavXPathFirst(aNode, aExpr, aType) {
   return cal.xml.evalXPathFirst(aNode, aExpr, caldavNSResolver, aType);
 }
 
-function calDavCalendar() {
+function CalDavCalendar() {
   this.initProviderBase();
   this.unmappedProperties = [];
   this.mUriParams = null;
   this.mItemInfoCache = {};
   this.mDisabled = false;
   this.mCalHomeSet = null;
   this.mInboxUrl = null;
   this.mOutboxUrl = null;
@@ -90,17 +89,17 @@ var calDavCalendarInterfaces = [
   Ci.calIFreeBusyProvider,
   Ci.nsIChannelEventSink,
   Ci.calIItipTransport,
   Ci.calISchedulingSupport,
   Ci.calICalendar,
   Ci.calIChangeLog,
   Ci.calICalDavCalendar,
 ];
-calDavCalendar.prototype = {
+CalDavCalendar.prototype = {
   __proto__: cal.provider.BaseClass.prototype,
   classID: calDavCalendarClassID,
   QueryInterface: cal.generateQI(calDavCalendarInterfaces),
   classInfo: cal.generateCI({
     classID: calDavCalendarClassID,
     contractID: "@mozilla.org/calendar/calendar;1?type=caldav",
     classDescription: "Calendar CalDAV back-end",
     interfaces: calDavCalendarInterfaces,
@@ -3272,15 +3271,8 @@ calDavObserver.prototype = {
     this.mCalendar.observers.notify("onPropertyDeleting", [aCalendar, aName]);
   },
 
   onError(aCalendar, aErrNo, aMessage) {
     this.mCalendar.readOnly = true;
     this.mCalendar.notifyError(aErrNo, aMessage);
   },
 };
-
-/** Module Registration */
-this.NSGetFactory = cid => {
-  Services.scriptloader.loadSubScript("resource:///components/calDavRequestHandlers.js", this);
-  this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calDavCalendar]);
-  return this.NSGetFactory(cid);
-};
deleted file mode 100644
--- a/calendar/providers/caldav/calDavCalendar.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {a35fc6ea-3d92-11d9-89f9-00045ace3b8d} calDavCalendar.js
-contract @mozilla.org/calendar/calendar;1?type=caldav {a35fc6ea-3d92-11d9-89f9-00045ace3b8d}
new file mode 100644
--- /dev/null
+++ b/calendar/providers/caldav/components.conf
@@ -0,0 +1,14 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/
+
+Classes = [
+  {
+    'cid': '{a35fc6ea-3d92-11d9-89f9-00045ace3b8d}',
+    'contract_ids': ['@mozilla.org/calendar/calendar;1?type=caldav'],
+    'jsm': 'resource:///modules/CalDavCalendar.jsm',
+    'constructor': 'CalDavCalendar',
+  },
+]
\ No newline at end of file
--- a/calendar/providers/caldav/moz.build
+++ b/calendar/providers/caldav/moz.build
@@ -1,18 +1,21 @@
 # vim: set filetype=python:
 # 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/.
 
 DIRS += ['public']
 
-EXTRA_COMPONENTS += [
-    'calDavCalendar.js',
-    'calDavCalendar.manifest',
+EXTRA_JS_MODULES += [
+    'CalDavCalendar.jsm',
+]
+
+XPCOM_MANIFESTS += [
+    'components.conf',
 ]
 
 # These files go in components so they can be packaged correctly.
 FINAL_TARGET_FILES.components += [
     'calDavRequestHandlers.js',
 ]
 
 with Files('**'):
rename from calendar/providers/composite/calCompositeCalendar.js
rename to calendar/providers/composite/CalCompositeCalendar.jsm
--- a/calendar/providers/composite/calCompositeCalendar.js
+++ b/calendar/providers/composite/CalCompositeCalendar.jsm
@@ -1,18 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-var { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
+var EXPORTED_SYMBOLS = ["CalCompositeCalendar"];
 
-//
-// calCompositeCalendar.js
-//
+var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
 /**
  * Calendar specific utility functions
  */
 var calIOperationListener = Ci.calIOperationListener;
 
 function calCompositeCalendarObserverHelper(compCalendar) {
   this.compCalendar = compCalendar;
@@ -65,34 +62,34 @@ calCompositeCalendarObserverHelper.proto
     this.compCalendar.mObservers.notify("onPropertyChanged", arguments);
   },
 
   onPropertyDeleting(aCalendar, aName) {
     this.compCalendar.mObservers.notify("onPropertyDeleting", arguments);
   },
 };
 
-function calCompositeCalendar() {
+function CalCompositeCalendar() {
   this.mObserverHelper = new calCompositeCalendarObserverHelper(this);
   this.wrappedJSObject = this;
 
   this.mCalendars = [];
   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,
 ];
-calCompositeCalendar.prototype = {
+CalCompositeCalendar.prototype = {
   classID: calCompositeCalendarClassID,
   QueryInterface: ChromeUtils.generateQI(calCompositeCalendarInterfaces),
 
   //
   // calICalendarProvider interface
   //
   get prefChromeOverlay() {
     return null;
@@ -524,11 +521,8 @@ calCompositeGetListenerHelper.prototype 
       aItems = aItems.slice(0, itemsCount);
     }
 
     // send GetResults to the real listener
     this.mRealListener.onGetResult(aCalendar, aStatus, aItemType, aDetail, aItems);
     this.mItemsReceived += itemsCount;
   },
 };
-
-/** Module Registration */
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calCompositeCalendar]);
deleted file mode 100644
--- a/calendar/providers/composite/calCompositeCalendar.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {aeff788d-63b0-4996-91fb-40a7654c6224} calCompositeCalendar.js
-contract @mozilla.org/calendar/calendar;1?type=composite {aeff788d-63b0-4996-91fb-40a7654c6224}
new file mode 100644
--- /dev/null
+++ b/calendar/providers/composite/components.conf
@@ -0,0 +1,14 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/
+
+Classes = [
+  {
+    'cid': '{aeff788d-63b0-4996-91fb-40a7654c6224}',
+    'contract_ids': ['@mozilla.org/calendar/calendar;1?type=composite'],
+    'jsm': 'resource:///modules/CalCompositeCalendar.jsm',
+    'constructor': 'CalCompositeCalendar',
+  },
+]
\ No newline at end of file
--- a/calendar/providers/composite/moz.build
+++ b/calendar/providers/composite/moz.build
@@ -1,10 +1,13 @@
 # vim: set filetype=python:
 # 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/.
 
-EXTRA_COMPONENTS += [
-    'calCompositeCalendar.js',
-    'calCompositeCalendar.manifest',
+EXTRA_JS_MODULES += [
+    'CalCompositeCalendar.jsm',
 ]
 
+XPCOM_MANIFESTS += [
+    'components.conf',
+]
+
rename from calendar/providers/ics/calICSCalendar.js
rename to calendar/providers/ics/CalICSCalendar.jsm
--- a/calendar/providers/ics/calICSCalendar.js
+++ b/calendar/providers/ics/CalICSCalendar.jsm
@@ -1,20 +1,18 @@
 /* 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 EXPORTED_SYMBOLS = ["CalICSCalendar"];
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
-//
-// calICSCalendar.js
-//
 // This is a non-sync ics file. It reads the file pointer to by uri when set,
 // then writes it on updates. External changes to the file will be
 // ignored and overwritten.
 //
 // XXX Should do locks, so that external changes are not overwritten.
 
 var calICalendar = Ci.calICalendar;
 var calIErrors = Ci.calIErrors;
@@ -23,17 +21,17 @@ function icsNSResolver(prefix) {
   const ns = { D: "DAV:" }; // eslint-disable-line id-length
   return ns[prefix] || null;
 }
 
 function icsXPathFirst(aNode, aExpr, aType) {
   return cal.xml.evalXPathFirst(aNode, aExpr, icsNSResolver, aType);
 }
 
-function calICSCalendar() {
+function CalICSCalendar() {
   this.initProviderBase();
   this.initICSCalendar();
 
   this.unmappedComponents = [];
   this.unmappedProperties = [];
   this.queue = [];
   this.mModificationActions = [];
 }
@@ -42,17 +40,17 @@ var calICSCalendarInterfaces = [
   Ci.calICalendarProvider,
   Ci.calICalendar,
   Ci.calISchedulingSupport,
   Ci.nsIStreamListener,
   Ci.nsIStreamLoaderObserver,
   Ci.nsIChannelEventSink,
   Ci.nsIInterfaceRequestor,
 ];
-calICSCalendar.prototype = {
+CalICSCalendar.prototype = {
   __proto__: cal.provider.BaseClass.prototype,
   classID: calICSCalendarClassID,
   QueryInterface: cal.generateQI(calICSCalendarInterfaces),
   classInfo: cal.generateCI({
     classID: calICSCalendarClassID,
     contractID: "@mozilla.org/calendar/calendar;1?type=ics",
     classDescription: "Calendar ICS provider",
     interfaces: calICSCalendarInterfaces,
@@ -1105,10 +1103,8 @@ fileHooks.prototype = {
 
   onAfterPut(aChannel, aRespFunc) {
     let filechannel = aChannel.QueryInterface(Ci.nsIFileChannel);
     this.mtime = filechannel.file.lastModifiedTime;
     aRespFunc();
     return true;
   },
 };
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calICSCalendar]);
deleted file mode 100644
--- a/calendar/providers/ics/calICSCalendar.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {f8438bff-a3c9-4ed5-b23f-2663b5469abf} calICSCalendar.js
-contract @mozilla.org/calendar/calendar;1?type=ics {f8438bff-a3c9-4ed5-b23f-2663b5469abf}
new file mode 100644
--- /dev/null
+++ b/calendar/providers/ics/components.conf
@@ -0,0 +1,14 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/
+
+Classes = [
+  {
+    'cid': '{f8438bff-a3c9-4ed5-b23f-2663b5469abf}',
+    'contract_ids': ['@mozilla.org/calendar/calendar;1?type=ics'],
+    'jsm': 'resource:///modules/CalICSCalendar.jsm',
+    'constructor': 'CalICSCalendar',
+  },
+]
\ No newline at end of file
--- a/calendar/providers/ics/moz.build
+++ b/calendar/providers/ics/moz.build
@@ -1,12 +1,15 @@
 # vim: set filetype=python:
 # 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/.
 
-EXTRA_COMPONENTS += [
-    'calICSCalendar.js',
-    'calICSCalendar.manifest',
+EXTRA_JS_MODULES += [
+    'CalICSCalendar.jsm',
+]
+
+XPCOM_MANIFESTS += [
+    'components.conf',
 ]
 
 with Files('**'):
     BUG_COMPONENT = ('Calendar', 'Provider: ICS/WebDAV')
rename from calendar/providers/memory/calMemoryCalendar.js
rename to calendar/providers/memory/CalMemoryCalendar.jsm
--- a/calendar/providers/memory/calMemoryCalendar.js
+++ b/calendar/providers/memory/CalMemoryCalendar.jsm
@@ -1,35 +1,31 @@
 /* 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 EXPORTED_SYMBOLS = ["CalMemoryCalendar"];
 
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 
-//
-// calMemoryCalendar.js
-//
-
 var cICL = Ci.calIChangeLog;
 
-function calMemoryCalendar() {
+function CalMemoryCalendar() {
   this.initProviderBase();
   this.initMemoryCalendar();
 }
 var calMemoryCalendarClassID = Components.ID("{bda0dd7f-0a2f-4fcf-ba08-5517e6fbf133}");
 var calMemoryCalendarInterfaces = [
   Ci.calICalendar,
   Ci.calISchedulingSupport,
   Ci.calIOfflineStorage,
   Ci.calISyncWriteCalendar,
   Ci.calICalendarProvider,
 ];
-calMemoryCalendar.prototype = {
+CalMemoryCalendar.prototype = {
   __proto__: cal.provider.BaseClass.prototype,
   classID: calMemoryCalendarClassID,
   QueryInterface: cal.generateQI(calMemoryCalendarInterfaces),
   classInfo: cal.generateCI({
     classID: calMemoryCalendarClassID,
     contractID: "@mozilla.org/calendar/calendar;1?type=memory",
     classDescription: "Calendar Memory Provider",
     interfaces: calMemoryCalendarInterfaces,
@@ -610,11 +606,8 @@ calMemoryCalendar.prototype = {
   },
   getAllMetaDataIds() {
     return [...this.mMetaData.keys()];
   },
   getAllMetaDataValues() {
     return [...this.mMetaData.values()];
   },
 };
-
-/** Module Registration */
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calMemoryCalendar]);
deleted file mode 100644
--- a/calendar/providers/memory/calMemoryCalendar.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {bda0dd7f-0a2f-4fcf-ba08-5517e6fbf133} calMemoryCalendar.js
-contract @mozilla.org/calendar/calendar;1?type=memory {bda0dd7f-0a2f-4fcf-ba08-5517e6fbf133}
new file mode 100644
--- /dev/null
+++ b/calendar/providers/memory/components.conf
@@ -0,0 +1,14 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/
+
+Classes = [
+  {
+    'cid': '{bda0dd7f-0a2f-4fcf-ba08-5517e6fbf133}',
+    'contract_ids': ['@mozilla.org/calendar/calendar;1?type=memory'],
+    'jsm': 'resource:///modules/CalMemoryCalendar.jsm',
+    'constructor': 'CalMemoryCalendar',
+  },
+]
\ No newline at end of file
--- a/calendar/providers/memory/moz.build
+++ b/calendar/providers/memory/moz.build
@@ -1,10 +1,13 @@
 # vim: set filetype=python:
 # 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/.
 
-EXTRA_COMPONENTS += [
-    'calMemoryCalendar.js',
-    'calMemoryCalendar.manifest',
+EXTRA_JS_MODULES += [
+    'CalMemoryCalendar.jsm',
 ]
 
+XPCOM_MANIFESTS += [
+    'components.conf',
+]
+
rename from calendar/providers/storage/calStorageCalendar.js
rename to calendar/providers/storage/CalStorageCalendar.jsm
--- a/calendar/providers/storage/calStorageCalendar.js
+++ b/calendar/providers/storage/CalStorageCalendar.jsm
@@ -1,44 +1,41 @@
 /* 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 EXPORTED_SYMBOLS = ["CalStorageCalendar"];
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
 var { upgradeDB } = ChromeUtils.import("resource:///modules/calendar/calStorageUpgrade.jsm");
 var { CAL_ITEM_FLAG, newDateTime } = ChromeUtils.import(
   "resource:///modules/calendar/calStorageHelpers.jsm"
 );
 
 var USECS_PER_SECOND = 1000000;
 var kCalICalendar = Ci.calICalendar;
 var cICL = Ci.calIChangeLog;
 
-//
-// calStorageCalendar
-//
-
-function calStorageCalendar() {
+function CalStorageCalendar() {
   this.initProviderBase();
   this.mItemCache = new Map();
   this.mRecEventCache = new Map();
   this.mRecTodoCache = new Map();
 }
 var calStorageCalendarClassID = Components.ID("{b3eaa1c4-5dfe-4c0a-b62a-b3a514218461}");
 var calStorageCalendarInterfaces = [
   Ci.calICalendar,
   Ci.calICalendarProvider,
   Ci.calIOfflineStorage,
   Ci.calISchedulingSupport,
   Ci.calISyncWriteCalendar,
 ];
-calStorageCalendar.prototype = {
+CalStorageCalendar.prototype = {
   __proto__: cal.provider.BaseClass.prototype,
   classID: calStorageCalendarClassID,
   QueryInterface: cal.generateQI(calStorageCalendarInterfaces),
   classInfo: cal.generateCI({
     classID: calStorageCalendarClassID,
     contractID: "@mozilla.org/calendar/calendar;1?type=storage",
     classDescription: "Calendar Storage Provider",
     interfaces: calStorageCalendarInterfaces,
@@ -848,17 +845,17 @@ calStorageCalendar.prototype = {
       this.prepareStatement(query);
       query.params.id = aItem.id;
       try {
         await this.executeAsync(query, row => {
           flag = row.getResultByName("offline_journal") || null;
         });
       } catch (ex) {
         aListener.onOperationComplete(
-          self,
+          this,
           ex.result,
           Ci.calIOperationListener.GET,
           aItem.id,
           aItem
         );
         return;
       }
     }
@@ -2600,10 +2597,8 @@ calStorageCalendar.prototype = {
           } else {
             ex.deleteProperty("SEQUENCE");
           }
         }
       }
     }
   },
 };
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calStorageCalendar]);
deleted file mode 100644
--- a/calendar/providers/storage/calStorageCalendar.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {b3eaa1c4-5dfe-4c0a-b62a-b3a514218461} calStorageCalendar.js
-contract @mozilla.org/calendar/calendar;1?type=storage {b3eaa1c4-5dfe-4c0a-b62a-b3a514218461}
new file mode 100644
--- /dev/null
+++ b/calendar/providers/storage/components.conf
@@ -0,0 +1,14 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/
+
+Classes = [
+  {
+    'cid': '{b3eaa1c4-5dfe-4c0a-b62a-b3a514218461}',
+    'contract_ids': ['@mozilla.org/calendar/calendar;1?type=storage'],
+    'jsm': 'resource:///modules/CalStorageCalendar.jsm',
+    'constructor': 'CalStorageCalendar',
+  },
+]
\ No newline at end of file
--- a/calendar/providers/storage/moz.build
+++ b/calendar/providers/storage/moz.build
@@ -1,16 +1,19 @@
 # vim: set filetype=python:
 # 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/.
 
-EXTRA_COMPONENTS += [
-    'calStorageCalendar.js',
-    'calStorageCalendar.manifest',
+EXTRA_JS_MODULES += [
+    'CalStorageCalendar.jsm',
+]
+
+XPCOM_MANIFESTS += [
+    'components.conf',
 ]
 
 EXTRA_JS_MODULES.calendar += [
     'calStorageHelpers.jsm',
     'calStorageUpgrade.jsm',
 ]
 
 with Files('**'):
--- a/calendar/test/unit/test_imip.js
+++ b/calendar/test/unit/test_imip.js
@@ -1,18 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-var calItipEmailTransport = {};
-Services.scriptloader.loadSubScript(
-  "resource:///components/calItipEmailTransport.js",
-  calItipEmailTransport
-);
+var { CalItipEmailTransport } = ChromeUtils.import("resource:///modules/CalItipEmailTransport.jsm");
 
 function itipItemForTest(title, seq) {
   let itipItem = Cc["@mozilla.org/calendar/itip-item;1"].createInstance(Ci.calIItipItem);
   itipItem.init(
     [
       "BEGIN:VCALENDAR",
       "METHOD:REQUEST",
       "BEGIN:VEVENT",
@@ -20,17 +16,17 @@ function itipItemForTest(title, seq) {
       "SEQUENCE:" + (seq || 0),
       "END:VEVENT",
       "END:VCALENDAR",
     ].join("\r\n")
   );
   return itipItem;
 }
 
-let transport = new calItipEmailTransport.calItipEmailTransport();
+let transport = new CalItipEmailTransport();
 
 add_task(function test_title_in_subject() {
   Services.prefs.setBoolPref("calendar.itip.useInvitationSubjectPrefixes", false);
   let items = transport._prepareItems(itipItemForTest("foo"));
   equal(items.subject, "foo");
 });
 
 add_task(function test_title_in_summary() {
--- a/mail/installer/package-manifest.in
+++ b/mail/installer/package-manifest.in
@@ -319,84 +319,30 @@
 @RESPATH@/chrome/lightning.manifest
 
 @RESPATH@/res/zones.json
 @RESPATH@/@PREF_DIR@/lightning.js
 
 # Files added to components directory via `EXTRA_COMPONENTS`.
 @RESPATH@/components/calBackendLoader.js
 @RESPATH@/components/calBackendLoader.manifest
-@RESPATH@/components/calDefaultACLManager.js
-@RESPATH@/components/calDefaultACLManager.manifest
-@RESPATH@/components/calItemModule.js
-@RESPATH@/components/calItemModule.manifest
-@RESPATH@/components/calSleepMonitor.js
-@RESPATH@/components/calSleepMonitor.manifest
-@RESPATH@/components/calTimezoneService.js
-@RESPATH@/components/calTimezoneService.manifest
-@RESPATH@/components/calImportExportModule.js
-@RESPATH@/components/calImportExportModule.manifest
-@RESPATH@/components/calItipEmailTransport.js
-@RESPATH@/components/calItipEmailTransport.manifest
-@RESPATH@/components/calItipProtocolHandler.js
-@RESPATH@/components/calItipProtocolHandler.manifest
-@RESPATH@/components/lightningTextCalendarConverter.js
-@RESPATH@/components/lightningTextCalendarConverter.manifest
-@RESPATH@/components/calDavCalendar.js
-@RESPATH@/components/calDavCalendar.manifest
-@RESPATH@/components/calCompositeCalendar.js
-@RESPATH@/components/calCompositeCalendar.manifest
-@RESPATH@/components/calICSCalendar.js
-@RESPATH@/components/calICSCalendar.manifest
-@RESPATH@/components/calMemoryCalendar.js
-@RESPATH@/components/calMemoryCalendar.manifest
-@RESPATH@/components/calStorageCalendar.js
-@RESPATH@/components/calStorageCalendar.manifest
 @RESPATH@/components/calICALJSComponents.js
 
 # Files added to components directory via `FINAL_TARGET_FILES.components`.
-@RESPATH@/components/calAlarm.js
-@RESPATH@/components/calAlarmMonitor.js
-@RESPATH@/components/calAlarmService.js
-@RESPATH@/components/calAttachment.js
-@RESPATH@/components/calAttendee.js
 @RESPATH@/components/calCachedCalendar.js
-@RESPATH@/components/calCalendarManager.js
-@RESPATH@/components/calCalendarSearchService.js
-@RESPATH@/components/calDateTimeFormatter.js
 @RESPATH@/components/calDateTime.js
 @RESPATH@/components/calDavRequestHandlers.js
-@RESPATH@/components/calDeletedItems.js
 @RESPATH@/components/calDuration.js
-@RESPATH@/components/calEvent.js
 @RESPATH@/components/calFilter.js
-@RESPATH@/components/calFreeBusyService.js
-@RESPATH@/components/calHtmlExport.js
-@RESPATH@/components/calIcsImportExport.js
-@RESPATH@/components/calIcsParser.js
-@RESPATH@/components/calIcsSerializer.js
 @RESPATH@/components/calICSService.js
 @RESPATH@/components/calICSService-worker.js
 @RESPATH@/components/calItemBase.js
-@RESPATH@/components/calItipItem.js
-@RESPATH@/components/calListFormatter.js
-@RESPATH@/components/calMonthGridPrinter.js
-@RESPATH@/components/calOutlookCSVImportExport.js
 @RESPATH@/components/calPeriod.js
-@RESPATH@/components/calProtocolHandler.js
-@RESPATH@/components/calRecurrenceDate.js
-@RESPATH@/components/calRecurrenceInfo.js
 @RESPATH@/components/calRecurrenceRule.js
-@RESPATH@/components/calRelation.js
-@RESPATH@/components/calStartupService.js
 @RESPATH@/components/calTimezone.js
-@RESPATH@/components/calTodo.js
-@RESPATH@/components/calTransactionManager.js
-@RESPATH@/components/calWeekInfoService.js
-@RESPATH@/components/calWeekPrinter.js
 
 @RESPATH@/features/wetransfer@extensions.thunderbird.net/
 
 @RESPATH@/components/servicesComponents.manifest
 @RESPATH@/components/servicesSettings.manifest
 @RESPATH@/components/cryptoComponents.manifest
 @RESPATH@/components/Push.manifest