Fix bug 576746 - More Component (to NSGetModule) - Make calendar XPCOM components use new manifests and data tables.
authorPhilipp Kewisch <mozilla@kewis.ch>
Sun, 08 Aug 2010 16:19:31 +0200
changeset 6088 0776ec4be64aec483d5f5dc3048457b0cb7d6d7d
parent 6087 5e2cc46e715401bfd64f252d75aac6618e1b129f
child 6089 5c79111293364fc0e8b0e323139c252d8f8f8cb0
push idunknown
push userunknown
push dateunknown
bugs576746
Fix bug 576746 - More Component (to NSGetModule) - Make calendar XPCOM components use new manifests and data tables.
calendar/itip/calItipEmailTransport.js
calendar/lightning/components/calItipProtocolHandler.js
calendar/lightning/components/lightningTextCalendarConverter.js
calendar/lightning/jar.mn
calendar/providers/caldav/Makefile.in
calendar/providers/caldav/calDavCalendar.js
calendar/providers/caldav/calDavCalendarModule.js
calendar/providers/composite/Makefile.in
calendar/providers/composite/calCompositeCalendar.js
calendar/providers/gdata/components/calGoogleCalendar.js
calendar/providers/gdata/components/calGoogleCalendarModule.js
calendar/providers/gdata/components/calGoogleRequest.js
calendar/providers/gdata/components/calGoogleSession.js
calendar/providers/ics/Makefile.in
calendar/providers/ics/calICSCalendar.js
calendar/providers/ics/calICSCalendarModule.js
calendar/providers/memory/Makefile.in
calendar/providers/memory/calMemoryCalendar.js
calendar/providers/memory/calMemoryCalendarModule.js
calendar/providers/storage/Makefile.in
calendar/providers/storage/calStorageCalendar.js
calendar/providers/storage/calStorageCalendarModule.js
calendar/providers/wcap/Makefile.in
calendar/providers/wcap/calWcapCalendar.js
calendar/providers/wcap/calWcapCalendarModule.js
calendar/providers/wcap/calWcapRequest.js
calendar/providers/wcap/calWcapSession.js
--- a/calendar/itip/calItipEmailTransport.js
+++ b/calendar/itip/calItipEmailTransport.js
@@ -34,41 +34,54 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
 function convertFromUnicode(aCharset, aSrc) {
-    var unicodeConverter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
+    let unicodeConverter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
                                      .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
     unicodeConverter.charset = aCharset;
     return unicodeConverter.ConvertFromUnicode(aSrc);
 }
 
 /**
  * Constructor of calItipEmailTransport object
  */
 function calItipEmailTransport() {
     this.wrappedJSObject = this;
     this._initEmailTransport();
 }
 
 calItipEmailTransport.prototype = {
+    classID: Components.ID("{d4d7b59e-c9e0-4a7a-b5e8-5958f85515f0}"),
+    contractID: "@mozilla.org/calendar/itip-transport;1?type=email",
+    classDescription: "Calendar iTIP Email Transport",
 
-    QueryInterface: function cietQI(aIid) {
-        if (!aIid.equals(Components.interfaces.nsISupports) &&
-            !aIid.equals(Components.interfaces.calIItipTransport))
-        {
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-        }
+    getInterfaces: function getInterfaces(count) {
+        const ifaces = [Components.interfaces.calIItipTransport,
+                        Components.interfaces.nsIClassInfo,
+                        Components.interfaces.nsISupports];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+    getHelperForLanguage: function getHelperForLanguage(language) {
+        return null;
+    },
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
 
-        return this;
+    QueryInterface: function QueryInterface(aIID) {
+        return cal.doQueryInterface(this, calItipEmailTransport.prototype, aIID, null, this);
     },
 
     mHasXpcomMail: false,
     mDefaultAccount: null,
     mDefaultIdentity: null,
     mDefaultSmtpServer: null,
 
     get scheme() {
@@ -84,74 +97,74 @@ calItipEmailTransport.prototype = {
     },
 
     get type() {
         return "email";
     },
 
     sendItems: function cietSI(aCount, aRecipients, aItipItem) {
         if (this.mHasXpcomMail) {
-            LOG("sendItems: Sending Email...");
+            cal.LOG("sendItems: Sending Email...");
 
-            var item = aItipItem.getItemList({})[0];
+            let item = aItipItem.getItemList({})[0];
 
             // Get ourselves some default text - when we handle organizer properly
             // We'll need a way to configure the Common Name attribute and we should
             // use it here rather than the email address
 
-            var summary = (item.getProperty("SUMMARY") || "");
-            var aSubject = "";
-            var aBody = "";
+            let summary = (item.getProperty("SUMMARY") || "");
+            let aSubject = "";
+            let aBody = "";
             switch (aItipItem.responseMethod) {
                 case 'REQUEST':
-                    aSubject = calGetString("lightning",
-                                            "itipRequestSubject",
-                                            [summary],
-                                            "lightning");
-                    aBody = calGetString("lightning",
-                                         "itipRequestBody",
-                                         [item.organizer ? item.organizer.toString() : "", summary],
-                                         "lightning");
+                    aSubject = cal.calGetString("lightning",
+                                                "itipRequestSubject",
+                                                [summary],
+                                                "lightning");
+                    aBody = cal.calGetString("lightning",
+                                             "itipRequestBody",
+                                             [item.organizer ? item.organizer.toString() : "", summary],
+                                             "lightning");
                     break;
                 case 'CANCEL':
-                    aSubject = calGetString("lightning",
-                                            "itipCancelSubject",
-                                            [summary],
-                                            "lightning");
-                    aBody = calGetString("lightning",
-                                         "itipCancelBody",
-                                         [item.organizer ? item.organizer.toString() : "", summary],
-                                         "lightning");
+                    aSubject = cal.calGetString("lightning",
+                                                "itipCancelSubject",
+                                                [summary],
+                                                "lightning");
+                    aBody = cal.calGetString("lightning",
+                                             "itipCancelBody",
+                                             [item.organizer ? item.organizer.toString() : "", summary],
+                                             "lightning");
                     break;
                 case 'REPLY': {
                     // Get my participation status
-                    var att = (calInstanceOf(aItipItem.targetCalendar, Components.interfaces.calISchedulingSupport)
+                    let att = (cal.calInstanceOf(aItipItem.targetCalendar, Components.interfaces.calISchedulingSupport)
                                ? aItipItem.targetCalendar.getInvitedAttendee(item) : null);
                     if (!att && aItipItem.identity) {
                         att = item.getAttendeeById("mailto:" + aItipItem.identity);
                     }
                     if (!att) { // should not happen anymore
                         return;
                     }
 
                     // work around BUG 351589, the below just removes RSVP:
                     aItipItem.setAttendeeStatus(att.id, att.participationStatus);
-                    var myPartStat = att.participationStatus;
-                    var name = att.toString();
+                    let myPartStat = att.participationStatus;
+                    let name = att.toString();
 
                     // Generate proper body from my participation status
-                    aSubject = calGetString("lightning",
-                                            "itipReplySubject",
-                                            [summary],
-                                            "lightning");
-                    aBody = calGetString("lightning",
-                                         (myPartStat == "DECLINED") ? "itipReplyBodyDecline"
-                                                                    : "itipReplyBodyAccept",
-                                         [name],
-                                         "lightning");
+                    aSubject = cal.calGetString("lightning",
+                                                "itipReplySubject",
+                                                [summary],
+                                                "lightning");
+                    aBody = cal.calGetString("lightning",
+                                             (myPartStat == "DECLINED") ? "itipReplyBodyDecline"
+                                                                        : "itipReplyBodyAccept",
+                                             [name],
+                                             "lightning");
                     break;
                 }
             }
 
             this._sendXpcomMail(aRecipients, aSubject, aBody, aItipItem);
         } else {
             // Sunbird case: Call user's default mailer on system.
             throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
@@ -178,114 +191,114 @@ calItipEmailTransport.prototype = {
                 let allIdentities = accountMgrSvc.allIdentities;
                 if (allIdentities.Count() > 0) {
                     this.mDefaultIdentity = allIdentities.GetElementAt(0)
                                                          .QueryInterface(Components.interfaces.nsIMsgIdentity);
                 } else {
                     // If there are no identities, then we are in the same
                     // situation as if we didn't have Xpcom Mail.
                     this.mHasXpcomMail = false;
-                    LOG("initEmailService: No XPCOM Mail available: " + e);
+                    cal.LOG("initEmailService: No XPCOM Mail available: " + e);
                 }
             }
         } catch (ex) {
             // Then we must resort to operating system specific means
             this.mHasXpcomMail = false;
         }
     },
 
     _sendXpcomMail: function cietSXM(aToList, aSubject, aBody, aItem) {
-        var identity = null;
-        var account;
+        let identity = null;
+        let account;
         if (aItem.targetCalendar) {
             identity = aItem.targetCalendar.getProperty("imip.identity");
             if (identity) {
                 identity = identity.QueryInterface(Components.interfaces.nsIMsgIdentity);
                 account = aItem.targetCalendar.getProperty("imip.account")
                                               .QueryInterface(Components.interfaces.nsIMsgAccount);
             } else {
-                WARN("No email identity configured for calendar " + aItem.targetCalendar.name);
+                cal.WARN("No email identity configured for calendar " + aItem.targetCalendar.name);
             }
         }
         if (!identity) { // use some default identity/account:
             identity = this.mDefaultIdentity;
             account = this.mDefaultAccount;
         }
 
-        var compatMode = 0;
+        let compatMode = 0;
         switch (aItem.autoResponse) {
             case (Components.interfaces.calIItipItem.USER): {
-                LOG("sendXpcomMail: Found USER autoResponse type.\n" +
-                    "This type is currently unsupported, the compose API will always enter a text/plain\n" +
-                    "or text/html part as first part of the message.\n" +
-                    "This will disable OL (up to 2003) to consume the mail as an iTIP invitation showing\n" +
-                    "the usual calendar buttons.");
+                cal.LOG("sendXpcomMail: Found USER autoResponse type.\n" +
+                        "This type is currently unsupported, the compose API will always enter a text/plain\n" +
+                        "or text/html part as first part of the message.\n" +
+                        "This will disable OL (up to 2003) to consume the mail as an iTIP invitation showing\n" +
+                        "the usual calendar buttons.");
                 // To somehow have a last resort before sending spam, the user can choose to send the mail.
-                var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+                let promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                                               .getService(Components.interfaces.nsIPromptService);
-                var prefCompatMode = getPrefSafe("calendar.itip.compatSendMode", 0);
-                var inoutCheck = { value: (prefCompatMode == 1) };
+                let prefCompatMode = getPrefSafe("calendar.itip.compatSendMode", 0);
+                let inoutCheck = { value: (prefCompatMode == 1) };
                 if (!promptService.confirmCheck(null,
-                                                calGetString("lightning", "imipSendMail.title", null, "lightning"),
-                                                calGetString("lightning", "imipSendMail.text", null, "lightning"),
-                                                calGetString("lightning", "imipSendMail.Outlook2000CompatMode.text", null, "lightning"),
+                                                cal.calGetString("lightning", "imipSendMail.title", null, "lightning"),
+                                                cal.calGetString("lightning", "imipSendMail.text", null, "lightning"),
+                                                cal.calGetString("lightning", "imipSendMail.Outlook2000CompatMode.text", null, "lightning"),
                                                 inoutCheck)) {
                     break;
                 } // else go on with auto sending for now
                 compatMode = (inoutCheck.value ? 1 : 0);
                 if (compatMode != prefCompatMode) {
                     setPref("calendar.itip.compatSendMode", compatMode);
                 }
             }
             case (Components.interfaces.calIItipItem.AUTO): {
-                LOG("sendXpcomMail: Found AUTO autoResponse type.");
-                var toList = "";
-                for each (var recipient in aToList) {
+                cal.LOG("sendXpcomMail: Found AUTO autoResponse type.");
+                let toList = "";
+                for each (let recipient in aToList) {
                     // Strip leading "mailto:" if it exists.
-                    var rId = recipient.id.replace(/^mailto:/i, "");
+                    let rId = recipient.id.replace(/^mailto:/i, "");
                     // Prevent trailing commas.
                     if (toList.length > 0) {
                         toList += ", ";
                     }
                     // Add this recipient id to the list.
                     toList += rId;
                 }
-                var mailFile = this._createTempImipFile(compatMode, toList, aSubject, aBody, aItem, identity);
+                let mailFile = this._createTempImipFile(compatMode, toList, aSubject, aBody, aItem, identity);
                 if (mailFile) {
                     // compose fields for message: from/to etc need to be specified both here and in the file
-                    var composeFields = Components.classes["@mozilla.org/messengercompose/composefields;1"]
+                    let composeFields = Components.classes["@mozilla.org/messengercompose/composefields;1"]
                                                   .createInstance(Components.interfaces.nsIMsgCompFields);
                     composeFields.characterSet = "UTF-8";
                     composeFields.to = toList;
                     composeFields.from = identity.email;
                     composeFields.replyTo = identity.replyTo;
 
                     // xxx todo: add send/progress UI, maybe recycle
                     //           "@mozilla.org/messengercompose/composesendlistener;1"
                     //           and/or "chrome://messenger/content/messengercompose/sendProgress.xul"
                     // i.e. bug 432662
-                    var msgSend = Components.classes["@mozilla.org/messengercompose/send;1"]
+                    let msgSend = Components.classes["@mozilla.org/messengercompose/send;1"]
                                             .createInstance(Components.interfaces.nsIMsgSend);
                     msgSend.sendMessageFile(identity,
                                             account.key,
                                             composeFields,
                                             mailFile,
                                             true  /* deleteSendFileOnCompletion */,
                                             false /* digest_p */,
-                                            (getIOService().offline ? Components.interfaces.nsIMsgSend.nsMsgQueueForLater
+                                            (cal.getIOService().offline ? Components.interfaces.nsIMsgSend.nsMsgQueueForLater
                                                                     : Components.interfaces.nsIMsgSend.nsMsgDeliverNow),
                                             null  /* nsIMsgDBHdr msgToReplace */,
                                             null  /* nsIMsgSendListener aListener */,
                                             null  /* nsIMsgStatusFeedback aStatusFeedback */,
                                             ""    /* password */);
                 }
                 break;
             }
             case (Components.interfaces.calIItipItem.NONE):
-                LOG("sendXpcomMail: Found NONE autoResponse type.");
+                cal.LOG("sendXpcomMail: Found NONE autoResponse type.");
 
                 // No response
                 break;
             default:
                 // Unknown autoResponse type
                 throw new Error("sendXpcomMail: " +
                                 "Unknown autoResponse type: " +
                                 aItem.autoResponse);
@@ -303,30 +316,30 @@ calItipEmailTransport.prototype = {
                 let fieldNameLen = (header.indexOf(": ") + 2);
                 return mimeConverter.encodeMimePartIIStr_UTF8(header,
                                                               false,
                                                               "UTF-8",
                                                               fieldNameLen,
                                                               Components.interfaces.nsIMimeConverter.MIME_ENCODED_WORD_SIZE);
             }
 
-            var itemList = aItem.getItemList({});
-            var serializer = Components.classes["@mozilla.org/calendar/ics-serializer;1"]
+            let itemList = aItem.getItemList({});
+            let serializer = Components.classes["@mozilla.org/calendar/ics-serializer;1"]
                                        .createInstance(Components.interfaces.calIIcsSerializer);
             serializer.addItems(itemList, itemList.length);
-            var methodProp = getIcsService().createIcalProperty("METHOD");
+            let methodProp = cal.getIcsService().createIcalProperty("METHOD");
             methodProp.value = aItem.responseMethod;
             serializer.addProperty(methodProp);
-            var calText = serializer.serializeToString();
-            var utf8CalText = encodeUTF8(calText);
+            let calText = serializer.serializeToString();
+            let utf8CalText = encodeUTF8(calText);
 
             // Home-grown mail composition; I'd love to use nsIMimeEmitter, but it's not clear to me whether
             // it can cope with nested attachments,
             // like multipart/alternative with enclosed text/calendar and text/plain.
-            var mailText = ("MIME-version: 1.0\r\n" +
+            let mailText = ("MIME-version: 1.0\r\n" +
                             (aIdentity.replyTo
                              ? "Return-path: " + aIdentity.replyTo + "\r\n" : "") +
                             "From: " + aIdentity.email + "\r\n" +
                             "To: " + aToList + "\r\n" +
                             "Date: " + (new Date()).toUTCString() + "\r\n" +
                             "Subject: " + encodeMimeHeader(aSubject.replace(/(\n|\r\n)/, "|")) + "\r\n");
             switch (compatMode) {
                 case 1:
@@ -363,99 +376,40 @@ calItipEmailTransport.prototype = {
                                  "Content-transfer-encoding: 8BIT\r\n" +
                                  "Content-disposition: attachment; filename=invite.ics\r\n" +
                                  "\r\n" +
                                  utf8CalText +
                                  "\r\n\r\n" +
                                  "--Boundary_(ID_qyG4ZdjoAsiZ+Jo19dCbWQ)--\r\n");
                     break;
             }
-            LOG("mail text:\n" + mailText);
+            cal.LOG("mail text:\n" + mailText);
 
-            var dirUtils = Components.classes["@mozilla.org/file/directory_service;1"]
+            let dirUtils = Components.classes["@mozilla.org/file/directory_service;1"]
                                      .createInstance(Components.interfaces.nsIProperties);
-            var tempFile = dirUtils.get("TmpD", Components.interfaces.nsIFile);
+            let tempFile = dirUtils.get("TmpD", Components.interfaces.nsIFile);
             tempFile.append("itipTemp");
             tempFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE,
                                   parseInt("0600", 8));
 
-            var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
+            let outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
                                          .createInstance(Components.interfaces.nsIFileOutputStream);
             // Let's write the file - constants from file-utils.js
             const MODE_WRONLY   = 0x02;
             const MODE_CREATE   = 0x08;
             const MODE_TRUNCATE = 0x20;
             outputStream.init(tempFile,
                               MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE,
                               parseInt("0600", 8),
                               0);
             outputStream.write(mailText, mailText.length);
             outputStream.close();
 
-            LOG("_createTempImipFile path: " + tempFile.path);
+            cal.LOG("_createTempImipFile path: " + tempFile.path);
             return tempFile;
         } catch (exc) {
-            ASSERT(false, exc);
+            cal.ASSERT(false, exc);
             return null;
         }
     }
 };
 
-// nsIFactory
-const calItipEmailTransportFactory = {
-    createInstance: function (outer, iid) {
-        if (outer != null)
-            throw Components.results.NS_ERROR_NO_AGGREGATION;
-        return (new calItipEmailTransport()).QueryInterface(iid);
-    }
-};
-
-/****
- **** module registration
- ****/
-
-var calItipEmailTransportModule = {
-
-    mCID: Components.ID("{d4d7b59e-c9e0-4a7a-b5e8-5958f85515f0}"),
-    mContractID: "@mozilla.org/calendar/itip-transport;1?type=email",
-
-    mUtilsLoaded: false,
-    loadUtils: function itipEmailLoadUtils() {
-        if (this.mUtilsLoaded)
-            return;
-
-        Components.utils.import("resource://calendar/modules/calUtils.jsm");
-        cal.loadScripts(["calUtils.js"], Components.utils.getGlobalForObject(this));
-
-        this.mUtilsLoaded = true;
-    },
-    
-    registerSelf: function (compMgr, fileSpec, location, type) {
-        compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
-        compMgr.registerFactoryLocation(this.mCID,
-                                        "Calendar iTIP Email Transport",
-                                        this.mContractID,
-                                        fileSpec,
-                                        location,
-                                        type);
-    },
-
-    getClassObject: function (compMgr, cid, iid) {
-        if (!cid.equals(this.mCID))
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-
-        if (!iid.equals(Components.interfaces.nsIFactory))
-            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-
-        this.loadUtils();
-
-        return calItipEmailTransportFactory;
-    },
-
-    canUnload: function(compMgr) {
-        return true;
-    }
-};
-
-function NSGetModule(compMgr, fileSpec) {
-    return calItipEmailTransportModule;
-}
-
+var NSGetModule = XPCOMUtils.generateNSGetModule([calItipEmailTransport]);
--- a/calendar/lightning/components/calItipProtocolHandler.js
+++ b/calendar/lightning/components/calItipProtocolHandler.js
@@ -1,9 +1,8 @@
-/* -*- Mode: javascript; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
  *
@@ -15,87 +14,73 @@
  * The Original Code is Lightning code.
  *
  * The Initial Developer of the Original Code is Oracle Corporation
  * Portions created by the Initial Developer are Copyright (C) 2005
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Mike Shaver <shaver@mozilla.org>
+ *   Philipp Kewisch <mozilla@kewis.ch>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or 
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
 const CI = Components.interfaces;
 
 const ITIP_HANDLER_MIMETYPE = "application/x-itip-internal";
 const ITIP_HANDLER_PROTOCOL = "moz-cal-handle-itip";
 
-const CAL_ITIP_PROTO_HANDLER_CID =
-    Components.ID("{6E957006-B4CE-11D9-B053-001124736B74}");
-const CAL_ITIP_PROTO_HANDLER_CONTRACTID =
-    "@mozilla.org/network/protocol;1?name=" + ITIP_HANDLER_PROTOCOL;
-
-const CALMGR_CONTRACTID = "@mozilla.org/calendar/manager;1";
-
-const ItipProtocolHandlerFactory =
-{
-    createInstance: function (outer, iid) {
-        if (outer != null)
-            throw Components.results.NS_ERROR_NO_AGGREGATION;
-
-        return (new ItipProtocolHandler()).QueryInterface(iid);
-    }
-};
-
-const CAL_ITIP_CONTENT_HANDLER_CID =
-    Components.ID("{47C31F2B-B4DE-11D9-BFE6-001124736B74}");
-const CAL_ITIP_CONTENT_HANDLER_CONTRACTID =
-    "@mozilla.org/uriloader/content-handler;1?type=" +
-    ITIP_HANDLER_MIMETYPE;
-
-const ItipContentHandlerFactory =
-{
-    createInstance: function (outer, iid) {
-        if (outer != null)
-            throw Components.results.NS_ERROR_NO_AGGREGATION;
-
-        return (new ItipContentHandler()).QueryInterface(iid);
-    }
-};
 
 function NYI()
 {
     throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
 }
 
 function ItipChannel(URI)
 {
    this.URI = this.originalURI = URI;
 }
 
 ItipChannel.prototype = {
-    QueryInterface: function (aIID) {
-        if (!aIID.equals(CI.nsISupports) &&
-            !aIID.equals(CI.nsIChannel) &&
-            !aIID.equals(CI.nsIRequest))
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-        
-        return this;
+    classID: Components.ID("{643e0328-36f6-411d-a107-16238dff9cd7}"),
+    contractID: "@mozilla.org/calendar/itip-channel;1",
+    classDescription: "Calendar Itip Channel",
+
+    getInterfaces: function getInterfaces(count) {
+        const ifaces = [Components.interfaces.nsIChannel,
+                        Components.interfaces.nsIRequest,
+                        Components.interfaces.nsIClassInfo,
+                        Components.interfaces.nsISupports];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+    getHelperForLanguage: function getHelperForLanguage(language) {
+        return null;
+    },
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
+
+    QueryInterface: function QueryInterface(aIID) {
+        return cal.doQueryInterface(this, ItipChannel.prototype, aIID, null, this);
     },
     
     contentType: ITIP_HANDLER_MIMETYPE,
     loadAttributes: null,
     contentLength: 0,
     owner: null,
     loadGroup: null,
     notificationCallbacks: null,
@@ -114,110 +99,97 @@ ItipChannel.prototype = {
     cancel: function (status) { this.status = status; },
     suspend: NYI,
     resume: NYI,
 };
 
 function ItipProtocolHandler() { }
 
 ItipProtocolHandler.prototype = {
-    QueryInterface: function (aIID) {
-        if (!aIID.equals(CI.nsISupports) &&
-            !aIID.equals(CI.nsIProtocolHandler))
-            throw Components.results.NS_ERROR_NO_INTERFACE;
+    classID: Components.ID("{6e957006-b4ce-11d9-b053-001124736B74}"),
+    contractID: "@mozilla.org/network/protocol;1?name=" + ITIP_HANDLER_PROTOCOL,
+    getInterfaces: function getInterfaces(count) {
+        const ifaces = [Components.interfaces.nsIProtocolHandler,
+                        Components.interfaces.nsIClassInfo,
+                        Components.interfaces.nsISupports];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+    getHelperForLanguage: function getHelperForLanguage(language) {
+        return null;
+    },
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
 
-        return this;
+    QueryInterface: function QI(aIID) {
+        return cal.doQueryInterface(this, ItipProtocolHandler.prototype, aIID, null, this);
     },
     
     protocolFlags: CI.nsIProtocolHandler.URI_NORELATIVE | CI.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD,
     allowPort: function () { return false; },
     isSecure: false,
     newURI: function (spec, charSet, baseURI)
     {
-        var cls = Components.classes["@mozilla.org/network/standard-url;1"];
-        var url = cls.createInstance(CI.nsIStandardURL);
+        let cls = Components.classes["@mozilla.org/network/standard-url;1"];
+        let url = cls.createInstance(CI.nsIStandardURL);
         url.init(CI.nsIStandardURL.URLTYPE_STANDARD, 0, spec, charSet, baseURI);
         dump("Creating new URI for " + spec + "\n");
         return url.QueryInterface(CI.nsIURI);
     },
     
     newChannel: function (URI) {
         dump("Creating new ItipChannel for " + URI + "\n");
         return new ItipChannel(URI);
     },
 };
 
 function ItipContentHandler() { }
 
 ItipContentHandler.prototype = {
+    classID: Components.ID("{47c31f2b-b4de-11d9-bfe6-001124736B74}"),
+    contractID: "@mozilla.org/uriloader/content-handler;1?type=" + ITIP_HANDLER_MIMETYPE,
+    classDescription: "Lightning text/calendar content handler",
+
+    getInterfaces: function getInterfaces(count) {
+        const ifaces = [Components.interfaces.nsIContentHandler,
+                        Components.interfaces.nsIClassInfo,
+                        Components.interfaces.nsISupports];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+    getHelperForLanguage: function getHelperForLanguage(language) {
+        return null;
+    },
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
+
     QueryInterface: function (aIID) {
-        if (!aIID.equals(CI.nsISupports) &&
-            !aIID.equals(CI.nsIContentHandler))
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-        
-        return this;
+        return cal.doQueryInterface(this, ItipContentHandler.prototype, aIID, null, this);
     },
 
     handleContent: function (contentType, windowTarget, request)
     {
-        dump("Handling some itip content, whee\n");
-        var channel = request.QueryInterface(CI.nsIChannel);
-        var uri = channel.URI.spec;
+        let channel = request.QueryInterface(CI.nsIChannel);
+        let uri = channel.URI.spec;
         if (uri.indexOf(ITIP_HANDLER_PROTOCOL + ":") != 0) {
-            dump("unexpected uri " + uri + "\n");
+            cal.ERROR("Unexpected iTIP uri: " + uri + "\n");
             return Components.results.NS_ERROR_FAILURE;
         }
         // moz-cal-handle-itip:///?
-        var paramString = uri.substring(ITIP_HANDLER_PROTOCOL.length + 4);
-        var paramArray = paramString.split("&");
-        var paramBlock = { };
+        let paramString = uri.substring(ITIP_HANDLER_PROTOCOL.length + 4);
+        let paramArray = paramString.split("&");
+        let paramBlock = { };
         paramArray.forEach(function (v) {
-            var parts = v.split("=");
+            let parts = v.split("=");
             paramBlock[parts[0]] = unescape(unescape(parts[1]));
             });
         // dump("content-handler: have params " + paramBlock.toSource() + "\n");
-        var event = Components.classes["@mozilla.org/calendar/event;1"].
-            createInstance(CI.calIEvent);
-        event.icalString = paramBlock.data;
+        let event = cal.createEvent(paramBlock.data);
         dump("Processing iTIP event '" + event.title + "' from " +
             event.organizer.id + " (" + event.id + ")\n");
-        var calMgr = Components.classes[CALMGR_CONTRACTID].getService(CI.calICalendarManager);
-        var cals = calMgr.getCalendars({});
+        let calMgr = cal.getCalendarManager();
+        let cals = calMgr.getCalendars({});
         cals[0].addItem(event, null);
     }
 };
 
-var myModule = {
-    registerSelf: function (compMgr, fileSpec, location, type) {
-        debug("*** Registering Lightning " + ITIP_HANDLER_PROTOCOL + ": handler\n");
-        compMgr = compMgr.QueryInterface(CI.nsIComponentRegistrar);
-        compMgr.registerFactoryLocation(CAL_ITIP_PROTO_HANDLER_CID,
-                                        "Lightning " + ITIP_HANDLER_PROTOCOL + ": handler",
-                                        CAL_ITIP_PROTO_HANDLER_CONTRACTID,
-                                        fileSpec, location, type);
-        debug("*** Registering Lightning " + ITIP_HANDLER_MIMETYPE + " handler\n");
-        compMgr.registerFactoryLocation(CAL_ITIP_CONTENT_HANDLER_CID,
-                                        "Lightning " + ITIP_HANDLER_MIMETYPE + " handler",
-                                        CAL_ITIP_CONTENT_HANDLER_CONTRACTID,
-                                        fileSpec, location, type);
-    },
-
-    getClassObject: function (compMgr, cid, iid) {
-        if (!iid.equals(Components.interfaces.nsIFactory))
-            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-
-        if (cid.equals(CAL_ITIP_PROTO_HANDLER_CID))
-            return ItipProtocolHandlerFactory;
-
-        if (cid.equals(CAL_ITIP_CONTENT_HANDLER_CID))
-            return ItipContentHandlerFactory;
-
-       throw Components.results.NS_ERROR_NO_INTERFACE;
-    },
-
-    canUnload: function(compMgr) {
-        return true;
-    }
-};
-
-function NSGetModule(compMgr, fileSpec) {
-    return myModule;
-}
+var components = [ItipChannel, ItipProtocolHandler, ItipContentHandler];
+var NSGetModule = XPCOMUtils.generateNSGetModule(components);
--- a/calendar/lightning/components/lightningTextCalendarConverter.js
+++ b/calendar/lightning/components/lightningTextCalendarConverter.js
@@ -1,9 +1,8 @@
-/* -*- Mode: javascript; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
  *
@@ -34,16 +33,19 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
 function makeTableRow(val) {
     return "<tr><td>" + val[0] + "</td><td>" + val[1] + "</td></tr>\n";
 }
 
 function getLightningStringBundle()
 {
     var svc = Components.classes["@mozilla.org/intl/stringbundle;1"].
               getService(Components.interfaces.nsIStringBundleService);
@@ -144,17 +146,17 @@ function createHtml(event)
 
         var eventLocation = event.getProperty("LOCATION");
         if (eventLocation) {
             labelText = stringBundle.GetStringFromName("imipHtml.location");
             html.body.table.appendChild(createHtmlTableSection(labelText,
                                                                eventLocation));
         }
 
-        var dateString = getDateFormatter().formatItemInterval(event);
+        var dateString = cal.getDateFormatter().formatItemInterval(event);
         var labelText = stringBundle.GetStringFromName("imipHtml.when");
         html.body.table.appendChild(createHtmlTableSection(labelText,
                                                            dateString));
 
         if (event.organizer &&
             (event.organizer.commonName || event.organizer.id))
         {
             labelText = stringBundle.GetStringFromName("imipHtml.organizer");
@@ -181,41 +183,57 @@ function createHtml(event)
     }
 
     return html;
 }
 
 function ltnMimeConverter() { }
 
 ltnMimeConverter.prototype = {
+    classID: Components.ID("{c70acb08-464e-4e55-899d-b2c84c5409fa}"),
+    contractID: "@mozilla.org/lightning/mime-converter;1",
+    classDescription: "Lightning text/calendar handler",
+
+    getInterfaces: function getInterfaces(count) {
+        const ifaces = [Components.interfaces.nsISimpleMimeConverter,
+                        Components.interfaces.nsIClassInfo,
+                        Components.interfaces.nsISupports];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+    getHelperForLanguage: function getHelperForLanguage(language) {
+        return null;
+    },
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
+
+    _xpcom_categories: [{
+        category: 'simple-mime-converters',
+        entry: 'text/calendar'
+    }],
+
     QueryInterface: function QI(aIID) {
-        if (!aIID.equals(Components.interfaces.nsISupports) &&
-            !aIID.equals(Components.interfaces.nsISimpleMimeConverter))
-        {
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-        }
-
-        return this;
+        return cal.doQueryInterface(this, ltnMimeConverter.prototype, aIID, null, this);
     },
 
     mUri: null,
     get uri() {
         return this.mUri;
     },
     set uri(aUri) {
         return (this.mUri = aUri);
     },
 
     convertToHTML: function lmcCTH(contentType, data) {
         let parser = Components.classes["@mozilla.org/calendar/ics-parser;1"]
                                .createInstance(Components.interfaces.calIIcsParser);
         parser.parseString(data);
         let event = null;
         for each (var item in parser.getItems({})) {
-            if (isEvent(item)) {
+            if (cal.isEvent(item)) {
                 if (item.hasProperty("X-MOZ-FAKED-MASTER")) {
                     // if it's a faked master, take any overridden item to get a real occurrence:
                     let exc = item.recurrenceInfo.getExceptionFor(item.startDate);
                     cal.ASSERT(exc, "unexpected!");
                     if (exc) {
                         item = exc;
                     }
                 }
@@ -257,66 +275,9 @@ ltnMimeConverter.prototype = {
         } catch (e) {
             Components.utils.reportError("[ltnMimeConverter] convertToHTML: " + e);
         }
 
         return html;
     }
 };
 
-var myModule = {
-    registerSelf: function RS(aCompMgr, aFileSpec, aLocation, aType) {
-        debug("*** Registering Lightning text/calendar handler\n");
-        var compMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
-        compMgr.registerFactoryLocation(this.myCID,
-                                        "Lightning text/calendar handler",
-                                        this.myContractID,
-                                        aFileSpec,
-                                        aLocation,
-                                        aType);
-
-        var catman = Components.classes["@mozilla.org/categorymanager;1"]
-                               .getService(Components.interfaces.nsICategoryManager);
-
-        catman.addCategoryEntry("simple-mime-converters", "text/calendar",
-                                this.myContractID, true, true);
-    },
-
-    mScriptsLoaded: false,
-    getClassObject: function GCO(aCompMgr, aCid, aIid) {
-        if (!this.mScriptsLoaded) {
-
-            Components.utils.import("resource://calendar/modules/calUtils.jsm");
-            cal.loadScripts(["calUtils.js"], Components.utils.getGlobalForObject(this));
-
-            this.mScriptsLoaded = true;
-        }
-
-        if (!aCid.equals(this.myCID)) {
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-        }
-        if (!aIid.equals(Components.interfaces.nsIFactory)) {
-            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-        }
-        return this.myFactory;
-    },
-
-    myCID: Components.ID("{c70acb08-464e-4e55-899d-b2c84c5409fa}"),
-
-    myContractID: "@mozilla.org/lightning/mime-converter;1",
-
-    myFactory: {
-        createInstance: function mfCI(aOuter, aIid) {
-            if (aOuter != null) {
-                throw Components.results.NS_ERROR_NO_AGGREGATION;
-            }
-            return (new ltnMimeConverter()).QueryInterface(aIid);
-        }
-    },
-
-    canUnload: function CU(aCompMgr) {
-        return true;
-    }
-};
-
-function NSGetModule(compMgr, fileSpec) {
-    return myModule;
-}
+var NSGetModule = XPCOMUtils.generateNSGetModule([ltnMimeConverter]);
--- a/calendar/lightning/jar.mn
+++ b/calendar/lightning/jar.mn
@@ -60,8 +60,9 @@ calendar.jar:
     content/calendar/datetimepickers/datetimepickers.css   (/calendar/resources/content/datetimepickers/datetimepickers.css)
 *   content/calendar/datetimepickers/datetimepickers.xml   (/calendar/resources/content/datetimepickers/datetimepickers.xml)
     content/calendar/mouseoverPreviews.js                  (/calendar/resources/content/mouseoverPreviews.js)
     content/calendar/publish.js                            (/calendar/resources/content/publish.js)
     content/calendar/publishDialog.js                      (/calendar/resources/content/publishDialog.js)
     content/calendar/publishDialog.xul                     (/calendar/resources/content/publishDialog.xul)
     content/calendar/sound.wav                             (/calendar/resources/content/sound.wav)
     skin/calendar/datetimepickers/datetimepickers.css      (/calendar/resources/skin/classic/datetimepickers/datetimepickers.css)
+% resource calendar .
--- a/calendar/providers/caldav/Makefile.in
+++ b/calendar/providers/caldav/Makefile.in
@@ -42,18 +42,18 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = caldav
 
 DIRS = public
 
-EXTRA_COMPONENTS = calDavCalendarModule.js
-EXTRA_SCRIPTS = calDavCalendar.js calDavRequestHandlers.js
+EXTRA_COMPONENTS = calDavCalendar.js
+EXTRA_SCRIPTS = calDavRequestHandlers.js
 
 libs:: $(EXTRA_SCRIPTS)
 	if test ! -d $(FINAL_TARGET)/calendar-js; then $(NSINSTALL) -D $(FINAL_TARGET)/calendar-js; fi
 	$(INSTALL) $^ $(FINAL_TARGET)/calendar-js
 
 # The install target must use SYSINSTALL, which is NSINSTALL in copy mode.
 install:: $(EXTRA_SCRIPTS)
 	$(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/calendar-js
--- a/calendar/providers/caldav/calDavCalendar.js
+++ b/calendar/providers/caldav/calDavCalendar.js
@@ -41,16 +41,19 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calIteratorUtils.jsm");
 Components.utils.import("resource://calendar/modules/calProviderUtils.jsm");
 Components.utils.import("resource://calendar/modules/calAuthUtils.jsm");
 
 //
 // calDavCalendar.js
 //
@@ -97,28 +100,44 @@ const kDavResourceTypeCalendar = 2;
 // used for etag checking
 const CALDAV_ADOPT_ITEM = 1;
 const CALDAV_MODIFY_ITEM = 2;
 const CALDAV_DELETE_ITEM = 3;
 
 calDavCalendar.prototype = {
     __proto__: cal.ProviderBase.prototype,
 
+    classID: Components.ID("{a35fc6ea-3d92-11d9-89f9-00045ace3b8d}"),
+    contractID: "@mozilla.org/calendar/calendar;1?type=caldav",
+    classDescription: "Calendar CalDAV back-end",
+
+    getInterfaces: function getInterfaces(count) {
+        const ifaces = [Components.interfaces.calICalendarProvider,
+                        Components.interfaces.nsIInterfaceRequestor,
+                        Components.interfaces.calIFreeBusyProvider,
+                        Components.interfaces.nsIChannelEventSink,
+                        Components.interfaces.calIItipTransport,
+                        Components.interfaces.calIChangeLog,
+                        calICalDavCalendar,
+                        Components.interfaces.nsIClassInfo,
+                        Components.interfaces.nsISupports];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+    getHelperForLanguage: function getHelperForLanguage(language) {
+        return null;
+    },
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
+
     //
     // nsISupports interface
     //
     QueryInterface: function caldav_QueryInterface(aIID) {
-        return doQueryInterface(this, calDavCalendar.prototype, aIID,
-                                [Components.interfaces.calICalendarProvider,
-                                 Components.interfaces.nsIInterfaceRequestor,
-                                 Components.interfaces.calIFreeBusyProvider,
-                                 Components.interfaces.nsIChannelEventSink,
-                                 Components.interfaces.calIItipTransport,
-                                 Components.interfaces.calIChangeLog,
-                                 calICalDavCalendar]);
+        return cal.doQueryInterface(this, calDavCalendar.prototype, aIID, null, this);
     },
 
     // An array of components that are supported by the server. The default is
     // to support VEVENT and VTODO, if queries for these components return a 4xx
     // error, then they will be removed from this array.
     mGenerallySupportedItemTypes: null,
     mSupportedItemTypes: null,
     suportedItemTypes: null,
@@ -2473,8 +2492,27 @@ calDavObserver.prototype = {
         this.mCalendar.observers.notify("onPropertyDeleting", [aCalendar, aName]);
     },
 
     onError: function(aCalendar, aErrNo, aMessage) {
         this.mCalendar.readOnly = true;
         this.mCalendar.notifyError(aErrNo, aMessage);
     }
 };
+
+/** Module Registration */
+const scriptLoadOrder = [
+    "calUtils.js",
+    "calDavRequestHandlers.js"
+];
+
+function NSGetModule(cid) {
+    if (!this.scriptsLoaded) {
+        Services.io.getProtocolHandler("resource")
+                .QueryInterface(Components.interfaces.nsIResProtocolHandler)
+                .setSubstitution("calendar", Services.io.newFileURI(__LOCATION__.parent.parent));
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+        cal.loadScripts(scriptLoadOrder, Components.utils.getGlobalForObject(this));
+        this.scriptsLoaded = true;
+    }
+
+    return (XPCOMUtils.generateNSGetModule([calDavCalendar]))(cid);
+}
deleted file mode 100644
--- a/calendar/providers/caldav/calDavCalendarModule.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Oracle Corporation code.
- *
- * The Initial Developer of the Original Code is
- *  Oracle Corporation
- * Portions created by the Initial Developer are Copyright (C) 2004
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
- *   Dan Mosedale <dan.mosedale@oracle.com>
- *   Mike Shaver <mike.x.shaver@oracle.com>
- *   Gary van der Merwe <garyvdm@gmail.com>
- *   Bruno Browning <browning@uwalumni.com>
- *   Matthew Willis <lilmatt@mozilla.com>
- *   Daniel Boelzle <daniel.boelzle@sun.com>
- *   Philipp Kewisch <mozilla@kewis.ch>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// nsIFactory
-const calDavCalendarFactory = {
-    QueryInterface: function (aIID) {
-        if (!aIID.equals(Components.interfaces.nsISupports) &&
-            !aIID.equals(Components.interfaces.nsIFactory)) {
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-        }
-        return this;
-    },
-
-    createInstance: function (outer, iid) {
-        if (outer != null)
-            throw Components.results.NS_ERROR_NO_AGGREGATION;
-        return (new calDavCalendar()).QueryInterface(iid);
-    }
-};
-
-/****
- **** module registration
- ****/
-
-var calDavCalendarModule = {
-    mCID: Components.ID("{a35fc6ea-3d92-11d9-89f9-00045ace3b8d}"),
-    mContractID: "@mozilla.org/calendar/calendar;1?type=caldav",
-
-    mUtilsLoaded: false,
-    loadUtils: function cDCM_loadUtils() {
-        if (this.mUtilsLoaded) {
-            return;
-        }
-
-        Components.utils.import("resource://calendar/modules/calUtils.jsm");
-        cal.loadScripts(["calUtils.js", "calDavCalendar.js", "calDavRequestHandlers.js" ],
-                        Components.utils.getGlobalForObject(this));
-
-        this.mUtilsLoaded = true;
-    },
-
-    registerSelf: function (compMgr, fileSpec, location, type) {
-        compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
-        compMgr.registerFactoryLocation(this.mCID,
-                                        "Calendar CalDAV back-end",
-                                        this.mContractID,
-                                        fileSpec,
-                                        location,
-                                        type);
-    },
-
-    getClassObject: function (compMgr, cid, iid) {
-        if (!cid.equals(this.mCID))
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-
-        if (!iid.equals(Components.interfaces.nsIFactory))
-            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-
-        this.loadUtils();
-
-        return calDavCalendarFactory;
-    },
-
-    canUnload: function(compMgr) {
-        return true;
-    }
-};
-
-function NSGetModule(compMgr, fileSpec) {
-    return calDavCalendarModule;
-}
--- a/calendar/providers/composite/Makefile.in
+++ b/calendar/providers/composite/Makefile.in
@@ -15,16 +15,17 @@
 # The Original Code is the Oracle Corporation code.
 #
 # The Initial Developer of the Original Code is Oracle Corporation.
 # Portions created by the Initial Developer are Copyright (C) 2004
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #   Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
+#   Philipp Kewisch <mozilla@kewis.ch>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
--- a/calendar/providers/composite/calCompositeCalendar.js
+++ b/calendar/providers/composite/calCompositeCalendar.js
@@ -31,16 +31,19 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
 //
 // calCompositeCalendar.js
 //
 
 /**
  * Calendar specific utility functions
  */
 const calIOperationListener = Components.interfaces.calIOperationListener;
@@ -106,45 +109,54 @@ function calCompositeCalendar () {
     this.mCalendars = new Array();
     this.mCompositeObservers = new cal.ObserverBag(Components.interfaces.calICompositeObserver);
     this.mObservers = new cal.ObserverBag(Components.interfaces.calIObserver);
     this.mDefaultCalendar = null;
     this.mStatusObserver = null;
 }
 
 calCompositeCalendar.prototype = {
+    classID: Components.ID("{aeff788d-63b0-4996-91fb-40a7654c6224}"),
+    contractID: "@mozilla.org/calendar/calendar;1?type=composite",
+    classDescription: "Composite Calendar Provider",
+
+    getInterfaces: function getInterfaces(count) {
+        const ifaces = [Components.interfaces.calICalendarProvider,
+                        Components.interfaces.calICalendar,
+                        Components.interfaces.calICompositeCalendar,
+                        Components.interfaces.nsIClassInfo,
+                        Components.interfaces.nsISupports];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+    getHelperForLanguage: function getHelperForLanguage(language) {
+        return null;
+    },
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
+
+    QueryInterface: function (aIID) {
+        return cal.doQueryInterface(this, calCompositeCalendar.prototype, aIID, null, this);
+    },
+
     //
     // private members
     //
     mDefaultCalendar: null,
 
-    //
-    // nsISupports interface
-    //
-    QueryInterface: function (aIID) {
-        if (!aIID.equals(Components.interfaces.nsISupports) &&
-            !aIID.equals(Components.interfaces.calICalendarProvider) &&
-            !aIID.equals(Components.interfaces.calICalendar) &&
-            !aIID.equals(Components.interfaces.calICompositeCalendar))
-        {
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-        }
-
-        return this;
-    },
 
     //
     // calICalendarProvider interface
     //
     get prefChromeOverlay() {
         return null;
     },
 
     get displayName() {
-        return calGetString("calendar", "compositeName");
+        return cal.calGetString("calendar", "compositeName");
     },
 
     createCalendar: function comp_createCal() {
         throw NS_ERROR_NOT_IMPLEMENTED;
     },
 
     deleteCalendar: function comp_deleteCal(calendar, listener) {
         // You shouldn't be able to delete from the composite calendar.
@@ -171,18 +183,18 @@ calCompositeCalendar.prototype = {
         if (this.mPrefPrefix) {
             for each (let calendar in this.mCalendars) {
                 this.removeCalendar(calendar);
             }
         }
         this.mPrefPrefix = aPrefPrefix;
         this.mActivePref = aPrefPrefix + "-in-composite";
         this.mDefaultPref = aPrefPrefix + "-default";
-        var mgr = getCalendarManager();
-        var cals = mgr.getCalendars({});
+        let mgr = cal.getCalendarManager();
+        let cals = mgr.getCalendars({});
 
         cals.forEach(function (c) {
             if (c.getProperty(this.mActivePref))
                 this.addCalendar(c);
             if (c.getProperty(this.mDefaultPref))
                 this.setDefaultCalendar(c, false);
         }, this);
     },
@@ -332,117 +344,117 @@ calCompositeCalendar.prototype = {
     deleteProperty: function(aName) {
         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
     },
 
     // void addObserver( in calIObserver observer );
     mCompositeObservers: null,
     mObservers: null,
     addObserver: function (aObserver) {
-        if (calInstanceOf(aObserver, Components.interfaces.calICompositeObserver)) {
+        if (cal.calInstanceOf(aObserver, Components.interfaces.calICompositeObserver)) {
             this.mCompositeObservers.add(aObserver);
         }
         this.mObservers.add(aObserver);
     },
 
     // void removeObserver( in calIObserver observer );
     removeObserver: function (aObserver) {
-        if (calInstanceOf(aObserver, Components.interfaces.calICompositeObserver)) {
+        if (cal.calInstanceOf(aObserver, Components.interfaces.calICompositeObserver)) {
             this.mCompositeObservers.remove(aObserver);
         }
         this.mObservers.remove(aObserver);
     },
 
     refresh: function cCC_refresh() {
         if (this.mStatusObserver) {
             this.mStatusObserver.startMeteors(Components.interfaces.calIStatusObserver.DETERMINED_PROGRESS, this.mCalendars.length);
         }
         for each (let calendar in this.enabledCalendars) {
             try {
                 if (calendar.canRefresh) {
                     this.mObserverHelper.pendingLoads[calendar.id] = true;
                     calendar.refresh();
                 }
             } catch (e) {
-                ASSERT(false, e);
+                cal.ASSERT(false, e);
                 delete this.mObserverHelper.pendingLoads[calendar.id];
             }
         }
         // send out a single onLoad for this composite calendar,
         // although e.g. the ics provider will trigger another
         // onLoad asynchronously; we cannot rely on every calendar
         // sending an onLoad:
         this.mObservers.notify("onLoad", [this]);
     },
 
     // void modifyItem( in calIItemBase aNewItem, in calIItemBase aOldItem, in calIOperationListener aListener );
     modifyItem: function (aNewItem, aOldItem, aListener) {
-        ASSERT(aNewItem.calendar, "Composite can't modify item with null calendar", true);
-        ASSERT(aNewItem.calendar != this, "Composite can't modify item with this calendar", true);
+        cal.ASSERT(aNewItem.calendar, "Composite can't modify item with null calendar", true);
+        cal.ASSERT(aNewItem.calendar != this, "Composite can't modify item with this calendar", true);
 
         return aNewItem.calendar.modifyItem(aNewItem, aOldItem, aListener);
     },
 
     // void deleteItem( in string id, in calIOperationListener aListener );
     deleteItem: function (aItem, aListener) {
-        ASSERT(aItem.calendar, "Composite can't delete item with null calendar", true);
-        ASSERT(aItem.calendar != this, "Composite can't delete item with this calendar", true);
+        cal.ASSERT(aItem.calendar, "Composite can't delete item with null calendar", true);
+        cal.ASSERT(aItem.calendar != this, "Composite can't delete item with this calendar", true);
 
         return aItem.calendar.deleteItem(aItem, aListener);
     },
 
     // void addItem( in calIItemBase aItem, in calIOperationListener aListener );
     addItem: function (aItem, aListener) {
         return this.mDefaultCalendar.addItem(aItem, aListener);
     },
 
     // void getItem( in string aId, in calIOperationListener aListener );
     getItem: function (aId, aListener) {
-        var enabledCalendars = this.enabledCalendars;
-        var cmpListener = new calCompositeGetListenerHelper(this, aListener);
+        let enabledCalendars = this.enabledCalendars;
+        let cmpListener = new calCompositeGetListenerHelper(this, aListener);
         for each (let calendar in enabledCalendars) {
             try {
                 cmpListener.opGroup.add(calendar.getItem(aId, cmpListener));
             } catch (exc) {
-                ASSERT(false, exc);
+                cal.ASSERT(false, exc);
             }
         }
         return cmpListener.opGroup;
     },
 
     // void getItems( in unsigned long aItemFilter, in unsigned long aCount,
     //                in calIDateTime aRangeStart, in calIDateTime aRangeEnd,
     //                in calIOperationListener aListener );
     getItems: function (aItemFilter, aCount, aRangeStart, aRangeEnd, aListener) {
         // If there are no calendars, then we just call onOperationComplete
-        var enabledCalendars = this.enabledCalendars;
+        let enabledCalendars = this.enabledCalendars;
         if (enabledCalendars.length == 0) {
             aListener.onOperationComplete (this,
                                            Components.results.NS_OK,
                                            calIOperationListener.GET,
                                            null,
                                            null);
             return;
         }
         if (this.mStatusObserver) {
             if (this.mStatusObserver.spinning == Components.interfaces.calIStatusObserver.NO_PROGRESS) {
                 this.mStatusObserver.startMeteors(Components.interfaces.calIStatusObserver.UNDETERMINED_PROGRESS, -1);
             }
         }
-        var cmpListener = new calCompositeGetListenerHelper(this, aListener, aCount);
+        let cmpListener = new calCompositeGetListenerHelper(this, aListener, aCount);
 
         for each (let calendar in enabledCalendars) {
             try {
                 cmpListener.opGroup.add(calendar.getItems(aItemFilter,
                                                           aCount,
                                                           aRangeStart,
                                                           aRangeEnd,
                                                           cmpListener));
             } catch (exc) {
-                ASSERT(false, exc);
+                cal.ASSERT(false, exc);
             }
         }
         return cmpListener.opGroup;
     },
 
     startBatch: function () {
         this.mCompositeObservers.notify("onStartBatch");
     },
@@ -481,30 +493,30 @@ calCompositeGetListenerHelper.prototype 
     mOpGroup: null,
     mReceivedCompletes: 0,
     mFinished: false,
     mMaxItems: 0,
     mItemsReceived: 0,
 
     get opGroup() {
         if (!this.mOpGroup) {
-            var this_ = this;
+            let this_ = this;
             function cancelFunc() { // operation group has been cancelled
-                var listener = this_.mRealListener;
+                let listener = this_.mRealListener;
                 this_.mRealListener = null;
                 if (listener) {
                     listener.onOperationComplete(
                         this_, Components.interfaces.calIErrors.OPERATION_CANCELLED,
                         calIOperationListener.GET, null, null);
                     if (this_.mCompositeCalendar.statusDisplayed) {
                         this_.mCompositeCalendar.mStatusObserver.stopMeteors();
                     }
                 }
             }
-            this.mOpGroup = new calOperationGroup(cancelFunc);
+            this.mOpGroup = new cal.calOperationGroup(cancelFunc);
         }
         return this.mOpGroup;
     },
 
     QueryInterface: function (aIID) {
         if (!aIID.equals(Components.interfaces.nsISupports) &&
             !aIID.equals(Components.interfaces.calIOperationListener))
         {
@@ -576,67 +588,10 @@ calCompositeGetListenerHelper.prototype 
 
         // send GetResults to the real listener
         this.mRealListener.onGetResult (aCalendar, aStatus, aItemType, aDetail, aCount, aItems);
         this.mItemsReceived += aCount;
     }
 
 };
 
-// nsIFactory
-const calCompositeCalendarFactory = {
-    createInstance: function (outer, iid) {
-        if (outer != null)
-            throw Components.results.NS_ERROR_NO_AGGREGATION;
-        return (new calCompositeCalendar()).QueryInterface(iid);
-    }
-};
-
-/****
- **** module registration
- ****/
-
-var calCompositeCalendarModule = {
-    mCID: Components.ID("{aeff788d-63b0-4996-91fb-40a7654c6224}"),
-    mContractID: "@mozilla.org/calendar/calendar;1?type=composite",
-
-    mUtilsLoaded: false,
-    loadUtils: function compositeLoadUtils() {
-        if (this.mUtilsLoaded)
-            return;
-
-        Components.utils.import("resource://calendar/modules/calUtils.jsm");
-        Components.utils.import("resource://calendar/modules/calProviderUtils.jsm");
-        cal.loadScripts(["calUtils.js"], Components.utils.getGlobalForObject(this));
-
-        this.mUtilsLoaded = true;
-    },
-
-    registerSelf: function (compMgr, fileSpec, location, type) {
-        compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
-        compMgr.registerFactoryLocation(this.mCID,
-                                        "Calendar composite provider",
-                                        this.mContractID,
-                                        fileSpec,
-                                        location,
-                                        type);
-    },
-
-    getClassObject: function (compMgr, cid, iid) {
-        if (!cid.equals(this.mCID))
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-
-        if (!iid.equals(Components.interfaces.nsIFactory))
-            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-
-        this.loadUtils();
-
-        return calCompositeCalendarFactory;
-    },
-
-    canUnload: function(compMgr) {
-        return true;
-    }
-};
-
-function NSGetModule(compMgr, fileSpec) {
-    return calCompositeCalendarModule;
-}
+/** Module Registration */
+var NSGetModule = XPCOMUtils.generateNSGetModule([calCompositeCalendar]);
--- a/calendar/providers/gdata/components/calGoogleCalendar.js
+++ b/calendar/providers/gdata/components/calGoogleCalendar.js
@@ -32,38 +32,59 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 Components.utils.import("resource://calendar/modules/calProviderUtils.jsm");
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 /**
  * calGoogleCalendar
  * This Implements a calICalendar Object adapted to the Google Calendar
  * Provider.
  *
  * @class
  * @constructor
  */
 function calGoogleCalendar() {
     this.initProviderBase();
 }
 
 calGoogleCalendar.prototype = {
     __proto__: cal.ProviderBase.prototype,
 
+    classDescription: "Google Calendar Provider",
+    contractID: "@mozilla.org/calendar/calendar;1?type=gdata",
+    classID:  Components.ID("{d1a6e988-4b4d-45a5-ba46-43e501ea96e3}"),
+
+    getInterfaces: function cI_cGC_getInterfaces (count) {
+        var ifaces = [
+            Components.interfaces.nsISupports,
+            Components.interfaces.calICalendar,
+            Components.interfaces.calIGoogleCalendar,
+            Components.interfaces.calISchedulingSupport,
+            Components.interfaces.calIChangeLog,
+            Components.interfaces.nsIClassInfo
+        ];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+
+    getHelperForLanguage: function cI_cGC_getHelperForLanguage(aLanguage) {
+        return null;
+    },
+
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
+
     QueryInterface: function cGS_QueryInterface(aIID) {
-        return doQueryInterface(this,
-                                calGoogleCalendar.prototype,
-                                aIID,
-                                null,
-                                g_classInfo["calGoogleCalendar"]);
+        return cal.doQueryInterface(this, calGoogleCalendar.prototype, aIID, null, this);
     },
 
     /* Member Variables */
     mSession: null,
     mFullUri: null,
     mCalendarName: null,
 
     /*
--- a/calendar/providers/gdata/components/calGoogleCalendarModule.js
+++ b/calendar/providers/gdata/components/calGoogleCalendarModule.js
@@ -29,205 +29,51 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+Components.utils.import("resource://gre/modules/Services.jsm");
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
 // This constant is used internally to signal a failed login to the login
 // handler's response function.
 const kGOOGLE_LOGIN_FAILED = 1;
 
-var g_classInfo = {
-     calGoogleCalendar: {
-        getInterfaces: function cI_cGC_getInterfaces (count) {
-            var ifaces = [
-                Components.interfaces.nsISupports,
-                Components.interfaces.calICalendar,
-                Components.interfaces.calIGoogleCalendar,
-                Components.interfaces.calISchedulingSupport,
-                Components.interfaces.calIChangeLog,
-                Components.interfaces.nsIClassInfo
-            ];
-            count.value = ifaces.length;
-            return ifaces;
-        },
-
-        getHelperForLanguage: function cI_cGC_getHelperForLanguage(aLanguage) {
-            return null;
-        },
-
-        classDescription: "Google Calendar Provider",
-        contractID: "@mozilla.org/calendar/calendar;1?type=gdata",
-        classID:  Components.ID("{d1a6e988-4b4d-45a5-ba46-43e501ea96e3}"),
-        implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
-        constructor: "calGoogleCalendar",
-        flags: 0
-    },
-
-    calGoogleSession: {
-        getInterfaces: function cI_cGS_getInterfaces (aCount) {
-            var ifaces = [
-                Components.interfaces.nsISupports,
-                Components.interfaces.calIGoogleSession,
-                Components.interfaces.nsIClassInfo
-            ];
-            aCount.value = ifaces.length;
-            return ifaces;
-        },
-
-        getHelperForLanguage: function cI_cGS_getHelperForLanguage(aLanguage) {
-            return null;
-        },
-
-        classDescription: "Google Calendar Session",
-        contractID: "@mozilla.org/calendar/providers/gdata/session;1",
-        classID:  Components.ID("{652f6233-e03f-438a-bd3b-39877f68c0f4}"),
-        implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
-        constructor: "calGoogleSession",
-        flags: 0
-    },
+/** Module Registration */
+const calendarScriptLoadOrder = [
+    "calUtils.js",
+];
 
-    calGoogleSessionManager: {
-        getInterfaces: function cI_cGSM_getInterfaces (aCount) {
-            var ifaces = [
-                Components.interfaces.nsISupports,
-                Components.interfaces.calIGoogleSessionManager,
-                Components.interfaces.nsIClassInfo
-            ];
-            aCount.value = ifaces.length;
-            return ifaces;
-        },
-
-        getHelperForLanguage: function cI_cGSM_getHelperForLanguage(aLanguage) {
-            return null;
-        },
+const gdataScriptLoadOrder = [
+    "calGoogleCalendar.js",
+    "calGoogleSession.js",
+    "calGoogleRequest.js",
+    "calGoogleUtils.js"
+];
 
-        classDescription: "Google Calendar Session Manager",
-        contractID: "@mozilla.org/calendar/providers/gdata/session-manager;1",
-        classID:  Components.ID("{6a7ba1f0-f271-49b0-8e93-5ca33651b4af}"),
-        implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
-        constructor: "calGoogleSessionManager",
-        flags: Components.interfaces.nsIClassInfo.SINGLETON
-    },
-    calGoogleRequest: {
-        getInterfaces: function cI_cGR_getInterfaces (aCount) {
-            var ifaces = [
-                Components.interfaces.nsISupports,
-                Components.interfaces.calIGoogleRequest,
-                Components.interfaces.calIOperation,
-                Components.interfaces.nsIStreamLoaderObserver,
-                Components.interfaces.nsIInterfaceRequestor,
-                Components.interfaces.nsIChannelEventSink,
-                Components.interfaces.nsIClassInfo
-            ];
-            aCount.value = ifaces.length;
-            return ifaces;
-        },
+function NSGetModule(cid) {
+    if (!this.scriptsLoaded) {
+        // First load the calendar scripts
+        cal.loadScripts(calendarScriptLoadOrder, Components.utils.getGlobalForObject(this));
 
-        getHelperForLanguage: function cI_cGR_getHelperForLanguage(aLanguage) {
-            return null;
-        },
-
-        classDescription: "Google Calendar Request",
-        contractID: "@mozilla.org/calendar/providers/gdata/request;1",
-        classID:  Components.ID("{53a3438a-21bc-4a0f-b813-77a8b4f19282}"),
-        implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
-        constructor: "calGoogleRequest",
-        flags: 0
-    }
-};
-
-var calGoogleCalendarModule = {
-
-    mUtilsLoaded: false,
-
-    loadUtils: function cGCM_loadUtils() {
-        if (this.mUtilsLoaded)
-            return;
-
-        Components.utils.import("resource://calendar/modules/calUtils.jsm");
-        Components.utils.import("resource://calendar/modules/calProviderUtils.jsm");
-        Components.utils.import("resource://calendar/modules/calAuthUtils.jsm");
-        cal.loadScripts(["calUtils.js"], Components.utils.getGlobalForObject(this));
-
-        // Now load gdata extension scripts. Note that unintuitively,
-        // __LOCATION__.parent == . We expect to find the subscripts in ./../js
+        // Now load gdata extension scripts. __LOCATION__ is the current
+        // filename, so  __LOCATION__.parent == . We expect to find the
+        // subscripts in ./../js
         let thisDir = __LOCATION__.parent.parent.clone();
         thisDir.append("js");
-        cal.loadScripts(["calGoogleCalendar.js", "calGoogleSession.js",
-                         "calGoogleRequest.js", "calGoogleUtils.js"],
-                        Components.utils.getGlobalForObject(this),
-                        thisDir);
-
-        this.mUtilsLoaded = true;
-    },
-
-    unregisterSelf: function cGCM_unregisterSelf(aComponentManager) {
-        aComponentManager = aComponentManager
-                            .QueryInterface(Components.interfaces.nsIComponentRegistrar);
-        for each (var component in g_classInfo) {
-            aComponentManager.unregisterFactoryLocation(component.classID);
-        }
-    },
-
-    registerSelf: function cGCM_registerSelf(aComponentManager,
-                                             aFileSpec,
-                                             aLocation,
-                                             aType) {
-        aComponentManager = aComponentManager
-                            .QueryInterface(Components.interfaces.nsIComponentRegistrar);
-
-        for each (var component in g_classInfo) {
-            aComponentManager.registerFactoryLocation(
-                component.classID,
-                component.classDescription,
-                component.contractID,
-                aFileSpec,
-                aLocation,
-                aType);
-        }
-    },
+        cal.loadScripts(gdataScriptLoadOrder, Components.utils.getGlobalForObject(this), thisDir);
+        this.scriptsLoaded = true;
+    }
 
-    makeFactoryFor: function cGCM_makeFactoryFor(aConstructor) {
-        var factory = {
-            QueryInterface: function (aIID) {
-                if (!aIID.equals(Components.interfaces.nsISupports) &&
-                    !aIID.equals(Components.interfaces.nsIFactory))
-                    throw Components.results.NS_ERROR_NO_INTERFACE;
-                return this;
-            },
-
-            createInstance: function (aOuter, aIID) {
-                if (aOuter != null)
-                    throw Components.results.NS_ERROR_NO_AGGREGATION;
-                return (new aConstructor()).QueryInterface(aIID);
-            }
-        };
-        return factory;
-    },
+    let components = [
+        calGoogleCalendar,
+        calGoogleSession,
+        calGoogleSessionManager,
+        calGoogleRequest
+    ];
 
-    getClassObject: function cGCM_getClassObject(aComponentManager,
-                                                 aCID,
-                                                 aIID) {
-        if (!aIID.equals(Components.interfaces.nsIFactory))
-            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-
-        this.loadUtils();
-
-        for each (var component in g_classInfo) {
-            if (aCID.equals(component.classID)) {
-                return this.makeFactoryFor(eval(component.constructor));
-            }
-        }
-        throw Components.results.NS_ERROR_NO_INTERFACE;
-    },
-
-    canUnload: function(aComponentManager) {
-        return true;
-    }
-};
-
-function NSGetModule(aComponentManager, aFileSpec) {
-    return calGoogleCalendarModule;
+    return (XPCOMUtils.generateNSGetModule(components))(cid);
 }
--- a/calendar/providers/gdata/components/calGoogleRequest.js
+++ b/calendar/providers/gdata/components/calGoogleRequest.js
@@ -29,16 +29,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
 /**
  * calGoogleRequest
  * This class represents a HTTP request sent to Google
  *
  * @constructor
  * @class
  */
 function calGoogleRequest(aSession) {
@@ -79,22 +81,45 @@ calGoogleRequest.prototype = {
     itemRangeEnd: null,
     itemFilter: null,
     itemId: null,
     calendar: null,
     newItem: null,
     oldItem: null,
     destinationCal: null,
 
+    /* nsIClassInfo */
+    getInterfaces: function cI_cGR_getInterfaces (aCount) {
+        var ifaces = [
+            Components.interfaces.nsISupports,
+            Components.interfaces.calIGoogleRequest,
+            Components.interfaces.calIOperation,
+            Components.interfaces.nsIStreamLoaderObserver,
+            Components.interfaces.nsIInterfaceRequestor,
+            Components.interfaces.nsIChannelEventSink,
+            Components.interfaces.nsIClassInfo
+        ];
+        aCount.value = ifaces.length;
+        return ifaces;
+    },
+
+    getHelperForLanguage: function cI_cGR_getHelperForLanguage(aLanguage) {
+        return null;
+    },
+
+    classDescription: "Google Calendar Request",
+    contractID: "@mozilla.org/calendar/providers/gdata/request;1",
+    classID:  Components.ID("{53a3438a-21bc-4a0f-b813-77a8b4f19282}"),
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    constructor: "calGoogleRequest",
+    flags: 0,
+
+    /* nsISupports */
     QueryInterface: function cGR_QueryInterface(aIID) {
-        return doQueryInterface(this,
-                                calGoogleRequest.prototype,
-                                aIID,
-                                null,
-                                g_classInfo["calGoogleRequest"]);
+        return cal.doQueryInterface(this, calGoogleRequest.prototype, aIID, null, this);
     },
 
     /**
      * Implement calIOperation
      */
     get isPending() {
         return (this.mLoader && this.mLoader.request != null);
     },
--- a/calendar/providers/gdata/components/calGoogleSession.js
+++ b/calendar/providers/gdata/components/calGoogleSession.js
@@ -44,22 +44,38 @@ const kMANY_EVENTS = 0x7FFFFFFF;
 function calGoogleSessionManager() {
     this.wrappedJSObject = this;
 
 }
 
 calGoogleSessionManager.prototype = {
     mSessionMap: {},
 
+    getInterfaces: function cI_cGSM_getInterfaces (aCount) {
+        var ifaces = [
+            Components.interfaces.nsISupports,
+            Components.interfaces.calIGoogleSessionManager,
+            Components.interfaces.nsIClassInfo
+        ];
+        aCount.value = ifaces.length;
+        return ifaces;
+    },
+
+    getHelperForLanguage: function cI_cGSM_getHelperForLanguage(aLanguage) {
+        return null;
+    },
+
+    classDescription: "Google Calendar Session Manager",
+    contractID: "@mozilla.org/calendar/providers/gdata/session-manager;1",
+    classID:  Components.ID("{6a7ba1f0-f271-49b0-8e93-5ca33651b4af}"),
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: Components.interfaces.nsIClassInfo.SINGLETON,
+
     QueryInterface: function cGSM_QueryInterface(aIID) {
-        return doQueryInterface(this,
-                                calGoogleSessionManager.prototype,
-                                aIID,
-                                null,
-                                g_classInfo["calGoogleSessionManager"]);
+        return cal.doQueryInterface(this, calGoogleSessionManager.prototype, aIID, null, this);
     },
 
     /**
      * getSessionByUsername
      * Get a Session object for the specified username. If aCreate is false,
      * null will be returned if the session doesn't exist. Otherwise, the
      * session will be created.
      *
@@ -101,23 +117,37 @@ function calGoogleSession(aUsername) {
     this.mGoogleUser = aUsername;
     this.wrappedJSObject = this;
 
     // Register a freebusy provider for this session
     getFreeBusyService().addProvider(this);
 }
 
 calGoogleSession.prototype = {
+    classDescription: "Google Calendar Session",
+    contractID: "@mozilla.org/calendar/providers/gdata/session;1",
+    classID:  Components.ID("{652f6233-e03f-438a-bd3b-39877f68c0f4}"),
+
+    getInterfaces: function cI_cGS_getInterfaces (aCount) {
+        let ifaces = [
+            Components.interfaces.nsISupports,
+            Components.interfaces.calIGoogleSession,
+            Components.interfaces.nsIClassInfo
+        ];
+        aCount.value = ifaces.length;
+        return ifaces;
+    },
+    getHelperForLanguage: function cI_cGS_getHelperForLanguage(aLanguage) {
+        return null;
+    },
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
 
     QueryInterface: function cGS_QueryInterface(aIID) {
-        return doQueryInterface(this,
-                                calGoogleSessionManager.prototype,
-                                aIID,
-                                null,
-                                g_classInfo["calGoogleSession"]);
+        return cal.doQueryInterface(this, calGoogleSession.prototype, aIID, null, this);
     },
 
     /* Member Variables */
     mGoogleUser: null,
     // This must be |undefined|, we need this variable to be tri-state.
     mGooglePass: undefined,
     mGoogleFullName: null,
     mAuthToken: null,
--- a/calendar/providers/ics/Makefile.in
+++ b/calendar/providers/ics/Makefile.in
@@ -39,22 +39,13 @@
 
 DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = calICSalendar
-
-EXTRA_COMPONENTS = calICSCalendarModule.js
-EXTRA_SCRIPTS = calICSCalendar.js
+MODULE = calICSCalendar
 
-libs:: $(EXTRA_SCRIPTS)
-	if test ! -d $(FINAL_TARGET)/calendar-js; then $(NSINSTALL) -D $(FINAL_TARGET)/calendar-js; fi
-	$(INSTALL) $^ $(FINAL_TARGET)/calendar-js
-
-# The install target must use SYSINSTALL, which is NSINSTALL in copy mode.
-install:: $(EXTRA_SCRIPTS)
-	$(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/calendar-js
+EXTRA_COMPONENTS = calICSCalendar.js
 
 include $(topsrcdir)/config/rules.mk
--- a/calendar/providers/ics/calICSCalendar.js
+++ b/calendar/providers/ics/calICSCalendar.js
@@ -34,16 +34,20 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calProviderUtils.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.
@@ -63,26 +67,44 @@ function calICSCalendar() {
     this.unmappedProperties = [];
     this.queue = new Array();
     this.mModificationActions = [];
 }
 
 calICSCalendar.prototype = {
     __proto__: cal.ProviderBase.prototype,
 
+    classID: Components.ID("{f8438bff-a3c9-4ed5-b23f-2663b5469abf}"),
+    contractID: "@mozilla.org/calendar/calendar;1?type=ics",
+    classDescription: "Calendar ICS provider",
+
+    getInterfaces: function getInterfaces(count) {
+        const ifaces = [Components.interfaces.calICalendarProvider,
+                        Components.interfaces.calICalendar,
+                        Components.interfaces.calISchedulingSupport,
+                        Components.interfaces.nsIStreamListener,
+                        Components.interfaces.nsIStreamLoaderObserver,
+                        Components.interfaces.nsIChannelEventSink,
+                        Components.interfaces.nsIInterfaceRequestor,
+                        Components.interfaces.nsIClassInfo,
+                        Components.interfaces.nsISupports];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+    getHelperForLanguage: function getHelperForLanguage(language) {
+        return null;
+    },
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
+
     mObserver: null,
     locked: false,
 
     QueryInterface: function (aIID) {
-        return doQueryInterface(this, calICSCalendar.prototype, aIID,
-                                [Components.interfaces.calICalendarProvider,
-                                 Components.interfaces.nsIStreamListener,
-                                 Components.interfaces.nsIStreamLoaderObserver,
-                                 Components.interfaces.nsIChannelEventSink,
-                                 Components.interfaces.nsIInterfaceRequestor]);
+        return cal.doQueryInterface(this, calICSCalendar.prototype, aIID, null, this);
     },
     
     initICSCalendar: function() {
         this.mMemoryCalendar = Components.classes["@mozilla.org/calendar/calendar;1?type=memory"]
                                          .createInstance(Components.interfaces.calICalendar);
 
         this.mMemoryCalendar.superCalendar = this;
         this.mObserver = new calICSObserver(this);
@@ -1027,8 +1049,26 @@ fileHooks.prototype = {
 
     onAfterPut: function fH_onAfterPut(aChannel, aRespFunc) {
         let filechannel = this.mChannel.QueryInterface(Components.interfaces.nsIFileChannel);
         this.mtime = filechannel.file.lastModifiedTime;
         aRespFunc();
         return true;
     }
 };
+
+/** Module Registration */
+const scriptLoadOrder = [
+    "calUtils.js",
+];
+
+function NSGetModule(cid) {
+    if (!this.scriptsLoaded) {
+        Services.io.getProtocolHandler("resource")
+                .QueryInterface(Components.interfaces.nsIResProtocolHandler)
+                .setSubstitution("calendar", Services.io.newFileURI(__LOCATION__.parent.parent));
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+        cal.loadScripts(scriptLoadOrder, Components.utils.getGlobalForObject(this));
+        this.scriptsLoaded = true;
+    }
+
+    return (XPCOMUtils.generateNSGetModule([calICSCalendar]))(cid);
+}
deleted file mode 100644
--- a/calendar/providers/ics/calICSCalendarModule.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla calendar code.
- *
- * The Initial Developer of the Original Code is
- *   Michiel van Leeuwen <mvl@exedo.nl>
- * Portions created by the Initial Developer are Copyright (C) 2004
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
- *   Dan Mosedale <dan.mosedale@oracle.com>
- *   Joey Minta <jminta@gmail.com>
- *   Philipp Kewisch <mozilla@kewis.ch>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// nsIFactory
-const calICSCalendarFactory = {
-    QueryInterface: function (aIID) {
-        if (!aIID.equals(Components.interfaces.nsISupports) &&
-            !aIID.equals(Components.interfaces.nsIFactory)) {
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-        }
-        return this;
-    },
-
-    createInstance: function (outer, iid) {
-        if (outer != null)
-            throw Components.results.NS_ERROR_NO_AGGREGATION;
-        return (new calICSCalendar()).QueryInterface(iid);
-    }
-};
-
-/****
- **** module registration
- ****/
-
-var calICSCalendarModule = {
-
-    mCID: Components.ID("{f8438bff-a3c9-4ed5-b23f-2663b5469abf}"),
-    mContractID: "@mozilla.org/calendar/calendar;1?type=ics",
-
-    mUtilsLoaded: false,
-    loadUtils: function cICM_loadUtils() {
-        if (this.mUtilsLoaded) {
-            return;
-        }
-
-        Components.utils.import("resource://calendar/modules/calUtils.jsm");
-        cal.loadScripts(["calUtils.js", "calICSCalendar.js"],
-                        Components.utils.getGlobalForObject(this));
-
-        this.mUtilsLoaded = true;
-    },
-
-    registerSelf: function (compMgr, fileSpec, location, type) {
-        compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
-        compMgr.registerFactoryLocation(this.mCID,
-                                        "Calendar ICS provider",
-                                        this.mContractID,
-                                        fileSpec,
-                                        location,
-                                        type);
-    },
-
-    getClassObject: function (compMgr, cid, iid) {
-        if (!cid.equals(this.mCID))
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-
-        if (!iid.equals(Components.interfaces.nsIFactory))
-            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-
-        this.loadUtils();
-
-        return calICSCalendarFactory;
-    },
-
-    canUnload: function(compMgr) {
-        return true;
-    }
-};
-
-function NSGetModule(compMgr, fileSpec) {
-    return calICSCalendarModule;
-}
--- a/calendar/providers/memory/Makefile.in
+++ b/calendar/providers/memory/Makefile.in
@@ -40,20 +40,11 @@ DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = calMemoryCalendar
 
-EXTRA_COMPONENTS = calMemoryCalendarModule.js
-EXTRA_SCRIPTS = calMemoryCalendar.js
-
-libs:: $(EXTRA_SCRIPTS)
-	if test ! -d $(FINAL_TARGET)/calendar-js; then $(NSINSTALL) -D $(FINAL_TARGET)/calendar-js; fi
-	$(INSTALL) $^ $(FINAL_TARGET)/calendar-js
-
-# The install target must use SYSINSTALL, which is NSINSTALL in copy mode.
-install:: $(EXTRA_SCRIPTS)
-	$(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/calendar-js
+EXTRA_COMPONENTS = calMemoryCalendar.js
 
 include $(topsrcdir)/config/rules.mk
--- a/calendar/providers/memory/calMemoryCalendar.js
+++ b/calendar/providers/memory/calMemoryCalendar.js
@@ -32,67 +32,89 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
+
 Components.utils.import("resource://calendar/modules/calProviderUtils.jsm");
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 //
 // calMemoryCalendar.js
 //
 
 const calCalendarManagerContractID = "@mozilla.org/calendar/manager;1";
 const calICalendarManager = Components.interfaces.calICalendarManager;
 
 function calMemoryCalendar() {
     this.initProviderBase();
     this.initMemoryCalendar();
 }
 
 calMemoryCalendar.prototype = {
     __proto__: cal.ProviderBase.prototype,
 
+    classID: Components.ID("{bda0dd7f-0a2f-4fcf-ba08-5517e6fbf133}"),
+    contractID: "@mozilla.org/calendar/calendar;1?type=memory",
+    classDescription: "Calendar Memory Provider",
+
+    getInterfaces: function getInterfaces(count) {
+        const ifaces = [Components.interfaces.calICalendar,
+                        Components.interfaces.calISchedulingSupport,
+                        Components.interfaces.calISyncWriteCalendar,
+                        Components.interfaces.calICalendarProvider,
+                        Components.interfaces.nsIClassInfo,
+                        Components.interfaces.nsISupports];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+    getHelperForLanguage: function getHelperForLanguage(language) {
+        return null;
+    },
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
+
     //
     // nsISupports interface
     // 
     QueryInterface: function (aIID) {
-        return doQueryInterface(this, calMemoryCalendar.prototype, aIID,
-                                [Components.interfaces.calISyncWriteCalendar,
-                                 Components.interfaces.calICalendarProvider]);
+        return cal.doQueryInterface(this, calMemoryCalendar.prototype, aIID, null, this);
     },
 
     initMemoryCalendar: function() {
         this.mObservers = new cal.ObserverBag(Components.interfaces.calIObserver);
         this.mItems = {};
-        this.mMetaData = new calPropertyBag();
+        this.mMetaData = new cal.calPropertyBag();
     },
 
     //
     // calICalendarProvider interface
     //
     get prefChromeOverlay() {
         return null;
     },
 
     get displayName() {
-        return calGetString("calendar", "memoryName");
+        return cal.calGetString("calendar", "memoryName");
     },
 
     createCalendar: function mem_createCal() {
         throw NS_ERROR_NOT_IMPLEMENTED;
     },
 
     deleteCalendar: function mem_deleteCal(cal, listener) {
         cal = cal.wrappedJSObject;
         cal.mItems = {};
-        cal.mMetaData = new calPropertyBag();
+        cal.mMetaData = new cal.calPropertyBag();
 
         try {
             listener.onDeleteCalendar(cal, Components.results.NS_OK, null);
         } catch(ex) {}
     },
 
     mRelaxedMode: undefined,
     get relaxedMode() {
@@ -311,19 +333,19 @@ calMemoryCalendar.prototype = {
                                          aId,
                                          null);
             return;
         }
 
         var item = this.mItems[aId];
         var iid = null;
 
-        if (isEvent(item)) {
+        if (cal.isEvent(item)) {
             iid = Components.interfaces.calIEvent;
-        } else if (isToDo(item)) {
+        } else if (cal.isToDo(item)) {
             iid = Components.interfaces.calITodo;
         } else {
             this.notifyOperationComplete(aListener,
                                          Components.results.NS_ERROR_FAILURE,
                                          Components.interfaces.calIOperationListener.GET,
                                          aId,
                                          "Can't deduce item type based on QI");
             return;
@@ -410,22 +432,22 @@ calMemoryCalendar.prototype = {
                 typeIID = Components.interfaces.calIItemBase;
             } else if (wantEvents) {
                 typeIID = Components.interfaces.calIEvent;
             } else if (wantTodos) {
                 typeIID = Components.interfaces.calITodo;
             }
         }
 
-        aRangeStart = ensureDateTime(aRangeStart);
-        aRangeEnd = ensureDateTime(aRangeEnd);
+        aRangeStart = cal.ensureDateTime(aRangeStart);
+        aRangeEnd = cal.ensureDateTime(aRangeEnd);
 
-        for (var itemIndex in this.mItems) {
-            var item = this.mItems[itemIndex];
-            var isEvent_ = isEvent(item);
+        for (let itemIndex in this.mItems) {
+            let item = this.mItems[itemIndex];
+            let isEvent_ = cal.isEvent(item);
             if (isEvent_) {
                 if (!wantEvents) {
                     continue;
                 }
             } else if (!wantTodos) {
                 continue;
             }
 
@@ -436,17 +458,17 @@ calMemoryCalendar.prototype = {
                     occurrences = occurrences.filter(checkUnrespondedInvitation);
                 }
                 if (!isEvent_) {
                     occurrences = occurrences.filter(checkCompleted);
                 }
                 itemsFound = itemsFound.concat(occurrences);
             } else if ((!wantUnrespondedInvitations || checkUnrespondedInvitation(item)) &&
                        (isEvent_ || checkCompleted(item)) &&
-                       checkIfInRange(item, aRangeStart, aRangeEnd)) {
+                       cal.checkIfInRange(item, aRangeStart, aRangeEnd)) {
                 // This needs fixing for recurring items, e.g. DTSTART of parent may occur before aRangeStart.
                 // This will be changed with bug 416975.
                 itemsFound.push(item);
             }
             if (aCount && itemsFound.length >= aCount) {
                 break;
             }
 
@@ -481,8 +503,11 @@ calMemoryCalendar.prototype = {
     },
     getAllMetaData: function memory_getAllMetaData(out_count,
                                                    out_ids,
                                                    out_values) {
         this.mMetaData.getAllProperties(out_ids, out_values);
         out_count.value = out_ids.value.length;
     }
 };
+
+/** Module Registration */
+var NSGetModule = XPCOMUtils.generateNSGetModule([calMemoryCalendar]);
deleted file mode 100644
--- a/calendar/providers/memory/calMemoryCalendarModule.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Oracle Corporation code.
- *
- * The Initial Developer of the Original Code is
- *  Oracle Corporation
- * Portions created by the Initial Developer are Copyright (C) 2004
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
- *   Philipp Kewisch <mozilla@kewis.ch>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// nsIFactory
-const calMemoryCalendarFactory = {
-    QueryInterface: function (aIID) {
-        if (!aIID.equals(Components.interfaces.nsISupports) &&
-            !aIID.equals(Components.interfaces.nsIFactory)) {
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-        }
-        return this;
-    },
-
-    createInstance: function (outer, iid) {
-        if (outer != null)
-            throw Components.results.NS_ERROR_NO_AGGREGATION;
-        return (new calMemoryCalendar()).QueryInterface(iid);
-    }
-};
-
-/****
- **** module registration
- ****/
-
-var calMemoryCalendarModule = {
-    mCID: Components.ID("{bda0dd7f-0a2f-4fcf-ba08-5517e6fbf133}"),
-    mContractID: "@mozilla.org/calendar/calendar;1?type=memory",
-
-    mUtilsLoaded: false,
-    loadUtils: function cMCM_loadUtils() {
-        if (this.mUtilsLoaded) {
-            return;
-        }
-
-        Components.utils.import("resource://calendar/modules/calUtils.jsm");
-        cal.loadScripts(["calUtils.js", "calMemoryCalendar.js"],
-                        Components.utils.getGlobalForObject(this));
-
-        this.mUtilsLoaded = true;
-    },
-
-    registerSelf: function (compMgr, fileSpec, location, type) {
-        compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
-        compMgr.registerFactoryLocation(this.mCID,
-                                        "Calendar in-memory back-end",
-                                        this.mContractID,
-                                        fileSpec,
-                                        location,
-                                        type);
-    },
-
-    getClassObject: function (compMgr, cid, iid) {
-        if (!cid.equals(this.mCID))
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-
-        if (!iid.equals(Components.interfaces.nsIFactory))
-            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-
-        this.loadUtils();
-
-        return calMemoryCalendarFactory;
-    },
-
-    canUnload: function(compMgr) {
-        return true;
-    }
-};
-
-function NSGetModule(compMgr, fileSpec) {
-    return calMemoryCalendarModule;
-}
--- a/calendar/providers/storage/Makefile.in
+++ b/calendar/providers/storage/Makefile.in
@@ -39,24 +39,15 @@ DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = calStorageCalendar
 
-EXTRA_COMPONENTS = calStorageCalendarModule.js
-EXTRA_SCRIPTS = calStorageCalendar.js
+EXTRA_COMPONENTS = calStorageCalendar.js
 EXTRA_JS_MODULES = \
     calStorageHelpers.jsm \
     calStorageUpgrade.jsm \
     $(NULL)
 
-libs:: $(EXTRA_SCRIPTS)
-	if test ! -d $(FINAL_TARGET)/calendar-js; then $(NSINSTALL) -D $(FINAL_TARGET)/calendar-js; fi
-	$(INSTALL) $^ $(FINAL_TARGET)/calendar-js
-
-# The install target must use SYSINSTALL, which is NSINSTALL in copy mode.
-install:: $(EXTRA_SCRIPTS)
-	$(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/calendar-js
-
 include $(topsrcdir)/config/rules.mk
--- a/calendar/providers/storage/calStorageCalendar.js
+++ b/calendar/providers/storage/calStorageCalendar.js
@@ -38,20 +38,22 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-Components.utils.import("resource://calendar/modules/calProviderUtils.jsm");
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
 
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calAlarmUtils.jsm");
+Components.utils.import("resource://calendar/modules/calProviderUtils.jsm");
 Components.utils.import("resource://calendar/modules/calStorageUpgrade.jsm");
 Components.utils.import("resource://calendar/modules/calStorageHelpers.jsm");
 
 const USECS_PER_SECOND = 1000000;
 const kCalICalendar = Components.interfaces.calICalendar;
 
 //
 // calStorageCalendar
@@ -61,16 +63,38 @@ function calStorageCalendar() {
     this.initProviderBase();
     this.mItemCache = {};
     this.mRecEventCache = {};
     this.mRecTodoCache = {};
 }
 
 calStorageCalendar.prototype = {
     __proto__: cal.ProviderBase.prototype,
+
+    classID: Components.ID("{b3eaa1c4-5dfe-4c0a-b62a-b3a514218461}"),
+    contractID: "@mozilla.org/calendar/calendar;1?type=storage",
+    classDescription: "Calendar Storage Provider",
+    getInterfaces: function (count) {
+        let ifaces = [
+            Components.interfaces.nsISupports,
+            Components.interfaces.calICalendarManager,
+            Components.interfaces.calIStartupService,
+            Components.interfaces.nsIObserver,
+            Components.interfaces.nsIClassInfo
+        ];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+
+    getHelperForLanguage: function (language) {
+        return null;
+    },
+
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
     //
     // private members
     //
     mDB: null,
     mItemCache: null,
     mRecItemCacheInited: false,
     mRecEventCache: null,
     mRecTodoCache: null,
@@ -2339,8 +2363,26 @@ calStorageCalendar.prototype = {
         }
 
         if (exception) {
             logMessage += "\nException: " + exception;
         }
         cal.ERROR(logMessage + "\n" + STACK(10));
     }
 };
+
+/** Module Registration */
+const scriptLoadOrder = [
+    "calUtils.js",
+];
+
+function NSGetModule(cid) {
+    if (!this.scriptsLoaded) {
+        Services.io.getProtocolHandler("resource")
+                .QueryInterface(Components.interfaces.nsIResProtocolHandler)
+                .setSubstitution("calendar", Services.io.newFileURI(__LOCATION__.parent.parent));
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+        cal.loadScripts(scriptLoadOrder, Components.utils.getGlobalForObject(this));
+        this.scriptsLoaded = true;
+    }
+
+    return (XPCOMUtils.generateNSGetModule([calStorageCalendar]))(cid);
+}
deleted file mode 100644
--- a/calendar/providers/storage/calStorageCalendarModule.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Oracle Corporation code.
- *
- * The Initial Developer of the Original Code is
- *  Oracle Corporation
- * Portions created by the Initial Developer are Copyright (C) 2005, 2006
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
- *   Joey Minta <jminta@gmail.com>
- *   Dan Mosedale <dan.mosedale@oracle.com>
- *   Thomas Benisch <thomas.benisch@sun.com>
- *   Matthew Willis <lilmatt@mozilla.com>
- *   Philipp Kewisch <mozilla@kewis.ch>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// nsIFactory
-const calStorageCalendarFactory = {
-    QueryInterface: function (aIID) {
-        if (!aIID.equals(Components.interfaces.nsISupports) &&
-            !aIID.equals(Components.interfaces.nsIFactory)) {
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-        }
-        return this;
-    },
-
-    createInstance: function (outer, iid) {
-        if (outer != null)
-            throw Components.results.NS_ERROR_NO_AGGREGATION;
-        return (new calStorageCalendar()).QueryInterface(iid);
-    }
-};
-
-/****
- **** module registration
- ****/
-
-var calStorageCalendarModule = {
-    mCID: Components.ID("{b3eaa1c4-5dfe-4c0a-b62a-b3a514218461}"),
-    mContractID: "@mozilla.org/calendar/calendar;1?type=storage",
-
-    mUtilsLoaded: false,
-    loadUtils: function storageLoadUtils() {
-        if (this.mUtilsLoaded)
-            return;
-
-        Components.utils.import("resource://calendar/modules/calUtils.jsm");
-
-        cal.loadScripts(["calUtils.js", "calStorageCalendar.js"],
-                        Components.utils.getGlobalForObject(this));
-
-        this.mUtilsLoaded = true;
-    },
-
-    registerSelf: function (compMgr, fileSpec, location, type) {
-        compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
-        compMgr.registerFactoryLocation(this.mCID,
-                                        "Calendar mozStorage/SQL back-end",
-                                        this.mContractID,
-                                        fileSpec,
-                                        location,
-                                        type);
-    },
-
-    getClassObject: function (compMgr, cid, iid) {
-        if (!cid.equals(this.mCID)) {
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-        }
-
-        if (!iid.equals(Components.interfaces.nsIFactory)) {
-            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-        }
-
-        this.loadUtils();
-        return calStorageCalendarFactory;
-    },
-
-    canUnload: function(compMgr) {
-        return true;
-    }
-};
-
-function NSGetModule(compMgr, fileSpec) {
-    return calStorageCalendarModule;
-}
--- a/calendar/providers/wcap/Makefile.in
+++ b/calendar/providers/wcap/Makefile.in
@@ -15,16 +15,17 @@
 #
 # The Initial Developer of the Original Code is
 # Sun Microsystems, Inc.
 # Portions created by the Initial Developer are Copyright (C) 2007
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #   Daniel Boelzle <daniel.boelzle@sun.com>
+#   Philipp Kewisch <mozilla@kewis.ch>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
--- a/calendar/providers/wcap/calWcapCalendar.js
+++ b/calendar/providers/wcap/calWcapCalendar.js
@@ -31,27 +31,49 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
 function calWcapCalendar(/*optional*/session, /*optional*/calProps) {
     this.initProviderBase();
     this.m_session = session;
     this.m_calProps = calProps;
 }
 calWcapCalendar.prototype = {
     __proto__: cal.ProviderBase.prototype,
 
+    getInterfaces: function ci_wcapCalendar_getInterfaces(count) {
+        const ifaces = [calIWcapCalendar,
+                        calICalendar,
+                        Components.interfaces.calISchedulingSupport,
+                        Components.interfaces.calIChangeLog,
+                        Components.interfaces.calICalendarProvider,
+                        Components.interfaces.nsIClassInfo,
+                        nsISupports];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+    classDescription: "Sun Java System Calendar Server WCAP Provider",
+    contractID: "@mozilla.org/calendar/calendar;1?type=wcap",
+    classID: Components.ID("{cf4d93e5-af79-451a-95f3-109055b32ef0}"),
+    getHelperForLanguage: function ci_wcapCalendar_getHelperForLanguage(language) {
+        return null;
+    },
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
+
     // nsISupports:
     QueryInterface: function calWcapCalendar_QueryInterface(iid) {
-        return doQueryInterface(this, calWcapCalendar.prototype, iid, null, g_classInfo.wcapCalendar);
+        return cal.doQueryInterface(this, calWcapCalendar.prototype, iid, null, this);
     },
 
     toString: function calWcapCalendar_toString() {
         var str = this.session.toString();
         if (this.m_calId) {
             str += (", calId=" + this.calId);
         } else {
             str += ", default calendar";
@@ -380,9 +402,8 @@ calWcapCalendar.prototype = {
         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
     },
 
     getAccessControlDefinitions: function calWcapCalendar_getAccessControlDefinitions(out_count, out_users,
                                                                                       out_accessControlBits) {
         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
     }
 };
-
--- a/calendar/providers/wcap/calWcapCalendarModule.js
+++ b/calendar/providers/wcap/calWcapCalendarModule.js
@@ -31,16 +31,19 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+Components.utils.import("resource://gre/modules/Services.jsm");
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
 //
 // init code for globals, prefs:
 //
 
 // constants:
 const NS_OK = Components.results.NS_OK;
 const NS_ERROR_UNEXPECTED = Components.results.NS_ERROR_UNEXPECTED;
 const nsIException = Components.interfaces.nsIException;
@@ -84,136 +87,44 @@ function initWcapProvider() {
 
         CACHE_LAST_RESULTS = getPref("calendar.wcap.cache_last_results", 4);
         CACHE_LAST_RESULTS_INVALIDATE = getPref("calendar.wcap.cache_last_results_invalidate", 120);
     } catch (exc) {
         logError(exc, "error in init sequence");
     }
 }
 
-var calWcapCalendarFactory = { // nsIFactory:
-    lockFactory: function calWcapCalendarFactory_lockFactory(lock) {
-    },
-
-    createInstance: function calWcapCalendarFactory_createInstance(outer, iid) {
-        if (outer) {
-            throw Components.results.NS_ERROR_NO_AGGREGATION;
-        }
-        return (new calWcapCalendar()).QueryInterface(iid);
-    }
-};
-
-var g_classInfo = {
-    wcapCalendar: { // nsIClassInfo:
-        getInterfaces: function ci_wcapCalendar_getInterfaces(count) {
-            const ifaces = [calIWcapCalendar,
-                            calICalendar,
-                            Components.interfaces.calISchedulingSupport,
-                            Components.interfaces.calIChangeLog,
-                            Components.interfaces.calICalendarProvider,
-                            Components.interfaces.nsIClassInfo,
-                            nsISupports];
-            count.value = ifaces.length;
-            return ifaces;
-        },
-        classDescription: "Sun Java System Calendar Server WCAP Provider",
-        contractID: "@mozilla.org/calendar/calendar;1?type=wcap",
-        classID: Components.ID("{CF4D93E5-AF79-451a-95F3-109055B32EF0}"),
-        getHelperForLanguage: function ci_wcapCalendar_getHelperForLanguage(language) {
-            return null;
-        },
-        implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
-        flags: 0
-    },
-
-    wcapSession: { // nsIClassInfo:
-        getInterfaces: function ci_wcapSession_getInterfaces(count) {
-            const ifaces = [calIWcapSession,
-                            calIFreeBusyProvider,
-                            calICalendarSearchProvider,
-                            Components.interfaces.calITimezoneProvider,
-                            Components.interfaces.calICalendarManagerObserver,
-                            Components.interfaces.nsIClassInfo,
-                            nsISupports];
-            count.value = ifaces.length;
-            return ifaces;
-        },
-        classDescription: "Sun Java System Calendar Server WCAP Session",
-        contractID: "@mozilla.org/calendar/wcap/session;1",
-        classID: Components.ID("{CBF803FD-4469-4999-AE39-367AF1C7B077}"),
-        getHelperForLanguage: function ci_wcapSession_getHelperForLanguage(language) {
-            return null;
-        },
-        implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
-        flags: 0
-    },
+/** Module Registration */
+const scriptLoadOrder = [
+    "calUtils.js",
+    "calWcapUtils.js",
+    "calWcapErrors.js",
+    "calWcapRequest.js",
+    "calWcapSession.js",
+    "calWcapCalendar.js",
+    "calWcapCalendarItems.js"
+];
 
-    wcapNetworkRequest: { // nsIClassInfo:
-        getInterfaces: function ci_wcapNetworkRequest_getInterfaces(count) {
-            const ifaces = [Components.interfaces.nsIUnicharStreamLoaderObserver,
-                            Components.interfaces.nsIInterfaceRequestor,
-                            Components.interfaces.nsIChannelEventSink,
-                            Components.interfaces.calIOperation,
-                            Components.interfaces.nsIClassInfo,
-                            nsISupports];
-            count.value = ifaces.length;
-            return ifaces;
-        },
-        classDescription: "Sun Java System Calendar Server WCAP Network Request",
-        contractID: "@mozilla.org/calendar/wcap/network-request;1",
-        classID: Components.ID("{E3C62B37-83CF-41EC-9872-0AF9F952430A}"),
-        getHelperForLanguage: function ci_wcapNetworkRequest_getHelperForLanguage(language) {
-            return null;
-        },
-        implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
-        flags: 0
+function NSGetModule(cid) {
+    try {
+    if (!this.scriptsLoaded) {
+        Services.io.getProtocolHandler("resource")
+                .QueryInterface(Components.interfaces.nsIResProtocolHandler)
+                .setSubstitution("calendar", Services.io.newFileURI(__LOCATION__.parent.parent));
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+        cal.loadScripts(scriptLoadOrder, Components.utils.getGlobalForObject(this));
+        initWcapProvider();
+        this.scriptsLoaded = true;
+
     }
-};
-
-var calWcapCalendarModule = { // nsIModule:
-    
-    registerSelf: function calWcapCalendarModule_registerSelf(compMgr, fileSpec, location, type) {
-        compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
-        compMgr.registerFactoryLocation(g_classInfo.wcapCalendar.classID,
-                                        g_classInfo.wcapCalendar.classDescription,
-                                        g_classInfo.wcapCalendar.contractID,
-                                        fileSpec, location, type);
-    },
 
-    unregisterSelf: function calWcapCalendarModule_unregisterSelf(compMgr, fileSpec, location) {
-        compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
-        compMgr.unregisterFactoryLocation(g_classInfo.wcapCalendar.classID, fileSpec);
-    },
-
-    m_scriptsLoaded: false,
-    getClassObject: function calWcapCalendarModule_getClassObject(compMgr, cid, iid) {
-        if (!this.m_scriptsLoaded) {
-            Components.utils.import("resource://calendar/modules/calUtils.jsm");
-            Components.utils.import("resource://calendar/modules/calProviderUtils.jsm");
-            Components.utils.import("resource://calendar/modules/calAuthUtils.jsm");
-            cal.loadScripts(["calUtils.js",
-                             "calWcapUtils.js", "calWcapErrors.js",
-                             "calWcapRequest.js", "calWcapSession.js",
-                             "calWcapCalendar.js", "calWcapCalendarItems.js"],
-                            Components.utils.getGlobalForObject(this));
-            initWcapProvider();
-            this.m_scriptsLoaded = true;
-        }
+    let components = [
+        calWcapCalendar,
+        calWcapNetworkRequest,
+        calWcapSession
+    ];
 
-        if (!iid.equals(Components.interfaces.nsIFactory)) {
-            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-        }
-        if (!cid.equals(g_classInfo.wcapCalendar.classID)) {
-            throw Components.results.NS_ERROR_NO_INTERFACE;
-        }
-        return calWcapCalendarFactory;
-    },
+    return (XPCOMUtils.generateNSGetModule(components))(cid);
 
-    canUnload: function calWcapCalendarModule_canUnload(compMgr) {
-        return true;
+    } catch (e) {
+        cal.WARN("ERROR: " + e);
     }
-};
-
-/** module export */
-function NSGetModule(compMgr, fileSpec) {
-    return calWcapCalendarModule;
 }
-
--- a/calendar/providers/wcap/calWcapRequest.js
+++ b/calendar/providers/wcap/calWcapRequest.js
@@ -225,18 +225,37 @@ function calWcapNetworkRequest(url, resp
 }
 calWcapNetworkRequest.prototype = {
     m_id: 0,
     m_url: null,
     m_loader: null,
     m_respFunc: null,
     m_bLogging: false,
 
+    getInterfaces: function ci_wcapNetworkRequest_getInterfaces(count) {
+        const ifaces = [Components.interfaces.nsIUnicharStreamLoaderObserver,
+                        Components.interfaces.nsIInterfaceRequestor,
+                        Components.interfaces.nsIChannelEventSink,
+                        Components.interfaces.calIOperation,
+                        Components.interfaces.nsIClassInfo,
+                        nsISupports];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+    classDescription: "Sun Java System Calendar Server WCAP Network Request",
+    contractID: "@mozilla.org/calendar/wcap/network-request;1",
+    classID: Components.ID("{e3c62b37-83cf-41ec-9872-0af9f952430a}"),
+    getHelperForLanguage: function ci_wcapNetworkRequest_getHelperForLanguage(language) {
+        return null;
+    },
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
+
     QueryInterface: function calWcapNetworkRequest_QueryInterface(iid) {
-        return doQueryInterface(this, calWcapNetworkRequest.prototype, iid, null, g_classInfo.wcapNetworkRequest);
+        return cal.doQueryInterface(this, calWcapNetworkRequest.prototype, iid, null, this);
     },
 
     /**
      * @see nsIInterfaceRequestor
      * @see calProviderUtils.jsm
      */
     getInterface: cal.InterfaceRequestor_getInterface,
 
--- a/calendar/providers/wcap/calWcapSession.js
+++ b/calendar/providers/wcap/calWcapSession.js
@@ -131,19 +131,39 @@ function calWcapSession(contextId) {
 
     // listen for shutdown, being logged out:
     var observerService = Components.classes["@mozilla.org/observer-service;1"]
                                     .getService(Components.interfaces.nsIObserverService);
     observerService.addObserver(this, "quit-application", false /* don't hold weakly */);
     getCalendarManager().addObserver(this);
 }
 calWcapSession.prototype = {
+    getInterfaces: function ci_wcapSession_getInterfaces(count) {
+        const ifaces = [calIWcapSession,
+                        calIFreeBusyProvider,
+                        calICalendarSearchProvider,
+                        Components.interfaces.calITimezoneProvider,
+                        Components.interfaces.calICalendarManagerObserver,
+                        Components.interfaces.nsIClassInfo,
+                        nsISupports];
+        count.value = ifaces.length;
+        return ifaces;
+    },
+    classDescription: "Sun Java System Calendar Server WCAP Session",
+    contractID: "@mozilla.org/calendar/wcap/session;1",
+    classID: Components.ID("{cbf803fd-4469-4999-ae39-367af1c7b077}"),
+    getHelperForLanguage: function ci_wcapSession_getHelperForLanguage(language) {
+        return null;
+    },
+    implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
+    flags: 0,
+
     // nsISupports:
     QueryInterface: function calWcapSession_QueryInterface(iid) {
-        return doQueryInterface(this, calWcapSession.prototype, iid, null, g_classInfo.wcapSession);
+        return cal.doQueryInterface(this, calWcapSession.prototype, iid, null, this);
     },
 
     toString: function calWcapSession_toString(msg) {
         let str = ("context-id: " + this.m_contextId + ", uri: " + (this.uri ? this.uri.spec : "unknown"));
         if (this.credentials.userId) {
             str += (", userId=" + this.credentials.userId);
         }
         if (!this.m_sessionId) {