Bug 1347149 - Remove inclusion of calUtils.js and use cal prefix for all calUtils functions. r=MakeMyDay
authorPhilipp Kewisch <mozilla@kewis.ch>
Mon, 05 Jun 2017 21:47:01 +0200
changeset 28278 4bafb6c2ddaf96fce9afed6ad76793224927207e
parent 28277 693678f602cfbdf0ff0f1f3f9214f142816bd61b
child 28279 291cefb09dff00a327062580caf17c1830d4a50b
push id1966
push userclokep@gmail.com
push dateMon, 12 Jun 2017 16:57:35 +0000
treeherdercomm-beta@32d9b8d10da1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMakeMyDay
bugs1347149
Bug 1347149 - Remove inclusion of calUtils.js and use cal prefix for all calUtils functions. r=MakeMyDay
calendar/base/content/agenda-listbox.js
calendar/base/content/agenda-listbox.xml
calendar/base/content/calendar-base-view.xml
calendar/base/content/calendar-clipboard.js
calendar/base/content/calendar-common-sets.js
calendar/base/content/calendar-daypicker.xml
calendar/base/content/calendar-dnd-listener.js
calendar/base/content/calendar-extract.js
calendar/base/content/calendar-invitations-manager.js
calendar/base/content/calendar-item-bindings.xml
calendar/base/content/calendar-item-editing.js
calendar/base/content/calendar-management.js
calendar/base/content/calendar-menus.xml
calendar/base/content/calendar-month-view.xml
calendar/base/content/calendar-multiday-view.xml
calendar/base/content/calendar-statusbar.js
calendar/base/content/calendar-task-editing.js
calendar/base/content/calendar-task-tree.js
calendar/base/content/calendar-task-tree.xml
calendar/base/content/calendar-task-view.js
calendar/base/content/calendar-ui-utils.js
calendar/base/content/calendar-unifinder.js
calendar/base/content/calendar-view-core.xml
calendar/base/content/calendar-views.js
calendar/base/content/calendar-views.xml
calendar/base/content/dialogs/calendar-alarm-dialog.js
calendar/base/content/dialogs/calendar-alarm-dialog.xul
calendar/base/content/dialogs/calendar-conflicts-dialog.xul
calendar/base/content/dialogs/calendar-creation.js
calendar/base/content/dialogs/calendar-dialog-utils.js
calendar/base/content/dialogs/calendar-event-dialog-attendees.js
calendar/base/content/dialogs/calendar-event-dialog-attendees.xml
calendar/base/content/dialogs/calendar-event-dialog-attendees.xul
calendar/base/content/dialogs/calendar-event-dialog-freebusy.xml
calendar/base/content/dialogs/calendar-event-dialog-recurrence-preview.xml
calendar/base/content/dialogs/calendar-event-dialog-recurrence.js
calendar/base/content/dialogs/calendar-event-dialog-recurrence.xul
calendar/base/content/dialogs/calendar-event-dialog-reminder.js
calendar/base/content/dialogs/calendar-event-dialog-reminder.xul
calendar/base/content/dialogs/calendar-event-dialog-timezone.js
calendar/base/content/dialogs/calendar-event-dialog-timezone.xul
calendar/base/content/dialogs/calendar-event-dialog.xul
calendar/base/content/dialogs/calendar-invitations-dialog.xul
calendar/base/content/dialogs/calendar-invitations-list.xml
calendar/base/content/dialogs/calendar-migration-dialog.js
calendar/base/content/dialogs/calendar-migration-dialog.xul
calendar/base/content/dialogs/calendar-print-dialog.js
calendar/base/content/dialogs/calendar-print-dialog.xul
calendar/base/content/dialogs/calendar-properties-dialog.xul
calendar/base/content/dialogs/calendar-subscriptions-dialog.js
calendar/base/content/dialogs/calendar-subscriptions-dialog.xul
calendar/base/content/dialogs/calendar-summary-dialog.js
calendar/base/content/dialogs/calendar-summary-dialog.xul
calendar/base/content/import-export.js
calendar/base/content/preferences/categories.js
calendar/base/content/preferences/general.js
calendar/base/content/preferences/general.xul
calendar/base/content/today-pane.xul
calendar/base/content/widgets/calendar-alarm-widget.xml
calendar/base/content/widgets/calendar-list-tree.xml
calendar/base/content/widgets/calendar-widgets.xml
calendar/base/content/widgets/minimonth.xml
calendar/base/jar.mn
calendar/base/modules/calProviderUtils.jsm
calendar/base/modules/calUtils.jsm
calendar/base/src/calAlarm.js
calendar/base/src/calAlarmMonitor.js
calendar/base/src/calAlarmService.js
calendar/base/src/calAttachment.js
calendar/base/src/calAttendee.js
calendar/base/src/calCachedCalendar.js
calendar/base/src/calCalendarManager.js
calendar/base/src/calCalendarSearchService.js
calendar/base/src/calDateTimeFormatter.js
calendar/base/src/calEvent.js
calendar/base/src/calFilter.js
calendar/base/src/calFreeBusyService.js
calendar/base/src/calIcsParser.js
calendar/base/src/calIcsSerializer.js
calendar/base/src/calItemBase.js
calendar/base/src/calItemModule.js
calendar/base/src/calRecurrenceInfo.js
calendar/base/src/calRelation.js
calendar/base/src/calTodo.js
calendar/base/src/calTransactionManager.js
calendar/base/src/calUtils.js
calendar/lightning/content/html-item-editing/lightning-item-iframe.html
calendar/lightning/content/imip-bar-overlay.xul
calendar/lightning/content/lightning-item-iframe.js
calendar/lightning/content/lightning-item-iframe.xul
calendar/lightning/content/messenger-overlay-accountCentral.xul
calendar/lightning/content/messenger-overlay-preferences.xul
calendar/lightning/content/messenger-overlay-sidebar.js
calendar/lightning/content/messenger-overlay-sidebar.xul
calendar/lightning/content/suite-overlay-preferences.xul
calendar/providers/caldav/calDavCalendar.js
calendar/providers/gdata/content/gdata-migration-wizard.xul
calendar/providers/gdata/content/gdata-migration.js
calendar/providers/ics/calICSCalendar.js
calendar/providers/storage/calStorageCalendar.js
calendar/providers/wcap/calWcapCalendarItems.js
calendar/providers/wcap/calWcapCalendarModule.js
calendar/providers/wcap/calWcapErrors.js
calendar/providers/wcap/calWcapRequest.js
calendar/providers/wcap/calWcapSession.js
calendar/providers/wcap/calWcapUtils.js
calendar/resources/content/calendarCreation.js
calendar/resources/content/calendarCreation.xul
calendar/resources/content/datetimepickers/datetimepickers.xml
calendar/resources/content/mouseoverPreviews.js
calendar/resources/content/publish.js
calendar/resources/content/publishDialog.xul
calendar/test/mozmill/shared-modules/test-calendar-utils.js
calendar/test/unit/head_consts.js
calendar/test/unit/test_alarm.js
calendar/test/unit/test_attachment.js
calendar/test/unit/test_bug486186.js
calendar/test/unit/test_freebusy_service.js
calendar/test/unit/test_ltninvitationutils.js
calendar/test/unit/test_recur.js
calendar/test/unit/test_utils.js
--- a/calendar/base/content/agenda-listbox.js
+++ b/calendar/base/content/agenda-listbox.js
@@ -110,17 +110,17 @@ agendaListbox.removePeriodListItem = fun
 /**
  * Handler function called when changing the checkbox state on period items.
  *
  * @param event     The DOM event that triggered the checkbox state change.
  */
 agendaListbox.onCheckboxChange = function(event) {
     let periodCheckbox = event.target;
     let lopen = (periodCheckbox.getAttribute("checked") == "true");
-    let listItem = getParentNodeOrThis(periodCheckbox, "agenda-checkbox-richlist-item");
+    let listItem = cal.getParentNodeOrThis(periodCheckbox, "agenda-checkbox-richlist-item");
     let period = listItem.getItem();
     period.open = lopen;
     // as the agenda-checkboxes are only transient we have to set the "checked"
     // attribute at their hidden origins to make that attribute persistent.
     document.getElementById(listItem.id + "-hidden").setAttribute("checked",
                             periodCheckbox.getAttribute("checked"));
     if (lopen) {
         agendaListbox.refreshCalendarQuery(period.start, period.end);
@@ -216,17 +216,17 @@ agendaListbox.editSelectedItem = functio
  * item occurrs tomorrow.
  *
  * @param aItem     The item to find the period for.
  */
 agendaListbox.findPeriodsForItem = function(aItem) {
     let retPeriods = [];
     for (let i = 0; i < this.periods.length; i++) {
         if (this.periods[i].open) {
-            if (checkIfInRange(aItem, this.periods[i].start, this.periods[i].end)) {
+            if (cal.checkIfInRange(aItem, this.periods[i].start, this.periods[i].end)) {
                 retPeriods.push(this.periods[i]);
             }
         }
     }
     return retPeriods;
 };
 
 /**
@@ -289,17 +289,17 @@ agendaListbox.addItemBefore = function(a
 /**
  * Adds an item to the agenda listbox. This function finds the correct period
  * for the item and inserts it correctly so the period stays sorted.
  *
  * @param aItem         The calIItemBase to add.
  * @return              The newly created XUL element.
  */
 agendaListbox.addItem = function(aItem) {
-    if (!isEvent(aItem)) {
+    if (!cal.isEvent(aItem)) {
         return null;
     }
     let periods = this.findPeriodsForItem(aItem);
     if (periods.length == 0) {
         return null;
     }
     let newlistItem = null;
     for (let i = 0; i < periods.length; i++) {
@@ -510,17 +510,17 @@ agendaListbox.deleteItemsFromCalendar = 
  * matches
  *
  * @param aItem         The item to compare.
  * @param aCompItem     The item to compare with.
  * @return              True, if the items match with the above noted criteria.
  */
 agendaListbox.isSameEvent = function(aItem, aCompItem) {
     return aItem.id == aCompItem.id &&
-           aItem[calGetStartDateProp(aItem)].compare(aCompItem[calGetStartDateProp(aCompItem)]) == 0;
+           aItem[cal.calGetStartDateProp(aItem)].compare(aCompItem[cal.calGetStartDateProp(aCompItem)]) == 0;
 };
 
 /**
  * Checks if the currently selected node in the listbox is an Event item (not a
  * period item).
  *
  * @return              True, if the node is not a period item.
  */
@@ -702,33 +702,33 @@ agendaListbox.setupCalendar = function()
  * Usually called at midnight to update the agenda pane. Also retrieves the
  * items from the calendar.
  *
  * @see #refreshCalendarQuery
  * @param newDate       The first date to show if the agenda pane doesn't show
  *                        today.
  */
 agendaListbox.refreshPeriodDates = function(newDate) {
-    this.kDefaultTimezone = calendarDefaultTimezone();
+    this.kDefaultTimezone = cal.calendarDefaultTimezone();
     // Today: now until midnight of tonight
     let oldshowstoday = this.showstoday;
     this.showstoday = this.showsToday(newDate);
     if ((this.showstoday) && (!oldshowstoday)) {
         this.addPeriodListItem(this.tomorrow, "tomorrow-header");
         this.addPeriodListItem(this.soon, "nextweek-header");
     } else if (!this.showstoday) {
         this.removePeriodListItem(this.tomorrow);
         this.removePeriodListItem(this.soon);
     }
     newDate.isDate = true;
     for (let i = 0; i < this.periods.length; i++) {
         let curPeriod = this.periods[i];
         newDate.hour = newDate.minute = newDate.second = 0;
         if (i == 0 && this.showstoday) {
-            curPeriod.start = now();
+            curPeriod.start = cal.now();
         } else {
             curPeriod.start = newDate.clone();
         }
         newDate.day += curPeriod.duration;
         curPeriod.end = newDate.clone();
         curPeriod.listItem.setItem(curPeriod, this.showstoday);
     }
     this.refreshCalendarQuery();
@@ -750,17 +750,17 @@ agendaListbox.addListener = function(aLi
  * @param aStartDate    (optional) The day to check if its "today".
  * @return              Returns true if today is shown.
  */
 agendaListbox.showsToday = function(aStartDate) {
     let lstart = aStartDate;
     if (!lstart) {
         lstart = this.today.start;
     }
-    let lshowsToday = sameDay(now(), lstart);
+    let lshowsToday = cal.sameDay(cal.now(), lstart);
     if (lshowsToday) {
         this.periods = [this.today, this.tomorrow, this.soon];
     } else {
         this.periods = [this.today];
     }
     return lshowsToday;
 };
 
@@ -884,17 +884,17 @@ agendaListbox.calendarObserver.onStartBa
 agendaListbox.calendarObserver.onEndBatch = function() {
 };
 
 agendaListbox.calendarObserver.onLoad = function() {
     this.agendaListbox.refreshCalendarQuery();
 };
 
 agendaListbox.calendarObserver.onAddItem = function(item) {
-    if (!isEvent(item)) {
+    if (!cal.isEvent(item)) {
         return;
     }
     // get all sub items if it is a recurring item
     let occs = this.getOccurrencesBetween(item);
     occs.forEach(this.agendaListbox.addItem, this.agendaListbox);
     setCurrentEvent();
 };
 
@@ -908,34 +908,34 @@ agendaListbox.calendarObserver.getOccurr
     return occs;
 };
 
 agendaListbox.calendarObserver.onDeleteItem = function(item, rebuildFlag) {
     this.onLocalDeleteItem(item, true);
 };
 
 agendaListbox.calendarObserver.onLocalDeleteItem = function(item, moveSelection) {
-    if (!isEvent(item)) {
+    if (!cal.isEvent(item)) {
         return false;
     }
     let selectedItemHashId = -1;
     // get all sub items if it is a recurring item
     let occs = this.getOccurrencesBetween(item);
     for (let i = 0; i < occs.length; i++) {
         let isSelected = this.agendaListbox.deleteItem(occs[i], moveSelection);
         if (isSelected) {
             selectedItemHashId = occs[i].hashId;
         }
     }
     return selectedItemHashId;
 };
 
 agendaListbox.calendarObserver.onModifyItem = function(newItem, oldItem) {
     let selectedItemHashId = this.onLocalDeleteItem(oldItem, false);
-    if (!isEvent(newItem)) {
+    if (!cal.isEvent(newItem)) {
         return;
     }
     this.onAddItem(newItem);
     if (selectedItemHashId != -1) {
         let listItem = agendaListbox.getListItemByHashId(selectedItemHashId);
         if (listItem) {
             agendaListbox.agendaListboxControl.clearSelection();
             agendaListbox.agendaListboxControl.ensureElementIsVisible(listItem);
@@ -991,17 +991,17 @@ agendaListbox.calendarObserver.onDefault
  * Updates the "Upcoming" section of today pane when preference soondays changes
  **/
 agendaListbox.updateSoonSection = function() {
     this.soon.duration = this.soonDays;
     this.soon.open = true;
     let soonHeader = document.getElementById("nextweek-header");
     if (soonHeader) {
         soonHeader.setItem(this.soon, true);
-        agendaListbox.refreshPeriodDates(now());
+        agendaListbox.refreshPeriodDates(cal.now());
     }
 };
 
 /**
  * Updates the event considered "current". This goes through all "today" items
  * and sets the "current" attribute on all list items that are currently
  * occurring.
  *
@@ -1010,17 +1010,17 @@ agendaListbox.updateSoonSection = functi
 function setCurrentEvent() {
     if (!agendaListbox.showsToday() || !agendaListbox.today.open) {
         return;
     }
 
     let msScheduleTime = -1;
     let complistItem = agendaListbox.tomorrow.listItem.previousSibling;
     let removelist = [];
-    let anow = now();
+    let anow = cal.now();
     let msuntillend = 0;
     let msuntillstart = 0;
     let leaveloop;
     do {
         leaveloop = !agendaListbox.isEventListItem(complistItem);
         if (!leaveloop) {
             msuntillstart = complistItem.occurrence.startDate
                                         .getInTimezone(agendaListbox.kDefaultTimezone)
--- a/calendar/base/content/agenda-listbox.xml
+++ b/calendar/base/content/agenda-listbox.xml
@@ -42,16 +42,17 @@
     <content>
       <xul:treenode-checkbox class="agenda-checkbox" anonid="agenda-checkbox-widget"
                                                    flex="1"
                                                    xbl:inherits="selected,label,hidden,disabled"/>
     </content>
     <implementation>
       <field name="kCheckbox">null</field>;
       <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
         this.kCheckbox = document.getAnonymousElementByAttribute(this, "anonid", "agenda-checkbox-widget");
       ]]></constructor>
 
       <method name="getItem">
         <body><![CDATA[
           return this.mItem;
         ]]></body>
       </method>
@@ -67,19 +68,19 @@
               if (this.id == "nextweek-header") {
                   if (duration > 7) {
                       this.kCheckbox.label += " (" + unitPluralForm(duration / 7, "weeks") + ")";
                   } else {
                       this.kCheckbox.label += " (" + unitPluralForm(duration, "days") + ")";
                   }
               }
           } else if (synthetic.duration == 1) {
-              this.kCheckbox.label = getDateFormatter().formatDate(synthetic.start);
+              this.kCheckbox.label = cal.getDateFormatter().formatDate(synthetic.start);
           } else {
-              this.kCheckbox.label = getDateFormatter().formatInterval(synthetic.start, synthetic.end);
+              this.kCheckbox.label = cal.getDateFormatter().formatInterval(synthetic.start, synthetic.end);
           }
         ]]></body>
       </method>
 
       <method name="getCheckbox">
         <body><![CDATA[
           return this.kCheckbox;
         ]]></body>
@@ -105,33 +106,34 @@
           </xul:hbox>
         </xul:vbox>
       </xul:hbox>
     </content>
     <implementation>
       <field name="mAllDayItem">null</field>;
 
       <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
         this.mAllDayItem = document.getAnonymousElementByAttribute(this, "anonid", "allday-item");
       ]]></constructor>
 
       <method name="setOccurrence">
         <parameter name="aOccurrence"/>
         <parameter name="aPeriod"/>
         <body><![CDATA[
           this.mOccurrence = aOccurrence;
           this.mAllDayItem.occurrence = aOccurrence;
           let dateFormatter = cal.getDateFormatter();
           let periodStartDate = aPeriod.start.clone();
           periodStartDate.isDate = true;
           let periodEndDate = aPeriod.end;
-          let startDate = this.mOccurrence[calGetStartDateProp(this.mOccurrence)]
-                              .getInTimezone(calendarDefaultTimezone());
-          let endDate = this.mOccurrence[calGetEndDateProp(this.mOccurrence)]
-                            .getInTimezone(calendarDefaultTimezone());
+          let startDate = this.mOccurrence[cal.calGetStartDateProp(this.mOccurrence)]
+                              .getInTimezone(cal.calendarDefaultTimezone());
+          let endDate = this.mOccurrence[cal.calGetEndDateProp(this.mOccurrence)]
+                            .getInTimezone(cal.calendarDefaultTimezone());
           let endPreviousDay = endDate.clone();
           endPreviousDay.day--;
           // Show items's date for long periods but also for "Upcoming"
           // period with one day duration.
           let showDate = aPeriod.multiday || aPeriod.duration > 1;
 
           let date = "";
           let iconType = "";
@@ -198,26 +200,26 @@
     <implementation>
       <method name="setOccurrence">
         <parameter name="aItem"/>
         <parameter name="aPeriod"/>
         <body><![CDATA[
           this.mOccurrence = aItem;
           this.setAttribute("status", aItem.status);
           let dateFormatter = Components.classes["@mozilla.org/calendar/datetime-formatter;1"]
-                                .getService(Components.interfaces.calIDateTimeFormatter);
+                                        .getService(Components.interfaces.calIDateTimeFormatter);
 
           let periodStartDate = aPeriod.start.clone();
           periodStartDate.isDate = true;
           let periodEndDate = aPeriod.end.clone();
           periodEndDate.day--;
-          let start = this.mOccurrence[calGetStartDateProp(this.mOccurrence)]
-                          .getInTimezone(calendarDefaultTimezone());
-          let end = this.mOccurrence[calGetEndDateProp(this.mOccurrence)]
-                        .getInTimezone(calendarDefaultTimezone());
+          let start = this.mOccurrence[cal.calGetStartDateProp(this.mOccurrence)]
+                          .getInTimezone(cal.calendarDefaultTimezone());
+          let end = this.mOccurrence[cal.calGetEndDateProp(this.mOccurrence)]
+                        .getInTimezone(cal.calendarDefaultTimezone());
           let startDate = start.clone();
           startDate.isDate = true;
           let endDate = end.clone();
           endDate.isDate = true;
           let endAtMidnight = (end.hour == 0 && end.minute == 0);
           if (endAtMidnight) {
               endDate.day--;
           }
@@ -238,18 +240,18 @@
               duration = longFormat ? dateFormatter.formatDateTime(start)
                                     : dateFormatter.formatTime(start);
           } else if (endDate.compare(periodStartDate) >= 0 &&
                      endDate.compare(periodEndDate) <= 0) {
               // event spanning multiple days, end date within period
               iconType = "end";
               if (endAtMidnight) {
                   duration = dateFormatter.formatDate(endDate) + " ";
-                  duration = longFormat ? duration + calGetString("dateFormat", "midnight")
-                                        : calGetString("dateFormat", "midnight");
+                  duration = longFormat ? duration + cal.calGetString("dateFormat", "midnight")
+                                        : cal.calGetString("dateFormat", "midnight");
               } else {
                   duration = longFormat ? dateFormatter.formatDateTime(end)
                                         : dateFormatter.formatTime(end);
               }
           } else {
               iconType = "continue";
           }
           let multiDayImage = document.getAnonymousElementByAttribute(this, "anonid", "agenda-multiDayEvent-image");
--- a/calendar/base/content/calendar-base-view.xml
+++ b/calendar/base/content/calendar-base-view.xml
@@ -238,19 +238,19 @@
                                 .getAttribute("checked") == "true");
         this.tasksInView = (document.getElementById(kTasksInViewCommand)
                                 .getAttribute("checked") == "true");
         this.rotated = (document.getElementById(kOrientation)
                                 .getAttribute("checked") == "true");
         this.showCompleted = (document.getElementById(kShowCompleted)
                                 .getAttribute("checked") == "true");
 
-        this.mTimezone = calendarDefaultTimezone();
+        this.mTimezone = cal.calendarDefaultTimezone();
         let alarmService = Components.classes["@mozilla.org/calendar/alarm-service;1"]
-                           .getService(Components.interfaces.calIAlarmService);
+                                     .getService(Components.interfaces.calIAlarmService);
         alarmService.addObserver(this.mObserver);
         this.setAttribute("type", this.type);
         this.mResizeHandler = () => {
             this.onResize(this);
         };
         this.viewBroadcaster.addEventListener(this.getAttribute("type") + "viewresized", this.mResizeHandler, true);
         // add a preference observer to monitor changes
         Services.prefs.addObserver("calendar.", this.mPrefObserver, false);
@@ -263,17 +263,17 @@
 
       <destructor><![CDATA[
         Components.utils.import("resource://gre/modules/Services.jsm");
 
         if (this.mCalendar) {
             this.mCalendar.removeObserver(this.mObserver);
         }
         let alarmService = Components.classes["@mozilla.org/calendar/alarm-service;1"]
-                           .getService(Components.interfaces.calIAlarmService);
+                                     .getService(Components.interfaces.calIAlarmService);
         alarmService.removeObserver(this.mObserver);
         this.viewBroadcaster.removeEventListener(this.getAttribute("type") + "viewresized", this.mResizeHandler, true);
         Services.prefs.removeObserver("calendar.", this.mPrefObserver);
       ]]></destructor>
 
       <property name="type" readonly="true">
         <getter><![CDATA[
             let typelist = this.id.split("-");
@@ -380,17 +380,17 @@
         <parameter name="aDate"/>
         <body><![CDATA[
           this.showDate(aDate);
         ]]></body>
       </method>
 
       <method name="getRangeDescription">
         <body><![CDATA[
-          return getDateFormatter().formatInterval(this.rangeStartDate, this.rangeEndDate);
+          return cal.getDateFormatter().formatInterval(this.rangeStartDate, this.rangeEndDate);
         ]]></body>
       </method>
 
       <!-- This function guarantees that the
        labels are clipped in the instance that the overflow occurrs,
        avoiding horizontal scrollbars from showing up for a short period. -->
       <method name="adjustWeekdayLength">
         <parameter name="forceShortName"/>
@@ -630,17 +630,17 @@
               case "calendar.week.d2tuesdaysoff":
               case "calendar.week.d3wednesdaysoff":
               case "calendar.week.d4thursdaysoff":
               case "calendar.week.d5fridaysoff":
               case "calendar.week.d6saturdaysoff":
                   this.updateDaysOffPrefs();
                   break;
               case "calendar.timezone.local":
-                  this.timezone = calendarDefaultTimezone();
+                  this.timezone = cal.calendarDefaultTimezone();
                   this.refreshView();
                   break;
               case "calendar.alarms.indicator.show":
                   // Break here to ensure the view is refreshed
                   break;
               case "calendar.week.start":
                   this.weekStartOffset = aSubject.getIntPref(aPreference);
                   break;
@@ -860,18 +860,18 @@
       <property name="longName" readonly="true"
                 onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'longWeekdayName');"/>
       <property name="shortName" readonly="true"
                 onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'shortWeekdayName');"/>
       <property name="weekDay">
         <getter>return this.mWeekday;</getter>
         <setter><![CDATA[
           this.mWeekday = val % 7;
-          this.longName.value = getDateFormatter().dayName(val);
-          this.shortName.value = getDateFormatter().shortDayName(val);
+          this.longName.value = cal.getDateFormatter().dayName(val);
+          this.shortName.value = cal.getDateFormatter().shortDayName(val);
           return this.mWeekday;
         ]]></setter>
       </property>
 
       <property name="date">
         <getter><![CDATA[
           return this.mDate;
         ]]></getter>
--- a/calendar/base/content/calendar-clipboard.js
+++ b/calendar/base/content/calendar-clipboard.js
@@ -169,17 +169,17 @@ function pasteFromClipboard() {
             }
             let firstDate = currentView().selectedDay;
 
             let offset = null;
             if (earliestDate) {
                 // Timezones and DT/DST time may differ between the earliest item
                 // and the selected day. Determine the offset between the
                 // earliestDate in local time and the selected day in whole days.
-                earliestDate = earliestDate.getInTimezone(calendarDefaultTimezone());
+                earliestDate = earliestDate.getInTimezone(cal.calendarDefaultTimezone());
                 earliestDate.isDate = true;
                 offset = firstDate.subtractDate(earliestDate);
                 let deltaDST = firstDate.timezoneOffset - earliestDate.timezoneOffset;
                 offset.inSeconds += deltaDST;
             }
 
             startBatchTransaction();
             for (let item of items) {
--- a/calendar/base/content/calendar-common-sets.js
+++ b/calendar/base/content/calendar-common-sets.js
@@ -270,37 +270,37 @@ var calendarController = {
         return false;
     },
 
     doCommand: function(aCommand) {
         switch (aCommand) {
             // Common Commands
             case "calendar_new_event_command":
                 createEventWithDialog(getSelectedCalendar(),
-                                      getDefaultStartDate(currentView().selectedDay));
+                                      cal.getDefaultStartDate(currentView().selectedDay));
                 break;
             case "calendar_new_event_context_command": {
                 let newStart = currentView().selectedDateTime;
                 if (!newStart) {
-                    newStart = getDefaultStartDate(currentView().selectedDay);
+                    newStart = cal.getDefaultStartDate(currentView().selectedDay);
                 }
                 createEventWithDialog(getSelectedCalendar(), newStart,
                                       null, null, null,
                                       newStart.isDate == true);
                 break;
             }
             case "calendar_modify_event_command":
                 editSelectedEvents();
                 break;
             case "calendar_modify_focused_item_command": {
                 let focusedElement = document.commandDispatcher.focusedElement;
                 if (!focusedElement && this.defaultController && !this.isCalendarInForeground()) {
                     this.defaultController.doCommand(aCommand);
                 } else {
-                    let focusedRichListbox = getParentNodeOrThis(focusedElement, "richlistbox");
+                    let focusedRichListbox = cal.getParentNodeOrThis(focusedElement, "richlistbox");
                     if (focusedRichListbox && focusedRichListbox.id == "agenda-listbox") {
                         agendaListbox.editSelectedItem();
                     } else if (focusedElement && focusedElement.className == "calendar-task-tree") {
                         modifyTaskFromContext();
                     } else if (this.isInMode("calendar")) {
                         editSelectedEvents();
                     }
                 }
@@ -309,62 +309,62 @@ var calendarController = {
             case "calendar_delete_event_command":
                 deleteSelectedEvents();
                 break;
             case "calendar_delete_focused_item_command": {
                 let focusedElement = document.commandDispatcher.focusedElement;
                 if (!focusedElement && this.defaultController && !this.isCalendarInForeground()) {
                     this.defaultController.doCommand(aCommand);
                 } else {
-                    let focusedRichListbox = getParentNodeOrThis(focusedElement, "richlistbox");
+                    let focusedRichListbox = cal.getParentNodeOrThis(focusedElement, "richlistbox");
                     if (focusedRichListbox && focusedRichListbox.id == "agenda-listbox") {
                         agendaListbox.deleteSelectedItem(false);
                     } else if (focusedElement && focusedElement.className == "calendar-task-tree") {
                         deleteToDoCommand(null, false);
                     } else if (this.isInMode("calendar")) {
                         deleteSelectedEvents();
                     }
                 }
                 break;
             }
             case "calendar_new_todo_command":
                 createTodoWithDialog(getSelectedCalendar(),
                                      null, null, null,
-                                     getDefaultStartDate(currentView().selectedDay));
+                                     cal.getDefaultStartDate(currentView().selectedDay));
                 break;
             case "calendar_new_todo_context_command": {
                 let initialDate = currentView().selectedDateTime;
                 if (!initialDate || initialDate.isDate) {
-                    initialDate = getDefaultStartDate(currentView().selectedDay);
+                    initialDate = cal.getDefaultStartDate(currentView().selectedDay);
                 }
                 createTodoWithDialog(getSelectedCalendar(),
                                      null, null, null,
                                      initialDate);
                 break;
             }
             case "calendar_new_todo_todaypane_command":
                 createTodoWithDialog(getSelectedCalendar(),
                                      null, null, null,
-                                     getDefaultStartDate(agendaListbox.today.start));
+                                     cal.getDefaultStartDate(agendaListbox.today.start));
                 break;
             case "calendar_delete_todo_command":
                 deleteToDoCommand();
                 break;
             case "calendar_modify_todo_command":
-                modifyTaskFromContext(null, getDefaultStartDate(currentView().selectedDay));
+                modifyTaskFromContext(null, cal.getDefaultStartDate(currentView().selectedDay));
                 break;
             case "calendar_modify_todo_todaypane_command":
-                modifyTaskFromContext(null, getDefaultStartDate(agendaListbox.today.start));
+                modifyTaskFromContext(null, cal.getDefaultStartDate(agendaListbox.today.start));
                 break;
 
             case "calendar_new_calendar_command":
-                openCalendarWizard();
+                cal.openCalendarWizard(window);
                 break;
             case "calendar_edit_calendar_command":
-                openCalendarProperties(getSelectedCalendar());
+                cal.openCalendarProperties(window, getSelectedCalendar());
                 break;
             case "calendar_delete_calendar_command":
                 promptDeleteCalendar(getSelectedCalendar());
                 break;
 
             case "calendar_import_command":
                 loadEventsFromFile();
                 break;
@@ -535,68 +535,68 @@ var calendarController = {
     get offline() {
         return Services.io.offline;
     },
 
     /**
      * Returns a boolean indicating if all calendars are readonly.
      */
     get all_readonly() {
-        let calMgr = getCalendarManager();
+        let calMgr = cal.getCalendarManager();
         return (calMgr.readOnlyCalendarCount == calMgr.calendarCount);
     },
 
     /**
      * Returns a boolean indicating if all calendars are local
      */
     get no_network_calendars() {
-        return (getCalendarManager().networkCalendarCount == 0);
+        return (cal.getCalendarManager().networkCalendarCount == 0);
     },
 
     /**
      * Returns a boolean indicating if there are calendars that don't require
      * network access.
      */
     get has_local_calendars() {
-        let calMgr = getCalendarManager();
+        let calMgr = cal.getCalendarManager();
         return (calMgr.networkCalendarCount < calMgr.calendarCount);
     },
 
     /**
      * Returns a boolean indicating if there are cached calendars and thus that don't require
      * network access.
      */
     get has_cached_calendars() {
-        let calMgr = getCalendarManager();
+        let calMgr = cal.getCalendarManager();
         let calendars = calMgr.getCalendars({});
         for (let calendar of calendars) {
             if (calendar.getProperty("cache.enabled") || calendar.getProperty("cache.always")) {
                 return true;
             }
         }
         return false;
     },
 
     /**
      * Returns a boolean indicating that there is only one calendar left.
      */
     get last_calendar() {
-        return (getCalendarManager().calendarCount < 2);
+        return (cal.getCalendarManager().calendarCount < 2);
     },
 
     /**
      * Returns a boolean indicating that all local calendars are readonly
      */
     get all_local_calendars_readonly() {
         // We might want to speed this part up by keeping track of this in the
         // calendar manager.
-        let calendars = getCalendarManager().getCalendars({});
+        let calendars = cal.getCalendarManager().getCalendars({});
         let count = calendars.length;
         for (let calendar of calendars) {
-            if (!isCalendarWritable(calendar)) {
+            if (!cal.isCalendarWritable(calendar)) {
                 count--;
             }
         }
         return (count == 0);
     },
 
     /**
      * Returns a boolean indicating that at least one of the items selected
@@ -640,17 +640,17 @@ var calendarController = {
 
     /**
      * Returns a boolean indicating that at least one task in the selection is
      * on a calendar that is writable.
      */
     get todo_items_writable() {
         let selectedTasks = getSelectedTasks();
         for (let task of selectedTasks) {
-            if (isCalendarWritable(task.calendar)) {
+            if (cal.isCalendarWritable(task.calendar)) {
                 return true;
             }
         }
         return false;
     }
 };
 
 /**
@@ -737,17 +737,17 @@ var calendarController2 = {
             case "cmd_redo":
                 redo();
                 break;
             case "cmd_pageSetup":
                 PrintUtils.showPageSetup();
                 break;
             case "button_print":
             case "cmd_print":
-                calPrint();
+                cal.calPrint(window);
                 break;
 
             // Thunderbird commands
             case "cmd_goForward":
                 currentView().moveView(1);
                 break;
             case "cmd_goBack":
                 currentView().moveView(-1);
@@ -812,27 +812,27 @@ function removeCalendarCommandController
  * @param items         An array of items (usually the selected items) to adapt
  *                        the context menu for.
  * @return              True, to show the popup menu.
  */
 function setupContextItemType(event, items) {
     function adaptModificationMenuItem(aMenuItemId, aItemType) {
         let menuItem = document.getElementById(aMenuItemId);
         if (menuItem) {
-            menuItem.setAttribute("label", calGetString("calendar", "delete" + aItemType + "Label"));
-            menuItem.setAttribute("accesskey", calGetString("calendar", "delete" + aItemType + "Accesskey"));
+            menuItem.setAttribute("label", cal.calGetString("calendar", "delete" + aItemType + "Label"));
+            menuItem.setAttribute("accesskey", cal.calGetString("calendar", "delete" + aItemType + "Accesskey"));
         }
     }
-    if (items.some(isEvent) && items.some(isToDo)) {
+    if (items.some(cal.isEvent) && items.some(cal.isToDo)) {
         event.target.setAttribute("type", "mixed");
         adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "Item");
-    } else if (items.length && isEvent(items[0])) {
+    } else if (items.length && cal.isEvent(items[0])) {
         event.target.setAttribute("type", "event");
         adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "Event");
-    } else if (items.length && isToDo(items[0])) {
+    } else if (items.length && cal.isToDo(items[0])) {
         event.target.setAttribute("type", "todo");
         adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "Task");
     } else {
         event.target.removeAttribute("type");
         adaptModificationMenuItem("calendar-item-context-menu-delete-menuitem", "Item");
     }
 
     let menu = document.getElementById("calendar-item-context-menu-attendance-menu");
@@ -904,17 +904,17 @@ function calendarUpdateNewItemsCommand()
                          "calendar_new_event_context_command"];
     let taskCommands = ["calendar_new_todo_command",
                         "calendar_new_todo_context_command",
                         "calendar_new_todo_todaypane_command"];
 
     // re-calculate command status
     CalendarNewEventsCommandEnabled = false;
     CalendarNewTasksCommandEnabled = false;
-    let calendars = cal.getCalendarManager().getCalendars({}).filter(cal.isCalendarWritable).filter(userCanAddItemsToCalendar);
+    let calendars = cal.getCalendarManager().getCalendars({}).filter(cal.isCalendarWritable).filter(cal.userCanAddItemsToCalendar);
     if (calendars.some(cal.isEventCalendar)) {
         CalendarNewEventsCommandEnabled = true;
     }
     if (calendars.some(cal.isTaskCalendar)) {
         CalendarNewTasksCommandEnabled = true;
     }
 
     // update command status if required
@@ -927,17 +927,17 @@ function calendarUpdateNewItemsCommand()
 }
 
 function calendarUpdateDeleteCommand(selectedItems) {
     let oldValue = CalendarDeleteCommandEnabled;
     CalendarDeleteCommandEnabled = (selectedItems.length > 0);
 
     /* we must disable "delete" when at least one item cannot be deleted */
     for (let item of selectedItems) {
-        if (!userCanDeleteItemsFromCalendar(item.calendar)) {
+        if (!cal.userCanDeleteItemsFromCalendar(item.calendar)) {
             CalendarDeleteCommandEnabled = false;
             break;
         }
     }
 
     if (CalendarDeleteCommandEnabled != oldValue) {
         let commands = ["calendar_delete_event_command",
                         "calendar_delete_todo_command",
--- a/calendar/base/content/calendar-daypicker.xml
+++ b/calendar/base/content/calendar-daypicker.xml
@@ -239,27 +239,28 @@
                   }
               }
           }
           return days;
         ]]></getter>
       </property>
 
       <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
         let mainbox =
             document.getAnonymousElementByAttribute(
                 this, "anonid", "mainbox");
         let numRows = mainbox.childNodes.length;
         let child = null;
         for (let i = 0; i < numRows; i++) {
             let row = mainbox.childNodes[i];
             let numChilds = row.childNodes.length;
             for (let j = 0; j < numChilds; j++) {
                 child = row.childNodes[j];
                 child.calendar = this;
             }
         }
-        let labelLastDay = calGetString("calendar-event-dialog", "eventRecurrenceMonthlyLastDayLabel");
+        let labelLastDay = cal.calGetString("calendar-event-dialog", "eventRecurrenceMonthlyLastDayLabel");
         child.setAttribute("label", labelLastDay);
       ]]></constructor>
     </implementation>
   </binding>
 </bindings>
--- a/calendar/base/content/calendar-dnd-listener.js
+++ b/calendar/base/content/calendar-dnd-listener.js
@@ -182,17 +182,17 @@ var itemConversion = {
     }
 };
 
 /**
  * A base class for drag and drop observers
  * @class calDNDBaseObserver
  */
 function calDNDBaseObserver() {
-    ASSERT(false, "Inheriting objects call calDNDBaseObserver!");
+    cal.ASSERT(false, "Inheriting objects call calDNDBaseObserver!");
 }
 
 calDNDBaseObserver.prototype = {
     // initialize this class's members
     initBase: function calDNDInitBase() {
     },
 
     getSupportedFlavours: function calDNDGetFlavors() {
@@ -250,17 +250,17 @@ calDNDBaseObserver.prototype = {
                 parser.parseString(data);
                 this.onDropItems(parser.getItems({}).concat(parser.getParentlessItems({})));
                 break;
             case "text/unicode":
                 var droppedUrl = this.retrieveURLFromData(data, bestFlavor.value);
                 if (!droppedUrl)
                     return;
 
-                var url = makeURL(droppedUrl);
+                var url = cal.makeURL(droppedUrl);
 
                 var localFileInstance = Components.classes["@mozilla.org/file/local;1"]
                                         .createInstance(Components.interfaces.nsILocalFile);
                 localFileInstance.initWithPath(url.path);
 
                 var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
                                   .createInstance(Components.interfaces.nsIFileInputStream);
                 inputStream.init(localFileInstance,
@@ -323,17 +323,17 @@ calDNDBaseObserver.prototype = {
                 } catch(e) {
                     Components.utils.reportError(e)
                 }
                 break;
             case "text/x-moz-message":
                 this.onDropMessage(messenger.msgHdrFromURI(data));
                 break;
             default:
-                ASSERT(false, "unknown data flavour:" + bestFlavor.value+'\n');
+                cal.ASSERT(false, "unknown data flavour:" + bestFlavor.value+'\n');
                 break;
         }
     },
 
     onDragStart: function calDNDStart(aEvent, aTransferData, aDragAction) {},
     onDragOver: function calDNDOver(aEvent, aFlavor, aDragSession) {},
     onDragExit: function calDNDExit(aEvent, aDragSession) {},
 
@@ -415,17 +415,17 @@ calMailButtonDNDObserver.prototype = {
      *
      * @param aItems        An array of items to handle.
      */
     onDropItems: function(aItems) {
         if (aItems && aItems.length > 0) {
             let item = aItems[0];
             let recipients = cal.getRecipientList(item.getAttendees({}));
             let identity = item.calendar.getProperty("imip.identity");
-            sendMailTo(recipients, item.title, item.getProperty("DESCRIPTION"), identity);
+            cal.sendMailTo(recipients, item.title, item.getProperty("DESCRIPTION"), identity);
         }
     },
 
     /**
      * calMailButtonDNDObserver::onDropMessage
      *
      * Gets called in case we're dropping a message
      * on the 'mail mode'-button.
@@ -456,17 +456,17 @@ calCalendarButtonDNDObserver.prototype =
      * Gets called in case we're dropping an array of items
      * on the 'calendar mode'-button.
      *
      * @param aItems        An array of items to handle.
      */
     onDropItems: function(aItems) {
         for (var item of aItems) {
             var newItem = item;
-            if (isToDo(item)) {
+            if (cal.isToDo(item)) {
                 newItem = itemConversion.eventFromTask(item);
             }
             createEventWithDialog(null, null, null, null, newItem);
         }
     },
 
     /**
      * calCalendarButtonDNDObserver::onDropMessage
@@ -474,17 +474,17 @@ calCalendarButtonDNDObserver.prototype =
      * Gets called in case we're dropping a message on the
      * 'calendar mode'-button. In this case we create a new
      * event from the mail. We open the default event dialog
      * and just use the subject of the message as the event title.
      *
      * @param aMessage     The message to handle.
      */
     onDropMessage: function(aMessage) {
-        var newItem = createEvent();
+        var newItem = cal.createEvent();
         itemConversion.calendarItemFromMessage(newItem, aMessage);
         createEventWithDialog(null, null, null, null, newItem);
     }
 };
 
 /**
  * calTaskButtonDNDObserver::calTaskButtonDNDObserver
  *
@@ -505,33 +505,33 @@ calTaskButtonDNDObserver.prototype = {
      * Gets called in case we're dropping an array of items
      * on the 'task mode'-button.
      *
      * @param aItems        An array of items to handle.
      */
     onDropItems: function(aItems) {
         for (var item of aItems) {
             var newItem = item;
-            if (isEvent(item)) {
+            if (cal.isEvent(item)) {
                 newItem = itemConversion.taskFromEvent(item);
             }
             createTodoWithDialog(null, null, null, newItem);
         }
     },
 
     /**
      * calTaskButtonDNDObserver::onDropMessage
      *
      * Gets called in case we're dropping a message
      * on the 'task mode'-button.
      *
      * @param aMessage     The message to handle.
      */
     onDropMessage: function(aMessage) {
-        var todo = createTodo();
+        var todo = cal.createTodo();
         itemConversion.calendarItemFromMessage(todo, aMessage);
         createTodoWithDialog(null, null, null, todo);
     }
 };
 
 /**
  * Invoke a drag session for the passed item. The passed box will be used as a
  * source.
@@ -550,25 +550,25 @@ function invokeEventDragSession(aItem, a
 
         item: aItem,
         getFlavorData: function(aInTransferable, aInFlavor, aOutData, aOutDataLen) {
             if ((aInFlavor == "application/vnd.x-moz-cal-event") ||
                 (aInFlavor == "application/vnd.x-moz-cal-task")) {
                 aOutData.value = aItem;
                 aOutDataLen.value = 1;
             } else {
-                ASSERT(false, "error:" + aInFlavor);
+                cal.ASSERT(false, "error:" + aInFlavor);
             }
         }
     };
 
-    if (isEvent(aItem)) {
+    if (cal.isEvent(aItem)) {
       transfer.addDataFlavor("application/vnd.x-moz-cal-event");
       transfer.setTransferData("application/vnd.x-moz-cal-event", flavourProvider, 0);
-    } else if (isToDo(aItem)) {
+    } else if (cal.isToDo(aItem)) {
       transfer.addDataFlavor("application/vnd.x-moz-cal-task");
       transfer.setTransferData("application/vnd.x-moz-cal-task", flavourProvider, 0);
     }
 
     // Also set some normal data-types, in case we drag into another app
     let serializer = Components.classes["@mozilla.org/calendar/ics-serializer;1"]
                                .createInstance(Components.interfaces.calIIcsSerializer);
     serializer.addItems([aItem], 1);
--- a/calendar/base/content/calendar-extract.js
+++ b/calendar/base/content/calendar-extract.js
@@ -186,19 +186,19 @@ var calendarExtract = {
                 }
                 if (endGuess.hour != null) {
                     dueDate.setHours(endGuess.hour);
                 }
                 if (endGuess.minute != null) {
                     dueDate.setMinutes(endGuess.minute);
                 }
 
-                setItemProperty(item, "entryDate", cal.jsDateToDateTime(date, dtz));
+                cal.setItemProperty(item, "entryDate", cal.jsDateToDateTime(date, dtz));
                 if (endGuess.year != null) {
-                    setItemProperty(item, "dueDate", cal.jsDateToDateTime(dueDate, dtz));
+                    cal.setItemProperty(item, "dueDate", cal.jsDateToDateTime(dueDate, dtz));
                 }
             }
 
             // if time not guessed set allday for events
             if (allDay) {
                 createEventWithDialog(null, null, null, null, item, true);
             } else {
                 createEventWithDialog(null, null, null, null, item);
--- a/calendar/base/content/calendar-invitations-manager.js
+++ b/calendar/base/content/calendar-invitations-manager.js
@@ -122,17 +122,17 @@ InvitationsManager.prototype = {
         if (operationListener2) {
             listeners.push(operationListener2);
         }
 
         gInvitationsRequestManager.cancelPendingRequests();
         this.updateStartDate();
         this.deleteAllItems();
 
-        let cals = getCalendarManager().getCalendars({});
+        let cals = cal.getCalendarManager().getCalendars({});
 
         let opListener = {
             QueryInterface: XPCOMUtils.generateQI([Components.interfaces.calIOperationListener]),
             mCount: cals.length,
             mRequestManager: gInvitationsRequestManager,
             mInvitationsManager: this,
             mHandledItems: {},
 
@@ -158,17 +158,17 @@ InvitationsManager.prototype = {
                                                      this.mInvitationsManager.mItemList);
                             }
                             listener.onOperationComplete(null,
                                                          Components.results.NS_OK,
                                                          Components.interfaces.calIOperationListener.GET,
                                                          null,
                                                          null);
                         } catch (exc) {
-                            ERROR(exc);
+                            cal.ERROR(exc);
                         }
                     }
                 }
             },
 
             onGetResult: function(aCalendar,
                                   aStatus,
                                   aItemType,
@@ -186,17 +186,17 @@ InvitationsManager.prototype = {
                             this.mInvitationsManager.addItem(item);
                         }
                     }
                 }
             }
         };
 
         for (let calendar of cals) {
-            if (!isCalendarWritable(calendar) || calendar.getProperty("disabled")) {
+            if (!cal.isCalendarWritable(calendar) || calendar.getProperty("disabled")) {
                 opListener.onOperationComplete();
                 continue;
             }
 
             // temporary hack unless calCachedCalendar supports REQUEST_NEEDS_ACTION filter:
             calendar = calendar.getProperty("cache.uncachedCalendar");
             if (!calendar) {
                 opListener.onOperationComplete();
@@ -213,17 +213,17 @@ InvitationsManager.prototype = {
                                                   // should be fixed with bug 416975
                                                   Components.interfaces.calICalendar.ITEM_FILTER_CLASS_OCCURRENCES,
                                                   0, this.mStartDate,
                                                   endDate /* we currently cannot pass null here, because of bug 416975 */,
                                                   opListener);
                 gInvitationsRequestManager.addRequestStatus(calendar, operation);
             } catch (exc) {
                 opListener.onOperationComplete();
-                ERROR(exc);
+                cal.ERROR(exc);
             }
         }
     },
 
     /**
      * Open the invitations dialog, non-modal.
      *
      * XXX Passing these listeners in instead of keeping them in the window
@@ -374,17 +374,17 @@ InvitationsManager.prototype = {
 
     /**
      * Helper function to create a start date to search from. This date is the
      * current time with hour/minute/second set to zero.
      *
      * @return      Potential start date.
      */
     getStartDate: function() {
-        let date = now();
+        let date = cal.now();
         date.second = 0;
         date.minute = 0;
         date.hour = 0;
         return date;
     },
 
     /**
      * Updates the start date for the invitations manager to the date returned
@@ -410,13 +410,12 @@ InvitationsManager.prototype = {
      * @param item      The item to check
      * @return          A boolean indicating if the item is a valid invitation.
      */
     validateItem: function(item) {
         if (item.calendar instanceof Components.interfaces.calISchedulingSupport &&
             !item.calendar.isInvitation(item)) {
             return false; // exclude if organizer has invited himself
         }
-        let start = item[calGetStartDateProp(item)] || item[calGetEndDateProp(item)];
-        return (cal.isOpenInvitation(item) &&
-                start.compare(this.mStartDate) >= 0);
+        let start = item[cal.calGetStartDateProp(item)] || item[cal.calGetEndDateProp(item)];
+        return cal.isOpenInvitation(item) && start.compare(this.mStartDate) >= 0;
     }
 };
--- a/calendar/base/content/calendar-item-bindings.xml
+++ b/calendar/base/content/calendar-item-bindings.xml
@@ -16,25 +16,30 @@
       <xul:label xbl:inherits="value=label,control" class="header"/>
       <xul:separator class="groove" flex="1"/>
     </content>
   </binding>
 
   <binding id="item-date-row" extends="xul:row">
     <resources>
       <stylesheet src="chrome://calendar/skin/calendar-event-dialog.css"/>
-    </resources>      
+    </resources>
     <content xbl:inherits="mode">
       <xul:label anonid="item-datetime-label"
                  class="headline"
                  xbl:inherits="align"/>
       <xul:label anonid="item-datetime-value"/>
     </content>
     <implementation>
       <field name="mItem">null</field>
+
+      <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+      ]]></constructor>
+
       <property name="mode"
                 readonly="true">
         <getter><![CDATA[
           if (this.hasAttribute("mode")) {
               return this.getAttribute("mode");
           } else {
               return "start";
           }
@@ -45,45 +50,45 @@
           return mItem;
         ]]></getter>
         <setter><![CDATA[
           this.mItem = val;
           let headerLabel = document.getAnonymousElementByAttribute(this, "anonid", "item-datetime-label");
           let itemDateTimeLabel = document.getAnonymousElementByAttribute(this, "anonid", "item-datetime-value");
           let date;
           if (this.mode == "start") {
-              date = this.mItem[calGetStartDateProp(this.mItem)];
+              date = this.mItem[cal.calGetStartDateProp(this.mItem)];
               if (date) {
                   let label;
-                  if (isToDo(this.mItem)) {
+                  if (cal.isToDo(this.mItem)) {
                       label = this.getAttribute("taskStartLabel");
                   } else {
                       label = this.getAttribute("eventStartLabel");
                   }
                   headerLabel.value = label;
               }
           } else {
-              date = this.mItem[calGetEndDateProp(this.mItem)];
+              date = this.mItem[cal.calGetEndDateProp(this.mItem)];
               if (date) {
                   let label;
-                  if (isToDo(this.mItem)) {
+                  if (cal.isToDo(this.mItem)) {
                       label = this.getAttribute("taskDueLabel");
                   } else {
                       label = this.getAttribute("eventEndLabel");
                   }
                   headerLabel.value = label;
               }
           }
           let hideLabels = (date == null);
           if (hideLabels) {
               this.setAttribute("hidden", "true");
           } else {
               const kDefaultTimezone = cal.calendarDefaultTimezone();
               let localTime = date.getInTimezone(kDefaultTimezone);
-              let formatter = getDateFormatter();
+              let formatter = cal.getDateFormatter();
               itemDateTimeLabel.value = formatter.formatDateTime(localTime);
               if (!date.timezone.isFloating && date.timezone.tzid != kDefaultTimezone.tzid) {
                   // we additionally display the original datetime with timezone
                   let orgTime = cal.calGetString("calendar",
                                                  "datetimeWithTimezone",
                                                  [formatter.formatDateTime(date),
                                                   date.timezone.tzid]);
                   itemDateTimeLabel.value += " (" + orgTime + ")";
--- a/calendar/base/content/calendar-item-editing.js
+++ b/calendar/base/content/calendar-item-editing.js
@@ -384,55 +384,55 @@ function openEventDialog(calendarItem, c
         dlg.focus();
         disposeJob(job);
         return;
     }
 
     // Set up some defaults
     mode = mode || "new";
     calendar = calendar || getSelectedCalendar();
-    let calendars = getCalendarManager().getCalendars({});
-    calendars = calendars.filter(isCalendarWritable);
+    let calendars = cal.getCalendarManager().getCalendars({});
+    calendars = calendars.filter(cal.isCalendarWritable);
 
     let isItemSupported;
-    if (isToDo(calendarItem)) {
+    if (cal.isToDo(calendarItem)) {
         isItemSupported = function(aCalendar) {
             return (aCalendar.getProperty("capabilities.tasks.supported") !== false);
         };
-    } else if (isEvent(calendarItem)) {
+    } else if (cal.isEvent(calendarItem)) {
         isItemSupported = function(aCalendar) {
             return (aCalendar.getProperty("capabilities.events.supported") !== false);
         };
     }
 
     // Filter out calendars that don't support the given calendar item
     calendars = calendars.filter(isItemSupported);
 
     // Filter out calendar/items that we cannot write to/modify
     if (mode == "new") {
-        calendars = calendars.filter(userCanAddItemsToCalendar);
+        calendars = calendars.filter(cal.userCanAddItemsToCalendar);
     } else { /* modify */
         calendars = calendars.filter((aCalendar) => {
             /* If the calendar is the item calendar, we check that the item
              * can be modified. If the calendar is NOT the item calendar, we
              * check that the user can remove items from that calendar and
              * add items to the current one.
              */
             let isSameCalendar = calendarItem.calendar == aCalendar;
-            let canModify = userCanModifyItem(calendarItem);
-            let canMoveItems = userCanDeleteItemsFromCalendar(calendarItem.calendar) &&
-                               userCanAddItemsToCalendar(aCalendar);
+            let canModify = cal.userCanModifyItem(calendarItem);
+            let canMoveItems = cal.userCanDeleteItemsFromCalendar(calendarItem.calendar) &&
+                               cal.userCanAddItemsToCalendar(aCalendar);
 
             return isSameCalendar ? canModify : canMoveItems;
         });
     }
 
     if (mode == "new" &&
-        (!isCalendarWritable(calendar) ||
-         !userCanAddItemsToCalendar(calendar) ||
+        (!cal.isCalendarWritable(calendar) ||
+         !cal.userCanAddItemsToCalendar(calendar) ||
          !isItemSupported(calendar))) {
         if (calendars.length < 1) {
             // There are no writable calendars or no calendar supports the given
             // item. Don't show the dialog.
             disposeJob(job);
             return;
         } else {
             // Pick the first calendar that supports the item and is writable
@@ -448,17 +448,17 @@ function openEventDialog(calendarItem, c
 
     // Setup the window arguments
     let args = {};
     args.calendarEvent = calendarItem;
     args.calendar = calendar;
     args.mode = mode;
     args.onOk = callback;
     args.job = job;
-    args.initialStartDateValue = initialDate || getDefaultStartDate();
+    args.initialStartDateValue = initialDate || cal.getDefaultStartDate();
     args.counterProposal = counterProposal;
     args.inTab = Preferences.get("calendar.item.editInTab", false);
     args.useNewItemUI = Preferences.get("calendar.item.useNewItemUI", false);
 
     // this will be called if file->new has been selected from within the dialog
     args.onNewEvent = function(opcalendar) {
         createEventWithDialog(opcalendar, null, null);
     };
@@ -472,18 +472,18 @@ function openEventDialog(calendarItem, c
     // ask the provide if this item is an invitation. if this is the case
     // we'll open the summary dialog since the user is not allowed to change
     // the details of the item.
     let wrappedCalendar = cal.wrapInstance(calendar, Components.interfaces.calISchedulingSupport);
     let isInvitation = wrappedCalendar && wrappedCalendar.isInvitation(calendarItem);
 
     // open the dialog modeless
     let url;
-    let isEditable = mode == "modify" && !isInvitation && userCanModifyItem(calendarItem);
-    if (isCalendarWritable(calendar) && (mode == "new" || isEditable)) {
+    let isEditable = mode == "modify" && !isInvitation && cal.userCanModifyItem(calendarItem);
+    if (cal.isCalendarWritable(calendar) && (mode == "new" || isEditable)) {
         if (args.inTab) {
             url = args.useNewItemUI ? "chrome://lightning/content/html-item-editing/lightning-item-iframe.html"
                                     : "chrome://lightning/content/lightning-item-iframe.xul";
         } else {
             url = "chrome://calendar/content/calendar-event-dialog.xul";
         }
     } else {
         url = "chrome://calendar/content/calendar-summary-dialog.xul";
--- a/calendar/base/content/calendar-management.js
+++ b/calendar/base/content/calendar-management.js
@@ -112,17 +112,17 @@ function loadCalendarManager() {
 /**
  * Creates the initial "Home" calendar if no calendar exists.
  */
 function initHomeCalendar() {
     let calMgr = cal.getCalendarManager();
     let composite = cal.getCompositeCalendar(window);
     let url = cal.makeURL("moz-storage-calendar://");
     let homeCalendar = calMgr.createCalendar("storage", url);
-    homeCalendar.name = calGetString("calendar", "homeCalendarName");
+    homeCalendar.name = cal.calGetString("calendar", "homeCalendarName");
     calMgr.registerCalendar(homeCalendar);
     Preferences.set("calendar.list.sortOrder", homeCalendar.id);
     composite.addCalendar(homeCalendar);
 
     // Wrapping this in a try/catch block, as if any of the migration code
     // fails, the app may not load.
     if (Preferences.get("calendar.migrator.enabled", true)) {
         try {
@@ -168,36 +168,36 @@ function updateSortOrderPref(event) {
  */
 function calendarListTooltipShowing(event) {
     let tree = document.getElementById("calendar-list-tree-widget");
     let calendar = tree.getCalendarFromEvent(event);
     let tooltipText = false;
     if (calendar) {
         let currentStatus = calendar.getProperty("currentStatus");
         if (!Components.isSuccessCode(currentStatus)) {
-            tooltipText = calGetString("calendar", "tooltipCalendarDisabled", [calendar.name]);
+            tooltipText = cal.calGetString("calendar", "tooltipCalendarDisabled", [calendar.name]);
         } else if (calendar.readOnly) {
-            tooltipText = calGetString("calendar", "tooltipCalendarReadOnly", [calendar.name]);
+            tooltipText = cal.calGetString("calendar", "tooltipCalendarReadOnly", [calendar.name]);
         }
     }
     setElementValue("calendar-list-tooltip", tooltipText, "label");
     return (tooltipText != false);
 }
 
 /**
  * A handler called to set up the context menu on the calendar list.
  *
  * @param event         The DOM event that caused the context menu to open.
  * @return              Returns true if the context menu should be shown.
  */
 function calendarListSetupContextMenu(event) {
     let col = {};
     let row = {};
     let calendar;
-    let calendars = getCalendarManager().getCalendars({});
+    let calendars = cal.getCalendarManager().getCalendars({});
     let treeNode = document.getElementById("calendar-list-tree-widget");
     let composite = cal.getCompositeCalendar(window);
 
     if (document.popupNode.localName == "tree") {
         // Using VK_APPS to open the context menu will target the tree
         // itself. In that case we won't have a client point even for
         // opening the context menu. The "target" element should then be the
         // selected calendar.
@@ -214,17 +214,17 @@ function calendarListSetupContextMenu(ev
         col.value.element.getAttribute("anonid") == "checkbox-treecol") {
         // Don't show the context menu if the checkbox was clicked.
         return false;
     }
 
     document.getElementById("list-calendars-context-menu").contextCalendar = calendar;
 
     // Only enable calendar search if there's actually the chance of finding something:
-    let hasProviders = getCalendarSearchService().getProviders({}).length < 1 && "true";
+    let hasProviders = cal.getCalendarSearchService().getProviders({}).length < 1 && "true";
     setElementValue("list-calendars-context-find", hasProviders, "collapsed");
 
     if (calendar) {
         enableElement("list-calendars-context-edit");
         enableElement("list-calendars-context-publish");
 
         enableElement("list-calendars-context-togglevisible");
         setElementValue("list-calendars-context-togglevisible", false, "collapsed");
--- a/calendar/base/content/calendar-menus.xml
+++ b/calendar/base/content/calendar-menus.xml
@@ -12,18 +12,20 @@
 
   <binding id="task-menupopup" extends="xul:menupopup">
     <implementation>
       <field name="mType">null</field>;
       <field name="mPopupHandler">null</field>
       <field name="mParentMenuPopup">null</field>
 
       <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
         this.mPopupHandler = () => { this.schangeMenuByPropertyName(); };
-        this.mParentMenuPopup = getParentNodeOrThis(this, "menupopup");
+        this.mParentMenuPopup = cal.getParentNodeOrThis(this, "menupopup");
         this.mParentMenuPopup.addEventListener("popupshowing", this.mPopupHandler, true);
       ]]></constructor>
 
       <destructor><![CDATA[
         this.mParentMenuPopup.removeEventListener("popupshowing", this.mPopupHandler, true);
       ]]></destructor>
 
       <!-- This method checks a command which naming follows
@@ -46,21 +48,21 @@
               // We are in a task tab (editing a single task).
               propertyValue = gConfig[this.mType];
           } else {
               // We are in the Tasks tab.
               let tasks = getSelectedTasks();
               let tasksSelected = (tasks != null) && (tasks.length > 0);
               if (tasksSelected) {
                   let task = tasks[0];
-                  if (isPropertyValueSame(tasks, this.mType)) {
+                  if (cal.isPropertyValueSame(tasks, this.mType)) {
                       propertyValue = task[this.mType];
                   }
               } else {
-                  applyAttributeToMenuChildren(this, "disabled", !tasksSelected);
+                  cal.applyAttributeToMenuChildren(this, "disabled", !tasksSelected);
               }
           }
           if (propertyValue || propertyValue == 0) {
               let command = document.getElementById("calendar_" + this.mType + "-" + propertyValue + "_command");
               if (command) {
                   command.setAttribute("checked", "true");
               }
           }
--- a/calendar/base/content/calendar-month-view.xml
+++ b/calendar/base/content/calendar-month-view.xml
@@ -1,15 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
-<!-- Note that this file depends on helper functions in calUtils.js-->
-
 <!DOCTYPE bindings SYSTEM "chrome://global/locale/global.dtd" >
 
 <bindings id="calendar-month-view-bindings"
           xmlns="http://www.mozilla.org/xbl"
           xmlns:html="http://www.w3.org/1999/xhtml"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
           xmlns:xbl="http://www.mozilla.org/xbl">
 
@@ -66,31 +64,35 @@
                 </xul:hbox>
               </xul:stack>
             </xul:box>
           </xul:box>
         </xul:hbox>
       </xul:vbox>
     </content>
     <implementation>
+      <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+      ]]></constructor>
+
       <property name="occurrence">
         <getter><![CDATA[
           return this.mOccurrence;
         ]]></getter>
         <setter><![CDATA[
-          ASSERT(!this.mOccurrence, "Code changes needed to set the occurrence twice", true);
+          cal.ASSERT(!this.mOccurrence, "Code changes needed to set the occurrence twice", true);
           this.mOccurrence = val;
           if (cal.isEvent(val)) {
               if (!val.startDate.isDate) {
                   let label = document.getAnonymousElementByAttribute(this, "anonid", "item-label");
                   let formatter = Components.classes["@mozilla.org/calendar/datetime-formatter;1"]
                                             .getService(Components.interfaces.calIDateTimeFormatter);
                   let timezone = this.calendarView ? this.calendarView.mTimezone
-                                                   : calendarDefaultTimezone();
-                  let parentDate = ensureDateTime(this.parentBox.date);
+                                                   : cal.calendarDefaultTimezone();
+                  let parentDate = cal.ensureDateTime(this.parentBox.date);
                   let startTime = val.startDate.getInTimezone(timezone);
                   let endTime = val.endDate.getInTimezone(timezone);
                   let nextDay = parentDate.clone();
                   nextDay.day++;
                   let comp = endTime.compare(nextDay);
                   if (startTime.compare(parentDate) == -1) {
                       if (comp == 1) {
                           label.value = "↔";
@@ -133,16 +135,20 @@
                    xbl:inherits="relation,selected,value"/>
       </xul:hbox>
       <xul:vbox anonid="day-items" class="calendar-month-day-box-items-box" flex="1">
         <children/>
       </xul:vbox>
     </content>
 
     <implementation>
+      <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+      ]]></constructor>
+
       <field name="mDate">null</field>
       <field name="mItemHash">{}</field>
       <field name="mShowMonthLabel">false</field>
 
       <property name="date"
                 onget="return this.mDate"
                 onset="this.setDate(val); return val;"/>
 
@@ -178,17 +184,17 @@
               return val;
           }
           this.mShowMonthLabel = val;
 
           if (!this.mDate) {
               return val;
           }
           if (val) {
-              this.setAttribute("value", getDateFormatter().formatDateWithoutYear(this.mDate));
+              this.setAttribute("value", cal.getDateFormatter().formatDateWithoutYear(this.mDate));
           } else {
               this.setAttribute("value", this.mDate.day);
           }
           return val;
         ]]></setter>
       </property>
 
       <method name="setDate">
@@ -211,17 +217,17 @@
           // Set up DOM attributes for custom CSS coloring.
           let weekTitle = cal.getWeekInfoService().getWeekTitle(aDate);
           this.setAttribute("year", aDate.year);
           this.setAttribute("month", aDate.month + 1);
           this.setAttribute("week", weekTitle);
           this.setAttribute("day", aDate.day);
 
           if (this.mShowMonthLabel) {
-              let monthName = calGetString("dateFormat", "month." + (aDate.month + 1) + ".Mmm");
+              let monthName = cal.calGetString("dateFormat", "month." + (aDate.month + 1) + ".Mmm");
               this.setAttribute("value", aDate.day + " " + monthName);
           } else {
               this.setAttribute("value", aDate.day);
           }
         ]]></body>
       </method>
 
       <method name="addItem">
@@ -282,18 +288,18 @@
       <method name="onDropItem">
         <parameter name="aItem"/>
         <body><![CDATA[
           // When item's timezone is different than the default one, the
           // item might get moved on a day different than the drop day.
           // Changing the drop day allows to compensate a possible difference.
 
           // Figure out if the timezones cause a days difference.
-          let start = (aItem[calGetStartDateProp(aItem)] ||
-                       aItem[calGetEndDateProp(aItem)]).clone();
+          let start = (aItem[cal.calGetStartDateProp(aItem)] ||
+                       aItem[cal.calGetEndDateProp(aItem)]).clone();
           let dayboxDate = this.mDate.clone();
           if (start.timezone != dayboxDate.timezone) {
               let startInDefaultTz = start.clone().getInTimezone(dayboxDate.timezone);
               start.isDate = true;
               startInDefaultTz.isDate = true;
               startInDefaultTz.timezone = start.timezone;
               let dayDiff = start.subtractDate(startInDefaultTz);
               // Change the day where to drop the item.
@@ -317,17 +323,17 @@
         this.calendarView.controller.createNewEvent();
       ]]></handler>
       <handler event="click" button="0"><![CDATA[
         if (!(event.ctrlKey || event.metaKey)) {
             this.calendarView.setSelectedItems(0, []);
         }
       ]]></handler>
       <handler event="wheel"><![CDATA[
-        if (getParentNodeOrThisByAttribute(event.originalTarget, "anonid", "day-label") == null) {
+        if (cal.getParentNodeOrThisByAttribute(event.originalTarget, "anonid", "day-label") == null) {
             if (this.dayitems.scrollHeight > this.dayitems.clientHeight) {
                 event.stopPropagation();
             }
         }
       ]]></handler>
     </handlers>
   </binding>
 
@@ -408,16 +414,17 @@
         </xul:grid>
       </xul:vbox>
     </content>
 
     <implementation implements="calICalendarView">
       <constructor><![CDATA[
         Components.utils.import("resource://gre/modules/Preferences.jsm");
         Components.utils.import("resource://calendar/modules/calViewUtils.jsm");
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
         // Set the preference for the default start of the week
         this.weekStartOffset = Preferences.get("calendar.week.start", 0);
 
         for (let i = 0; i < 7; i++) {
             let hdr = createXULElement("calendar-day-label");
             this.labeldaybox.appendChild(hdr);
             hdr.weekDay = (i + this.mWeekStartOffset) % 7;
@@ -597,17 +604,17 @@
           }
           this.fireEvent("dayselect", realVal);
           return val;
         ]]></setter>
       </property>
 
       <property name="selectedDateTime">
         <getter><![CDATA[
-            return getDefaultStartDate(this.selectedDay);
+            return cal.getDefaultStartDate(this.selectedDay);
         ]]></getter>
         <setter><![CDATA[
             this.mClickedTime = val;
         ]]></setter>
       </property>
 
       <method name="showDate">
         <parameter name="aDate"/>
--- a/calendar/base/content/calendar-multiday-view.xml
+++ b/calendar/base/content/calendar-multiday-view.xml
@@ -1,15 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
-<!-- Note that this file depends on helper functions in calUtils.js-->
-
 <!DOCTYPE bindings SYSTEM "chrome://global/locale/global.dtd" >
 
 <bindings id="calendar-multiday-view-bindings"
   xmlns="http://www.mozilla.org/xbl"
   xmlns:html="http://www.w3.org/1999/xhtml"
   xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
   xmlns:xbl="http://www.mozilla.org/xbl">
 
@@ -241,18 +239,20 @@
           <xul:label anonid="fgdragbox-endlabel" class="fgdragbox-label"/>
         </xul:box>
       </xul:stack>
       <xul:calendar-event-box anonid="config-box" hidden="true" xbl:inherits="orient"/>
     </content>
 
     <implementation>
       <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
         this.mEventInfos = [];
-        this.mTimezone = UTC();
+        this.mTimezone = cal.UTC();
         this.mSelectedItemIds = {};
       ]]></constructor>
 
       <!-- fields -->
       <field name="mPixPerMin">0.6</field>
       <field name="mStartMin">0</field>
       <field name="mEndMin">24 * 60</field>
       <field name="mDayStartMin">8 * 60</field>
@@ -328,17 +328,17 @@
 
       <property name="date">
         <getter><![CDATA[
           return this.mDate;
         ]]></getter>
         <setter><![CDATA[
           this.mDate = val;
 
-          if (!compareObjects(val.timezone, this.mTimezone)) {
+          if (!cal.compareObjects(val.timezone, this.mTimezone)) {
               this.mTimezone = val.timezone;
               if (!this.mLayoutBatchCount) {
                   this.recalculateStartEndMinutes();
               }
           }
 
           return val;
         ]]></setter>
@@ -516,21 +516,21 @@
            minutes of the whole occurrence (which could span multiple days)
            relative to the time 0:00 of the day in this column -->
       <method name="getStartEndMinutesForOccurrence">
         <parameter name="aOccurrence"/>
         <body><![CDATA[
           let stdate = aOccurrence.startDate || aOccurrence.entryDate || aOccurrence.dueDate;
           let enddate = aOccurrence.endDate || aOccurrence.dueDate || aOccurrence.entryDate;
 
-          if (!compareObjects(stdate.timezone, this.mTimezone)) {
+          if (!cal.compareObjects(stdate.timezone, this.mTimezone)) {
               stdate = stdate.getInTimezone(this.mTimezone);
           }
 
-          if (!compareObjects(enddate.timezone, this.mTimezone)) {
+          if (!cal.compareObjects(enddate.timezone, this.mTimezone)) {
               enddate = enddate.getInTimezone(this.mTimezone);
           }
 
           let startHour = stdate.hour;
           let startMinute = stdate.minute;
           let endHour = enddate.hour;
           let endMinute = enddate.minute;
 
@@ -1198,31 +1198,31 @@
                       prevEnd = col[col.length - 1].endDate.clone();
                   } else {
                       // First event in the column, add a placeholder for the
                       // blank time from this.mStartMin to the event's start
                       prevEnd = start.clone();
                       prevEnd.hour = 0;
                       prevEnd.minute = this.mStartMin;
                   }
-                  prevEnd.timezone = floating();
+                  prevEnd.timezone = cal.floating();
                   // the reason why we need to calculate time durations
                   // based on floating timezones is that we need avoid
                   // dst gaps in this case. converting the date/times to
                   // floating conveys this idea in a natural way. note that
                   // we explicitly don't use getInTimezone() as it would
                   // be slightly more expensive in terms of performance.
                   let floatstart = start.clone();
-                  floatstart.timezone = floating();
+                  floatstart.timezone = cal.floating();
                   let dur = floatstart.subtractDate(prevEnd);
                   if (dur.inSeconds) {
                       col.push({ duration: dur });
                   }
                   let floatend = end.clone();
-                  floatend.timezone = floating();
+                  floatend.timezone = cal.floating();
                   col.push({
                       event: data.itemInfo.event,
                       endDate: end,
                       startDate: start,
                       duration: floatend.subtractDate(floatstart)
                   });
               }
               layerOffset = layers.length;
@@ -1794,18 +1794,18 @@
         <parameter name="aOccurrence"/>
         <!-- "start", "end", "middle" -->
         <parameter name="aGrabbedElement"/>
         <!-- mouse screenX/screenY from the event -->
         <parameter name="aMouseX"/>
         <parameter name="aMouseY"/>
         <parameter name="aSnapInt"/>
         <body><![CDATA[
-          if (!isCalendarWritable(aOccurrence.calendar) ||
-              !userCanModifyItem(aOccurrence) ||
+          if (!cal.isCalendarWritable(aOccurrence.calendar) ||
+              !cal.userCanModifyItem(aOccurrence) ||
               (aOccurrence.calendar instanceof Components.interfaces.calISchedulingSupport && aOccurrence.calendar.isInvitation(aOccurrence)) ||
               aOccurrence.calendar.getProperty("capabilities.events.supported") === false) {
               return;
           }
 
           this.mDragState = {
               origColumn: this,
               dragOccurrence: aOccurrence,
@@ -1964,19 +1964,19 @@
           let startstr = timeFormatter.formatTime(cal.jsDateToDateTime(jsTime, cal.floating()));
           jsTime.setHours(endhr, endmin);
           let endstr = timeFormatter.formatTime(cal.jsDateToDateTime(jsTime, cal.floating()));
 
           // Tasks without Entry or Due date have a string as first label
           // instead of the time.
           if (cal.isToDo(this.mDragState.dragOccurrence)) {
               if (!this.mDragState.dragOccurrence.dueDate) {
-                  startstr = calGetString("calendar", "dragLabelTasksWithOnlyEntryDate");
+                  startstr = cal.calGetString("calendar", "dragLabelTasksWithOnlyEntryDate");
               } else if (!this.mDragState.dragOccurrence.entryDate) {
-                  startstr = calGetString("calendar", "dragLabelTasksWithOnlyDueDate");
+                  startstr = cal.calGetString("calendar", "dragLabelTasksWithOnlyDueDate");
               }
           }
           firstColumn.fgboxes.startlabel.setAttribute("value", startstr);
           lastColumn.fgboxes.endlabel.setAttribute("value", endstr);
 
         ]]></body>
       </method>
 
@@ -2042,17 +2042,17 @@
          - event.
         -->
       <handler event="mousedown"><![CDATA[
         // select this column
         this.calendarView.selectedDay = this.mDate;
 
         // If the selected calendar is readOnly, we don't want any sweeping.
         let calendar = getSelectedCalendar();
-        if (!isCalendarWritable(calendar) ||
+        if (!cal.isCalendarWritable(calendar) ||
             calendar.getProperty("capabilities.events.supported") === false) {
             return;
         }
 
         // Only start sweeping out an event if the left button was clicked
         if (event.button != 0) {
             return;
         }
@@ -2099,16 +2099,18 @@
   <binding id="calendar-header-container" extends="chrome://calendar/content/widgets/calendar-widgets.xml#dragndropContainer">
     <content xbl:inherits="selected" flex="1" class="calendar-event-column-header">
       <children/>
     </content>
 
     <implementation>
       <field name="mItemBoxes">null</field>
       <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
         this.mItemBoxes = [];
       ]]></constructor>
 
       <property name="date">
         <getter><![CDATA[
           return this.mDate;
         ]]></getter>
         <setter><![CDATA[
@@ -2298,17 +2300,19 @@
             </xul:stack>
           </xul:box>
         </xul:box>
       </xul:box>
     </content>
 
     <implementation>
       <constructor><![CDATA[
-         this.orient = this.getAttribute("orient");
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
+        this.orient = this.getAttribute("orient");
       ]]></constructor>
 
       <!-- fields -->
       <field name="mParentColumn">null</field>
 
       <!-- methods/properties -->
       <method name="setAttribute">
         <parameter name="aAttr"/>
@@ -2384,17 +2388,17 @@
         <body><![CDATA[
           let evl = this.eventNameLabel;
           let item = this.mOccurrence;
 
           if (item.title && item.title != "") {
               // Use <description> textContent so it can wrap.
               evl.textContent = item.title;
           } else {
-              evl.textContent = calGetString("calendar", "eventUntitled");
+              evl.textContent = cal.calGetString("calendar", "eventUntitled");
           }
 
           let gripbar = document.getAnonymousElementByAttribute(this, "anonid", "gripbar1").boxObject.height;
           let height = document.getAnonymousElementByAttribute(this, "anonid", "eventbox").boxObject.height;
           evl.setAttribute("style", "max-height: " + Math.max(0, height-gripbar * 2) + "px");
         ]]></body>
       </method>
     </implementation>
@@ -2515,16 +2519,17 @@
                    equalsize="always"/>
         </xul:scrollbox>
       </xul:box>
     </content>
 
     <implementation implements="calICalendarView">
       <constructor><![CDATA[
         Components.utils.import("resource://gre/modules/Preferences.jsm");
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
         // get day start/end hour from prefs and set on the view
         this.setDayStartEndMinutes(Preferences.get("calendar.view.daystarthour", 8) * 60,
                                    Preferences.get("calendar.view.dayendhour", 17) * 60);
 
         // initially scroll to the day start hour in the view
         this.scrollToMinute(this.mDayStartMin);
 
@@ -3033,23 +3038,23 @@
           } else { // undated todo
               return [];
           }
         ]]></body>
       </method>
 
       <method name="centerSelectedItems">
         <body><![CDATA[
-          let displayTZ = calendarDefaultTimezone();
+          let displayTZ = cal.calendarDefaultTimezone();
           let lowMinute = 24 * 60;
           let highMinute = 0;
 
           for (let item of this.mSelectedItems) {
-              let startDateProperty = calGetStartDateProp(item);
-              let endDateProperty = calGetEndDateProp(item);
+              let startDateProperty = cal.calGetStartDateProp(item);
+              let endDateProperty = cal.calGetEndDateProp(item);
 
               let occs = [];
               if (item.recurrenceInfo) {
                   // if selected a parent item, show occurrence(s) in view range
                   occs = item.getOccurrencesBetween(this.startDate, this.queryEndDate, {}, 0);
               } else {
                   occs = [item];
               }
@@ -3085,17 +3090,17 @@
                   if (occStart.timezone != displayTZ) {
                       occStart = occStart.getInTimezone(displayTZ);
                   }
                   if (occEnd.timezone != displayTZ) {
                       occEnd = occEnd.getInTimezone(displayTZ);
                   }
                   // If crosses midnite in current TZ, set end just
                   // before midnite after start so start/title usually visible.
-                  if (!sameDay(occStart, occEnd)) {
+                  if (!cal.sameDay(occStart, occEnd)) {
                       occEnd = occStart.clone();
                       occEnd.day = occStart.day;
                       occEnd.hour = 23;
                       occEnd.minute = 59;
                   }
 
                   // Ensure range shows occ
                   lowMinute = Math.min(occStart.hour * 60 + occStart.minute,
@@ -3515,19 +3520,19 @@
         <parameter name="aOccurrences"/>
         <body><![CDATA[
           if (!this.mDateColumns || !this.mDateColumns.length) {
               return [];
           }
 
           let occMap = {};
           for (let occ of aOccurrences) {
-              let startDate = occ[calGetStartDateProp(occ)]
+              let startDate = occ[cal.calGetStartDateProp(occ)]
                               .getInTimezone(this.mStartDate.timezone);
-              let endDate = occ[calGetEndDateProp(occ)]
+              let endDate = occ[cal.calGetEndDateProp(occ)]
                               .getInTimezone(this.mEndDate.timezone) || startDate;
               if (startDate.compare(this.mStartDate) >= 0 &&
                   endDate.compare(this.mEndDate) <= 0) {
                   for (let i = startDate.day; i <= endDate.day; i++) {
                       occMap[i] = true;
                   }
               }
           }
@@ -3607,18 +3612,18 @@
           }
           return null;
         ]]></body>
       </method>
 
       <method name="adjustScrollbarSpacersForAlldayEvents">
         <parameter name="aEvent"/>
         <body><![CDATA[
-          let startDate = aEvent[calGetStartDateProp(aEvent)];
-          let endDate = aEvent[calGetEndDateProp(aEvent)];
+          let startDate = aEvent[cal.calGetStartDateProp(aEvent)];
+          let endDate = aEvent[cal.calGetEndDateProp(aEvent)];
           if ((startDate && startDate.isDate) ||
               (endDate && endDate.isDate)) {
               // If this is an all day event, then the header with allday
               // events could possibly get a scrollbar. Readjust them.
               this.adjustScrollBarSpacers();
           }
         ]]></body>
       </method>
--- a/calendar/base/content/calendar-statusbar.js
+++ b/calendar/base/content/calendar-statusbar.js
@@ -1,13 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 /* exported gCalendarStatusFeedback */
 
 /**
  * This code might change soon if we support Thunderbird's activity manager.
  * NOTE: The naming "Meteors" is historical.
  */
 var gCalendarStatusFeedback = {
@@ -57,17 +58,17 @@ var gCalendarStatusFeedback = {
                 this.mCalendarStep = Math.trunc(100 / this.mCalendarCount);
             }
             this.mProgressMode = aProgressMode;
             this.mStatusProgressPanel.removeAttribute("collapsed");
             if (this.mProgressMode == Components.interfaces.calIStatusObserver.DETERMINED_PROGRESS) {
                 this.mStatusBar.removeAttribute("collapsed");
                 this.mStatusBar.setAttribute("mode", "determined");
                 this.mStatusBar.value = 0;
-                let commonStatus = calGetString("calendar", "gettingCalendarInfoCommon");
+                let commonStatus = cal.calGetString("calendar", "gettingCalendarInfoCommon");
                 this.showStatusString(commonStatus);
             }
             if (this.mThrobber) {
                 this.mThrobber.setAttribute("busy", true);
             }
         }
     },
 
@@ -93,18 +94,18 @@ var gCalendarStatusFeedback = {
             return;
         }
         if (this.spinning != Components.interfaces.calIStatusObserver.NO_PROGRESS) {
             if (this.spinning == Components.interfaces.calIStatusObserver.DETERMINED_PROGRESS) {
                 if (!this.mCalendars[aCalendar.id] || this.mCalendars[aCalendar.id] === undefined) {
                     this.mCalendars[aCalendar.id] = true;
                     this.mStatusBar.value = parseInt(this.mStatusBar.value, 10) + this.mCalendarStep;
                     this.mCurIndex++;
-                    let curStatus = calGetString("calendar", "gettingCalendarInfoDetail",
-                                                 [this.mCurIndex, this.mCalendarCount]);
+                    let curStatus = cal.calGetString("calendar", "gettingCalendarInfoDetail",
+                                                     [this.mCurIndex, this.mCalendarCount]);
                     this.showStatusString(curStatus);
                 }
             }
             if (this.mThrobber) {
                 this.mThrobber.setAttribute("busy", true);
             }
         }
     }
--- a/calendar/base/content/calendar-task-editing.js
+++ b/calendar/base/content/calendar-task-editing.js
@@ -68,24 +68,24 @@ var taskEdit = {
         }
 
         let calendar = getSelectedCalendar();
         edit.showsInstructions = true;
 
         if (calendar.getProperty("capabilities.tasks.supported") === false) {
             taskEdit.setupTaskField(edit,
                                     true,
-                                    calGetString("calendar", "taskEditInstructionsCapability"));
-        } else if (isCalendarWritable(calendar)) {
+                                    cal.calGetString("calendar", "taskEditInstructionsCapability"));
+        } else if (cal.isCalendarWritable(calendar)) {
             edit.showsInstructions = false;
             taskEdit.setupTaskField(edit, false, edit.savedValue || "");
         } else {
             taskEdit.setupTaskField(edit,
                                     true,
-                                    calGetString("calendar", "taskEditInstructionsReadonly"));
+                                    cal.calGetString("calendar", "taskEditInstructionsReadonly"));
         }
     },
 
     /**
      * Handler function to call when the quick-add textbox loses focus.
      *
      * @param aEvent    The DOM blur event
      */
@@ -102,28 +102,28 @@ var taskEdit = {
         if (!calendar) {
             // this must be a first run, we don't have a calendar yet
             return;
         }
 
         if (calendar.getProperty("capabilities.tasks.supported") === false) {
             taskEdit.setupTaskField(edit,
                                     true,
-                                    calGetString("calendar", "taskEditInstructionsCapability"));
-        } else if (isCalendarWritable(calendar)) {
+                                    cal.calGetString("calendar", "taskEditInstructionsCapability"));
+        } else if (cal.isCalendarWritable(calendar)) {
             if (!edit.showsInstructions) {
                 edit.savedValue = edit.value || "";
             }
             taskEdit.setupTaskField(edit,
                                     false,
-                                    calGetString("calendar", "taskEditInstructions"));
+                                    cal.calGetString("calendar", "taskEditInstructions"));
         } else {
             taskEdit.setupTaskField(edit,
                                     true,
-                                    calGetString("calendar", "taskEditInstructionsReadonly"));
+                                    cal.calGetString("calendar", "taskEditInstructionsReadonly"));
         }
         edit.showsInstructions = true;
     },
 
     /**
      * Handler function to call on keypress for the quick-add textbox.
      *
      * @param aEvent    The DOM keypress event
--- a/calendar/base/content/calendar-task-tree.js
+++ b/calendar/base/content/calendar-task-tree.js
@@ -3,16 +3,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* exported addCalendarNames, calendars, changeContextMenuForTask,
  *          contextChangeTaskCalendar, contextChangeTaskPriority,
  *          contextPostponeTask, modifyTaskFromContext, deleteToDoCommand,
  *          tasksToMail, tasksToEvents, toggleCompleted,
  */
 
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
 /**
  * Add registered calendars to the given menupopup. Removes all previous
  * children.
  *
  * XXX Either replace the existing items using replaceNode, or use helper
  * functions (cal.removeChildren).
  *
  * @param aEvent    The popupshowing event of the opening menu
@@ -21,17 +23,17 @@ function addCalendarNames(aEvent) {
     let calendarMenuPopup = aEvent.target;
     while (calendarMenuPopup.hasChildNodes()) {
         calendarMenuPopup.lastChild.remove();
     }
     let tasks = getSelectedTasks(aEvent);
     let tasksSelected = (tasks.length > 0);
     if (tasksSelected) {
         let selIndex = appendCalendarItems(tasks[0], calendarMenuPopup, null, "contextChangeTaskCalendar(event);");
-        if (isPropertyValueSame(tasks, "calendar") && (selIndex > -1)) {
+        if (cal.isPropertyValueSame(tasks, "calendar") && (selIndex > -1)) {
             calendarMenuPopup.childNodes[selIndex].setAttribute("checked", "true");
         }
     }
 }
 
 /**
  * Change the opening context menu for the selected tasks.
  *
@@ -51,34 +53,34 @@ function changeContextMenuForTask(aEvent
     document.getElementById("task-context-menu-modify-todaypane").hidden =
         (idnode == "calendar-task-tree");
     document.getElementById("task-context-menu-filter-todaypane").hidden =
         (idnode == "calendar-task-tree");
     document.getElementById("task-context-menu-separator-filter").hidden =
         (idnode == "calendar-task-tree");
 
     let tasksSelected = (items.length > 0);
-    applyAttributeToMenuChildren(aEvent.target, "disabled", (!tasksSelected));
+    cal.applyAttributeToMenuChildren(aEvent.target, "disabled", !tasksSelected);
     if (calendarController.isCommandEnabled("calendar_new_todo_command") &&
         calendarController.isCommandEnabled("calendar_new_todo_todaypane_command")) {
         document.getElementById("calendar_new_todo_command").removeAttribute("disabled");
         document.getElementById("calendar_new_todo_todaypane_command").removeAttribute("disabled");
     } else {
         document.getElementById("calendar_new_todo_command").setAttribute("disabled", "true");
         document.getElementById("calendar_new_todo_todaypane_command").setAttribute("disabled", "true");
     }
 
     // make sure the "Paste" and "Cut" menu items are enabled
     goUpdateCommand("cmd_paste");
     goUpdateCommand("cmd_cut");
 
     // make sure the filter menu is enabled
     document.getElementById("task-context-menu-filter-todaypane").removeAttribute("disabled");
-    applyAttributeToMenuChildren(document.getElementById("task-context-menu-filter-todaypane-popup"),
-                                 "disabled", false);
+    cal.applyAttributeToMenuChildren(document.getElementById("task-context-menu-filter-todaypane-popup"),
+                                     "disabled", false);
 
     changeMenuForTask(aEvent);
 
     let menu = document.getElementById("task-context-menu-attendance-menu");
     setupAttendanceMenu(menu, items);
 }
 
 /**
@@ -106,17 +108,17 @@ function changeMenuForTask(aEvent) {
      "calendar_general-progress_command",
      "calendar_general-priority_command",
      "calendar_general-postpone_command"].forEach(goUpdateCommand);
 
     let tasks = getSelectedTasks(aEvent);
     let tasksSelected = (tasks.length > 0);
     if (tasksSelected) {
         let cmd = document.getElementById("calendar_toggle_completed_command");
-        if (isPropertyValueSame(tasks, "isCompleted")) {
+        if (cal.isPropertyValueSame(tasks, "isCompleted")) {
             setBooleanAttribute(cmd, "checked", tasks[0].isCompleted);
         } else {
             setBooleanAttribute(cmd, "checked", false);
         }
     }
 }
 
 /**
--- a/calendar/base/content/calendar-task-tree.xml
+++ b/calendar/base/content/calendar-task-tree.xml
@@ -111,16 +111,17 @@
         <xul:treechildren tooltip="taskTreeTooltip" ondblclick="mTreeView.onDoubleClick(event)"/>
       </xul:tree>
     </content>
 
     <implementation implements="nsIObserver">
       <constructor><![CDATA[
         Components.utils.import("resource://gre/modules/PluralForm.jsm");
         Components.utils.import("resource://gre/modules/Services.jsm");
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
         Components.utils.import("resource://calendar/modules/calItemUtils.jsm");
         Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
         // set up the tree filter
         this.mFilter = new calFilter();
 
         // set up the custom tree view
         let tree = document.getAnonymousElementByAttribute(this, "anonid", "calendar-task-tree");
@@ -289,37 +290,37 @@
       <method name="duration">
         <parameter name="aTask"/>
         <body><![CDATA[
           if (aTask && aTask.dueDate && aTask.dueDate.isValid) {
               let dur = aTask.dueDate.subtractDate(cal.now());
               if (!dur.isNegative) {
                   let minutes = Math.ceil(dur.inSeconds / 60);
                   if (minutes >= 1440) { // 1 day or more
-                      let dueIn = PluralForm.get(dur.days, calGetString("calendar", "dueInDays"));
+                      let dueIn = PluralForm.get(dur.days, cal.calGetString("calendar", "dueInDays"));
                       return dueIn.replace("#1", dur.days);
                   } else if (minutes >= 60) { // 1 hour or more
-                      let dueIn = PluralForm.get(dur.hours, calGetString("calendar", "dueInHours"));
+                      let dueIn = PluralForm.get(dur.hours, cal.calGetString("calendar", "dueInHours"));
                       return dueIn.replace("#1", dur.hours);
                   } else {
                       // Less than one hour
-                      return calGetString("calendar", "dueInLessThanOneHour");
+                      return cal.calGetString("calendar", "dueInLessThanOneHour");
                   }
               } else if (!aTask.completedDate || !aTask.completedDate.isValid) {
                   // Overdue task
                   let minutes = Math.ceil(-dur.inSeconds / 60);
                   if (minutes >= 1440) { // 1 day or more
-                      let dueIn = PluralForm.get(dur.days, calGetString("calendar", "dueInDays"));
+                      let dueIn = PluralForm.get(dur.days, cal.calGetString("calendar", "dueInDays"));
                       return "-" + dueIn.replace("#1", dur.days);
                   } else if (minutes >= 60) { // 1 hour or more
-                      let dueIn = PluralForm.get(dur.hours, calGetString("calendar", "dueInHours"));
+                      let dueIn = PluralForm.get(dur.hours, cal.calGetString("calendar", "dueInHours"));
                       return "-" + dueIn.replace("#1", dur.hours);
                   } else {
                       // Less than one hour
-                      return calGetString("calendar", "dueInLessThanOneHour");
+                      return cal.calGetString("calendar", "dueInLessThanOneHour");
                   }
               }
           }
           // No due date specified
           return null;
         ]]></body>
       </method>
       <method name="getTaskAtRow">
@@ -509,35 +510,35 @@
           getRowProperties: function(aRow) {
               let properties = [];
               let item = this.binding.mTaskArray[aRow];
               if (item.priority > 0 && item.priority < 5) {
                   properties.push("highpriority");
               } else if (item.priority > 5 && item.priority < 10) {
                   properties.push("lowpriority");
               }
-              properties.push(getProgressAtom(item));
+              properties.push(cal.getProgressAtom(item));
 
               // Add calendar name and id atom
-              properties.push("calendar-" + formatStringForCSSRule(item.calendar.name));
-              properties.push("calendarid-" + formatStringForCSSRule(item.calendar.id));
+              properties.push("calendar-" + cal.formatStringForCSSRule(item.calendar.name));
+              properties.push("calendarid-" + cal.formatStringForCSSRule(item.calendar.id));
 
               // Add item status atom
               if (item.status) {
                   properties.push("status-" + item.status.toLowerCase());
               }
 
               // Alarm status atom
               if (item.getAlarms({}).length) {
                   properties.push("alarm");
               }
 
               // Task categories
               properties = properties.concat(item.getCategories({})
-                                                 .map(formatStringForCSSRule));
+                                                 .map(cal.formatStringForCSSRule));
 
               return properties.join(" ");
           },
 
           // Called on the view when a cell in a non-selectable cycling
           // column (e.g., unread/flag/etc.) is clicked.
           cycleCell: function(aRow, aCol) {
               let task = this.binding.mTaskArray[aRow];
@@ -584,23 +585,23 @@
               let task = this.binding.mTaskArray[aRow];
               if (!task) {
                   return false;
               }
 
               switch (aCol.element.getAttribute("itemproperty")) {
                   case "title":
                       // return title, or "Untitled" if empty/null
-                      return (task.title ? task.title.replace(/\n/g, " ") : calGetString("calendar", "eventUntitled"));
+                      return (task.title ? task.title.replace(/\n/g, " ") : cal.calGetString("calendar", "eventUntitled"));
                   case "entryDate":
-                      return task.recurrenceInfo ? calGetString("dateFormat", "Repeating") : this._formatDateTime(task.entryDate);
+                      return task.recurrenceInfo ? cal.calGetString("dateFormat", "Repeating") : this._formatDateTime(task.entryDate);
                   case "dueDate":
-                      return task.recurrenceInfo ? calGetString("dateFormat", "Repeating") : this._formatDateTime(task.dueDate);
+                      return task.recurrenceInfo ? cal.calGetString("dateFormat", "Repeating") : this._formatDateTime(task.dueDate);
                   case "completedDate":
-                      return task.recurrenceInfo ? calGetString("dateFormat", "Repeating") : this._formatDateTime(task.completedDate);
+                      return task.recurrenceInfo ? cal.calGetString("dateFormat", "Repeating") : this._formatDateTime(task.completedDate);
                   case "percentComplete":
                       return (task.percentComplete > 0 ? task.percentComplete + "%" : "");
                   case "categories":
                       return task.getCategories({}).join(", "); // TODO l10n-unfriendly
                   case "location":
                       return task.getProperty("LOCATION");
                   case "status":
                       return getToDoStatusString(task);
@@ -723,17 +724,17 @@
 
           /**
            * Task Tree Events
            */
           onSelect: function(event) {},
 
           onDoubleClick: function(event) {
               if (event.button == 0) {
-                  let initialDate = getDefaultStartDate(this.binding.getInitialDate());
+                  let initialDate = cal.getDefaultStartDate(this.binding.getInitialDate());
                   let col = {};
                   let item = this._getItemFromEvent(event, col);
                   if (item) {
                       let colAnonId = col.value.element.getAttribute("itemproperty");
                       if (colAnonId == "completed") {
                           // item holds checkbox state toggled by first click,
                           // so don't call modifyEventWithDialog
                           // to make sure user notices state changed.
@@ -803,17 +804,17 @@
 
           // Helper function to display datetimes
           _formatDateTime: function(aDateTime) {
               let dateFormatter = Components.classes["@mozilla.org/calendar/datetime-formatter;1"]
                                             .getService(Components.interfaces.calIDateTimeFormatter);
 
               // datetime is from todo object, it is not a javascript date
               if (aDateTime && aDateTime.isValid) {
-                  let dateTime = aDateTime.getInTimezone(calendarDefaultTimezone());
+                  let dateTime = aDateTime.getInTimezone(cal.calendarDefaultTimezone());
                   return dateFormatter.formatDateTime(dateTime);
               }
               return "";
           }
       })
       ]]></field>
 
       <!--
@@ -1012,17 +1013,17 @@
               let modifier = (this.mTreeView.sortDirection == "descending" ? -1 : 1);
               let column = this.mTreeView.selectedColumn;
               cal.sortEntry.mSortKey = column.getAttribute("sortKey")
                                        ? column.getAttribute("sortKey")
                                        : column.getAttribute("itemproperty");
               let sortType = cal.getSortTypeForSortKey(cal.sortEntry.mSortKey);
 
               // sort (key,item) entries
-              cal.sortEntry.mSortStartedDate = now();
+              cal.sortEntry.mSortStartedDate = cal.now();
               let entries = this.mTaskArray.map(cal.sortEntry, cal.sortEntry);
               entries.sort(cal.sortEntryComparer(sortType, modifier));
               this.mTaskArray = entries.map(cal.sortEntryItem);
           }
 
           this.recreateHashTable();
         ]]></body>
       </method>
@@ -1038,17 +1039,17 @@
               this.mTreeView.treebox.invalidate();
           }
         ]]></body>
       </method>
 
       <method name="getInitialDate">
         <body><![CDATA[
           let initialDate = currentView().selectedDay;
-          return initialDate ? initialDate : now();
+          return initialDate ? initialDate : cal.now();
         ]]></body>
       </method>
 
       <method name="doUpdateFilter">
         <parameter name="aFilter"/>
         <body><![CDATA[
           let needsRefresh = false;
           let oldStart = this.mFilter.mStartDate;
@@ -1163,36 +1164,41 @@
                 rowY = rowY + rowHeight;
             }
 
             // and finally, clip the result to be sure we don't spill over...
             if (!region.isEmpty()) {
                 region.intersectRect(bodyBox.x, bodyBox.y, bodyBox.width, bodyBox.height);
             }
         } catch (ex) {
-            ASSERT(false, "Error while building selection region: " + ex + "\n");
+            cal.ASSERT(false, "Error while building selection region: " + ex + "\n");
             region = null;
         }
         invokeEventDragSession(item, event.target);
       ]]></handler>
     </handlers>
 
   </binding>
 
   <binding id="calendar-task-tree-todaypane" extends="chrome://calendar/content/calendar-task-tree.xml#calendar-task-tree">
     <implementation>
+      <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+      ]]></constructor>
+
       <method name="getInitialDate">
         <body><![CDATA[
-          let initialDate = agendaListbox.today ? agendaListbox.today.start : now();
-          return initialDate ? initialDate : now();
+          let initialDate = agendaListbox.today ? agendaListbox.today.start : cal.now();
+          return initialDate ? initialDate : cal.now();
         ]]></body>
       </method>
+
       <method name="updateFilter">
         <parameter name="aFilter"/>
         <body><![CDATA[
           this.mFilter.selectedDate = agendaListbox.today && agendaListbox.today.start ?
-                                      agendaListbox.today.start : now();
+                                      agendaListbox.today.start : cal.now();
           this.doUpdateFilter(aFilter);
         ]]></body>
       </method>
     </implementation>
   </binding>
 </bindings>
--- a/calendar/base/content/calendar-task-view.js
+++ b/calendar/base/content/calendar-task-view.js
@@ -1,14 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* exported taskDetailsView, sendMailToOrganizer, taskViewCopyLink */
 
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calRecurrenceUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/AppConstants.jsm");
 
 var taskDetailsView = {
 
     /**
      * Task Details Events
@@ -60,45 +61,45 @@ var taskDetailsView = {
             displayElement("calendar-task-details-priority-normal", priority == 5);
             displayElement("calendar-task-details-priority-high", priority >= 1 && priority <= 4);
 
             let status = item.getProperty("STATUS");
             if (displayElement("calendar-task-details-status-row", status && status.length > 0)) {
                 let statusDetails = document.getElementById("calendar-task-details-status");
                 switch (status) {
                     case "NEEDS-ACTION": {
-                        statusDetails.value = calGetString(
+                        statusDetails.value = cal.calGetString(
                             "calendar",
                             "taskDetailsStatusNeedsAction");
                         break;
                     }
                     case "IN-PROCESS": {
                         let percent = 0;
                         let property = item.getProperty("PERCENT-COMPLETE");
                         if (property != null) {
                             percent = parseInt(property, 10);
                         }
-                        statusDetails.value = calGetString(
+                        statusDetails.value = cal.calGetString(
                             "calendar",
                             "taskDetailsStatusInProgress", [percent]);
                         break;
                     }
                     case "COMPLETED": {
                         if (item.completedDate) {
                             let completedDate = item.completedDate.getInTimezone(
-                                                    calendarDefaultTimezone());
-                            statusDetails.value = calGetString(
+                                                    cal.calendarDefaultTimezone());
+                            statusDetails.value = cal.calGetString(
                                 "calendar",
                                 "taskDetailsStatusCompletedOn",
                                 [dateFormatter.formatDateTime(completedDate)]);
                         }
                         break;
                     }
                     case "CANCELLED": {
-                        statusDetails.value = calGetString(
+                        statusDetails.value = cal.calGetString(
                             "calendar",
                             "taskDetailsStatusCancelled");
                         break;
                     }
                     default: {
                         displayElement("calendar-task-details-status-row", false);
                         break;
                     }
@@ -113,17 +114,17 @@ var taskDetailsView = {
             let parentItem = item;
             if (parentItem.parentItem != parentItem) {
                 // XXXdbo Didn't we want to get rid of these checks?
                 parentItem = parentItem.parentItem;
             }
             let recurrenceInfo = parentItem.recurrenceInfo;
             let recurStart = parentItem.recurrenceStartDate;
             if (displayElement("calendar-task-details-repeat-row", recurrenceInfo && recurStart)) {
-                let kDefaultTimezone = calendarDefaultTimezone();
+                let kDefaultTimezone = cal.calendarDefaultTimezone();
                 let startDate = recurStart.getInTimezone(kDefaultTimezone);
                 let endDate = item.dueDate ? item.dueDate.getInTimezone(kDefaultTimezone) : null;
                 let detailsString = recurrenceRule2String(recurrenceInfo, startDate, endDate, startDate.isDate);
                 if (detailsString) {
                     let rpv = document.getElementById("calendar-task-details-repeat");
                     rpv.value = detailsString.split("\n").join(" ");
                 }
             }
@@ -218,17 +219,17 @@ function taskViewUpdate(aFilter) {
  */
 function sendMailToOrganizer() {
     let item = document.getElementById("calendar-task-tree").currentTask;
     if (item != null) {
         let organizer = item.organizer;
         let email = cal.getAttendeeEmail(organizer, true);
         let emailSubject = cal.calGetString("calendar-event-dialog", "emailSubjectReply", [item.title]);
         let identity = item.calendar.getProperty("imip.identity");
-        sendMailTo(email, emailSubject, null, identity);
+        cal.sendMailTo(email, emailSubject, null, identity);
     }
 }
 
 /**
  * Handler function to observe changing of the calendar display deck. Updates
  * the task tree if the task view was selected.
  *
  * TODO Consolidate this function and anything connected, its still from times
--- a/calendar/base/content/calendar-ui-utils.js
+++ b/calendar/base/content/calendar-ui-utils.js
@@ -287,20 +287,20 @@ function appendCalendarItems(aItem, aCal
     let calendarToUse = aCalendarToUse || aItem.calendar;
     let calendars = sortCalendarArray(cal.getCalendarManager().getCalendars({}));
     let indexToSelect = 0;
     let index = -1;
     for (let i = 0; i < calendars.length; ++i) {
         let calendar = calendars[i];
         if (calendar.id == calendarToUse.id ||
             (calendar &&
-             isCalendarWritable(calendar) &&
-             (userCanAddItemsToCalendar(calendar) ||
-              (calendar == aItem.calendar && userCanModifyItem(aItem))) &&
-             isItemSupported(aItem, calendar))) {
+             cal.isCalendarWritable(calendar) &&
+             (cal.userCanAddItemsToCalendar(calendar) ||
+              (calendar == aItem.calendar && cal.userCanModifyItem(aItem))) &&
+             cal.isItemSupported(aItem, calendar))) {
             let menuitem = addMenuItem(aCalendarMenuParent, calendar.name, calendar.name);
             menuitem.calendar = calendar;
             index++;
             if (aOnCommand) {
                 menuitem.setAttribute("oncommand", aOnCommand);
             }
             if (aCalendarMenuParent.localName == "menupopup") {
                 menuitem.setAttribute("type", "checkbox");
--- a/calendar/base/content/calendar-unifinder.js
+++ b/calendar/base/content/calendar-unifinder.js
@@ -77,31 +77,31 @@ var unifinderObserver = {
             // those operations and refresh as soon as the unifinder is shown
             // again.
             gUnifinderNeedsRefresh = true;
             unifinderTreeView.clearItems();
         }
     },
 
     onAddItem: function(aItem) {
-        if (isEvent(aItem) &&
+        if (cal.isEvent(aItem) &&
             !gUnifinderNeedsRefresh &&
             unifinderTreeView.mFilter.isItemInFilters(aItem)
             ) {
             this.addItemToTree(aItem);
         }
     },
 
     onModifyItem: function(aNewItem, aOldItem) {
         this.onDeleteItem(aOldItem);
         this.onAddItem(aNewItem);
     },
 
     onDeleteItem: function(aDeletedItem) {
-        if (isEvent(aDeletedItem) && !gUnifinderNeedsRefresh) {
+        if (cal.isEvent(aDeletedItem) && !gUnifinderNeedsRefresh) {
             this.removeItemFromTree(aDeletedItem);
         }
     },
 
     onError: function(aCalendar, aErrNo, aMessage) {},
 
     onPropertyChanged: function(aCalendar, aName, aValue, aOldValue) {
         switch (aName) {
@@ -193,17 +193,17 @@ function prepareCalendarUnifinder() {
     branch.addObserver("calendar.", unifinderObserver, false);
 
     // Check if this is not the hidden window, which has no UI elements
     if (unifinderTree) {
         // set up our calendar event observer
         let ccalendar = cal.getCompositeCalendar(window);
         ccalendar.addObserver(unifinderObserver);
 
-        kDefaultTimezone = calendarDefaultTimezone();
+        kDefaultTimezone = cal.calendarDefaultTimezone();
 
         // Set up the filter
         unifinderTreeView.mFilter = new calFilter();
 
         // Set up the unifinder views.
         unifinderTreeView.treeElement = unifinderTree;
         unifinderTree.view = unifinderTreeView;
 
@@ -338,17 +338,17 @@ function unifinderSelect(event) {
 
     for (let range = 0; range < numRanges; range++) {
         tree.view.selection.getRangeAt(range, start, end);
 
         for (let i = start.value; i <= end.value; i++) {
             try {
                 selectedItems.push(unifinderTreeView.getItemAt(i));
             } catch (e) {
-                WARN("Error getting Event from row: " + e + "\n");
+                cal.WARN("Error getting Event from row: " + e + "\n");
             }
         }
     }
 
     if (selectedItems.length == 1) {
         // Go to the day of the selected item in the current view.
         currentView().goToDay(selectedItems[0].startDate);
     }
@@ -548,17 +548,17 @@ var unifinderTreeView = {
      */
     sortItems: function() {
         if (this.selectedColumn) {
             let modifier = (this.sortDirection == "descending" ? -1 : 1);
             let sortKey = unifinderTreeView.selectedColumn.getAttribute("itemproperty");
             let sortType = cal.getSortTypeForSortKey(sortKey);
             // sort (key,item) entries
             cal.sortEntry.mSortKey = sortKey;
-            cal.sortEntry.mSortStartedDate = now();
+            cal.sortEntry.mSortStartedDate = cal.now();
             let entries = this.eventArray.map(cal.sortEntry, cal.sortEntry);
             entries.sort(cal.sortEntryComparer(sortType, modifier));
             this.eventArray = entries.map(cal.sortEntryItem);
         }
         this.calculateIndexMap();
     },
 
     /**
@@ -688,31 +688,31 @@ var unifinderTreeView = {
         let item = this.eventArray[aRow];
         if (item.priority > 0 && item.priority < 5) {
             properties.push("highpriority");
         } else if (item.priority > 5 && item.priority < 10) {
             properties.push("lowpriority");
         }
 
         // Add calendar name atom
-        properties.push("calendar-" + formatStringForCSSRule(item.calendar.name));
+        properties.push("calendar-" + cal.formatStringForCSSRule(item.calendar.name));
 
         // Add item status atom
         if (item.status) {
             properties.push("status-" + item.status.toLowerCase());
         }
 
         // Alarm status atom
         if (item.getAlarms({}).length) {
             properties.push("alarm");
         }
 
         // Task categories
         properties = properties.concat(item.getCategories({})
-                                           .map(formatStringForCSSRule));
+                                           .map(cal.formatStringForCSSRule));
 
         return properties.join(" ");
     },
     getColumnProperties: function(aCol) { return ""; },
 
     isContainer: function() {
         return false;
     },
--- a/calendar/base/content/calendar-view-core.xml
+++ b/calendar/base/content/calendar-view-core.xml
@@ -1,15 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
-<!-- Note that this file depends on helper functions in calUtils.js-->
-
 <bindings id="calendar-core-view-bindings"
           xmlns="http://www.mozilla.org/xbl"
           xmlns:html="http://www.w3.org/1999/xhtml"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
           xmlns:xbl="http://www.mozilla.org/xbl">
 
   <binding id="calendar-editable-item">
     <content mousethrough="never"
@@ -157,17 +155,17 @@
 
       <method name="setCSSClasses">
         <body><![CDATA[
           let item = this.mOccurrence;
           this.setAttribute("calendar-uri", item.calendar.uri.spec);
           this.setAttribute("calendar-id", item.calendar.id);
           let categoriesArray = item.getCategories({});
           if (categoriesArray.length > 0) {
-              let cssClassesArray = categoriesArray.map(formatStringForCSSRule);
+              let cssClassesArray = categoriesArray.map(cal.formatStringForCSSRule);
               this.setAttribute("categories", cssClassesArray.join(" "));
           }
 
           // Add alarm icons as needed.
           let alarms = item.getAlarms({});
           if (alarms.length && Preferences.get("calendar.alarms.indicator.show", true)) {
               let iconsBox = document.getAnonymousElementByAttribute(this, "anonid", "alarm-icons-box");
               cal.alarms.addReminderImages(iconsBox, alarms);
@@ -191,17 +189,17 @@
           // Event type specific properties
           if (cal.isEvent(item)) {
               if (item.startDate.isDate) {
                   this.setAttribute("allday", "true");
               }
               this.setAttribute("itemType", "event");
           } else if (cal.isToDo(item)) {
               // progress attribute
-              this.setAttribute("progress", getProgressAtom(item));
+              this.setAttribute("progress", cal.getProgressAtom(item));
               // Attribute for tasks and tasks image.
               this.setAttribute("itemType", "todo");
               if (item.entryDate && !item.dueDate) {
                   this.setAttribute("todoType", "start");
               } else if (!item.entryDate && item.dueDate) {
                   this.setAttribute("todoType", "end");
               }
           }
@@ -234,17 +232,17 @@
 
           // calendar name
           this.setAttribute("calendar", item.calendar.name.toLowerCase());
 
           // Invitation
           if (cal.isInvitation(item)) {
               this.setAttribute("invitation-status", cal.getInvitedAttendee(item).participationStatus);
               this.setAttribute("readonly", "true");
-          } else if (!isCalendarWritable(item.calendar)) {
+          } else if (!cal.isCalendarWritable(item.calendar)) {
               this.setAttribute("readonly", "true");
           }
         ]]></body>
       </method>
 
       <method name="startEditing">
         <body><![CDATA[
           this.editingTimer = null;
@@ -319,17 +317,17 @@
         }
 
         // If the left button was used and the item is already selected
         // and there are no multiple items selected start
         // the 'single click edit' timeout. Otherwise select the item too.
         // Also, check if the calendar is readOnly or we are offline.
 
         if (this.selected && !(event.ctrlKey || event.metaKey) &&
-              isCalendarWritable(this.mOccurrence.calendar)) {
+              cal.isCalendarWritable(this.mOccurrence.calendar)) {
             if (this.editingTimer) {
                 clearTimeout(this.editingTimer);
             }
             this.editingTimer = setTimeout(() => this.startEditing(), 350);
         } else {
             this.select(event);
             event.stopPropagation();
         }
@@ -356,17 +354,17 @@
         }
       ]]></handler>
       <handler event="dragstart"><![CDATA[
         if (event.target.localName == "calendar-event-box") {
             return;
         }
         let item = this.occurrence;
         let isInvitation = item.calendar instanceof Components.interfaces.calISchedulingSupport && item.calendar.isInvitation(item);
-        if (!isCalendarWritable(item.calendar) || !userCanModifyItem(item) || isInvitation) {
+        if (!cal.isCalendarWritable(item.calendar) || !cal.userCanModifyItem(item) || isInvitation) {
             return;
         }
         if (!this.selected) {
             this.select(event);
         }
         invokeEventDragSession(item, this);
       ]]></handler>
     </handlers>
--- a/calendar/base/content/calendar-views.js
+++ b/calendar/base/content/calendar-views.js
@@ -33,17 +33,17 @@ var calendarViewController = {
      * Creates a new event
      * @see calICalendarViewController
      */
     createNewEvent: function(aCalendar, aStartTime, aEndTime, aForceAllday) {
         // if we're given both times, skip the dialog
         if (aStartTime && aEndTime && !aStartTime.isDate && !aEndTime.isDate) {
             let item = cal.createEvent();
             setDefaultItemValues(item, aCalendar, aStartTime, aEndTime);
-            item.title = calGetString("calendar", "newEvent");
+            item.title = cal.calGetString("calendar", "newEvent");
             doTransaction("add", item, item.calendar, null, null);
         } else {
             createEventWithDialog(aCalendar, aStartTime, null, null, null, aForceAllday);
         }
     },
 
     /**
      * Modifies the given occurrence
@@ -62,17 +62,17 @@ var calendarViewController = {
             // When we made the executive decision (in bug 352862) that
             // dragging an occurrence of a recurring event would _only_ act
             // upon _that_ occurrence, we removed a bunch of code from this
             // function. If we ever revert that decision, check CVS history
             // here to get that code back.
 
             if (aNewStartTime || aNewEndTime) {
                 // Yay for variable names that make this next line look silly
-                if (isEvent(instance)) {
+                if (cal.isEvent(instance)) {
                     if (aNewStartTime && instance.startDate) {
                         instance.startDate = aNewStartTime;
                     }
                     if (aNewEndTime && instance.endDate) {
                         instance.endDate = aNewEndTime;
                     }
                 } else {
                     if (aNewStartTime && instance.entryDate) {
@@ -115,17 +115,17 @@ var calendarViewController = {
         };
 
         // Make sure we are modifying a copy of aOccurrences, otherwise we will
         // run into race conditions when the view's doDeleteItem removes the
         // array elements while we are iterating through them. While we are at
         // it, filter out any items that have readonly calendars, so that
         // checking for one total item below also works out if all but one item
         // are readonly.
-        let occurrences = aOccurrences.filter(item => isCalendarWritable(item.calendar));
+        let occurrences = aOccurrences.filter(item => cal.isCalendarWritable(item.calendar));
 
         for (let itemToDelete of occurrences) {
             if (aUseParentItems) {
                 // Usually happens when ctrl-click is used. In that case we
                 // don't need to ask the user if he wants to delete an
                 // occurrence or not.
                 itemToDelete = itemToDelete.parentItem;
             } else if (!aDoNotConfirm && occurrences.length == 1) {
@@ -228,35 +228,35 @@ function switchToView(aViewType) {
      "today-view-button",
      "next-view-button"].forEach(x => setupViewNode(x, "tooltiptext"));
 
     try {
         selectedDay = viewDeck.selectedPanel.selectedDay;
         currentSelection = viewDeck.selectedPanel.getSelectedItems({});
     } catch (ex) {
         // This dies if no view has even been chosen this session, but that's
-        // ok because we'll just use now() below.
+        // ok because we'll just use cal.now() below.
     }
 
     if (!selectedDay) {
-        selectedDay = now();
+        selectedDay = cal.now();
     }
 
     // Anyone wanting to plug in a view needs to follow this naming scheme
     let view = document.getElementById(aViewType + "-view");
     viewDeck.selectedPanel = view;
 
     // Select the corresponding tab
     let viewTabs = document.getElementById("view-tabs");
     viewTabs.selectedIndex = getViewDeck().selectedIndex;
 
     let compositeCal = cal.getCompositeCalendar(window);
     if (view.displayCalendar != compositeCal) {
         view.displayCalendar = compositeCal;
-        view.timezone = calendarDefaultTimezone();
+        view.timezone = cal.calendarDefaultTimezone();
         view.controller = calendarViewController;
     }
 
     view.goToDay(selectedDay);
     view.setSelectedItems(currentSelection.length, currentSelection);
 
     onCalendarViewResize();
 }
@@ -407,17 +407,17 @@ var categoryManagement = {
     initCategories: function() {
         categoryPrefBranch = Services.prefs.getBranch("calendar.category.color.");
         let categories = categoryPrefBranch.getChildList("");
 
         // Fix illegally formatted category prefs.
         for (let i in categories) {
             let category = categories[i];
             if (category.search(/[^_0-9a-z-]/) != -1) {
-                let categoryFix = formatStringForCSSRule(category);
+                let categoryFix = cal.formatStringForCSSRule(category);
                 if (categoryPrefBranch.prefHasUserValue(categoryFix)) {
                     categories.splice(i, 1); // remove illegal name
                 } else {
                     let color = categoryPrefBranch.getCharPref(category);
                     categoryPrefBranch.setCharPref(categoryFix, color);
                     categoryPrefBranch.clearUserPref(category); // not usable
                     categories[i] = categoryFix;  // replace illegal name
                 }
@@ -673,37 +673,37 @@ function selectAllEvents() {
 }
 
 var cal = cal || {};
 cal.navigationBar = {
     setDateRange: function(aStartDate, aEndDate) {
         let docTitle = "";
         if (aStartDate) {
             let intervalLabel = document.getElementById("intervalDescription");
-            let firstWeekNo = getWeekInfoService().getWeekTitle(aStartDate);
+            let firstWeekNo = cal.getWeekInfoService().getWeekTitle(aStartDate);
             let secondWeekNo = firstWeekNo;
             let weekLabel = document.getElementById("calendarWeek");
             if (aStartDate.nativeTime == aEndDate.nativeTime) {
-                intervalLabel.value = getDateFormatter().formatDate(aStartDate);
+                intervalLabel.value = cal.getDateFormatter().formatDate(aStartDate);
             } else {
                 intervalLabel.value = currentView().getRangeDescription();
-                secondWeekNo = getWeekInfoService().getWeekTitle(aEndDate);
+                secondWeekNo = cal.getWeekInfoService().getWeekTitle(aEndDate);
             }
             if (secondWeekNo == firstWeekNo) {
-                weekLabel.value = calGetString("calendar", "singleShortCalendarWeek", [firstWeekNo]);
-                weekLabel.tooltipText = calGetString("calendar", "singleLongCalendarWeek", [firstWeekNo]);
+                weekLabel.value = cal.calGetString("calendar", "singleShortCalendarWeek", [firstWeekNo]);
+                weekLabel.tooltipText = cal.calGetString("calendar", "singleLongCalendarWeek", [firstWeekNo]);
             } else {
-                weekLabel.value = calGetString("calendar", "severalShortCalendarWeeks", [firstWeekNo, secondWeekNo]);
-                weekLabel.tooltipText = calGetString("calendar", "severalLongCalendarWeeks", [firstWeekNo, secondWeekNo]);
+                weekLabel.value = cal.calGetString("calendar", "severalShortCalendarWeeks", [firstWeekNo, secondWeekNo]);
+                weekLabel.tooltipText = cal.calGetString("calendar", "severalLongCalendarWeeks", [firstWeekNo, secondWeekNo]);
             }
             docTitle = intervalLabel.value;
         }
         if (document.getElementById("modeBroadcaster").getAttribute("mode") == "calendar") {
             document.title = (docTitle ? docTitle + " - " : "") +
-                calGetString("brand", "brandFullName", null, "branding");
+                cal.calGetString("brand", "brandFullName", null, "branding");
         }
         let viewTabs = document.getElementById("view-tabs");
         viewTabs.selectedIndex = getViewDeck().selectedIndex;
     }
 };
 
 /*
  * Timer for the time indicator in day and week view.
--- a/calendar/base/content/calendar-views.xml
+++ b/calendar/base/content/calendar-views.xml
@@ -7,16 +7,19 @@
           xmlns="http://www.mozilla.org/xbl"
           xmlns:html="http://www.w3.org/1999/xhtml"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
           xmlns:xbl="http://www.mozilla.org/xbl">
 
   <binding id="calendar-day-view"
            extends="chrome://calendar/content/calendar-multiday-view.xml#calendar-multiday-view">
     <implementation implements="calICalendarView">
+      <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+      ]]></constructor>
       <property name="observerID">
         <getter><![CDATA[
           return "day-view-observer";
         ]]></getter>
       </property>
       <property name="supportsWorkdaysOnly"
                 readonly="true"
                 onget="return false;"/>
@@ -37,27 +40,29 @@
       <method name="moveView">
         <parameter name="aNumber"/>
         <body><![CDATA[
           if (aNumber) {
               let currentDay = this.startDay.clone();
               currentDay.day += aNumber;
               this.goToDay(currentDay);
           } else {
-              this.goToDay(now());
+              this.goToDay(cal.now());
           }
         ]]></body>
       </method>
     </implementation>
   </binding>
 
   <binding id="calendar-week-view"
            extends="chrome://calendar/content/calendar-multiday-view.xml#calendar-multiday-view">
     <implementation implements="calICalendarView">
       <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
         // add a listener for the mode change
         this.mModeHandler = (event) => {
             if (event.attrName == "mode") {
                 this.onModeChanged(event);
             }
         };
         document.getElementById("modeBroadcaster").addEventListener("DOMAttrModified", this.mModeHandler, true);
       ]]></constructor>
@@ -102,27 +107,28 @@
       <method name="moveView">
         <parameter name="aNumber"/>
         <body><![CDATA[
           if (aNumber) {
               let date = this.selectedDay.clone();
               date.day += 7 * aNumber;
               this.goToDay(date);
           } else {
-              this.goToDay(now());
+              this.goToDay(cal.now());
           }
         ]]></body>
       </method>
     </implementation>
   </binding>
 
   <binding id="calendar-multiweek-view" extends="chrome://calendar/content/calendar-month-view.xml#calendar-month-base-view">
     <implementation implements="calICalendarView">
       <constructor><![CDATA[
         Components.utils.import("resource://gre/modules/Preferences.jsm");
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
         this.mWeeksInView = Preferences.get("calendar.weeks.inview", 4);
       ]]></constructor>
 
       <field name="mWeeksInView">4</field>
 
       <property name="weeksInView">
         <getter><![CDATA[
           return this.mWeeksInView;
@@ -206,27 +212,31 @@
               let savedSelectedDay = this.selectedDay.clone();
               // aNumber only corresponds to the number of weeks to move
               // make sure to compensate for previous weeks in view too
               date.day += 7 * (aNumber + Preferences.get("calendar.previousweeks.inview", 4));
               this.goToDay(date);
               savedSelectedDay.day += 7 * aNumber;
               this.selectedDay = savedSelectedDay;
           } else {
-              let date = now();
+              let date = cal.now();
               this.goToDay(date);
               this.selectedDay = date;
           }
         ]]></body>
       </method>
     </implementation>
   </binding>
 
   <binding id="calendar-month-view" extends="chrome://calendar/content/calendar-month-view.xml#calendar-month-base-view">
     <implementation implements="calICalendarView">
+      <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+      ]]></constructor>
+
       <property name="observerID">
         <getter><![CDATA[
           return "month-view-observer";
         ]]></getter>
       </property>
 
       <!--Public methods-->
       <method name="goToDay">
@@ -239,17 +249,17 @@
           }
           this.showDate(aDate);
         ]]></body>
       </method>
       <method name="getRangeDescription">
         <body><![CDATA[
           let monthName = cal.formatMonth(this.rangeStartDate.month + 1,
                                           "calendar", "monthInYear");
-          return calGetString("calendar", "monthInYear", [monthName, this.rangeStartDate.year]);
+          return cal.calGetString("calendar", "monthInYear", [monthName, this.rangeStartDate.year]);
          ]]></body>
        </method>
       <method name="moveView">
         <parameter name="aNumber"/>
         <body><![CDATA[
           let dates = this.getDateList({});
           this.displayDaysOff = !this.mWorkdaysOnly;
 
@@ -273,17 +283,17 @@
               // correct for accidental rollover into the next month
               if ((newSelectedDay.month - aNumber + 12) % 12 != oldSelectedDay.month) {
                   newSelectedDay.month -= 1;
                   newSelectedDay.day = newSelectedDay.endOfMonth.day;
               }
 
               this.selectedDay = newSelectedDay;
           } else {
-              let date = now();
+              let date = cal.now();
               this.goToDay(date);
               this.selectedDay = date;
           }
         ]]></body>
       </method>
     </implementation>
   </binding>
 </bindings>
--- a/calendar/base/content/dialogs/calendar-alarm-dialog.js
+++ b/calendar/base/content/dialogs/calendar-alarm-dialog.js
@@ -225,17 +225,17 @@ function aboveSnoozeLimit(aDuration) {
 
 /**
  * Sets up the window title, counting the number of alarms in the window.
  */
 function setupTitle() {
     let alarmRichlist = document.getElementById("alarm-richlist");
     let reminders = alarmRichlist.childNodes.length;
 
-    let title = PluralForm.get(reminders, calGetString("calendar", "alarmWindowTitle.label"));
+    let title = PluralForm.get(reminders, cal.calGetString("calendar", "alarmWindowTitle.label"));
     document.title = title.replace("#1", reminders);
 }
 
 /**
  * Comparison function for the start date of a calendar item and
  * the start date of a calendar-alarm-widget.
  *
  * @param aItem                 A calendar item for the comparison of the start date property
@@ -245,18 +245,18 @@ function setupTitle() {
  *                              0 - otherwise
  */
 function widgetAlarmComptor(aItem, aWidgetItem) {
     if (aItem == null || aWidgetItem == null) {
         return -1;
     }
 
     // Get the dates to compare
-    let aDate = aItem[calGetStartDateProp(aItem)];
-    let bDate = aWidgetItem[calGetStartDateProp(aWidgetItem)];
+    let aDate = aItem[cal.calGetStartDateProp(aItem)];
+    let bDate = aWidgetItem[cal.calGetStartDateProp(aWidgetItem)];
 
     return aDate.compare(bDate);
 }
 
 /**
  * Add an alarm widget for the passed alarm and item.
  *
  * @param aItem       The calendar item to add a widget for.
--- a/calendar/base/content/dialogs/calendar-alarm-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-alarm-dialog.xul
@@ -23,17 +23,16 @@
         onload="setupWindow(); window.arguments[0].wrappedJSObject.window_onLoad();"
         onunload="finishWindow();"
         onfocus="onFocusWindow();"
         onkeypress="if (event.keyCode == event.DOM_VK_ESCAPE) { window.close(); }"
         width="600"
         height="300">
   <script type="application/javascript" src="chrome://calendar/content/calendar-alarm-dialog.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-item-editing.js"/>
-  <script type="application/javascript" src="chrome://calendar/content/calUtils.js"/>
 
   <richlistbox id="alarm-richlist" flex="1" onselect="onSelectAlarm(event)"/>
 
   <hbox pack="end" id="alarm-actionbar" align="center">
     <button id="alarm-snooze-all-button"
             type="menu"
             label="&calendar.alarm.snoozeallfor.label;">
       <menupopup type="snooze-menupopup"
--- a/calendar/base/content/dialogs/calendar-conflicts-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-conflicts-dialog.xul
@@ -9,17 +9,16 @@
 <dialog id="calendar-conflicts-dialog"
         windowtype="Calendar:Conflicts"
         onload="onLoad()"
         ondialogaccept="return onAccept();"
         ondialogcancel="return onCancel();"
         persist="screenX screenY"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <script type="application/javascript" src="chrome://calendar/content/mouseoverPreviews.js"/>
-  <script type="application/javascript" src="chrome://calendar/content/calUtils.js"/>
   <script type="application/javascript"><![CDATA[
     Components.utils.import("resource://calendar/modules/calUtils.jsm");
     function onLoad() {
         let docEl = document.documentElement;
         let item = window.arguments[0].item;
         let vbox = getPreviewForEvent(item);
         let descr = document.getElementById("conflicts-description");
         descr.parentNode.insertBefore(vbox, descr);
--- a/calendar/base/content/dialogs/calendar-creation.js
+++ b/calendar/base/content/dialogs/calendar-creation.js
@@ -1,32 +1,34 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* exported openLocalCalendar */
 
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
 /**
  * Shows the filepicker and creates a new calendar with a local file using the ICS
  * provider.
  */
 function openLocalCalendar() {
     const nsIFilePicker = Components.interfaces.nsIFilePicker;
     let picker = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
-    picker.init(window, calGetString("calendar", "Open"), nsIFilePicker.modeOpen);
+    picker.init(window, cal.calGetString("calendar", "Open"), nsIFilePicker.modeOpen);
     let wildmat = "*.ics";
-    let description = calGetString("calendar", "filterIcs", [wildmat]);
+    let description = cal.calGetString("calendar", "filterIcs", [wildmat]);
     picker.appendFilter(description, wildmat);
     picker.appendFilters(nsIFilePicker.filterAll);
 
     if (picker.show() != nsIFilePicker.returnOK) {
         return;
     }
 
-    let calMgr = getCalendarManager();
+    let calMgr = cal.getCalendarManager();
     let calendars = calMgr.getCalendars({});
     if (calendars.some(x => x.uri == picker.fileURL)) {
         // The calendar already exists, select it and return.
         document.getElementById("calendar-list-tree-widget")
                 .tree.view.selection.select(index);
         return;
     }
 
@@ -36,14 +38,14 @@ function openLocalCalendar() {
     // calendarCreation.js
     let fullPathRegex = new RegExp("([^/:]+)[.]ics$");
     let prettyName = picker.fileURL.spec.match(fullPathRegex);
     let name;
 
     if (prettyName && prettyName.length >= 1) {
         name = decodeURIComponent(prettyName[1]);
     } else {
-        name = calGetString("calendar", "untitledCalendarName");
+        name = cal.calGetString("calendar", "untitledCalendarName");
     }
     openCalendar.name = name;
 
     calMgr.registerCalendar(openCalendar);
 }
--- a/calendar/base/content/dialogs/calendar-dialog-utils.js
+++ b/calendar/base/content/dialogs/calendar-dialog-utils.js
@@ -6,16 +6,17 @@
  *          dispose, setDialogId, loadReminders, saveReminder,
  *          commonUpdateReminder, updateLink, rearrangeAttendees
  */
 
 Components.utils.import("resource://gre/modules/PluralForm.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/iteratorUtils.jsm");
 
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calAlarmUtils.jsm");
 Components.utils.import("resource://calendar/modules/calIteratorUtils.jsm");
 Components.utils.import("resource://calendar/modules/calRecurrenceUtils.jsm");
 
 // Variables related to whether we are in a tab or a window dialog.
 var gInTab = false;
 var gMainWindow = null;
 var gTabmail = null;
@@ -134,17 +135,17 @@ function createReminderFromMenuitem(aMen
  */
 function editReminder() {
     let customItem = document.getElementById("reminder-custom-menuitem");
     let args = {};
     args.reminders = customItem.reminders;
     args.item = window.calendarItem;
     args.timezone = window.gStartTimezone ||
                     window.gEndTimezone ||
-                    calendarDefaultTimezone();
+                    cal.calendarDefaultTimezone();
 
     args.calendar = getCurrentCalendar();
 
     // While these are "just" callbacks, the dialog is opened modally, so aside
     // from whats needed to set up the reminders, nothing else needs to be done.
     args.onOk = function(reminders) {
         customItem.reminders = reminders;
     };
@@ -451,17 +452,17 @@ function commonUpdateReminder(aSuppressD
     reminderList.setAttribute("last-value", reminderList.value);
 
     // possibly the selected reminder conflicts with the item.
     // for example an end-relation combined with a task without duedate
     // is an invalid state we need to take care of. we take the same
     // approach as with recurring tasks. in case the reminder is related
     // to the entry date we check the entry date automatically and disable
     // the checkbox. the same goes for end related reminder and the due date.
-    if (isToDo(window.calendarItem)) {
+    if (cal.isToDo(window.calendarItem)) {
         // In general, (re-)enable the due/entry checkboxes. This will be
         // changed in case the alarms are related to START/END below.
         enableElementWithLock("todo-has-duedate", "reminder-lock");
         enableElementWithLock("todo-has-entrydate", "reminder-lock");
 
         let menuitem = reminderList.selectedItem;
         if (menuitem.value != "none") {
             // In case a reminder is selected, retrieve the array of alarms from
@@ -528,17 +529,17 @@ function updateLink() {
     if ((linkCommand && linkCommand.getAttribute("checked") != "true") ||
         !itemUrlString.length) {
         // Hide if there is no url, or the menuitem was chosen so that the url
         // should be hidden
         hideOrShow(false);
     } else {
         let handler, uri;
         try {
-            uri = makeURL(itemUrlString);
+            uri = cal.makeURL(itemUrlString);
             handler = Services.io.getProtocolHandler(uri.scheme);
         } catch (e) {
             // No protocol handler for the given protocol, or invalid uri
             hideOrShow(false);
             return;
         }
 
         // Only show if its either an internal protcol handler, or its external
--- a/calendar/base/content/dialogs/calendar-event-dialog-attendees.js
+++ b/calendar/base/content/dialogs/calendar-event-dialog-attendees.js
@@ -173,17 +173,17 @@ function zoomWithButtons(aZoomOut) {
  * Loads the passed start and end dates, fills global variables that give
  * information about the state of the dialog.
  *
  * @param aStartDate        The date/time the grid should start at.
  * @param aEndDate          The date/time the grid should end at.
  */
 function loadDateTime(aStartDate, aEndDate) {
     gDuration = aEndDate.subtractDate(aStartDate);
-    let kDefaultTimezone = calendarDefaultTimezone();
+    let kDefaultTimezone = cal.calendarDefaultTimezone();
     gStartTimezone = aStartDate.timezone;
     gEndTimezone = aEndDate.timezone;
     gStartDate = aStartDate.getInTimezone(kDefaultTimezone);
     gEndDate = aEndDate.getInTimezone(kDefaultTimezone);
     gStartDate.makeImmutable();
     gEndDate.makeImmutable();
 }
 
@@ -215,17 +215,17 @@ function propagateDateTime() {
                   (grid.endDate.compare(gEndDate) != 0);
     grid.startDate = gStartDate;
     grid.endDate = gEndDate;
     if (refresh) {
         grid.forceRefresh();
     }
 
     // Expand to 24hrs if the new range is outside of the default range.
-    let kDefaultTimezone = calendarDefaultTimezone();
+    let kDefaultTimezone = cal.calendarDefaultTimezone();
     let startTime = gStartDate.getInTimezone(kDefaultTimezone);
     let endTime = gEndDate.getInTimezone(kDefaultTimezone);
     if ((startTime.hour < gStartHour) ||
         (startTime.hour >= gEndHour) ||
         (endTime.hour >= gEndHour) ||
         (startTime.day != endTime.day) ||
         (startTime.isDate)) {
         setForce24Hours(true);
@@ -249,47 +249,47 @@ function updateDateTime() {
             document.getElementById("all-day")
                 .setAttribute("checked", "true");
         }
 
         // In the case where the timezones are different but
         // the timezone of the endtime is "UTC", we convert
         // the endtime into the timezone of the starttime.
         if (startTime && endTime) {
-            if (!compareObjects(startTime.timezone, endTime.timezone)) {
+            if (!cal.compareObjects(startTime.timezone, endTime.timezone)) {
                 if (endTime.timezone.isUTC) {
                     endTime = endTime.getInTimezone(startTime.timezone);
                 }
             }
         }
 
         // Before feeding the date/time value into the control we need
         // to set the timezone to 'floating' in order to avoid the
         // automatic conversion back into the OS timezone.
-        startTime.timezone = floating();
-        endTime.timezone = floating();
+        startTime.timezone = cal.floating();
+        endTime.timezone = cal.floating();
 
         document.getElementById("event-starttime").value = cal.dateTimeToJsDate(startTime);
         document.getElementById("event-endtime").value = cal.dateTimeToJsDate(endTime);
     } else {
-        let kDefaultTimezone = calendarDefaultTimezone();
+        let kDefaultTimezone = cal.calendarDefaultTimezone();
 
         let startTime = gStartDate.getInTimezone(kDefaultTimezone);
         let endTime = gEndDate.getInTimezone(kDefaultTimezone);
 
         if (startTime.isDate) {
             document.getElementById("all-day")
                 .setAttribute("checked", "true");
         }
 
         // Before feeding the date/time value into the control we need
         // to set the timezone to 'floating' in order to avoid the
         // automatic conversion back into the OS timezone.
-        startTime.timezone = floating();
-        endTime.timezone = floating();
+        startTime.timezone = cal.floating();
+        endTime.timezone = cal.floating();
 
         document.getElementById("event-starttime").value = cal.dateTimeToJsDate(startTime);
         document.getElementById("event-endtime").value = cal.dateTimeToJsDate(endTime);
     }
 
     updateTimezone();
     updateAllDay();
 }
@@ -302,17 +302,17 @@ function updateDateTime() {
 function updateTimezone() {
     gIgnoreUpdate = true;
 
     if (gDisplayTimezone) {
         let startTimezone = gStartTimezone;
         let endTimezone = gEndTimezone;
         let equalTimezones = false;
         if (startTimezone && endTimezone &&
-            (compareObjects(startTimezone, endTimezone) || endTimezone.isUTC)) {
+            (cal.compareObjects(startTimezone, endTimezone) || endTimezone.isUTC)) {
             equalTimezones = true;
         }
 
         let tzStart = document.getElementById("timezone-starttime");
         let tzEnd = document.getElementById("timezone-endtime");
         if (startTimezone) {
             tzStart.removeAttribute("collapsed");
             tzStart.value = startTimezone.displayName || startTimezone.tzid;
@@ -347,17 +347,17 @@ function updateStartTime() {
 
     let startWidgetId = "event-starttime";
 
     let startWidget = document.getElementById(startWidgetId);
 
     // jsDate is always in OS timezone, thus we create a calIDateTime
     // object from the jsDate representation and simply set the new
     // timezone instead of converting.
-    let timezone = gDisplayTimezone ? gStartTimezone : calendarDefaultTimezone();
+    let timezone = gDisplayTimezone ? gStartTimezone : cal.calendarDefaultTimezone();
     let start = cal.jsDateToDateTime(startWidget.value, timezone);
 
     gStartDate = start.clone();
     start.addDuration(gDuration);
     gEndDate = start.getInTimezone(gEndTimezone);
 
     let allDayElement = document.getElementById("all-day");
     let allDay = allDayElement.getAttribute("checked") == "true";
@@ -380,25 +380,25 @@ function updateEndTime() {
     let startWidgetId = "event-starttime";
     let endWidgetId = "event-endtime";
 
     let startWidget = document.getElementById(startWidgetId);
     let endWidget = document.getElementById(endWidgetId);
 
     let saveStartTime = gStartDate;
     let saveEndTime = gEndDate;
-    let kDefaultTimezone = calendarDefaultTimezone();
+    let kDefaultTimezone = cal.calendarDefaultTimezone();
 
     gStartDate = cal.jsDateToDateTime(startWidget.value,
-                                  gDisplayTimezone ? gStartTimezone : calendarDefaultTimezone());
+                                  gDisplayTimezone ? gStartTimezone : cal.calendarDefaultTimezone());
 
     let timezone = gEndTimezone;
     if (timezone.isUTC &&
         gStartDate &&
-        !compareObjects(gStartTimezone, gEndTimezone)) {
+        !cal.compareObjects(gStartTimezone, gEndTimezone)) {
         timezone = gStartTimezone;
     }
     gEndDate = cal.jsDateToDateTime(endWidget.value,
                                     gDisplayTimezone ? timezone : kDefaultTimezone);
 
     let allDayElement = document.getElementById("all-day");
     let allDay = allDayElement.getAttribute("checked") == "true";
     if (allDay) {
@@ -419,17 +419,17 @@ function updateEndTime() {
 
     propagateDateTime();
 
     if (warning) {
         let callback = function() {
             Services.prompt.alert(
                 null,
                 document.title,
-                calGetString("calendar", "warningEndBeforeStart"));
+                cal.calGetString("calendar", "warningEndBeforeStart"));
         };
         setTimeout(callback, 1);
     }
 }
 
 /**
  * Prompts the user to pick a new timezone for the starttime. The dialog is
  * opened modally.
@@ -442,17 +442,17 @@ function editStartTimezone() {
 
     let self = this;
     let args = {};
     args.calendar = window.arguments[0].calendar;
     args.time = gStartDate.getInTimezone(gStartTimezone);
     args.onOk = function(datetime) {
         let equalTimezones = false;
         if (gStartTimezone && gEndTimezone &&
-            compareObjects(gStartTimezone, gEndTimezone)) {
+            cal.compareObjects(gStartTimezone, gEndTimezone)) {
             equalTimezones = true;
         }
         gStartTimezone = datetime.timezone;
         if (equalTimezones) {
             gEndTimezone = datetime.timezone;
         }
         self.propagateDateTime();
     };
@@ -476,17 +476,17 @@ function editEndTimezone() {
     }
 
     let self = this;
     let args = {};
     args.calendar = window.arguments[0].calendar;
     args.time = gEndTime.getInTimezone(gEndTimezone);
     args.onOk = function(datetime) {
         if (gStartTimezone && gEndTimezone &&
-            compareObjects(gStartTimezone, gEndTimezone)) {
+            cal.compareObjects(gStartTimezone, gEndTimezone)) {
             gStartTimezone = datetime.timezone;
         }
         gEndTimezone = datetime.timezone;
         self.propagateDateTime();
     };
 
     // Open the dialog modally
     openDialog(
--- a/calendar/base/content/dialogs/calendar-event-dialog-attendees.xml
+++ b/calendar/base/content/dialogs/calendar-event-dialog-attendees.xml
@@ -902,17 +902,17 @@
               document.getAnonymousElementByAttribute(
                   this, "anonid", "listbox");
           return listbox.getIndexOfFirstVisibleRow();
         ]]></getter>
       </property>
 
       <method name="createAttendee">
         <body><![CDATA[
-          let attendee = createAttendee();
+          let attendee = cal.createAttendee();
           attendee.id = "";
           attendee.rsvp = "TRUE";
           attendee.role = "REQ-PARTICIPANT";
           attendee.participationStatus = "NEEDS-ACTION";
           return attendee;
         ]]></body>
       </method>
 
@@ -1256,16 +1256,17 @@
           this.mRatio = val;
           this.update();
           return val;
         ]]></setter>
       </property>
 
       <constructor><![CDATA[
         Components.utils.import("resource://gre/modules/Preferences.jsm");
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
         this.initTimeRange();
 
         // The basedate is the date/time from which the display
         // of the timebar starts. The range is the number of days
         // we should be able to show. the start- and enddate
         // is the time the event is scheduled for.
         this.mRange = Number(this.getAttribute("range"));
@@ -1274,49 +1275,49 @@
                 this, "anonid", "selection-bar");
       ]]></constructor>
 
       <property name="baseDate">
         <setter><![CDATA[
           // we need to convert the date/time in question in
           // order to calculate with hours that are aligned
           // with our timebar display.
-          let kDefaultTimezone = calendarDefaultTimezone();
+          let kDefaultTimezone = cal.calendarDefaultTimezone();
           this.mBaseDate = val.getInTimezone(kDefaultTimezone);
           this.mBaseDate.isDate = true;
           this.mBaseDate.makeImmutable();
           return val;
         ]]></setter>
       </property>
 
       <property name="startDate">
         <setter><![CDATA[
           // currently we *always* set the basedate to be
           // equal to the startdate. we'll most probably
           // want to change this later.
           this.baseDate = val;
           // we need to convert the date/time in question in
           // order to calculate with hours that are aligned
           // with our timebar display.
-          let kDefaultTimezone = calendarDefaultTimezone();
+          let kDefaultTimezone = cal.calendarDefaultTimezone();
           this.mStartDate = val.getInTimezone(kDefaultTimezone);
           this.mStartDate.makeImmutable();
           return val;
         ]]></setter>
         <getter><![CDATA[
           return this.mStartDate;
         ]]></getter>
       </property>
 
       <property name="endDate">
         <setter><![CDATA[
           // we need to convert the date/time in question in
           // order to calculate with hours that are aligned
           // with our timebar display.
-          let kDefaultTimezone = calendarDefaultTimezone();
+          let kDefaultTimezone = cal.calendarDefaultTimezone();
           this.mEndDate = val.getInTimezone(kDefaultTimezone);
           if (this.mEndDate.isDate) {
               this.mEndDate.day += 1;
           }
           this.mEndDate.makeImmutable();
           return val;
         ]]></setter>
         <getter><![CDATA[
--- a/calendar/base/content/dialogs/calendar-event-dialog-attendees.xul
+++ b/calendar/base/content/dialogs/calendar-event-dialog-attendees.xul
@@ -24,17 +24,16 @@
         persist="screenX screenY height width"
         orient="vertical"
         style="padding-top: 8px; padding-bottom: 10px; padding-inline-start: 8px; padding-inline-end: 10px;"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <!-- Javascript includes -->
   <script type="application/javascript" src="chrome://calendar/content/calendar-event-dialog-attendees.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-dialog-utils.js"/>
-  <script type="application/javascript" src="chrome://calendar/content/calUtils.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-statusbar.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-ui-utils.js"/>
 
   <hbox align="center" pack="end">
     <spacer flex="1"/>
     <label value="&event.freebusy.suggest.slot;"/>
     <button label="&event.freebusy.button.previous.slot;"
             dir="normal"
--- a/calendar/base/content/dialogs/calendar-event-dialog-freebusy.xml
+++ b/calendar/base/content/dialogs/calendar-event-dialog-freebusy.xml
@@ -420,28 +420,29 @@
         ]]></setter>
         <getter><![CDATA[
           return this.mScrollOffset;
         ]]></getter>
       </property>
 
       <constructor><![CDATA[
         Components.utils.import("resource://gre/modules/Preferences.jsm");
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
         let args = window.arguments[0];
         let startTime = args.startTime;
         let endTime = args.endTime;
 
         this.initTimeRange();
 
         // The basedate is the date/time from which the display
         // of the timebar starts. The range is the number of days
         // we should be able to show. The start- and enddate
         // is the time the event is scheduled for.
-        let kDefaultTimezone = calendarDefaultTimezone();
+        let kDefaultTimezone = cal.calendarDefaultTimezone();
         this.startDate = startTime.getInTimezone(kDefaultTimezone);
         this.endDate = endTime.getInTimezone(kDefaultTimezone);
         this.mRange = Number(this.getAttribute("range"));
 
         window.addEventListener("load", this.onLoad.bind(this), true);
       ]]></constructor>
 
       <method name="refresh">
@@ -479,17 +480,17 @@
       </method>
 
       <method name="initialize">
         <body><![CDATA[
           let args = window.arguments[0];
           let startTime = args.startTime;
           let endTime = args.endTime;
 
-          let kDefaultTimezone = calendarDefaultTimezone();
+          let kDefaultTimezone = cal.calendarDefaultTimezone();
           this.startDate = startTime.getInTimezone(kDefaultTimezone);
           this.endDate = endTime.getInTimezone(kDefaultTimezone);
 
           // Set the number of 'freebusy-day'-elements
           // we need to fill up the content box.
           // TODO: hardcoded value
           this.mNumDays = 4 * this.mZoomFactor / 100;
           if (this.mNumDays < 2) {
@@ -683,16 +684,17 @@
                   this, "anonid", "container");
           container.x = offset;
           return val;
         ]]></setter>
       </property>
 
       <constructor><![CDATA[
         Components.utils.import("resource://gre/modules/Preferences.jsm");
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
         this.initTimeRange();
         this.mRange = Number(this.getAttribute("range"));
         this.onLoad();
       ]]></constructor>
 
       <method name="onLoad">
         <body><![CDATA[
@@ -756,17 +758,17 @@
           // which will map the entries to attributes on the xul elements.
           if (aEntries) {
               // Remember the free/busy array which is used to find a
               // new time for an event. We store this array only if
               // the provider returned a valid array. In any other case
               // (temporarily clean the display) we keep the last know result.
               this.mEntries = aEntries;
 
-              let kDefaultTimezone = calendarDefaultTimezone();
+              let kDefaultTimezone = cal.calendarDefaultTimezone();
 
               let start = this.mStartDate.clone();
               start.hour = 0;
               start.minute = 0;
               start.second = 0;
               start.timezone = kDefaultTimezone;
               let end = start.clone();
               end.day += this.mRange;
@@ -909,17 +911,17 @@
         <parameter name="aEndTime"/>
         <parameter name="allDay"/>
         <body><![CDATA[
           let newTime = aStartTime.clone();
           let duration = aEndTime.subtractDate(aStartTime);
           let newEndTime = newTime.clone();
           newEndTime.addDuration(duration);
 
-          let kDefaultTimezone = calendarDefaultTimezone();
+          let kDefaultTimezone = cal.calendarDefaultTimezone();
 
           if (this.mEntries) {
               for (let entry of this.mEntries) {
                   let rangeStart =
                       entry.interval.start.getInTimezone(kDefaultTimezone);
                   let rangeEnd =
                       entry.interval.end.getInTimezone(kDefaultTimezone);
 
@@ -1069,16 +1071,17 @@
           let rowcount = listbox.getRowCount();
           listbox.scrollToIndex(Math.floor(rowcount * val));
           return val;
         ]]></setter>
       </property>
 
       <constructor><![CDATA[
         Components.utils.import("resource://gre/modules/Preferences.jsm");
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
         this.initTimeRange();
 
         this.mRange = Number(this.getAttribute("range"));
 
         this.mMaxFreeBusy = 0;
         this.mPendingRequests = [];
 
@@ -1138,17 +1141,17 @@
       </method>
 
       <method name="onInitialize">
         <body><![CDATA[
           let args = window.arguments[0];
           let startTime = args.startTime;
           let endTime = args.endTime;
 
-          let kDefaultTimezone = calendarDefaultTimezone();
+          let kDefaultTimezone = cal.calendarDefaultTimezone();
           this.startDate = startTime.getInTimezone(kDefaultTimezone);
           this.endDate = endTime.getInTimezone(kDefaultTimezone);
 
           let listbox =
               document.getAnonymousElementByAttribute(
                   this, "anonid", "listbox");
           let template =
               document.getAnonymousElementByAttribute(
@@ -1259,17 +1262,17 @@
 
           this.updateFreeBusy();
         ]]></body>
       </method>
 
       <!-- updateFreeBusy(), implementation of the core functionality of this binding -->
       <method name="updateFreeBusy">
         <body><![CDATA[
-          let fbService = getFreeBusyService();
+          let fbService = cal.getFreeBusyService();
           for (let i = 1; i <= this.mMaxFreeBusy; i++) {
               // Retrieve the string from the appropriate row
               let freebusy = this.getFreeBusyElement(i);
               if (freebusy.hasAttribute("dirty")) {
                   freebusy.removeAttribute("dirty");
                   let calid = freebusy.getAttribute("calid");
                   if (calid && calid.length > 0) {
                       // Define the datetime range we would like to ask for.
--- a/calendar/base/content/dialogs/calendar-event-dialog-recurrence-preview.xml
+++ b/calendar/base/content/dialogs/calendar-event-dialog-recurrence-preview.xml
@@ -31,32 +31,34 @@
     </content>
 
     <implementation>
       <field name="mRecurrenceInfo">null</field>
       <field name="mResizeHandler">null</field>
       <field name="mDateTime">null</field>
 
       <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
         this.mResizeHandler = this.onResize.bind(this);
         window.addEventListener("resize", this.mResizeHandler, true);
       ]]></constructor>
 
       <destructor><![CDATA[
         window.removeEventListener("resize", this.mResizeHandler, true);
       ]]></destructor>
 
       <property name="dateTime">
         <setter><![CDATA[
             this.mDateTime = val.clone();
             return this.mDateTime;
         ]]></setter>
         <getter><![CDATA[
             if (this.mDateTime == null) {
-                this.mDateTime = now();
+                this.mDateTime = cal.now();
             }
             return this.mDateTime;
         ]]></getter>
       </property>
       <method name="onResize">
         <body><![CDATA[
           let minimonth =
               document.getAnonymousElementByAttribute(
--- a/calendar/base/content/dialogs/calendar-event-dialog-recurrence.js
+++ b/calendar/base/content/dialogs/calendar-event-dialog-recurrence.js
@@ -23,17 +23,17 @@ function onLoad() {
     let args = window.arguments[0];
     let item = args.calendarEvent;
     let calendar = item.calendar;
     let recinfo = args.recurrenceInfo;
 
     gStartTime = args.startTime;
     gEndTime = args.endTime;
     let preview = document.getElementById("recurrence-preview");
-    preview.dateTime = gStartTime.getInTimezone(calendarDefaultTimezone());
+    preview.dateTime = gStartTime.getInTimezone(cal.calendarDefaultTimezone());
 
     onChangeCalendar(calendar);
 
     // Set starting value for 'repeat until' rule and highlight the start date.
     let repeatDate = cal.dateTimeToJsDate(gStartTime.getInTimezone(cal.floating()));
     setElementValue("repeat-until-date", repeatDate);
     document.getElementById("repeat-until-date").extraDate = repeatDate;
 
@@ -51,17 +51,17 @@ function onLoad() {
                 // We only handle 1 rule currently
                 rule = cal.wrapInstance(rules[0], Components.interfaces.calIRecurrenceRule);
             }
         } catch (ex) {
             Components.utils.reportError(ex);
         }
     }
     if (!rule) {
-        rule = createRecurrenceRule();
+        rule = cal.createRecurrenceRule();
         rule.type = "DAILY";
         rule.interval = 1;
         rule.count = -1;
     }
     initializeControls(rule);
 
     // Update controls
     updateRecurrenceDeck();
@@ -127,17 +127,17 @@ function initializeControls(rule) {
             document.getElementById("period-list").selectedIndex = 0;
             dump("unable to handle your rule type!\n");
             break;
     }
 
     let byDayRuleComponent = rule.getComponent("BYDAY", {});
     let byMonthDayRuleComponent = rule.getComponent("BYMONTHDAY", {});
     let byMonthRuleComponent = rule.getComponent("BYMONTH", {});
-    let kDefaultTimezone = calendarDefaultTimezone();
+    let kDefaultTimezone = cal.calendarDefaultTimezone();
     let startDate = gStartTime.getInTimezone(kDefaultTimezone);
 
     // "DAILY" ruletype
     // byDayRuleComponents may have been set priorily by "MONTHLY"- ruletypes
     // where they have a different context-
     // that's why we also query the current rule-type
     if (byDayRuleComponent.length == 0 || rule.type != "DAILY") {
         document.getElementById("daily-group").selectedIndex = 0;
@@ -271,20 +271,20 @@ function onSave(item) {
     if (recurrenceInfo) {
         recurrenceInfo = recurrenceInfo.clone();
         let rrules = splitRecurrenceRules(recurrenceInfo);
         if (rrules[0].length > 0) {
             recurrenceInfo.deleteRecurrenceItem(rrules[0][0]);
         }
         recurrenceInfo.item = item;
     } else {
-        recurrenceInfo = createRecurrenceInfo(item);
+        recurrenceInfo = cal.createRecurrenceInfo(item);
     }
 
-    let recRule = createRecurrenceRule();
+    let recRule = cal.createRecurrenceRule();
     const ALL_WEEKDAYS = [2, 3, 4, 5, 6, 7, 1]; // The sequence MO,TU,WE,TH,FR,SA,SU.
     switch (deckNumber) {
         case 0: {
             recRule.type = "DAILY";
             let dailyGroup = document.getElementById("daily-group");
             if (dailyGroup.selectedIndex == 0) {
                 let ndays = Math.max(1, Number(getElementValue("daily-days")));
                 recRule.interval = ndays;
@@ -463,17 +463,17 @@ function onChangeCalendar(calendar) {
  *
  * @param item        The item to check.
  */
 function disableOrEnable(item) {
     if (item.parentItem != item) {
         disableRecurrenceFields("disable-on-occurrence");
     } else if (gIsReadOnly) {
         disableRecurrenceFields("disable-on-readonly");
-    } else if (isToDo(item) && !gStartTime) {
+    } else if (cal.isToDo(item) && !gStartTime) {
         disableRecurrenceFields("disable-on-readonly");
     } else {
         enableRecurrenceFields("disable-on-readonly");
     }
 }
 
 /**
  * Disables all fields that have an attribute that matches the argument and is
@@ -590,28 +590,28 @@ function updatePreview() {
         item = item.parentItem;
     }
 
     // TODO: We should better start the whole dialog with a newly cloned item
     // and always pump changes immediately into it. This would eliminate the
     // need to break the encapsulation, as we do it here. But we need the item
     // to contain the startdate in order to calculate the recurrence preview.
     item = item.clone();
-    let kDefaultTimezone = calendarDefaultTimezone();
-    if (isEvent(item)) {
+    let kDefaultTimezone = cal.calendarDefaultTimezone();
+    if (cal.isEvent(item)) {
         let startDate = gStartTime.getInTimezone(kDefaultTimezone);
         let endDate = gEndTime.getInTimezone(kDefaultTimezone);
         if (startDate.isDate) {
             endDate.day--;
         }
 
         item.startDate = startDate;
         item.endDate = endDate;
     }
-    if (isToDo(item)) {
+    if (cal.isToDo(item)) {
         let entryDate = gStartTime;
         if (entryDate) {
             entryDate = entryDate.getInTimezone(kDefaultTimezone);
         } else {
             item.recurrenceInfo = null;
         }
         item.entryDate = entryDate;
         let dueDate = gEndTime;
@@ -756,19 +756,19 @@ function changeOrderForElements(aPropKey
 
     for (let key in aPropParams) {
         // Save original parents so that the nodes to reorder get appended to
         // the correct parent nodes.
         parents[key] = document.getElementById(aPropParams[key]).parentNode;
     }
 
     try {
-        localeOrder = calGetString("calendar-event-dialog",
-                                   aPropKey,
-                                   aPropParams);
+        localeOrder = cal.calGetString("calendar-event-dialog",
+                                       aPropKey,
+                                       aPropParams);
 
         localeOrder = localeOrder.split(" ");
     } catch (ex) {
         let msg = "The key " + aPropKey + " in calendar-event-dialog.prop" +
                   "erties has incorrect number of params. Expected " +
                   aPropParams.length + " params.";
         Components.utils.reportError(msg + " " + ex);
         return;
--- a/calendar/base/content/dialogs/calendar-event-dialog-recurrence.xul
+++ b/calendar/base/content/dialogs/calendar-event-dialog-recurrence.xul
@@ -21,17 +21,16 @@
         ondialogcancel="return onCancel();"
         persist="screenX screenY width height"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <!-- Javascript includes -->
   <script type="application/javascript" src="chrome://calendar/content/calendar-event-dialog-recurrence.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-dialog-utils.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-ui-utils.js"/>
-  <script type="application/javascript" src="chrome://calendar/content/calUtils.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-statusbar.js"/>
 
   <!-- recurrence pattern -->
   <groupbox id="recurrence-pattern-groupbox">
     <caption id="recurrence-pattern-caption"
              label="&event.recurrence.pattern.label;"/>
     <grid id="recurrence-pattern-grid">
       <columns id="recurrence-pattern-columns">
--- a/calendar/base/content/dialogs/calendar-event-dialog-reminder.js
+++ b/calendar/base/content/dialogs/calendar-event-dialog-reminder.js
@@ -90,17 +90,17 @@ function loadReminders() {
             // action is actually supported by the calendar.
             listbox.appendChild(setupListItem(null, reminders[i].clone(), args.item));
         }
     }
 
     // Set up a default absolute date. This will be overridden if the selected
     // alarm is absolute.
     let absDate = document.getElementById("reminder-absolute-date");
-    absDate.value = cal.dateTimeToJsDate(getDefaultStartDate());
+    absDate.value = cal.dateTimeToJsDate(cal.getDefaultStartDate());
 
     if (listbox.childNodes.length) {
         // We have reminders, select the first by default. For some reason,
         // setting the selected index in a load handler makes the selection
         // break for the set item, therefore we need a setTimeout.
         setupMaxReminders();
         setTimeout(() => { listbox.selectedIndex = 0; }, 0);
     } else {
@@ -166,19 +166,19 @@ function setupMaxReminders() {
 
     // If we hit the maximum number of reminders, show the error box and
     // disable the new button.
     setElementValue("reminder-new-button", cond && "true", "disabled");
 
     if (!setupMaxReminders.notification) {
         let notification = createXULElement("notification");
         let localeErrorString =
-            calGetString("calendar-alarms",
-                         getItemBundleStringName("reminderErrorMaxCountReached"),
-                         [maxReminders]);
+            cal.calGetString("calendar-alarms",
+                             getItemBundleStringName("reminderErrorMaxCountReached"),
+                             [maxReminders]);
         let pluralErrorLabel = PluralForm.get(maxReminders, localeErrorString)
                                          .replace("#1", maxReminders);
 
         notification.setAttribute("label", pluralErrorLabel);
         notification.setAttribute("type", "warning");
         notification.setAttribute("hideclose", "true");
         setupMaxReminders.notification = notification;
     }
@@ -348,29 +348,29 @@ function updateReminder(event) {
 /**
  * Gets the locale stringname that is dependant on the item type. This function
  * appends the item type, i.e |aPrefix + "Event"|.
  *
  * @param aPrefix       The prefix to prepend to the item type
  * @return              The full string name.
  */
 function getItemBundleStringName(aPrefix) {
-    if (isEvent(window.arguments[0].item)) {
+    if (cal.isEvent(window.arguments[0].item)) {
         return aPrefix + "Event";
     } else {
         return aPrefix + "Task";
     }
 }
 
 /**
  * Handler function to be called when the "new" button is pressed, to create a
  * new reminder item.
  */
 function onNewReminder() {
-    let itemType = (isEvent(window.arguments[0].item) ? "event" : "todo");
+    let itemType = (cal.isEvent(window.arguments[0].item) ? "event" : "todo");
     let listbox = document.getElementById("reminder-listbox");
 
     let reminder = cal.createAlarm();
     let alarmlen = Preferences.get("calendar.alarms." + itemType + "alarmlen", 15);
 
     // Default is a relative DISPLAY alarm, |alarmlen| minutes before the event.
     // If DISPLAY is not supported by the provider, then pick the provider's
     // first alarm type.
--- a/calendar/base/content/dialogs/calendar-event-dialog-reminder.xul
+++ b/calendar/base/content/dialogs/calendar-event-dialog-reminder.xul
@@ -18,17 +18,16 @@
         ondialogaccept="return onAccept();"
         ondialogcancel="return onCancel();"
         persist="screenX screenY width height"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <!-- Javascript includes -->
   <script type="application/javascript" src="chrome://calendar/content/calendar-event-dialog-reminder.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-ui-utils.js"/>
-  <script type="application/javascript" src="chrome://calendar/content/calUtils.js"/>
 
   <notificationbox id="reminder-notifications"/>
 
   <!-- Listbox with custom reminders -->
   <vbox flex="1">
     <listbox id="reminder-listbox"
              seltype="single"
              class="event-dialog-listbox"
--- a/calendar/base/content/dialogs/calendar-event-dialog-timezone.js
+++ b/calendar/base/content/dialogs/calendar-event-dialog-timezone.js
@@ -19,20 +19,20 @@ function onLoad() {
                      cal.getTimezoneService();
     window.tzProvider = tzProvider;
 
     let menulist = document.getElementById("timezone-menulist");
     let tzMenuPopup = document.getElementById("timezone-menupopup");
 
     // floating and UTC (if supported) at the top:
     if (args.calendar.getProperty("capabilities.timezones.floating.supported") !== false) {
-        addMenuItem(tzMenuPopup, floating().displayName, floating().tzid);
+        addMenuItem(tzMenuPopup, cal.floating().displayName, cal.floating().tzid);
     }
     if (args.calendar.getProperty("capabilities.timezones.UTC.supported") !== false) {
-        addMenuItem(tzMenuPopup, UTC().displayName, UTC().tzid);
+        addMenuItem(tzMenuPopup, cal.UTC().displayName, cal.UTC().tzid);
     }
 
     let enumerator = tzProvider.timezoneIds;
     let tzids = {};
     let displayNames = [];
     while (enumerator.hasMore()) {
         let timezone = tzProvider.getTimezone(enumerator.getNext());
         if (timezone && !timezone.isFloating && !timezone.isUTC) {
@@ -45,17 +45,17 @@ function onLoad() {
     displayNames.sort((a, b) => a.localeCompare(b));
     for (let i = 0; i < displayNames.length; ++i) {
         let displayName = displayNames[i];
         addMenuItem(tzMenuPopup, displayName, tzids[displayName]);
     }
 
     let index = findTimezone(window.time.timezone);
     if (index < 0) {
-        index = findTimezone(calendarDefaultTimezone());
+        index = findTimezone(cal.calendarDefaultTimezone());
         if (index < 0) {
             index = 0;
         }
     }
 
     menulist = document.getElementById("timezone-menulist");
     menulist.selectedIndex = index;
 
--- a/calendar/base/content/dialogs/calendar-event-dialog-timezone.xul
+++ b/calendar/base/content/dialogs/calendar-event-dialog-timezone.xul
@@ -23,17 +23,16 @@
         ondialogcancel="return onCancel();"
         persist="screenX screenY width height"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <!-- Javascript includes -->
   <script type="application/javascript" src="chrome://calendar/content/calendar-event-dialog-timezone.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-dialog-utils.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-ui-utils.js"/>
-  <script type="application/javascript" src="chrome://calendar/content/calUtils.js"/>
 
   <hbox align="center">
     <spacer flex="1"/>
     <datetimepicker id="timezone-time" disabled="true"/>
   </hbox>
 
   <menulist id="timezone-menulist" oncommand="updateTimezone()">
     <menupopup id="timezone-menupopup" style="height: 460px;"/>
--- a/calendar/base/content/dialogs/calendar-event-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-event-dialog.xul
@@ -92,17 +92,17 @@
              oncommand="onCommandSave()"/>
     <command id="cmd_item_delete"
              disable-on-readonly="true"
              oncommand="onCommandDeleteItem()"/>
     <command id="cmd_printSetup"
              oncommand="PrintUtils.showPageSetup()"/>
     <command id="cmd_print"
              disabled="true"
-             oncommand="calPrint()"/>
+             oncommand="cal.calPrint(window)"/>
 
     <!-- Edit menu -->
     <command id="cmd_undo"
              disabled="true"
              oncommand="goDoCommand('cmd_undo')"/>
     <command id="cmd_redo"
              disabled="true"
              oncommand="goDoCommand('cmd_redo')"/>
--- a/calendar/base/content/dialogs/calendar-invitations-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-invitations-dialog.xul
@@ -20,17 +20,16 @@
   ondialogcancel="return onCancel();"
   onload="return onLoad();"
   onunload="return onUnload();"
   persist="screenX screenY width height"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <!-- Javascript includes -->
   <script type="application/javascript" src="chrome://calendar/content/calendar-invitations-dialog.js"/>
-  <script type="application/javascript" src="chrome://calendar/content/calUtils.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-ui-utils.js"/>
 
   <script type="application/javascript" >
     var invitationsText = "&calendar.invitations.dialog.invitations.text;";
   </script>
 
   <vbox id="dialog-box" flex="1">
     <stack flex="1">
--- a/calendar/base/content/dialogs/calendar-invitations-list.xml
+++ b/calendar/base/content/dialogs/calendar-invitations-list.xml
@@ -114,17 +114,17 @@
           icon.setAttribute("status", val);
           return val;
         ]]></setter>
       </property>
 
       <!-- constructor -->
       <constructor><![CDATA[
         Components.utils.import("resource://calendar/modules/calUtils.jsm");
-        this.mDateFormatter = getDateFormatter();
+        this.mDateFormatter = cal.getDateFormatter();
       ]]></constructor>
 
       <!-- methods -->
       <method name="setCalendarItem">
         <parameter name="aItem"/>
         <body><![CDATA[
           this.mCalendarItem = aItem;
           this.mInitialParticipationStatus =
--- a/calendar/base/content/dialogs/calendar-migration-dialog.js
+++ b/calendar/base/content/dialogs/calendar-migration-dialog.js
@@ -243,17 +243,17 @@ var gDataMigrator = {
             };
             req.send(null);
         }
 
         // Callback from the XHR above.  Parses CalendarManager.rdf and imports
         // the data describe therein.
         function parseAndMigrate(aDoc, aCallback) {
             // For duplicate detection
-            var calManager = getCalendarManager();
+            var calManager = cal.getCalendarManager();
             var uris = [];
             for (var oldCal of calManager.getCalendars({})) {
                 uris.push(oldCal.uri);
             }
 
             function getRDFAttr(aNode, aAttr) {
                 return aNode.getAttributeNS("http://home.netscape.com/NC-rdf#",
                                             aAttr);
@@ -270,17 +270,17 @@ var gDataMigrator = {
                     migLOG("not remote");
                     var localFile = Components.classes["@mozilla.org/file/local;1"]
                                     .createInstance(Components.interfaces.nsILocalFile);
                     localFile.initWithPath(getRDFAttr(node, "path"));
                     calendar = gDataMigrator.importICSToStorage(localFile);
                 } else {
                     // Remote subscription
                     // XXX check for duplicates
-                    var url = makeURL(getRDFAttr(node, "remotePath"));
+                    var url = cal.makeURL(getRDFAttr(node, "remotePath"));
                     calendar = calManager.createCalendar("ics", url);
                 }
                 calendar.name = getRDFAttr(node, "name");
                 calendar.setProperty("color", getRDFAttr(node, "color"));
                 calManager.registerCalendar(calendar);
                 cal.getCompositeCalendar(window).addCalendar(calendar);
             }
             aCallback();
@@ -338,17 +338,17 @@ var gDataMigrator = {
      * the user has created in it.
      */
     checkIcal: function gdm_ical() {
         migLOG("Checking for ical data");
 
         function icalMigrate(aDataDir, aCallback) {
             aDataDir.append("Sources");
             var dirs = aDataDir.directoryEntries;
-            var calManager = getCalendarManager();
+            var calManager = cal.getCalendarManager();
 
             var i = 1;
             while(dirs.hasMoreElements()) {
                 var dataDir = dirs.getNext().QueryInterface(Components.interfaces.nsIFile);
                 var dataStore = dataDir.clone();
                 dataStore.append("corestorage.ics");
                 if (!dataStore.exists()) {
                     continue;
@@ -437,17 +437,17 @@ var gDataMigrator = {
                     var calendar = gDataMigrator.importICSToStorage(dataStore);
                     calendar.name = "Evolution " + (i++);
                     calManager.registerCalendar(calendar);
                     cal.getCompositeCalendar(window).addCalendar(calendar);
                 }
                 return dataStore.exists();
             }
 
-            var calManager = getCalendarManager();
+            var calManager = cal.getCalendarManager();
             var dirs = aDataDir.directoryEntries;
             while (dirs.hasMoreElements()) {
                 var dataDir = dirs.getNext().QueryInterface(Components.interfaces.nsIFile);
                 var dataStore = dataDir.clone();
                 dataStore.append("calendar.ics");
                 evoDataMigrate(dataStore);
             }
 
@@ -535,36 +535,36 @@ var gDataMigrator = {
 
     /**
      * Creates and registers a storage calendar and imports the given ics file into it.
      *
      * @param icsFile     The nsI(Local)File to import.
      */
     importICSToStorage: function migrateIcsStorage(icsFile) {
         const uri = 'moz-storage-calendar://';
-        let calendar = cal.getCalendarManager().createCalendar("storage", makeURL(uri));
+        let calendar = cal.getCalendarManager().createCalendar("storage", cal.makeURL(uri));
         let icsImporter = Components.classes["@mozilla.org/calendar/import;1?type=ics"]
                                     .getService(Components.interfaces.calIImporter);
 
         let inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
                                     .createInstance(Components.interfaces.nsIFileInputStream);
         let items = [];
 
         calendar.id = cal.getUUID();
 
         try {
             inputStream.init(icsFile, MODE_RDONLY, parseInt("0444", 8), {});
             items = icsImporter.importFromStream(inputStream, {});
         } catch(ex) {
             switch (ex.result) {
                 case Components.interfaces.calIErrors.INVALID_TIMEZONE:
-                    cal.showError(calGetString("calendar", "timezoneError", [icsFile.path]), window);
+                    cal.showError(cal.calGetString("calendar", "timezoneError", [icsFile.path]), window);
                     break;
                 default:
-                    cal.showError(calGetString("calendar", "unableToRead") + icsFile.path + "\n"+ ex, window);
+                    cal.showError(cal.calGetString("calendar", "unableToRead") + icsFile.path + "\n"+ ex, window);
             }
         } finally {
            inputStream.close();
         }
 
         // Defined in import-export.js
         putItemsIntoCal(calendar, items, icsFile.leafName);
 
--- a/calendar/base/content/dialogs/calendar-migration-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-migration-dialog.xul
@@ -19,17 +19,16 @@
         windowtype="Calendar:MigrationWizard"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         onload="gMigrateWizard.loadMigrators()"
         branded="true"
         persist="screenX screenY">
 
     <script type="application/javascript" src="chrome://calendar/content/calendar-migration-dialog.js"/>
     <script type="application/javascript" src="chrome://calendar/content/import-export.js"/>
-    <script type="application/javascript" src="chrome://calendar/content/calUtils.js"/>
 
     <wizardpage id="wizardPage1"
                 pageid="initialPage"
                 next="progressPage"
                 label="&migration.welcome;">
         <label id="wizard-desc" control="datasource-list">&migration.list.description;</label>
         <listbox id="datasource-list" flex="1">
         </listbox>
--- a/calendar/base/content/dialogs/calendar-print-dialog.js
+++ b/calendar/base/content/dialogs/calendar-print-dialog.js
@@ -69,17 +69,17 @@ function loadCalendarPrintDialog() {
  * settings.
  *
  * @param receiverFunc  The callback function to call on completion.
  */
 function getPrintSettings(receiverFunc) {
     let tempTitle = document.getElementById("title-field").value;
     let settings = {};
     let requiresFetch = true;
-    settings.title = tempTitle || calGetString("calendar", "Untitled");
+    settings.title = tempTitle || cal.calGetString("calendar", "Untitled");
     settings.layoutCId = document.getElementById("layout-field").value;
     settings.start = null;
     settings.end = null;
     settings.eventList = [];
     settings.printEvents = document.getElementById("events").checked;
     settings.printTasks = document.getElementById("tasks").checked;
     settings.printCompletedTasks = document.getElementById("completed-tasks").checked;
     settings.printTasksWithNoDueDate = document.getElementById("tasks-with-no-due-date").checked;
@@ -197,17 +197,17 @@ function getFilter(settings) {
 
 /**
  * Looks at the selections the user has made (start date, layout, etc.), and
  * updates the HTML in the iframe accordingly. This is also called when a
  * dialog UI element has changed, since we'll want to refresh the preview.
  */
 function refreshHtml(finishFunc) {
     getPrintSettings((settings) => {
-        document.title = calGetString("calendar", "PrintPreviewWindowTitle", [settings.title]);
+        document.title = cal.calGetString("calendar", "PrintPreviewWindowTitle", [settings.title]);
 
         let printformatter = Components.classes[settings.layoutCId]
                                        .createInstance(Components.interfaces.calIPrintFormatter);
         let html = "";
         try {
             let pipe = Components.classes["@mozilla.org/pipe;1"]
                                  .createInstance(Components.interfaces.nsIPipe);
             const PR_UINT32_MAX = 4294967295; // signals "infinite-length"
@@ -298,17 +298,17 @@ function printAndClose() {
     });
     return false; // leave open
 }
 
 /**
  * Called when once a date has been selected in the datepicker.
  */
 function onDatePick() {
-    calRadioGroupSelectItem("view-field", "custom-range");
+    cal.calRadioGroupSelectItem("view-field", "custom-range");
     setTimeout(refreshHtml, 0);
 }
 
 function eventsAndTasksOptions(targetId) {
     let checkbox = document.getElementById(targetId);
     let checked = checkbox.getAttribute("checked") == "true";
     // Workaround to make the checkbox persistent (bug 15232).
     checkbox.setAttribute("checked", checked ? "true" : "false");
--- a/calendar/base/content/dialogs/calendar-print-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-print-dialog.xul
@@ -21,17 +21,16 @@
         buttonaccesskeyaccept="&calendar.print.button.accesskey;"
         defaultButton="accept"
         ondialogaccept="return printAndClose();"
         ondialogcancel="return true;"
         persist="screenX screenY width height"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <script type="application/javascript" src="chrome://calendar/content/calendar-print-dialog.js"/>
-  <script type="application/javascript" src="chrome://calendar/content/calUtils.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-ui-utils.js"/>
   <script type="application/javascript" src="chrome://global/content/printUtils.js"/>
 
   <hbox id="firstHbox" flex="1">
     <vbox id="groupboxVbox">
       <groupbox id="settingsGroup">
         <caption label="&calendar.print.settingsGroup.label;"/>
 
--- a/calendar/base/content/dialogs/calendar-properties-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-properties-dialog.xul
@@ -24,17 +24,16 @@
     ondialogcancel="return true;"
     onload="onLoad()"
     persist="screenX screenY"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
     xmlns:html="http://www.w3.org/1999/xhtml"
     width="500">
 
   <script type="application/javascript" src="chrome://calendar/content/calendar-properties-dialog.js"/>
-  <script type="application/javascript" src="chrome://calendar/content/calUtils.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-ui-utils.js"/>
 
   <description id="force-disabled-description" hidden="true">&calendarproperties.forceDisabled.label;</description>
 
   <checkbox id="calendar-enabled-checkbox"
             label="&calendarproperties.enabled.label;"
             oncommand="setupEnabledCheckbox()"/>
 
--- a/calendar/base/content/dialogs/calendar-subscriptions-dialog.js
+++ b/calendar/base/content/dialogs/calendar-subscriptions-dialog.js
@@ -1,16 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* exported onLoad, onUnload, onKeyPress, onTextBoxKeyPress, onAccept,
  *          onCancel, onSubscribe, onUnsubscribe
  */
 
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
 /**
  * Cancels any pending search operations.
  */
 var gCurrentSearchOperation = null;
 function cancelPendingSearchOperation() {
     if (gCurrentSearchOperation && gCurrentSearchOperation.isPending) {
         gCurrentSearchOperation.cancel(Components.interfaces.calIErrors.OPERATION_CANCELLED);
     }
@@ -71,19 +73,19 @@ function onAccept() {
     let richListBox = document.getElementById("subscriptions-listbox");
     let rowCount = richListBox.getRowCount();
     for (let i = 0; i < rowCount; i++) {
         let richListItem = richListBox.getItemAtIndex(i);
         let checked = richListItem.checked;
         if (checked != richListItem.subscribed) {
             let calendar = richListItem.calendar;
             if (checked) {
-                getCalendarManager().registerCalendar(calendar);
+                cal.getCalendarManager().registerCalendar(calendar);
             } else {
-                getCalendarManager().unregisterCalendar(calendar);
+                cal.getCalendarManager().unregisterCalendar(calendar);
             }
         }
     }
     return true;
 }
 
 /**
  * Handler function to be called when the cancel button is pressed.
@@ -96,17 +98,17 @@ function onCancel() {
  */
 function onSearch() {
     cancelPendingSearchOperation();
 
     let richListBox = document.getElementById("subscriptions-listbox");
     richListBox.clear();
 
     let registeredCals = {};
-    for (let calendar of getCalendarManager().getCalendars({})) {
+    for (let calendar of cal.getCalendarManager().getCalendars({})) {
         registeredCals[calendar.id] = true;
     }
 
     let opListener = {
         onResult: function(operation, result) {
             if (result) {
                 for (let calendar of result) {
                     richListBox.addCalendar(calendar, registeredCals[calendar.id]);
@@ -118,18 +120,18 @@ function onSearch() {
                     statusDeck.selectedIndex = 0;
                 } else {
                     statusDeck.selectedIndex = 2;
                 }
             }
         }
     };
 
-    let operation = getCalendarSearchService().searchForCalendars(document.getElementById("search-textbox").value,
-                                                           0 /* hints */, 50, opListener);
+    let operation = cal.getCalendarSearchService().searchForCalendars(document.getElementById("search-textbox").value,
+                                                                      0 /* hints */, 50, opListener);
     if (operation && operation.isPending) {
         gCurrentSearchOperation = op;
         document.getElementById("status-deck").selectedIndex = 1;
     }
 }
 
 /**
  * Markes the selected item in the subscriptions-listbox for subscribing. The
--- a/calendar/base/content/dialogs/calendar-subscriptions-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-subscriptions-dialog.xul
@@ -23,17 +23,16 @@
   onload="return onLoad();"
   onunload="return onUnload();"
   onkeypress="onKeyPress(event);"
   persist="screenX screenY width height"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <!-- Javascript includes -->
   <script type="application/javascript" src="chrome://calendar/content/calendar-subscriptions-dialog.js"/>
-  <script type="application/javascript" src="chrome://calendar/content/calUtils.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-ui-utils.js"/>
 
   <vbox flex="1">
     <grid flex="1">
       <columns>
         <column flex="1"/>
         <column/>
       </columns>
--- a/calendar/base/content/dialogs/calendar-summary-dialog.js
+++ b/calendar/base/content/dialogs/calendar-summary-dialog.js
@@ -47,21 +47,21 @@ function onLoad() {
         setDialogId(document.documentElement, "calendar-event-summary-dialog");
     } else if (cal.isToDo(item)) {
         setDialogId(document.documentElement, "calendar-task-summary-dialog");
     }
 
     window.attendees = item.getAttendees({});
 
     let calendar = cal.wrapInstance(item.calendar, Components.interfaces.calISchedulingSupport);
-    window.readOnly = !(isCalendarWritable(calendar) &&
-                        (userCanModifyItem(item) ||
+    window.readOnly = !(cal.isCalendarWritable(calendar) &&
+                        (cal.userCanModifyItem(item) ||
                          (calendar &&
                           item.calendar.isInvitation(item) &&
-                          userCanRespondToInvitation(item))));
+                          cal.userCanRespondToInvitation(item))));
     if (!window.readOnly && calendar) {
         let attendee = calendar.getInvitedAttendee(item);
         if (attendee) {
             // if this is an unresponded invitation, preset our default alarm values:
             if (!item.getAlarms({}).length &&
                 (attendee.participationStatus == "NEEDS-ACTION")) {
                 cal.alarms.setDefaultValues(item);
             }
@@ -301,17 +301,17 @@ function updateRepeatDetails() {
     // First of all collapse the details text. If we fail to
     // create a details string, we simply don't show anything.
     // this could happen if the repeat rule is something exotic
     // we don't have any strings prepared for.
     let repeatDetails = document.getElementById("repeat-details");
     repeatDetails.setAttribute("collapsed", "true");
 
     // Try to create a descriptive string from the rule(s).
-    let kDefaultTimezone = calendarDefaultTimezone();
+    let kDefaultTimezone = cal.calendarDefaultTimezone();
     let startDate = item.startDate || item.entryDate;
     let endDate = item.endDate || item.dueDate;
     startDate = startDate ? startDate.getInTimezone(kDefaultTimezone) : null;
     endDate = endDate ? endDate.getInTimezone(kDefaultTimezone) : null;
     let detailsString = recurrenceRule2String(recurrenceInfo, startDate,
                                               endDate, startDate.isDate);
 
     if (!detailsString) {
@@ -373,17 +373,17 @@ function browseDocument() {
  */
 function sendMailToOrganizer() {
     let args = window.arguments[0];
     let item = args.calendarEvent;
     let organizer = item.organizer;
     let email = cal.getAttendeeEmail(organizer, true);
     let emailSubject = cal.calGetString("calendar-event-dialog", "emailSubjectReply", [item.title]);
     let identity = item.calendar.getProperty("imip.identity");
-    sendMailTo(email, emailSubject, null, identity);
+    cal.sendMailTo(email, emailSubject, null, identity);
 }
 
 /**
  * Opens an attachment
  *
  * @param {AUTF8String}  aAttachmentId   The hashId of the attachment to open
  */
 function openAttachment(aAttachmentId) {
--- a/calendar/base/content/dialogs/calendar-summary-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-summary-dialog.xul
@@ -35,18 +35,16 @@
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <!-- Javascript includes -->
   <script type="application/javascript"
           src="chrome://calendar/content/calendar-summary-dialog.js"/>
   <script type="application/javascript"
           src="chrome://calendar/content/calendar-dialog-utils.js"/>
   <script type="application/javascript"
-          src="chrome://calendar/content/calUtils.js"/>
-  <script type="application/javascript"
           src="chrome://calendar/content/calendar-ui-utils.js"/>
   <script type="application/javascript"
           src="chrome://calendar/content/calendar-item-editing.js"/>
   <script type="application/javascript"
           src="chrome://calendar/content/calApplicationUtils.js"/>
 
   <!-- General -->
   <box id="item-general-box" orient="vertical">
--- a/calendar/base/content/import-export.js
+++ b/calendar/base/content/import-export.js
@@ -1,13 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 /* exported loadEventsFromFile, exportEntireCalendar */
 
 // File constants copied from file-utils.js
 var MODE_RDONLY = 0x01;
 var MODE_WRONLY = 0x02;
 var MODE_CREATE = 0x08;
 var MODE_TRUNCATE = 0x20;
@@ -19,17 +20,17 @@ var MODE_TRUNCATE = 0x20;
  *                              into the calendar
  */
 function loadEventsFromFile(aCalendar) {
     const nsIFilePicker = Components.interfaces.nsIFilePicker;
 
     let picker = Components.classes["@mozilla.org/filepicker;1"]
                            .createInstance(nsIFilePicker);
     picker.init(window,
-                calGetString("calendar", "filepickerTitleImport"),
+                cal.calGetString("calendar", "filepickerTitleImport"),
                 nsIFilePicker.modeOpen);
     picker.defaultExtension = "ics";
 
     // Get a list of importers
     let contractids = [];
     let catman = Components.classes["@mozilla.org/categorymanager;1"]
                            .getService(Components.interfaces.nsICategoryManager);
     let catenum = catman.enumerateCategory("cal-importers");
@@ -104,31 +105,31 @@ function loadEventsFromFile(aCalendar) {
         }
 
         if (aCalendar) {
             putItemsIntoCal(aCalendar, items);
             return;
         }
 
         let calendars = cal.getCalendarManager().getCalendars({});
-        calendars = calendars.filter(isCalendarWritable);
+        calendars = calendars.filter(cal.isCalendarWritable);
 
         if (calendars.length < 1) {
             // XXX alert something?
             return;
         } else if (calendars.length == 1) {
             // There's only one calendar, so it's silly to ask what calendar
             // the user wants to import into.
             putItemsIntoCal(calendars[0], items, filePath);
         } else {
             // Ask what calendar to import into
             let args = {};
             args.onOk = (aCal) => { putItemsIntoCal(aCal, items, filePath); };
             args.calendars = calendars;
-            args.promptText = calGetString("calendar", "importPrompt");
+            args.promptText = cal.calGetString("calendar", "importPrompt");
             openDialog("chrome://calendar/content/chooseCalendarDialog.xul",
                        "_blank", "chrome,titlebar,modal,resizable", args);
         }
     }
 }
 
 /**
  * Put items into a certain calendar, catching errors and showing them to the
@@ -169,19 +170,19 @@ function putItemsIntoCal(destCal, aItems
                     failedCount++;
                     lastError = aStatus;
                 }
             }
             // See if it is time to end the calendar's batch.
             if (count == aItems.length) {
                 destCal.endBatch();
                 if (!failedCount && duplicateCount) {
-                    cal.showError(calGetString("calendar", "duplicateError", [duplicateCount, aFilePath]), window);
+                    cal.showError(cal.calGetString("calendar", "duplicateError", [duplicateCount, aFilePath]), window);
                 } else if (failedCount) {
-                    cal.showError(calGetString("calendar", "importItemsFailed", [failedCount, lastError.toString()]), window);
+                    cal.showError(cal.calGetString("calendar", "importItemsFailed", [failedCount, lastError.toString()]), window);
                 }
             }
         }
     };
 
     for (let item of aItems) {
         // XXX prompt when finding a duplicate.
         try {
@@ -215,25 +216,25 @@ function saveEventsToFile(calendarEventA
 
     // Show the 'Save As' dialog and ask for a filename to save to
     const nsIFilePicker = Components.interfaces.nsIFilePicker;
 
     let picker = Components.classes["@mozilla.org/filepicker;1"]
                        .createInstance(nsIFilePicker);
 
     picker.init(window,
-                calGetString("calendar", "filepickerTitleExport"),
+                cal.calGetString("calendar", "filepickerTitleExport"),
                 nsIFilePicker.modeSave);
 
     if (aDefaultFileName && aDefaultFileName.length && aDefaultFileName.length > 0) {
         picker.defaultString = aDefaultFileName;
     } else if (calendarEventArray.length == 1 && calendarEventArray[0].title) {
         picker.defaultString = calendarEventArray[0].title;
     } else {
-        picker.defaultString = calGetString("calendar", "defaultFileName");
+        picker.defaultString = cal.calGetString("calendar", "defaultFileName");
     }
 
     picker.defaultExtension = "ics";
 
     // Get a list of exporters
     let contractids = [];
     let catman = Components.classes["@mozilla.org/categorymanager;1"]
                            .getService(Components.interfaces.nsICategoryManager);
@@ -301,17 +302,17 @@ function saveEventsToFile(calendarEventA
             // XXX Do the right thing with unicode and stuff. Or, again, should the
             //     exporter handle that?
             exporter.exportToStream(outputStream,
                                     calendarEventArray.length,
                                     calendarEventArray,
                                     null);
             outputStream.close();
         } catch (ex) {
-            cal.showError(calGetString("calendar", "unableToWrite") + filePath, window);
+            cal.showError(cal.calGetString("calendar", "unableToWrite") + filePath, window);
         }
     }
 }
 
 /**
  * Exports all the events and tasks in a calendar.  If aCalendar is not specified,
  * the user will be prompted with a list of calendars to choose which one to export.
  *
@@ -335,24 +336,24 @@ function exportEntireCalendar(aCalendar)
         aCal.getItems(Components.interfaces.calICalendar.ITEM_FILTER_ALL_ITEMS,
                       0, null, null, getListener);
     };
 
     if (aCalendar) {
         getItemsFromCal(aCalendar);
     } else {
         let count = {};
-        let calendars = getCalendarManager().getCalendars(count);
+        let calendars = cal.getCalendarManager().getCalendars(count);
 
         if (count.value == 1) {
             // There's only one calendar, so it's silly to ask what calendar
             // the user wants to import into.
             getItemsFromCal(calendars[0]);
         } else {
             // Ask what calendar to import into
             let args = {};
             args.onOk = getItemsFromCal;
-            args.promptText = calGetString("calendar", "exportPrompt");
+            args.promptText = cal.calGetString("calendar", "exportPrompt");
             openDialog("chrome://calendar/content/chooseCalendarDialog.xul",
                        "_blank", "chrome,titlebar,modal,resizable", args);
         }
     }
 }
--- a/calendar/base/content/preferences/categories.js
+++ b/calendar/base/content/preferences/categories.js
@@ -46,17 +46,17 @@ var gCategoriesPane = {
         let categories = document.getElementById("calendar.categories.names").value;
 
         // If no categories are configured load a default set from properties file
         if (!categories) {
             categories = cal.setupDefaultCategories();
             document.getElementById("calendar.categories.names").value = categories;
         }
 
-        gCategoryList = categoriesStringToArray(categories);
+        gCategoryList = cal.categoriesStringToArray(categories);
 
         // When categories is empty, split returns an array containing one empty
         // string, rather than an empty array. This results in an empty listbox
         // child with no corresponding category.
         if (gCategoryList.length == 1 && !gCategoryList[0].length) {
             gCategoryList.pop();
         }
 
@@ -83,17 +83,17 @@ var gCategoriesPane = {
     /**
      * Updates the listbox containing the categories from the categories saved
      * in preferences.
      */
 
     updatePrefs: function() {
         cal.sortArrayByLocaleCollator(gCategoryList);
         document.getElementById("calendar.categories.names").value =
-            categoriesArrayToString(gCategoryList);
+            cal.categoriesArrayToString(gCategoryList);
     },
 
     updateCategoryList: function() {
         this.updatePrefs();
         let listbox = document.getElementById("categorieslist");
 
         listbox.clearSelection();
         this.updateButtons();
@@ -103,17 +103,17 @@ var gCategoriesPane = {
             listbox.lastChild.remove();
         }
 
         for (let i = 0; i < gCategoryList.length; i++) {
             let newListItem = document.createElement("listitem");
             let categoryName = document.createElement("listcell");
             categoryName.setAttribute("id", gCategoryList[i]);
             categoryName.setAttribute("label", gCategoryList[i]);
-            let categoryNameFix = formatStringForCSSRule(gCategoryList[i]);
+            let categoryNameFix = cal.formatStringForCSSRule(gCategoryList[i]);
             let categoryColor = document.createElement("listcell");
             try {
                 let colorCode = categoryPrefBranch.getCharPref(categoryNameFix);
                 categoryColor.setAttribute("id", colorCode);
                 categoryColor.setAttribute("style", "background-color: " + colorCode + ";");
             } catch (ex) {
                 categoryColor.setAttribute("label", noneLabel);
             }
@@ -144,17 +144,17 @@ var gCategoriesPane = {
         }
     },
 
     /**
      * Edits the currently selected category using the edit category dialog.
      */
     editCategory: function() {
         let list = document.getElementById("categorieslist");
-        let categoryNameFix = formatStringForCSSRule(gCategoryList[list.selectedIndex]);
+        let categoryNameFix = cal.formatStringForCSSRule(gCategoryList[list.selectedIndex]);
         let currentColor = null;
         try {
             currentColor = categoryPrefBranch.getCharPref(categoryNameFix);
         } catch (ex) {
             // If the pref doesn't exist, don't bail out here.
         }
         let params = {
             title: editTitle,
@@ -174,17 +174,17 @@ var gCategoriesPane = {
      * Removes the selected category.
      */
     deleteCategory: function() {
         let list = document.getElementById("categorieslist");
         if (list.selectedCount < 1) {
             return;
         }
 
-        let categoryNameFix = formatStringForCSSRule(gCategoryList[list.selectedIndex]);
+        let categoryNameFix = cal.formatStringForCSSRule(gCategoryList[list.selectedIndex]);
         this.backupData(categoryNameFix);
         try {
             categoryPrefBranch.clearUserPref(categoryNameFix);
         } catch (ex) {
             // If the pref doesn't exist, don't bail out here.
         }
 
         // Remove category entry from listbox and gCategoryList.
@@ -235,17 +235,17 @@ var gCategoriesPane = {
             }
         }
 
         if (categoryName.length == 0) {
             Services.prompt.alert(null, null, noBlankCategories);
             return;
         }
 
-        let categoryNameFix = formatStringForCSSRule(categoryName);
+        let categoryNameFix = cal.formatStringForCSSRule(categoryName);
         if (list.selectedIndex == -1) {
             this.backupData(categoryNameFix);
             gCategoryList.push(categoryName);
             if (categoryColor) {
                 categoryPrefBranch.setCharPref(categoryNameFix, categoryColor);
             }
         } else {
             this.backupData(categoryNameFix);
--- a/calendar/base/content/preferences/general.js
+++ b/calendar/base/content/preferences/general.js
@@ -13,18 +13,18 @@ var gCalendarGeneralPane = {
     /**
      * Initialize the general pref pane. Sets up dialog controls to match the
      * values set in prefs.
      */
     init: function() {
         let formatter = Components.classes["@mozilla.org/calendar/datetime-formatter;1"]
                                   .getService(Components.interfaces.calIDateTimeFormatter);
 
-        let dateFormattedLong = formatter.formatDateLong(now());
-        let dateFormattedShort = formatter.formatDateShort(now());
+        let dateFormattedLong = formatter.formatDateLong(cal.now());
+        let dateFormattedShort = formatter.formatDateShort(cal.now());
 
         // menu items include examples of current date formats.
         document.getElementById("dateformat-long-menuitem")
                 .setAttribute("label", labelLong + ": " + dateFormattedLong);
         document.getElementById("dateformat-short-menuitem")
                 .setAttribute("label", labelShort + ": " + dateFormattedShort);
 
         // deselect and reselect to update visible item title
@@ -51,17 +51,17 @@ var gCalendarGeneralPane = {
         // the display names need to be sorted
         displayNames.sort((a, b) => a.localeCompare(b));
         for (let displayName of displayNames) {
             addMenuItem(tzMenuPopup, displayName, tzids[displayName]);
         }
 
         let prefValue = document.getElementById("calendar-timezone-local").value;
         if (!prefValue) {
-            prefValue = calendarDefaultTimezone().tzid;
+            prefValue = cal.calendarDefaultTimezone().tzid;
         }
         tzMenuList.value = prefValue;
 
         // Set the soondays menulist preference
         this.initializeTodaypaneMenu();
     },
 
     updateDefaultTodoDates: function() {
--- a/calendar/base/content/preferences/general.xul
+++ b/calendar/base/content/preferences/general.xul
@@ -15,18 +15,16 @@
 <overlay id="CalendarGeneralPaneOverlay"
          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <vbox id="calPreferencesBoxGeneral">
         <script type="application/javascript"
                 src="chrome://calendar/content/preferences/general.js"/>
         <script type="application/javascript"
                 src="chrome://calendar/content/calendar-ui-utils.js"/>
-        <script type="application/javascript"
-                src="chrome://calendar/content/calUtils.js"/>
 
         <!-- Get the localized text for use in the .js -->
         <script type="application/javascript">
             var labelLong  = "&pref.dateformat.long;";
             var labelShort = "&pref.dateformat.short;";
         </script>
 
         <preferences>
--- a/calendar/base/content/today-pane.xul
+++ b/calendar/base/content/today-pane.xul
@@ -110,17 +110,17 @@
                           <toolbarbutton id="previous-day-button"
                                          class="miniday-nav-buttons"
                                          tooltiptext="&onedaybackward.tooltip;"
                                          onmousedown="TodayPane.onMousedown(event, parseInt(this.getAttribute('dir')));"
                                          dir="-1"/>
                           <toolbarbutton id="today-button"
                                          class="miniday-nav-buttons"
                                          tooltiptext="&showToday.tooltip;"
-                                         oncommand="TodayPane.setDay(now());"/>
+                                         oncommand="TodayPane.setDay(cal.now());"/>
                           <toolbarbutton id="next-day-button"
                                          class="miniday-nav-buttons"
                                          tooltiptext="&onedayforward.tooltip;"
                                          onmousedown="TodayPane.onMousedown(event, parseInt(this.getAttribute('dir')));"
                                          dir="1"/>
                         </hbox>
                       </hbox>
                       <hbox pack="start">
--- a/calendar/base/content/widgets/calendar-alarm-widget.xml
+++ b/calendar/base/content/widgets/calendar-alarm-widget.xml
@@ -87,19 +87,19 @@
           // Dates
           if (cal.isEvent(this.mItem)) {
               dateLabel.textContent = formatter.formatItemInterval(this.mItem);
           } else if (cal.isToDo(this.mItem)) {
               let startDate = this.mItem.entryDate || this.mItem.dueDate;
               if (startDate) {
                   // A Task with a start or due date, show with label
                   startDate = startDate.getInTimezone(cal.calendarDefaultTimezone());
-                  dateLabel.textContent = calGetString("calendar",
-                                                       "alarmStarts",
-                                                       [formatter.formatDateTime(startDate)]);
+                  dateLabel.textContent = cal.calGetString("calendar",
+                                                           "alarmStarts",
+                                                           [formatter.formatDateTime(startDate)]);
               } else {
                   // If the task has no start date, then format the alarm date.
                   dateLabel.textContent = formatter.formatDateTime(this.mAlarm.alarmDate);
               }
           } else {
               throw Components.results.NS_ERROR_ILLEGAL_VALUE;
           }
 
@@ -117,43 +117,43 @@
       </method>
 
       <method name="updateRelativeDateLabel">
         <body><![CDATA[
           let formatter = cal.getDateFormatter();
           let item = this.mItem;
           let relativeDateLabel = document.getAnonymousElementByAttribute(this, "anonid", "alarm-relative-date-label");
           let relativeDateString;
-          let startDate = item[calGetStartDateProp(item)] || item[calGetEndDateProp(item)];
+          let startDate = item[cal.calGetStartDateProp(item)] || item[cal.calGetEndDateProp(item)];
           if (startDate) {
-              startDate = startDate.getInTimezone(calendarDefaultTimezone());
-              let currentDate = now();
+              startDate = startDate.getInTimezone(cal.calendarDefaultTimezone());
+              let currentDate = cal.now();
               let sinceDayStart = (currentDate.hour * 3600) + (currentDate.minute * 60);
 
               currentDate.second = 0;
               startDate.second = 0;
 
               let sinceAlarm = currentDate.subtractDate(startDate).inSeconds;
               this.mAlarmToday = (sinceAlarm < sinceDayStart) && (sinceAlarm > sinceDayStart - 86400);
 
               if (this.mAlarmToday) {
                   // The alarm is today
-                  relativeDateString = calGetString("calendar",
-                                                    "alarmTodayAt",
-                                                    [formatter.formatTime(startDate)]);
+                  relativeDateString = cal.calGetString("calendar",
+                                                        "alarmTodayAt",
+                                                        [formatter.formatTime(startDate)]);
               } else if (sinceAlarm <= sinceDayStart - 86400 && sinceAlarm > sinceDayStart - 172800) {
                   // The alarm is tomorrow
-                  relativeDateString = calGetString("calendar",
-                                                    "alarmTomorrowAt",
-                                                    [formatter.formatTime(startDate)]);
+                  relativeDateString = cal.calGetString("calendar",
+                                                        "alarmTomorrowAt",
+                                                        [formatter.formatTime(startDate)]);
               } else if (sinceAlarm < sinceDayStart + 86400 && sinceAlarm > sinceDayStart) {
                   // The alarm is yesterday
-                  relativeDateString = calGetString("calendar",
-                                                    "alarmYesterdayAt",
-                                                    [formatter.formatTime(startDate)]);
+                  relativeDateString = cal.calGetString("calendar",
+                                                        "alarmYesterdayAt",
+                                                        [formatter.formatTime(startDate)]);
               } else {
                   // The alarm is way back
                   relativeDateString = [formatter.formatDateTime(startDate)];
               }
           } else {
               // No start or end date, therefore the alarm must be absolute and
               // have an alarm date.
               relativeDateString = [formatter.formatDateTime(this.mAlarm.alarmDate)];
@@ -239,16 +239,17 @@
                            class="snooze-popup-button snooze-popup-cancel-button"
                            aria-label="&calendar.alarm.snooze.cancel;"
                            oncommand="snoozeCancel()"/>
       </xul:hbox>
     </content>
     <implementation>
       <constructor><![CDATA[
         Components.utils.import("resource://gre/modules/Preferences.jsm");
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
         let snoozePref = Preferences.get("calendar.alarms.defaultsnoozelength", 0);
         if (snoozePref <= 0) {
             snoozePref = 5;
         }
 
         let unitList = document.getAnonymousElementByAttribute(this, "anonid", "snooze-unit-menulist");
         let unitValue = document.getAnonymousElementByAttribute(this, "anonid", "snooze-value-textbox");
--- a/calendar/base/content/widgets/calendar-list-tree.xml
+++ b/calendar/base/content/widgets/calendar-list-tree.xml
@@ -39,17 +39,17 @@
         ]]></getter>
         <setter><![CDATA[
           this.mCompositeCalendar = val;
           this.mCompositeCalendar.addObserver(this.compositeObserver);
 
           // Now that we have a composite calendar, we can get all calendars
           // from the calendar manager.
           this.mAddingFromComposite = true;
-          let calendars = sortCalendarArray(getCalendarManager().getCalendars({}));
+          let calendars = sortCalendarArray(cal.getCalendarManager().getCalendars({}));
           calendars.forEach(this.addCalendar, this);
           this.mAddingFromComposite = false;
 
           return val;
         ]]></setter>
       </property>
 
       <property name="calendars">
@@ -151,19 +151,19 @@
         let calendar = this.getCalendarFromEvent(event, col);
         if (event.button != 0 ||
             (col.value && col.value.element &&
              col.value.element.getAttribute("anonid") == "checkbox-treecol")) {
             // Only left clicks that are not on the checkbox column
             return;
         }
         if (calendar) {
-            openCalendarProperties(calendar);
+            cal.openCalendarProperties(window, calendar);
         } else {
-            openCalendarWizard();
+            cal.openCalendarWizard(window);
         }
       ]]></handler>
     </handlers>
   </binding>
 
   <binding id="calendar-list-tree">
     <content>
       <xul:tree anonid="tree"
--- a/calendar/base/content/widgets/calendar-widgets.xml
+++ b/calendar/base/content/widgets/calendar-widgets.xml
@@ -41,16 +41,20 @@
                    class="categories-listbox"
                    onselect="document.getBindingParent(this).selectCategory()"
                    selType="multiple"
                    >
         <children/>
       </xul:listbox>
     </content>
     <implementation>
+      <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+      ]]></constructor>
+
       <field name="_maxCount">0</field>
 
       <property name="categories" readonly="true">
         <getter><![CDATA[
           let categoryListbox = document.getAnonymousElementByAttribute(this, "anonid", "categories-listbox");
           if (this.maxCount == 1) {
               let selectedItem = categoryListbox.selectedItem;
               return selectedItem ? [selectedItem.getAttribute("value")] : [];
@@ -175,17 +179,17 @@
           categoryListbox.ensureElementIsVisible(item);
         ]]></body>
       </method>
 
       <method name="loadItem">
         <parameter name="aItem"/>
         <body><![CDATA[
           let categoryListbox = document.getAnonymousElementByAttribute(this, "anonid", "categories-listbox");
-          let categoryList = getPrefCategoriesArray();
+          let categoryList = cal.getPrefCategoriesArray();
 
           cal.sortArrayByLocaleCollator(categoryList);
 
           removeChildren(categoryListbox);
 
           for (let cat of categoryList) {
               // First insert all categories from the prefs
               let item = categoryListbox.appendItem(cat, cat);
@@ -229,22 +233,23 @@
       </xul:stack>
       <xul:label class="toolbarbutton-text" crop="right" flex="1"
                  xbl:inherits="value=label,accesskey,crop,toolbarmode,buttonstyle"/>
       <xul:image class="toolbarbutton-icon-end" xbl:inherits="validate,src-end=image,toolbarmode,buttonstyle"/>
     </content>
 
     <implementation>
       <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
         this.setUpTodayDate();
       ]]></constructor>
 
       <method name="setUpTodayDate">
         <body><![CDATA[
-          let dayNumber = calGetString("dateFormat", "day." + cal.now().day + ".number");
+          let dayNumber = cal.calGetString("dateFormat", "day." + cal.now().day + ".number");
           document.getAnonymousElementByAttribute(this, "anonid", "day-label").value = dayNumber;
         ]]></body>
       </method>
     </implementation>
    </binding>
 
   <!-- this binding directly extends to a checkbox but is visualized as
        a treenode in a treecontrol-->
@@ -515,16 +520,20 @@
   <!-- This binding may server as a droptarget container for arbitrary items
        it contains methods to add DropShadows. This binding is meant to be used
        as a parent binding. The methods may be overwritten. -->
   <binding id="dragndropContainer">
     <implementation>
       <field name="mDropShadows">[]</field>
       <field name="mCalendarView">null</field>
 
+      <constructor><![CDATA[
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+      ]]></constructor>
+
       <!-- The ViewController that supports the interface 'calICalendarView'-->
       <property name="calendarView"
                 onget="return this.mCalendarView;"
                 onset="return (this.mCalendarView = val);"/>
 
       <!-- method to add individual code e.g to set up the new item during
        'ondrop' -->
       <method name="onDropItem">
@@ -677,17 +686,17 @@
             return;
         }
         let item = session.sourceNode.sourceObject.clone();
         this.setAttribute("dropbox", "false");
         let transfer = Components.classes["@mozilla.org/widget/transferable;1"]
                                  .createInstance(Components.interfaces.nsITransferable);
         transfer.init(null);
 
-        if (isEvent(item)) {
+        if (cal.isEvent(item)) {
             transfer.addDataFlavor("application/x-moz-cal-event");
         } else {
             transfer.addDataFlavor("application/x-moz-cal-task");
         }
 
         session.getData(transfer, 0);
         item = session.sourceNode.sourceObject;
 
--- a/calendar/base/content/widgets/minimonth.xml
+++ b/calendar/base/content/widgets/minimonth.xml
@@ -129,17 +129,19 @@
       </xul:popupset>
     </content>
     <implementation>
       <field name="kMinimonth">null</field>
       <field name="mPopup">null</field>
       <field name="mScrollYearsHandler">null</field>
       <field name="mPixelScrollDelta">0</field>
       <constructor><![CDATA[
-        this.kMinimonth = getParentNodeOrThis(this, "minimonth");
+        Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
+        this.kMinimonth = cal.getParentNodeOrThis(this, "minimonth");
         document.getAnonymousElementByAttribute(this, "anonid", "back-button").kMinimonth = this.kMinimonth;
         document.getAnonymousElementByAttribute(this, "anonid", "today-button").kMinimonth = this.kMinimonth;
         document.getAnonymousElementByAttribute(this, "anonid", "forward-button").kMinimonth = this.kMinimonth;
 
         this.mScrollYearsHandler = this.scrollYears.bind(this);
         document.getAnonymousElementByAttribute(this, "anonid", "years-popup")
                 .addEventListener("wheel", this.mScrollYearsHandler, true);
       ]]></constructor>
@@ -181,17 +183,17 @@
               this.kMinimonth.fireEvent("popuplisthidden");
           }
         ]]></body>
       </method>
 
       <method name="onMonthsPopupCommand">
         <parameter name="aItem"/>
         <body><![CDATA[
-          let popup = getParentNodeOrThis(aItem, "menupopup");
+          let popup = cal.getParentNodeOrThis(aItem, "menupopup");
           let triggerNode = popup.triggerNode || popup.anchorNode;
           let deck = triggerNode.parentNode;
 
           this.hidePopupList();
           this.kMinimonth.switchMonth(aItem.getAttribute("index"));
 
           deck.childNodes[deck.selectedIndex].focus();
         ]]></body>
@@ -233,17 +235,17 @@
               year.setFullYear(curfullYear + 1);
           }
         ]]></body>
       </method>
 
       <method name="scrollYears">
         <parameter name="event"/>
         <body><![CDATA[
-          let yearPopup = getParentNodeOrThis(event.target, "menupopup");
+          let yearPopup = cal.getParentNodeOrThis(event.target, "menupopup");
           const pixelThreshold = 75;
           if (yearPopup) {
               let monthList = yearPopup.getElementsByAttribute("class", "minimonth-list");
               if (monthList && monthList.length > 0) {
                   if (event.deltaMode == event.DOM_DELTA_PAGE) {
                       let dir = event.deltaY > 0 ? "up" : "down";
                       this.moveYears(dir, Math.abs(event.deltaY) * monthList.length);
                   } else if (event.deltaMode == event.DOM_DELTA_LINE) {
@@ -571,18 +573,18 @@
       <method name="setBusyDaysForOccurrence">
         <parameter name="aOccurrence"/>
         <parameter name="aState"/>
         <body><![CDATA[
           if (aOccurrence.getProperty("TRANSP") == "TRANSPARENT") {
               // Skip transparent events
               return;
           }
-          let start = aOccurrence[calGetStartDateProp(aOccurrence)] || aOccurrence.dueDate;
-          let end = aOccurrence[calGetEndDateProp(aOccurrence)] || start;
+          let start = aOccurrence[cal.calGetStartDateProp(aOccurrence)] || aOccurrence.dueDate;
+          let end = aOccurrence[cal.calGetEndDateProp(aOccurrence)] || start;
           if (!start) {
               return;
           }
 
           // We need to compare with midnight of the current day, so reset the
           // time here.
           let current = start.clone().getInTimezone(cal.calendarDefaultTimezone());
           current.hour = 0;
@@ -751,17 +753,17 @@
           let longDayList = new Array(7);
           let tempDate = new Date();
           let i, j;
           let useOSFormat;
           tempDate.setDate(tempDate.getDate() - (tempDate.getDay() - this.weekStart));
           for (i = 0; i < 7; i++) {
               // if available, use UILocale days, else operating system format
               try {
-                  dayList[i] = calGetString("dateFormat",
+                  dayList[i] = cal.calGetString("dateFormat",
                                "day." + (tempDate.getDay() + 1) + ".short");
               } catch (e) {
                   dayList[i] = tempDate.toLocaleDateString(undefined, { weekday: 'short' });
                   useOSFormat = true;
               }
               longDayList[i] = tempDate.toLocaleDateString(undefined, { weekday: 'long' });
               tempDate.setDate(tempDate.getDate() + 1);
           }
@@ -863,21 +865,21 @@
           let date = this._getStartDate(aDate);
 
           // get today's date
           let today = new Date();
 
           if (aDate.getFullYear() != (this.mValue || this.mExtraDate).getFullYear()) {
               let monthName = cal.formatMonth(aDate.getMonth() + 1,
                                               "calendar", "monthInYear");
-              let label = calGetString("calendar", "monthInYear",
+              let label = cal.calGetString("calendar", "monthInYear",
                                        [monthName, aDate.getFullYear()]);
               calbox.setAttribute("aria-label", label);
           } else {
-              calbox.setAttribute("aria-label", calGetString("dateFormat",
+              calbox.setAttribute("aria-label", cal.calGetString("dateFormat",
                                   "month." + (aDate.getMonth() + 1) + ".name"));
           }
 
           this.mDayMap = {};
           let defaultTz = cal.calendarDefaultTimezone();
           for (let k = 1; k < 7; k++) {
               // Set the week number.
               let firstElement = this._getCalBoxNode(k, 0);
--- a/calendar/base/jar.mn
+++ b/calendar/base/jar.mn
@@ -94,17 +94,16 @@ calendar.jar:
     content/calendar/preferences/views.xul                 (content/preferences/views.xul)
     content/calendar/widgets/minimonth.xml                 (content/widgets/minimonth.xml)
     content/calendar/widgets/calendar-alarm-widget.xml     (content/widgets/calendar-alarm-widget.xml)
     content/calendar/widgets/calendar-widgets.xml          (content/widgets/calendar-widgets.xml)
     content/calendar/widgets/calendar-list-tree.xml        (content/widgets/calendar-list-tree.xml)
     content/calendar/calendar-subscriptions-list.xml       (content/widgets/calendar-subscriptions-list.xml)
     content/calendar/widgets/calendar-widget-bindings.css  (content/widgets/calendar-widget-bindings.css)
     content/calendar/calApplicationUtils.js                (src/calApplicationUtils.js)
-    content/calendar/calUtils.js                           (src/calUtils.js)
     content/calendar/calFilter.js                          (src/calFilter.js)
     content/calendar/WindowsNTToZoneInfoTZId.properties    (src/WindowsNTToZoneInfoTZId.properties)
 % skin calendar classic/1.0 chrome/skin/linux/calendar/
 % skin calendar classic/1.0 chrome/skin/osx/calendar/ os=Darwin
 % skin calendar classic/1.0 chrome/skin/windows/calendar/ os=WINNT
 % skin calendar-common classic/1.0 chrome/skin/common/
 % style chrome://global/content/customizeToolbar.xul chrome://calendar/skin/calendar-task-view.css
 % style chrome://global/content/customizeToolbar.xul chrome://calendar/skin/calendar-event-dialog.css
--- a/calendar/base/modules/calProviderUtils.jsm
+++ b/calendar/base/modules/calProviderUtils.jsm
@@ -300,19 +300,16 @@ cal.getEmailIdentityOfCalendar = functio
  *
  * @param aStr          The RFC3339 compliant Date String
  * @param aTimezone     The timezone this date string is most likely in
  * @return              A calIDateTime object
  */
 cal.fromRFC3339 = function(aStr, aTimezone) {
     // XXX I have not covered leapseconds (matches[8]), this might need to
     // be done. The only reference to leap seconds I found is bug 227329.
-    //
-
-    // Create a DateTime instance (calUtils.js)
     let dateTime = cal.createDateTime();
 
     // Killer regex to parse RFC3339 dates
     let re = new RegExp("^([0-9]{4})-([0-9]{2})-([0-9]{2})" +
         "([Tt]([0-9]{2}):([0-9]{2}):([0-9]{2})(\\.[0-9]+)?)?" +
         "(([Zz]|([+-])([0-9]{2}):([0-9]{2})))?");
 
     let matches = re.exec(aStr);
--- a/calendar/base/modules/calUtils.jsm
+++ b/calendar/base/modules/calUtils.jsm
@@ -1,31 +1,25 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-// New code must not load/import calUtils.js, but should use calUtils.jsm.
-
 var gCalThreadingEnabled;
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 
 // Usually the backend loader gets loaded via profile-after-change, but in case
 // a calendar component hooks in earlier, its very likely it will use calUtils.
 // Getting the service here will load if its not already loaded
 Components.classes["@mozilla.org/calendar/backend-loader;1"].getService();
 
 this.EXPORTED_SYMBOLS = ["cal"];
 var cal = {
-    // new code should land here,
-    // and more code should be moved from calUtils.js into this object to avoid
-    // clashes with other extensions
-
     getDragService: generateServiceAccessor("@mozilla.org/widget/dragservice;1",
                                                 Components.interfaces.nsIDragService),
 
     /**
      * Loads an array of calendar scripts into the passed scope.
      *
      * @param scriptNames an array of calendar script names
      * @param scope       scope to load into
@@ -175,17 +169,17 @@ var cal = {
         // without cloning, because changes cannot be calculated if doing so.
         if (cal.isEvent(item)) {
             let date = item.startDate.clone();
             date.addDuration(offset);
             item.startDate = date;
             date = item.endDate.clone();
             date.addDuration(offset);
             item.endDate = date;
-        } else /* isToDo */ {
+        } else /* cal.isToDo */ {
             if (item.entryDate) {
                 let date = item.entryDate.clone();
                 date.addDuration(offset);
                 item.entryDate = date;
             }
             if (item.dueDate) {
                 let date = item.dueDate.clone();
                 date.addDuration(offset);
@@ -776,60 +770,60 @@ var cal = {
      * moves an item to another startDate
      *
      * @param aOldItem             The Item to be modified
      * @param aNewDate             The date at which the new item is going to start
      * @return                     The modified item
      */
     moveItem: function(aOldItem, aNewDate) {
         let newItem = aOldItem.clone();
-        let start = (aOldItem[calGetStartDateProp(aOldItem)] ||
-                     aOldItem[calGetEndDateProp(aOldItem)]).clone();
+        let start = (aOldItem[cal.calGetStartDateProp(aOldItem)] ||
+                     aOldItem[cal.calGetEndDateProp(aOldItem)]).clone();
         let isDate = start.isDate;
         start.resetTo(aNewDate.year, aNewDate.month, aNewDate.day,
                       start.hour, start.minute, start.second,
                       start.timezone);
         start.isDate = isDate;
-        if (newItem[calGetStartDateProp(newItem)]) {
-            newItem[calGetStartDateProp(newItem)] = start;
+        if (newItem[cal.calGetStartDateProp(newItem)]) {
+            newItem[cal.calGetStartDateProp(newItem)] = start;
             let oldDuration = aOldItem.duration;
             if (oldDuration) {
-                let oldEnd = aOldItem[calGetEndDateProp(aOldItem)];
+                let oldEnd = aOldItem[cal.calGetEndDateProp(aOldItem)];
                 let newEnd = start.clone();
                 newEnd.addDuration(oldDuration);
                 newEnd = newEnd.getInTimezone(oldEnd.timezone);
-                newItem[calGetEndDateProp(newItem)] = newEnd;
+                newItem[cal.calGetEndDateProp(newItem)] = newEnd;
             }
-        } else if (newItem[calGetEndDateProp(newItem)]) {
-            newItem[calGetEndDateProp(newItem)] = start;
+        } else if (newItem[cal.calGetEndDateProp(newItem)]) {
+            newItem[cal.calGetEndDateProp(newItem)] = start;
         }
         return newItem;
     },
 
     /**
      * sets the 'isDate' property of an item
      *
      * @param aItem         The Item to be modified
      * @param aIsDate       True or false indicating the new value of 'isDate'
      * @return              The modified item
      */
     setItemToAllDay: function(aItem, aIsDate) {
-        let start = aItem[calGetStartDateProp(aItem)];
-        let end = aItem[calGetEndDateProp(aItem)];
+        let start = aItem[cal.calGetStartDateProp(aItem)];
+        let end = aItem[cal.calGetEndDateProp(aItem)];
         if (start || end) {
             let item = aItem.clone();
             if (start && (start.isDate != aIsDate)) {
                 start = start.clone();
                 start.isDate = aIsDate;
-                item[calGetStartDateProp(item)] = start;
+                item[cal.calGetStartDateProp(item)] = start;
             }
             if (end && (end.isDate != aIsDate)) {
                 end = end.clone();
                 end.isDate = aIsDate;
-                item[calGetEndDateProp(item)] = end;
+                item[cal.calGetEndDateProp(item)] = end;
             }
             return item;
         } else {
             return aItem;
         }
     },
 
     /**
--- a/calendar/base/src/calAlarm.js
+++ b/calendar/base/src/calAlarm.js
@@ -7,17 +7,17 @@ Components.utils.import("resource://cale
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 var ALARM_RELATED_ABSOLUTE = Components.interfaces.calIAlarm.ALARM_RELATED_ABSOLUTE;
 var ALARM_RELATED_START = Components.interfaces.calIAlarm.ALARM_RELATED_START;
 var ALARM_RELATED_END = Components.interfaces.calIAlarm.ALARM_RELATED_END;
 
 function calAlarm() {
     this.wrappedJSObject = this;
-    this.mProperties = new calPropertyBag();
+    this.mProperties = new cal.calPropertyBag();
     this.mPropertyParams = {};
     this.mAttendees = [];
     this.mAttachments = [];
 }
 
 var calAlarmClassID = Components.ID("{b8db7c7f-c168-4e11-becb-f26c1c4f5f8f}");
 var calAlarmInterfaces = [Components.interfaces.calIAlarm];
 calAlarm.prototype = {
@@ -125,17 +125,17 @@ calAlarm.prototype = {
             if (this[member] && this[member].clone) {
                 cloned[member] = this[member].clone();
             } else {
                 cloned[member] = this[member];
             }
         }
 
         // X-Props
-        cloned.mProperties = new calPropertyBag();
+        cloned.mProperties = new cal.calPropertyBag();
         for (let [name, value] of this.mProperties) {
             if (value instanceof Components.interfaces.calIDateTime) {
                 value = value.clone();
             }
 
             cloned.mProperties.setProperty(name, value);
 
             let propBucket = this.mPropertyParams[name];
@@ -360,31 +360,31 @@ calAlarm.prototype = {
     },
 
     get icalString() {
         let comp = this.icalComponent;
         return (comp ? comp.serializeToICS() : "");
     },
     set icalString(val) {
         this.ensureMutable();
-        return (this.icalComponent = getIcsService().parseICS(val, null));
+        return (this.icalComponent = cal.getIcsService().parseICS(val, null));
     },
 
     promotedProps: {
         "ACTION": "action",
         "TRIGGER": "offset",
         "REPEAT": "repeat",
         "DURATION": "duration",
         "SUMMARY": "summary",
         "DESCRIPTION": "description",
         "X-MOZ-LASTACK": "lastAck"
     },
 
     get icalComponent() {
-        let icssvc = getIcsService();
+        let icssvc = cal.getIcsService();
         let comp = icssvc.createIcalComponent("VALARM");
 
         // Set up action (REQUIRED)
         let actionProp = icssvc.createIcalProperty("ACTION");
         actionProp.value = this.action;
         comp.addProperty(actionProp);
 
         // Set up trigger (REQUIRED)
@@ -436,28 +436,28 @@ calAlarm.prototype = {
             comp.addProperty(attachment.icalProperty);
         }
 
         // Set up summary (REQUIRED for EMAIL)
         if (this.summary || this.action == "EMAIL") {
             let summaryProp = icssvc.createIcalProperty("SUMMARY");
             // Summary needs to have a non-empty value
             summaryProp.value = this.summary ||
-                calGetString("calendar", "alarmDefaultSummary");
+                cal.calGetString("calendar", "alarmDefaultSummary");
             comp.addProperty(summaryProp);
         }
 
         // Set up the description (REQUIRED for DISPLAY and EMAIL)
         if (this.description ||
             this.action == "DISPLAY" ||
             this.action == "EMAIL") {
             let descriptionProp = icssvc.createIcalProperty("DESCRIPTION");
             // description needs to have a non-empty value
             descriptionProp.value = this.description ||
-                calGetString("calendar", "alarmDefaultDescription");
+                cal.calGetString("calendar", "alarmDefaultDescription");
             comp.addProperty(descriptionProp);
         }
 
         // Set up lastAck
         if (this.lastAck) {
             let lastAckProp = icssvc.createIcalProperty("X-MOZ-LASTACK");
             lastAckProp.value = this.lastAck;
             comp.addProperty(lastAckProp);
@@ -558,17 +558,17 @@ calAlarm.prototype = {
         // Set up description
         this.description = (descriptionProp ? descriptionProp.value : null);
 
         // Set up the alarm lastack. We can't use valueAsDatetime here since
         // the default for an X-Prop is TEXT and in older versions we didn't set
         // VALUE=DATE-TIME.
         this.lastAck = (lastAckProp ? cal.createDateTime(lastAckProp.valueAsIcalString) : null);
 
-        this.mProperties = new calPropertyBag();
+        this.mProperties = new cal.calPropertyBag();
         this.mPropertyParams = {};
 
         // Other properties
         for (let prop of cal.ical.propertyIterator(aComp)) {
             if (!this.promotedProps[prop.propertyName]) {
                 this.setProperty(prop.propertyName, prop.value);
 
                 for (let [paramName, param] of cal.ical.paramIterator(prop)) {
@@ -617,19 +617,19 @@ calAlarm.prototype = {
     },
 
     get propertyEnumerator() {
         return this.mProperties.enumerator;
     },
 
     toString: function(aItem) {
         function getItemBundleStringName(aPrefix) {
-            if (!aItem || isEvent(aItem)) {
+            if (!aItem || cal.isEvent(aItem)) {
                 return aPrefix + "Event";
-            } else if (isToDo(aItem)) {
+            } else if (cal.isToDo(aItem)) {
                 return aPrefix + "Task";
             } else {
                 return aPrefix;
             }
         }
 
         if (this.related == ALARM_RELATED_ABSOLUTE && this.mAbsoluteDate) {
             // this is an absolute alarm. Use the calendar default timezone and
@@ -639,21 +639,21 @@ calAlarm.prototype = {
             return formatter.formatDateTime(formatDate);
         } else if (this.related != ALARM_RELATED_ABSOLUTE && this.mOffset) {
             // Relative alarm length
             let alarmlen = Math.abs(this.mOffset.inSeconds / 60);
             if (alarmlen == 0) {
                 // No need to get the other information if the alarm is at the start
                 // of the event/task.
                 if (this.related == ALARM_RELATED_START) {
-                    return calGetString("calendar-alarms",
-                                        getItemBundleStringName("reminderTitleAtStart"));
+                    return cal.calGetString("calendar-alarms",
+                                            getItemBundleStringName("reminderTitleAtStart"));
                 } else if (this.related == ALARM_RELATED_END) {
-                    return calGetString("calendar-alarms",
-                                        getItemBundleStringName("reminderTitleAtEnd"));
+                    return cal.calGetString("calendar-alarms",
+                                            getItemBundleStringName("reminderTitleAtEnd"));
                 }
             }
 
             let unit;
             if (alarmlen % 1440 == 0) {
                 // Alarm is in days
                 unit = "unitDays";
                 alarmlen /= 1440;
@@ -679,20 +679,20 @@ calAlarm.prototype = {
             }
 
             if (this.offset.isNegative) {
                 originStringName += "Before";
             } else {
                 originStringName += "After";
             }
 
-            let originString = calGetString("calendar-alarms",
-                                            getItemBundleStringName(originStringName));
-            return calGetString("calendar-alarms",
-                                "reminderCustomTitle",
-                                [unitString, originString]);
+            let originString = cal.calGetString("calendar-alarms",
+                                                getItemBundleStringName(originStringName));
+            return cal.calGetString("calendar-alarms",
+                                    "reminderCustomTitle",
+                                    [unitString, originString]);
         } else {
             // This is an incomplete alarm, but then again we should never reach
             // this state.
             return "[Incomplete calIAlarm]";
         }
     }
 };
--- a/calendar/base/src/calAlarmMonitor.js
+++ b/calendar/base/src/calAlarmMonitor.js
@@ -97,17 +97,17 @@ calAlarmMonitor.prototype = {
                 this.mAlarmSoundCount++;
             }
 
             if (maxAlarmSoundCount > this.mAlarmSoundCount) {
                 // Only ring the alarm sound if we haven't hit the max count.
                 try {
                     let soundURL = Preferences.get("calendar.alarms.soundURL", null);
                     if (soundURL && soundURL.length > 0) {
-                        soundURL = makeURL(soundURL);
+                        soundURL = cal.makeURL(soundURL);
                         this.mSound.play(soundURL);
                     } else {
                         this.mSound.beep();
                     }
                 } catch (exc) {
                     cal.ERROR("Error playing alarm sound: " + exc);
                 }
             }
--- a/calendar/base/src/calAlarmService.js
+++ b/calendar/base/src/calAlarmService.js
@@ -26,17 +26,17 @@ function newTimerWithCallback(aCallback,
     return timer;
 }
 
 function calAlarmService() {
     this.wrappedJSObject = this;
 
     this.mLoadedCalendars = {};
     this.mTimerMap = {};
-    this.mObservers = new calListenerBag(Components.interfaces.calIAlarmServiceObserver);
+    this.mObservers = new cal.calListenerBag(Components.interfaces.calIAlarmServiceObserver);
 
     this.calendarObserver = {
         alarmService: this,
 
         QueryInterface: XPCOMUtils.generateQI([Components.interfaces.calIObserver]),
 
         // calIObserver:
         onStartBatch: function() { },
@@ -139,17 +139,17 @@ calAlarmService.prototype = {
     },
 
     /**
      * calIAlarmService APIs
      */
     get timezone() {
         // TODO Do we really need this? Do we ever set the timezone to something
         // different than the default timezone?
-        return this.mTimezone || calendarDefaultTimezone();
+        return this.mTimezone || cal.calendarDefaultTimezone();
     },
 
     set timezone(aTimezone) {
         return (this.mTimezone = aTimezone);
     },
 
     snoozeAlarm: function(aItem, aAlarm, aDuration) {
         // Right now we only support snoozing all alarms for the given item for
@@ -216,19 +216,19 @@ calAlarmService.prototype = {
         Services.obs.addObserver(this, "wake_notification", false);
 
         /* Tell people that we're alive so they can start monitoring alarms.
          */
         let notifier = Components.classes["@mozilla.org/embedcomp/appstartup-notifier;1"]
                                  .getService(Components.interfaces.nsIObserver);
         notifier.observe(null, "alarm-service-startup", null);
 
-        getCalendarManager().addObserver(this.calendarManagerObserver);
+        cal.getCalendarManager().addObserver(this.calendarManagerObserver);
 
-        for (let calendar of getCalendarManager().getCalendars({})) {
+        for (let calendar of cal.getCalendarManager().getCalendars({})) {
             this.observeCalendar(calendar);
         }
 
         /* set up a timer to update alarms every N hours */
         let timerCallback = {
             alarmService: this,
             notify: function() {
                 let now = nowUTC();
@@ -246,19 +246,19 @@ calAlarmService.prototype = {
                     this.alarmService.mRangeStart = start.clone();
                 }
                 let until = now.clone();
                 until.month += Components.interfaces.calIAlarmService.MAX_SNOOZE_MONTHS;
 
                 // We don't set timers for every future alarm, only those within 6 hours
                 let end = now.clone();
                 end.hour += kHoursBetweenUpdates;
-                this.alarmService.mRangeEnd = end.getInTimezone(UTC());
+                this.alarmService.mRangeEnd = end.getInTimezone(cal.UTC());
 
-                this.alarmService.findAlarms(getCalendarManager().getCalendars({}),
+                this.alarmService.findAlarms(cal.getCalendarManager().getCalendars({}),
                                              start, until);
             }
         };
         timerCallback.notify();
 
         this.mUpdateTimer = newTimerWithCallback(timerCallback, kHoursBetweenUpdates * 3600000, true);
 
         this.mStarted = true;
@@ -325,17 +325,17 @@ calAlarmService.prototype = {
 
             // Handle all day events.  This is kinda weird, because they don't have
             // a well defined startTime.  We just consider the start/end to be
             // midnight in the user's timezone.
             if (alarmDate.isDate) {
                 alarmDate = alarmDate.getInTimezone(this.timezone);
                 alarmDate.isDate = false;
             }
-            alarmDate = alarmDate.getInTimezone(UTC());
+            alarmDate = alarmDate.getInTimezone(cal.UTC());
 
             // Check for snooze
             let snoozeDate;
             if (aItem.parentItem == aItem) {
                 snoozeDate = aItem.getProperty("X-MOZ-SNOOZE-TIME");
             } else {
                 snoozeDate = aItem.parentItem.getProperty("X-MOZ-SNOOZE-TIME-" + aItem.recurrenceId.nativeTime);
             }
@@ -348,17 +348,17 @@ calAlarmService.prototype = {
             if (snoozeDate && snoozeDate.compare(alarmDate) > 0) {
                 // If the alarm was snoozed, the snooze time is more important.
                 alarmDate = snoozeDate;
             }
 
             let now = nowUTC();
             if (alarmDate.timezone.isFloating) {
                 now = cal.now();
-                now.timezone = floating();
+                now.timezone = cal.floating();
             }
 
             if (alarmDate.compare(now) >= 0) {
                 // We assume that future alarms haven't been acknowledged
                 // Delay is in msec, so don't forget to multiply
                 let timeout = alarmDate.subtractDate(now).inSeconds * 1000;
 
                 // No sense in keeping an extra timeout for an alarm thats past
--- a/calendar/base/src/calAttachment.js
+++ b/calendar/base/src/calAttachment.js
@@ -51,17 +51,17 @@ calAttachment.prototype = {
      */
 
     get uri() {
         let uri = null;
         if (this.getParameter("VALUE") != "BINARY") {
             // If this is not binary data, its likely an uri. Attempt to convert
             // and throw otherwise.
             try {
-                uri = makeURL(this.mData);
+                uri = cal.makeURL(this.mData);
             } catch (e) {
                 // Its possible that the uri contains malformed data. Often
                 // callers don't expect an exception here, so we just catch
                 // it and return null.
             }
         }
 
         return uri;
--- a/calendar/base/src/calAttendee.js
+++ b/calendar/base/src/calAttendee.js
@@ -3,17 +3,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calIteratorUtils.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 function calAttendee() {
     this.wrappedJSObject = this;
-    this.mProperties = new calPropertyBag();
+    this.mProperties = new cal.calPropertyBag();
 }
 
 var calAttendeeClassID = Components.ID("{5c8dcaa3-170c-4a73-8142-d531156f664d}");
 var calAttendeeInterfaces = [Components.interfaces.calIAttendee];
 calAttendee.prototype = {
     classID: calAttendeeClassID,
     QueryInterface: XPCOMUtils.generateQI(calAttendeeInterfaces),
     classInfo: XPCOMUtils.generateCI({
@@ -79,17 +79,17 @@ calAttendee.prototype = {
         for (let prop of this.icalAttendeePropMap) {
             this[prop.cal] = icalatt.getParameter(prop.ics);
             // Don't copy these to the property bag.
             promotedProps[prop.ics] = true;
         }
 
         // Reset the property bag for the parameters, it will be re-initialized
         // from the ical property.
-        this.mProperties = new calPropertyBag();
+        this.mProperties = new cal.calPropertyBag();
 
         for (let [name, value] of cal.ical.paramIterator(icalatt)) {
             if (!promotedProps[name]) {
                 this.setProperty(name, value);
             }
         }
     },
 
--- a/calendar/base/src/calCachedCalendar.js
+++ b/calendar/base/src/calCachedCalendar.js
@@ -1,12 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calProviderUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 
 var calICalendar = Components.interfaces.calICalendar;
 var cICL = Components.interfaces.calIChangeLog;
 var cIOL = Components.interfaces.calIOperationListener;
@@ -196,17 +197,17 @@ calCachedCalendar.prototype = {
                     case "memory": {
                         if (this.supportsChangeLog) {
                             // start with full sync:
                             this.mUncachedCalendar.resetLog();
                         }
                         break;
                     }
                     case "storage": {
-                        let file = getCalendarDirectory();
+                        let file = cal.getCalendarDirectory();
                         file.append("cache.sqlite");
                         cachedCalendar.uri = Services.io.newFileURI(file);
                         cachedCalendar.id = this.id;
                         break;
                     }
                     default: {
                         throw new Error("unsupported cache calendar type: " + calType);
                     }
--- a/calendar/base/src/calCalendarManager.js
+++ b/calendar/base/src/calCalendarManager.js
@@ -10,18 +10,18 @@ Components.utils.import("resource://cale
 
 var REGISTRY_BRANCH = "calendar.registry.";
 var DB_SCHEMA_VERSION = 10;
 var MAX_INT = Math.pow(2, 31) - 1;
 var MIN_INT = -MAX_INT;
 
 function calCalendarManager() {
     this.wrappedJSObject = this;
-    this.mObservers = new calListenerBag(Components.interfaces.calICalendarManagerObserver);
-    this.mCalendarObservers = new calListenerBag(Components.interfaces.calIObserver);
+    this.mObservers = new cal.calListenerBag(Components.interfaces.calICalendarManagerObserver);
+    this.mCalendarObservers = new cal.calListenerBag(Components.interfaces.calIObserver);
 }
 
 var calCalendarManagerClassID = Components.ID("{f42585e7-e736-4600-985d-9624c1c51992}");
 var calCalendarManagerInterfaces = [
     Components.interfaces.calICalendarManager,
     Components.interfaces.calIStartupService,
     Components.interfaces.nsIObserver,
 ];
@@ -398,21 +398,21 @@ calCalendarManager.prototype = {
 
     //
     // / DB migration code ends here
     //
 
     alertAndQuit: function() {
         // We want to include the extension name in the error message rather
         // than blaming Thunderbird.
-        let hostAppName = calGetString("brand", "brandShortName", null, "branding");
-        let calAppName = calGetString("lightning", "brandShortName", null, "lightning");
-        let errorBoxTitle = calGetString("calendar", "tooNewSchemaErrorBoxTitle", [calAppName]);
-        let errorBoxText = calGetString("calendar", "tooNewSchemaErrorBoxTextLightning", [calAppName, hostAppName]);
-        let errorBoxButtonLabel = calGetString("calendar", "tooNewSchemaButtonRestart", [hostAppName]);
+        let hostAppName = cal.calGetString("brand", "brandShortName", null, "branding");
+        let calAppName = cal.calGetString("lightning", "brandShortName", null, "lightning");
+        let errorBoxTitle = cal.calGetString("calendar", "tooNewSchemaErrorBoxTitle", [calAppName]);
+        let errorBoxText = cal.calGetString("calendar", "tooNewSchemaErrorBoxTextLightning", [calAppName, hostAppName]);
+        let errorBoxButtonLabel = cal.calGetString("calendar", "tooNewSchemaButtonRestart", [hostAppName]);
 
         let promptSvc = Services.prompt;
 
         let errorBoxButtonFlags = promptSvc.BUTTON_POS_0 *
                                   promptSvc.BUTTON_TITLE_IS_STRING +
                                   promptSvc.BUTTON_POS_0_DEFAULT;
 
         promptSvc.confirmEx(null,
@@ -455,20 +455,20 @@ calCalendarManager.prototype = {
                 uiMessage = ex.message;
             }
             switch (rc) {
                 case Components.interfaces.calIErrors.STORAGE_UNKNOWN_SCHEMA_ERROR:
                     // For now we alert and quit on schema errors like we've done before:
                     this.alertAndQuit();
                     return null;
                 case Components.interfaces.calIErrors.STORAGE_UNKNOWN_TIMEZONES_ERROR:
-                    uiMessage = calGetString("calendar", "unknownTimezonesError", [uri.spec]);
+                    uiMessage = cal.calGetString("calendar", "unknownTimezonesError", [uri.spec]);
                     break;
                 default:
-                    uiMessage = calGetString("calendar", "unableToCreateProvider", [uri.spec]);
+                    uiMessage = cal.calGetString("calendar", "unableToCreateProvider", [uri.spec]);
                     break;
             }
             // Log the original exception via error console to provide more debug info
             cal.ERROR(ex);
 
             // Log the possibly translated message via the UI.
             let paramBlock = Components.classes["@mozilla.org/embedcomp/dialogparam;1"]
                                        .createInstance(Components.interfaces.nsIDialogParamBlock);
@@ -939,30 +939,30 @@ calMgrCalendarObserver.prototype = {
         switch (aErrNo) {
             case calIErrors.CAL_UTF8_DECODING_FAILED:
                 message = props.GetStringFromName("utf8DecodeError");
                 break;
             case calIErrors.ICS_MALFORMEDDATA:
                 message = props.GetStringFromName("icsMalformedError");
                 break;
             case calIErrors.MODIFICATION_FAILED:
-                errMsg = calGetString("calendar", "errorWriting", [aCalendar.name]);
+                errMsg = cal.calGetString("calendar", "errorWriting", [aCalendar.name]);
                 // falls through
             default:
                 message = aMessage;
         }
 
 
         paramBlock.SetString(0, errMsg);
         paramBlock.SetString(1, errCode);
         paramBlock.SetString(2, message);
 
         this.storedReadOnly = this.calendar.readOnly;
-        let errorCode = calGetString("calendar", "errorCode", [errCode]);
-        let errorDescription = calGetString("calendar", "errorDescription", [message]);
+        let errorCode = cal.calGetString("calendar", "errorCode", [errCode]);
+        let errorDescription = cal.calGetString("calendar", "errorDescription", [message]);
         let summary = errMsg + " " + errorCode + ". " + errorDescription;
 
         // Log warnings in error console.
         // Report serious errors in both error console and in prompt window.
         if (aErrNo == calIErrors.MODIFICATION_FAILED) {
             Components.utils.reportError(summary);
             this.announceParamBlock(paramBlock);
         } else {
--- a/calendar/base/src/calCalendarSearchService.js
+++ b/calendar/base/src/calCalendarSearchService.js
@@ -1,18 +1,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
 function calCalendarSearchListener(numOperations, finalListener) {
     this.mFinalListener = finalListener;
     this.mNumOperations = numOperations;
     this.mResults = [];
 
-    this.opGroup = new calOperationGroup(() => {
+    this.opGroup = new cal.calOperationGroup(() => {
         this.notifyResult(null);
     });
 }
 calCalendarSearchListener.prototype = {
     mFinalListener: null,
     mNumOperations: 0,
     opGroup: null,
 
@@ -39,17 +41,17 @@ calCalendarSearchListener.prototype = {
                 this.notifyResult(aResult);
             }
         }
     }
 };
 
 function calCalendarSearchService() {
     this.wrappedJSObject = this;
-    this.mProviders = new calInterfaceBag(Components.interfaces.calICalendarSearchProvider);
+    this.mProviders = new cal.calInterfaceBag(Components.interfaces.calICalendarSearchProvider);
 }
 var calCalendarSearchServiceClassID = Components.ID("{f5f743cd-8997-428e-bc1b-644e73f61203}");
 var calCalendarSearchServiceInterfaces = [
     Components.interfaces.calICalendarSearchProvider,
     Components.interfaces.calICalendarSearchService
 ];
 calCalendarSearchService.prototype = {
     mProviders: null,
--- a/calendar/base/src/calDateTimeFormatter.js
+++ b/calendar/base/src/calDateTimeFormatter.js
@@ -97,25 +97,25 @@ calDateTimeFormatter.prototype = {
         // TODO should we check for the same day? The caller should know what
         // he is doing...
         return this.formatTime(aStartDate) + "\u2013" + this.formatTime(aEndDate);
     },
 
     formatInterval: function(aStartDate, aEndDate) {
         // Check for tasks without start and/or due date
         if (aEndDate == null && aStartDate == null) {
-            return calGetString("calendar", "datetimeIntervalTaskWithoutDate");
+            return cal.calGetString("calendar", "datetimeIntervalTaskWithoutDate");
         } else if (aEndDate == null) {
             let startDateString = this.formatDate(aStartDate);
             let startTime = this.formatTime(aStartDate);
-            return calGetString("calendar", "datetimeIntervalTaskWithoutDueDate", [startDateString, startTime]);
+            return cal.calGetString("calendar", "datetimeIntervalTaskWithoutDueDate", [startDateString, startTime]);
         } else if (aStartDate == null) {
             let endDateString = this.formatDate(aEndDate);
             let endTime = this.formatTime(aEndDate);
-            return calGetString("calendar", "datetimeIntervalTaskWithoutStartDate", [endDateString, endTime]);
+            return cal.calGetString("calendar", "datetimeIntervalTaskWithoutStartDate", [endDateString, endTime]);
         }
         // Here there are only events or tasks with both start and due date.
         // make sure start and end use the same timezone when formatting intervals:
         let endDate = aEndDate.getInTimezone(aStartDate.timezone);
         let testdate = aStartDate.clone();
         testdate.isDate = true;
         let sameDay = (testdate.compare(endDate) == 0);
         if (aStartDate.isDate) {
@@ -146,41 +146,41 @@ calDateTimeFormatter.prototype = {
             let endDateString = this.formatDate(endDate);
             let endTime = this.formatTime(endDate);
             // non-allday, so need to return date and time
             if (sameDay) {
                 // End is on the same day as start, so we can leave out the end date
                 if (startTime == endTime) {
                     // End time is on the same time as start, so we can leave out the end time
                     // "5 Jan 2006 13:00"
-                    return calGetString("calendar", "datetimeIntervalOnSameDateTime", [startDateString, startTime]);
+                    return cal.calGetString("calendar", "datetimeIntervalOnSameDateTime", [startDateString, startTime]);
                 } else {
                     // still include end time
                     // "5 Jan 2006 13:00 - 17:00"
-                    return calGetString("calendar", "datetimeIntervalOnSameDay", [startDateString, startTime, endTime]);
+                    return cal.calGetString("calendar", "datetimeIntervalOnSameDay", [startDateString, startTime, endTime]);
                 }
             } else {
                 // Spanning multiple days, so need to include date and time
                 // for start and end
                 // "5 Jan 2006 13:00 - 7 Jan 2006 9:00"
-                return calGetString("calendar", "datetimeIntervalOnSeveralDays", [startDateString, startTime, endDateString, endTime]);
+                return cal.calGetString("calendar", "datetimeIntervalOnSeveralDays", [startDateString, startTime, endDateString, endTime]);
             }
         }
     },
 
     formatDayWithOrdinal: function(aDay) {
         let ordinalSymbols = this.mDateStringBundle.GetStringFromName("dayOrdinalSymbol").split(",");
         let dayOrdinalSymbol = ordinalSymbols[aDay - 1] || ordinalSymbols[0];
         return aDay + dayOrdinalSymbol;
     },
 
     _getItemDates: function(aItem) {
-        let start = aItem[calGetStartDateProp(aItem)];
-        let end = aItem[calGetEndDateProp(aItem)];
-        let kDefaultTimezone = calendarDefaultTimezone();
+        let start = aItem[cal.calGetStartDateProp(aItem)];
+        let end = aItem[cal.calGetEndDateProp(aItem)];
+        let kDefaultTimezone = cal.calendarDefaultTimezone();
         // Check for tasks without start and/or due date
         if (start) {
             start = start.getInTimezone(kDefaultTimezone);
         }
         if (end) {
             end = end.getInTimezone(kDefaultTimezone);
         }
         // EndDate is exclusive. For all-day events, we ened to substract one day,
--- a/calendar/base/src/calEvent.js
+++ b/calendar/base/src/calEvent.js
@@ -76,28 +76,28 @@ calEvent.prototype = {
         return this.startDate;
     },
 
     icsEventPropMap: [
     { cal: "DTSTART", ics: "startTime" },
     { cal: "DTEND", ics: "endTime" }],
 
     set icalString(value) {
-        this.icalComponent = getIcsService().parseICS(value, null);
+        this.icalComponent = cal.getIcsService().parseICS(value, null);
     },
 
     get icalString() {
-        let calcomp = getIcsService().createIcalComponent("VCALENDAR");
-        calSetProdidVersion(calcomp);
+        let calcomp = cal.getIcsService().createIcalComponent("VCALENDAR");
+        cal.calSetProdidVersion(calcomp);
         calcomp.addSubcomponent(this.icalComponent);
         return calcomp.serializeToICS();
     },
 
     get icalComponent() {
-        let icssvc = getIcsService();
+        let icssvc = cal.getIcsService();
         let icalcomp = icssvc.createIcalComponent("VEVENT");
         this.fillIcalComponentFromBase(icalcomp);
         this.mapPropsToICS(icalcomp, this.icsEventPropMap);
 
         let bagenum = this.propertyEnumerator;
         while (bagenum.hasMoreElements()) {
             let iprop = bagenum.getNext()
                                .QueryInterface(Components.interfaces.nsIProperty);
--- a/calendar/base/src/calFilter.js
+++ b/calendar/base/src/calFilter.js
@@ -368,17 +368,17 @@ calFilter.prototype = {
     /**
      * Checks if the item matches the current filter date range.
      *
      * @param aItem               The item to check.
      * @return                    Returns true if the item falls within the date range
      *                            specified by mStartDate and mEndDate, false otherwise.
      */
     dateRangeFilter: function(aItem) {
-        return checkIfInRange(aItem, this.mStartDate, this.mEndDate);
+        return cal.checkIfInRange(aItem, this.mStartDate, this.mEndDate);
     },
 
     /**
      * Checks if the item matches the currently applied filter properties. Filter properties
      * with a value of null or that are not applicable to the item's type are not tested.
      *
      * @param aItem               The item to check.
      * @return                    Returns true if the item matches the filter properties
--- a/calendar/base/src/calFreeBusyService.js
+++ b/calendar/base/src/calFreeBusyService.js
@@ -1,19 +1,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 function calFreeBusyListener(numOperations, finalListener) {
     this.mFinalListener = finalListener;
     this.mNumOperations = numOperations;
 
-    this.opGroup = new calOperationGroup(() => {
+    this.opGroup = new cal.calOperationGroup(() => {
         this.notifyResult(null);
     });
 }
 calFreeBusyListener.prototype = {
     mFinalListener: null,
     mNumOperations: 0,
     opGroup: null,
 
@@ -46,17 +47,17 @@ calFreeBusyListener.prototype = {
                 this.notifyResult([]);
             }
         }
     }
 };
 
 function calFreeBusyService() {
     this.wrappedJSObject = this;
-    this.mProviders = new calInterfaceBag(Components.interfaces.calIFreeBusyProvider);
+    this.mProviders = new cal.calInterfaceBag(Components.interfaces.calIFreeBusyProvider);
 }
 var calFreeBusyServiceClassID = Components.ID("{29c56cd5-d36e-453a-acde-0083bd4fe6d3}");
 var calFreeBusyServiceInterfaces = [
     Components.interfaces.calIFreeBusyProvider,
     Components.interfaces.calIFreeBusyService
 ];
 calFreeBusyService.prototype = {
     mProviders: null,
--- a/calendar/base/src/calIcsParser.js
+++ b/calendar/base/src/calIcsParser.js
@@ -70,17 +70,17 @@ calIcsParser.prototype = {
 
         state.join(() => {
             let fakedParents = {};
             // tag "exceptions", i.e. items with rid:
             for (let item of state.excItems) {
                 let parent = state.uid2parent[item.id];
 
                 if (!parent) { // a parentless one, fake a master and override it's occurrence
-                    parent = isEvent(item) ? createEvent() : createTodo();
+                    parent = cal.isEvent(item) ? cal.createEvent() : cal.createTodo();
                     parent.id = item.id;
                     parent.setProperty("DTSTART", item.recurrenceId);
                     parent.setProperty("X-MOZ-FAKED-MASTER", "1"); // this tag might be useful in the future
                     parent.recurrenceInfo = cal.createRecurrenceInfo(parent);
                     fakedParents[item.id] = true;
                     state.uid2parent[item.id] = parent;
                     state.items.push(parent);
                 }
@@ -97,18 +97,18 @@ calIcsParser.prototype = {
             }
 
             if (Object.keys(state.tzErrors).length > 0) {
                 // Use an alert rather than a prompt because problems may appear in
                 // remote subscribed calendars the user cannot change.
                 if (Components.classes["@mozilla.org/alerts-service;1"]) {
                     let notifier = Components.classes["@mozilla.org/alerts-service;1"]
                                              .getService(Components.interfaces.nsIAlertsService);
-                    let title = calGetString("calendar", "TimezoneErrorsAlertTitle");
-                    let text = calGetString("calendar", "TimezoneErrorsSeeConsole");
+                    let title = cal.calGetString("calendar", "TimezoneErrorsAlertTitle");
+                    let text = cal.calGetString("calendar", "TimezoneErrorsSeeConsole");
                     try {
                         notifier.showAlertNotification("", title, text, false, null, null, title);
                     } catch (e) {
                         // The notifier may not be available, e.g. on xpcshell tests
                     }
                 }
             }
 
@@ -242,17 +242,17 @@ parserState.prototype = {
             let hid = item.hashId + "#" + tzid;
             if (!(hid in this.tzErrors)) {
                 // For now, publish errors to console and alert user.
                 // In future, maybe make them available through an interface method
                 // so this UI code can be removed from the parser, and caller can
                 // choose whether to alert, or show user the problem items and ask
                 // for fixes, or something else.
                 let msgArgs = [tzid, item.title, cal.getDateFormatter().formatDateTime(date)];
-                let msg = calGetString("calendar", "unknownTimezoneInItem", msgArgs);
+                let msg = cal.calGetString("calendar", "unknownTimezoneInItem", msgArgs);
 
                 cal.ERROR(msg + "\n" + item.icalString);
                 this.tzErrors[hid] = true;
             }
         }
     },
 
     /**
--- a/calendar/base/src/calIcsSerializer.js
+++ b/calendar/base/src/calIcsSerializer.js
@@ -56,18 +56,18 @@ calIcsSerializer.prototype = {
                                    .createInstance(Components.interfaces.nsIConverterOutputStream);
         convStream.init(aStream, "UTF-8", 0, 0x0000);
 
         convStream.writeString(str);
         convStream.close();
     },
 
     getIcalComponent: function() {
-        let calComp = getIcsService().createIcalComponent("VCALENDAR");
-        calSetProdidVersion(calComp);
+        let calComp = cal.getIcsService().createIcalComponent("VCALENDAR");
+        cal.calSetProdidVersion(calComp);
 
         // xxx todo: think about that the below code doesn't clone the properties/components,
         //           thus ownership is moved to returned VCALENDAR...
 
         for (let prop of this.mProperties) {
             calComp.addProperty(prop);
         }
         for (let comp of this.mComponents) {
--- a/calendar/base/src/calItemBase.js
+++ b/calendar/base/src/calItemBase.js
@@ -40,17 +40,17 @@ calItemBase.prototype = {
     mACLEntry: null,
 
     /**
      * Initialize the base item's attributes. Can be called from inheriting
      * objects in their constructor.
      */
     initItemBase: function() {
         this.wrappedJSObject = this;
-        this.mProperties = new calPropertyBag();
+        this.mProperties = new cal.calPropertyBag();
         this.mPropertyParams = {};
         this.mProperties.setProperty("CREATED", cal.jsDateToDateTime(new Date()));
     },
 
     /**
      * @see nsISupports
      */
     QueryInterface: XPCOMUtils.generateQI([Components.interfaces.calIItemBase]),
@@ -77,17 +77,17 @@ calItemBase.prototype = {
 
     // readonly attribute AUTF8String hashId;
     get hashId() {
         if (this.mHashId === null) {
             let rid = this.recurrenceId;
             let calendar = this.calendar;
             // some unused delim character:
             this.mHashId = [encodeURIComponent(this.id),
-                            rid ? rid.getInTimezone(UTC()).icalString : "",
+                            rid ? rid.getInTimezone(cal.UTC()).icalString : "",
                             calendar ? encodeURIComponent(calendar.id) : ""].join("#");
         }
         return this.mHashId;
     },
 
     // attribute AUTF8String id;
     get id() {
         return this.getProperty("UID");
@@ -111,45 +111,45 @@ calItemBase.prototype = {
     },
 
     // attribute calIRecurrenceInfo recurrenceInfo;
     get recurrenceInfo() {
         return this.mRecurrenceInfo;
     },
     set recurrenceInfo(value) {
         this.modify();
-        return (this.mRecurrenceInfo = calTryWrappedJSObject(value));
+        return (this.mRecurrenceInfo = cal.calTryWrappedJSObject(value));
     },
 
     // attribute calIItemBase parentItem;
     get parentItem() {
         return this.mParentItem || this;
     },
     set parentItem(value) {
         if (this.mImmutable) {
             throw Components.results.NS_ERROR_OBJECT_IS_IMMUTABLE;
         }
-        return (this.mParentItem = calTryWrappedJSObject(value));
+        return (this.mParentItem = cal.calTryWrappedJSObject(value));
     },
 
     /**
      * Initializes the base item to be an item proxy. Used by inheriting
      * objects createProxy() method.
      *
      * XXXdbo Explain proxy a bit better, either here or in
      * calIInternalShallowCopy.
      *
      * @see calIInternalShallowCopy
      * @param aParentItem     The parent item to initialize the proxy on.
      * @param aRecurrenceId   The recurrence id to initialize the proxy for.
      */
     initializeProxy: function(aParentItem, aRecurrenceId) {
         this.mIsProxy = true;
 
-        aParentItem = calTryWrappedJSObject(aParentItem);
+        aParentItem = cal.calTryWrappedJSObject(aParentItem);
         this.mParentItem = aParentItem;
         this.mCalendar = aParentItem.mCalendar;
         this.recurrenceId = aRecurrenceId;
 
         // Make sure organizer is unset, as the getter checks for this.
         this.mOrganizer = undefined;
 
         this.mImmutable = aParentItem.mImmutable;
@@ -246,36 +246,36 @@ calItemBase.prototype = {
      *
      * @param m     The item to clone this item into
      * @param aNewParent    (optional) The new parent item to set on m.
      */
     cloneItemBaseInto: function(cloned, aNewParent) {
         cloned.mImmutable = false;
         cloned.mACLEntry = this.mACLEntry;
         cloned.mIsProxy = this.mIsProxy;
-        cloned.mParentItem = calTryWrappedJSObject(aNewParent) || this.mParentItem;
+        cloned.mParentItem = cal.calTryWrappedJSObject(aNewParent) || this.mParentItem;
         cloned.mHashId = this.mHashId;
         cloned.mCalendar = this.mCalendar;
         if (this.mRecurrenceInfo) {
-            cloned.mRecurrenceInfo = calTryWrappedJSObject(this.mRecurrenceInfo.clone());
+            cloned.mRecurrenceInfo = cal.calTryWrappedJSObject(this.mRecurrenceInfo.clone());
             cloned.mRecurrenceInfo.item = cloned;
         }
 
         let org = this.organizer;
         if (org) {
             org = org.clone();
         }
         cloned.mOrganizer = org;
 
         cloned.mAttendees = [];
         for (let att of this.getAttendees({})) {
             cloned.mAttendees.push(att.clone());
         }
 
-        cloned.mProperties = new calPropertyBag();
+        cloned.mProperties = new cal.calPropertyBag();
         for (let [name, value] of this.mProperties) {
             if (value instanceof Components.interfaces.calIDateTime) {
                 value = value.clone();
             }
 
             cloned.mProperties.setProperty(name, value);
 
             let propBucket = this.mPropertyParams[name];
@@ -320,17 +320,17 @@ calItemBase.prototype = {
 
     // attribute calIDateTime alarmLastAck;
     get alarmLastAck() {
         return this.mAlarmLastAck;
     },
     set alarmLastAck(aValue) {
         this.modify();
         if (aValue && !aValue.timezone.isUTC) {
-            aValue = aValue.getInTimezone(UTC());
+            aValue = aValue.getInTimezone(cal.UTC());
         }
         return (this.mAlarmLastAck = aValue);
     },
 
     // readonly attribute calIDateTime lastModifiedTime;
     get lastModifiedTime() {
         this.ensureNotDirty();
         return this.getProperty("LAST-MODIFIED");
@@ -822,17 +822,17 @@ calItemBase.prototype = {
      *
      * @param icalcomp      The ical component to read.
      */
     setItemBaseFromICS: function(icalcomp) {
         this.modify();
 
         // re-initializing from scratch -- no light proxy anymore:
         this.mIsProxy = false;
-        this.mProperties = new calPropertyBag();
+        this.mProperties = new cal.calPropertyBag();
         this.mPropertyParams = {};
 
         this.mapPropsFromICS(icalcomp, this.icsBasePropMap);
 
         this.mAttendees = []; // don't inherit anything from parent
         for (let attprop of cal.ical.propertyIterator(icalcomp, "ATTENDEE")) {
             let att = new calAttendee();
             att.icalProperty = attprop;
@@ -1078,17 +1078,17 @@ calItemBase.prototype = {
     // void getOccurrencesBetween (in calIDateTime aStartDate, in calIDateTime aEndDate,
     //                             out PRUint32 aCount,
     //                             [array,size_is(aCount),retval] out calIItemBase aOccurrences);
     getOccurrencesBetween: function(aStartDate, aEndDate, aCount) {
         if (this.recurrenceInfo) {
             return this.recurrenceInfo.getOccurrences(aStartDate, aEndDate, 0, aCount);
         }
 
-        if (checkIfInRange(this, aStartDate, aEndDate)) {
+        if (cal.checkIfInRange(this, aStartDate, aEndDate)) {
             aCount.value = 1;
             return [this];
         }
 
         aCount.value = 0;
         return [];
     }
 };
--- a/calendar/base/src/calItemModule.js
+++ b/calendar/base/src/calItemModule.js
@@ -1,17 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 var scriptLoadOrder = [
     "calItemBase.js",
-    "calUtils.js",
     "calCachedCalendar.js",
 
     "calAlarm.js",
     "calAlarmService.js",
     "calAlarmMonitor.js",
     "calAttendee.js",
     "calAttachment.js",
     "calCalendarManager.js",
--- a/calendar/base/src/calRecurrenceInfo.js
+++ b/calendar/base/src/calRecurrenceInfo.js
@@ -6,17 +6,17 @@ Components.utils.import("resource://cale
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 function getRidKey(date) {
     if (!date) {
         return null;
     }
     let timezone = date.timezone;
     if (!timezone.isUTC && !timezone.isFloating) {
-        date = date.getInTimezone(UTC());
+        date = date.getInTimezone(cal.UTC());
     }
     return date.icalString;
 }
 
 function calRecurrenceInfo() {
     this.mRecurrenceItems = [];
     this.mExceptionMap = {};
 
@@ -119,17 +119,17 @@ calRecurrenceInfo.prototype = {
      * calIRecurrenceInfo
      */
     get item() {
         return this.mBaseItem;
     },
     set item(value) {
         this.ensureMutable();
 
-        value = calTryWrappedJSObject(value);
+        value = cal.calTryWrappedJSObject(value);
         this.mBaseItem = value;
         // patch exception's parentItem:
         for (let ex in this.mExceptionMap) {
             let exitem = this.mExceptionMap[ex];
             exitem.parentItem = value;
         }
     },
 
@@ -281,19 +281,19 @@ calRecurrenceInfo.prototype = {
                                                   null,
                                                   0,
                                                   {});
                 // Map all negative dates.
                 for (let rdate of rdates) {
                     negMap[getRidKey(rdate)] = true;
                 }
             } else {
-                WARN("Item '" + this.mBaseItem.title + "'" +
-                     (this.mBaseItem.calendar ? " (" + this.mBaseItem.calendar.name + ")" : "") +
-                     " has an infinite negative rule (EXRULE)");
+                cal.WARN("Item '" + this.mBaseItem.title + "'" +
+                         (this.mBaseItem.calendar ? " (" + this.mBaseItem.calendar.name + ")" : "") +
+                         " has an infinite negative rule (EXRULE)");
             }
         }
 
         let bailCounter = 0;
         do {
             invalidOccurrences = 0;
             // Go through all positive rules and get the next recurrence id
             // according to that rule. If for all rules the rid is "invalid",
@@ -359,17 +359,17 @@ calRecurrenceInfo.prototype = {
                     }
                 }
             }
 
             // To make sure users don't just report bugs like "the application
             // hangs", bail out after 100 runs. If this happens, it is most
             // likely a bug.
             if (bailCounter++ > 100) {
-                ERROR("Could not find next occurrence after 100 runs!");
+                cal.ERROR("Could not find next occurrence after 100 runs!");
                 return null;
             }
 
             // We counted how many positive rules found out that their next
             // candidate is invalid. If all rules produce invalid next
             // occurrences, a second round is needed.
         } while (invalidOccurrences == this.mPositiveRules.length);
 
@@ -402,17 +402,17 @@ calRecurrenceInfo.prototype = {
         // TODO libical currently does not provide us with easy means of
         // getting the previous occurrence. This could be fixed to improve
         // performance greatly. Filed as libical feature request 1944020.
 
         // HACK We never know how early an RDATE might be before the actual
         // recurrence start. Since rangeStart cannot be null for recurrence
         // items like calIRecurrenceRule, we need to work around by supplying a
         // very early date. Again, this might have a high performance penalty.
-        let early = createDateTime();
+        let early = cal.createDateTime();
         early.icalString = "00000101T000000Z";
 
         let rids = this.calculateDates(early,
                                        aTime,
                                        0);
         // The returned dates are sorted, so the last one is a good
         // candidate, if it exists.
         return (rids.length > 0 ? this.getOccurrenceFor(rids[rids.length - 1].id) : null);
@@ -423,18 +423,18 @@ calRecurrenceInfo.prototype = {
         this.ensureBaseItem();
         this.ensureSortedRecurrenceRules();
 
         function ridDateSortComptor(a, b) {
             return a.rstart.compare(b.rstart);
         }
 
         // workaround for UTC- timezones
-        let rangeStart = ensureDateTime(aRangeStart);
-        let rangeEnd = ensureDateTime(aRangeEnd);
+        let rangeStart = cal.ensureDateTime(aRangeStart);
+        let rangeEnd = cal.ensureDateTime(aRangeEnd);
 
         // If aRangeStart falls in the middle of an occurrence, libical will
         // not return that occurrence when we go and ask for an
         // icalrecur_iterator_new.  This actually seems fairly rational, so
         // instead of hacking libical, I'm going to move aRangeStart back far
         // enough to make sure we get the occurrences we might miss.
         let searchStart = rangeStart.clone();
         let baseDuration = this.mBaseItem.duration;
@@ -454,30 +454,30 @@ calRecurrenceInfo.prototype = {
 
         let dates = [];
 
         // toss in exceptions first. Save a map of all exceptions ids, so we
         // don't add the wrong occurrences later on.
         let occurrenceMap = {};
         for (let ex in this.mExceptionMap) {
             let item = this.mExceptionMap[ex];
-            let occDate = checkIfInRange(item, aRangeStart, aRangeEnd, true);
+            let occDate = cal.checkIfInRange(item, aRangeStart, aRangeEnd, true);
             occurrenceMap[ex] = true;
             if (occDate) {
-                binaryInsert(dates, { id: item.recurrenceId, rstart: occDate }, ridDateSortComptor);
+                cal.binaryInsert(dates, { id: item.recurrenceId, rstart: occDate }, ridDateSortComptor);
             }
         }
 
         // DTSTART/DUE is always part of the (positive) expanded set:
         // DTSTART always equals RECURRENCE-ID for items expanded from RRULE
-        let baseOccDate = checkIfInRange(this.mBaseItem, aRangeStart, aRangeEnd, true);
+        let baseOccDate = cal.checkIfInRange(this.mBaseItem, aRangeStart, aRangeEnd, true);
         let baseOccDateKey = getRidKey(baseOccDate);
         if (baseOccDate && !occurrenceMap[baseOccDateKey]) {
             occurrenceMap[baseOccDateKey] = true;
-            binaryInsert(dates, { id: baseOccDate, rstart: baseOccDate }, ridDateSortComptor);
+            cal.binaryInsert(dates, { id: baseOccDate, rstart: baseOccDate }, ridDateSortComptor);
         }
 
         // if both range start and end are specified, we ask for all of the occurrences,
         // to make sure we catch all possible exceptions.  If aRangeEnd isn't specified,
         // then we have to ask for aMaxCount, and hope for the best.
         let maxCount;
         if (rangeStart && rangeEnd) {
             maxCount = 0;
@@ -516,17 +516,17 @@ calRecurrenceInfo.prototype = {
                 let dateKey = getRidKey(date);
                 if (occurrenceMap[dateKey]) {
                     // Don't add occurrences twice (i.e exception was
                     // already added before)
                     continue;
                 }
                 // TODO if cur_dates[] is also sorted, then this binary
                 // search could be optimized further
-                binaryInsert(dates, { id: date, rstart: date }, ridDateSortComptor);
+                cal.binaryInsert(dates, { id: date, rstart: date }, ridDateSortComptor);
                 occurrenceMap[dateKey] = true;
             }
         }
 
         // Apply negative rules
         for (let ritem of this.mNegativeRules) {
             let cur_dates = ritem.getOccurrences(startDate,
                                                  searchStart,
@@ -670,26 +670,26 @@ calRecurrenceInfo.prototype = {
     // This implementation does the first approach (RECURRENCE-ID will
     // never change even if DTSTART for that instance changes), which
     // I think is the right thing to do for CalDAV; I don't know what
     // we'll do for incoming ITIP events though.
     //
     modifyException: function(anItem, aTakeOverOwnership) {
         this.ensureBaseItem();
 
-        anItem = calTryWrappedJSObject(anItem);
+        anItem = cal.calTryWrappedJSObject(anItem);
 
         if (anItem.parentItem.calendar != this.mBaseItem.calendar &&
             anItem.parentItem.id != this.mBaseItem.id) {
-            ERROR("recurrenceInfo::addException: item parentItem != this.mBaseItem (calendar/id)!");
+            cal.ERROR("recurrenceInfo::addException: item parentItem != this.mBaseItem (calendar/id)!");
             throw Components.results.NS_ERROR_INVALID_ARG;
         }
 
         if (anItem.recurrenceId == null) {
-            ERROR("recurrenceInfo::addException: item with null recurrenceId!");
+            cal.ERROR("recurrenceInfo::addException: item with null recurrenceId!");
             throw Components.results.NS_ERROR_INVALID_ARG;
         }
 
         let itemtoadd;
         if (aTakeOverOwnership && anItem.isMutable) {
             itemtoadd = anItem;
             itemtoadd.parentItem = this.mBaseItem;
         } else {
@@ -739,17 +739,17 @@ calRecurrenceInfo.prototype = {
         cal.ASSERT(aNewStartTime, "invalid arg!", true);
 
         // no need to check for changes if there's no previous starttime.
         if (!aOldStartTime) {
             return;
         }
 
         // convert both dates to UTC since subtractDate is not timezone aware.
-        let timeDiff = aNewStartTime.getInTimezone(UTC()).subtractDate(aOldStartTime.getInTimezone(UTC()));
+        let timeDiff = aNewStartTime.getInTimezone(cal.UTC()).subtractDate(aOldStartTime.getInTimezone(cal.UTC()));
 
         let rdates = {};
 
         // take RDATE's and EXDATE's into account.
         const kCalIRecurrenceDate = Components.interfaces.calIRecurrenceDate;
         let ritems = this.getRecurrenceItems({});
         for (let ritem of ritems) {
             let rDateInstance = cal.wrapInstance(ritem, kCalIRecurrenceDate);
--- a/calendar/base/src/calRelation.js
+++ b/calendar/base/src/calRelation.js
@@ -9,17 +9,17 @@ Components.utils.import("resource://gre/
 /**
  * calRelation prototype definition
  *
  * @implements calIRelation
  * @constructor
  */
 function calRelation() {
     this.wrappedJSObject = this;
-    this.mProperties = new calPropertyBag();
+    this.mProperties = new cal.calPropertyBag();
 }
 var calRelationClassID = Components.ID("{76810fae-abad-4019-917a-08e95d5bbd68}");
 var calRelationInterfaces = [Components.interfaces.calIRelation];
 calRelation.prototype = {
     mType: null,
     mId: null,
 
     classID: calRelationClassID,
@@ -45,17 +45,17 @@ calRelation.prototype = {
     get relId() {
         return this.mId;
     },
     set relId(aRelId) {
         return (this.mId = aRelId);
     },
 
     get icalProperty() {
-        let icssvc = getIcsService();
+        let icssvc = cal.getIcsService();
         let icalatt = icssvc.createIcalProperty("RELATED-TO");
         if (this.mId) {
             icalatt.value = this.mId;
         }
 
         if (this.mType) {
             icalatt.setParameter("RELTYPE", this.mType);
         }
@@ -74,17 +74,17 @@ calRelation.prototype = {
             }
         }
         return icalatt;
     },
 
     set icalProperty(attProp) {
         // Reset the property bag for the parameters, it will be re-initialized
         // from the ical property.
-        this.mProperties = new calPropertyBag();
+        this.mProperties = new cal.calPropertyBag();
 
         if (attProp.value) {
             this.mId = attProp.value;
         }
         for (let [name, value] of cal.ical.paramIterator(attProp)) {
             if (name == "RELTYPE") {
                 this.mType = value;
                 continue;
--- a/calendar/base/src/calTodo.js
+++ b/calendar/base/src/calTodo.js
@@ -114,28 +114,28 @@ calTodo.prototype = {
     },
 
     icsEventPropMap: [
     { cal: "DTSTART", ics: "startTime" },
     { cal: "DUE", ics: "dueTime" },
     { cal: "COMPLETED", ics: "completedTime" }],
 
     set icalString(value) {
-        this.icalComponent = getIcsService().parseICS(value, null);
+        this.icalComponent = cal.getIcsService().parseICS(value, null);
     },
 
     get icalString() {
-        let calcomp = getIcsService().createIcalComponent("VCALENDAR");
-        calSetProdidVersion(calcomp);
+        let calcomp = cal.getIcsService().createIcalComponent("VCALENDAR");
+        cal.calSetProdidVersion(calcomp);
         calcomp.addSubcomponent(this.icalComponent);
         return calcomp.serializeToICS();
     },
 
     get icalComponent() {
-        let icssvc = getIcsService();
+        let icssvc = cal.getIcsService();
         let icalcomp = icssvc.createIcalComponent("VTODO");
         this.fillIcalComponentFromBase(icalcomp);
         this.mapPropsToICS(icalcomp, this.icsEventPropMap);
 
         let bagenum = this.propertyEnumerator;
         while (bagenum.hasMoreElements()) {
             let iprop = bagenum.getNext()
                                .QueryInterface(Components.interfaces.nsIProperty);
--- a/calendar/base/src/calTransactionManager.js
+++ b/calendar/base/src/calTransactionManager.js
@@ -1,12 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calItipUtils.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 function calTransactionManager() {
     this.wrappedJSObject = this;
     if (!this.transactionManager) {
         this.transactionManager =
             Components.classes["@mozilla.org/transactionmanager;1"]
@@ -44,18 +45,18 @@ calTransactionManager.prototype = {
 
     endBatch: function() {
         this.transactionManager.endBatch(false);
     },
 
     checkWritable: function(transaction) {
         function checkItem(item) {
             return item && item.calendar &&
-                   isCalendarWritable(item.calendar) &&
-                   userCanAddItemsToCalendar(item.calendar);
+                   cal.isCalendarWritable(item.calendar) &&
+                   cal.userCanAddItemsToCalendar(item.calendar);
         }
 
         let trans = transaction && transaction.wrappedJSObject;
         return trans && checkItem(trans.mItem) && checkItem(trans.mOldItem);
     },
 
     undo: function() {
         this.transactionManager.undoTransaction();
--- a/calendar/base/src/calUtils.js
+++ b/calendar/base/src/calUtils.js
@@ -350,50 +350,54 @@ function attendeeMatchesAddresses(anAtte
 function userCanRespondToInvitation(aItem) {
     let aclEntry = aItem.aclEntry;
     return userCanModifyItem(aItem) || aclEntry.userCanRespond;
 }
 
 /**
  * Opens the Create Calendar wizard
  *
+ * @param aWindow The window to show the dialog in.
  * @param aCallback  a function to be performed after calendar creation
  */
-function openCalendarWizard(aCallback) {
-    openDialog("chrome://calendar/content/calendarCreation.xul", "caEditServer",
-               // Workaround for Bug 1151440 - the HTML color picker won't work
-               // in linux when opened from modal dialog
-               AppConstants.platform == "linux"
-                   ? "chrome,titlebar,resizable"
-                   : "modal,chrome,titlebar,resizable",
-               aCallback);
+function openCalendarWizard(aWindow, aCallback) {
+    aWindow.openDialog("chrome://calendar/content/calendarCreation.xul", "caEditServer",
+                       // Workaround for Bug 1151440 - the HTML color picker won't work
+                       // in linux when opened from modal dialog
+                       AppConstants.platform == "linux"
+                           ? "chrome,titlebar,resizable"
+                           : "modal,chrome,titlebar,resizable",
+                       aCallback);
 }
 
 /**
  * Opens the calendar properties window for aCalendar
  *
+ * @param aWindow The window to show the dialog in.
  * @param aCalendar  the calendar whose properties should be displayed
  */
-function openCalendarProperties(aCalendar) {
-    openDialog("chrome://calendar/content/calendar-properties-dialog.xul",
-               "CalendarPropertiesDialog",
-               // Workaround for Bug 1151440 - the HTML color picker won't work
-               // in linux when opened from modal dialog
-               AppConstants.platform == "linux"
-                   ? "chrome,titlebar,resizable"
-                   : "modal,chrome,titlebar,resizable",
-               { calendar: aCalendar });
+function openCalendarProperties(aWindow, aCalendar) {
+    aWindow.openDialog("chrome://calendar/content/calendar-properties-dialog.xul",
+                       "CalendarPropertiesDialog",
+                       // Workaround for Bug 1151440 - the HTML color picker won't work
+                       // in linux when opened from modal dialog
+                       AppConstants.platform == "linux"
+                           ? "chrome,titlebar,resizable"
+                           : "modal,chrome,titlebar,resizable",
+                       { calendar: aCalendar });
 }
 
 /**
  * Opens the print dialog
+ *
+ * @param aWindow The window to show the dialog in.
  */
-function calPrint() {
-    openDialog("chrome://calendar/content/calendar-print-dialog.xul", "Print",
-               "centerscreen,chrome,resizable");
+function calPrint(aWindow) {
+    aWindow.openDialog("chrome://calendar/content/calendar-print-dialog.xul", "Print",
+                       "centerscreen,chrome,resizable");
 }
 
 /**
  * Other functions
  */
 
 /**
  * Takes a string and returns an nsIURI
--- a/calendar/lightning/content/html-item-editing/lightning-item-iframe.html
+++ b/calendar/lightning/content/html-item-editing/lightning-item-iframe.html
@@ -15,14 +15,13 @@
       <p>
         If you can see this, React is still loading or is not working right.
       </p>
     </div>
     <script type="application/javascript" src="resource://devtools/client/shared/vendor/react.js"></script>
     <script type="application/javascript" src="resource://devtools/client/shared/vendor/react-dom.js"></script>
     <script src='chrome://calendar/content/calendar-dialog-utils.js'></script>
     <script src='chrome://calendar/content/calendar-ui-utils.js'></script>
-    <script src='chrome://calendar/content/calUtils.js'></script>
     <script src='chrome://global/content/globalOverlay.js'></script>
     <script src='chrome://lightning/content/lightning-item-iframe.js'></script>
     <script src='chrome://lightning/content/html-item-editing/react-code.js'></script>
   </body>
 </html>
--- a/calendar/lightning/content/imip-bar-overlay.xul
+++ b/calendar/lightning/content/imip-bar-overlay.xul
@@ -10,18 +10,16 @@
 
 <?xml-stylesheet href="chrome://lightning/content/lightning-widgets.css" type="text/css"?>
 
 <overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <script type="application/javascript"
             src="chrome://lightning/content/lightning-utils.js"/>
     <script type="application/javascript"
-            src="chrome://calendar/content/calUtils.js"/>
-    <script type="application/javascript"
             src="chrome://lightning/content/imip-bar.js"/>
     <script type="application/javascript"
             src="chrome://calendar/content/calendar-management.js"/>
     <script type="application/javascript"
             src="chrome://calendar/content/calendar-ui-utils.js"/>
 
     <vbox id="messagepanebox">
       <vbox id="singlemessage" insertbefore="msgHeaderView">
--- a/calendar/lightning/content/lightning-item-iframe.js
+++ b/calendar/lightning/content/lightning-item-iframe.js
@@ -79,20 +79,20 @@ var eventDialogCalendarObserver = {
         if (this.isObserving && "calendarItem" in window &&
             window.calendarItem && window.calendarItem.id == aOldItem.id) {
             let doUpdate = true;
 
             // The item has been modified outside the dialog. We only need to
             // prompt if there have been local changes also.
             if (isItemChanged()) {
                 let promptService = Components.interfaces.nsIPromptService;
-                let promptTitle = calGetString("calendar", "modifyConflictPromptTitle");
-                let promptMessage = calGetString("calendar", "modifyConflictPromptMessage");
-                let promptButton1 = calGetString("calendar", "modifyConflictPromptButton1");
-                let promptButton2 = calGetString("calendar", "modifyConflictPromptButton2");
+                let promptTitle = cal.calGetString("calendar", "modifyConflictPromptTitle");
+                let promptMessage = cal.calGetString("calendar", "modifyConflictPromptMessage");
+                let promptButton1 = cal.calGetString("calendar", "modifyConflictPromptButton1");
+                let promptButton2 = cal.calGetString("calendar", "modifyConflictPromptButton2");
                 let flags = promptService.BUTTON_TITLE_IS_STRING *
                             promptService.BUTTON_POS_0 +
                             promptService.BUTTON_TITLE_IS_STRING *
                             promptService.BUTTON_POS_1;
 
                 let choice = Services.prompt.confirmEx(window, promptTitle, promptMessage, flags,
                                                        promptButton1, promptButton2, null, null, {});
                 if (!choice) {
@@ -303,17 +303,17 @@ function onLoad() {
     // set the iframe's top level id for event vs task
     if (!cal.isEvent(item)) {
         setDialogId(document.documentElement, "calendar-task-dialog-inner");
     }
 
     // new items should have a non-empty title.
     if (item.isMutable && (!item.title || item.title.length <= 0)) {
         item.title = cal.calGetString("calendar-event-dialog",
-                                      isEvent(item) ? "newEvent" : "newTask");
+                                      cal.isEvent(item) ? "newEvent" : "newTask");
     }
 
     window.onAcceptCallback = args.onOk;
     window.mode = args.mode;
 
     // we store the item in the window to be able
     // to access this from any location. please note
     // that the item is either an occurrence [proxy]
@@ -360,17 +360,17 @@ function onLoad() {
     }
 
     window.recurrenceInfo = null;
     if (parentItem.recurrenceInfo) {
         window.recurrenceInfo = parentItem.recurrenceInfo.clone();
     }
 
     // Set initial values for datepickers in New Tasks dialog
-    if (isToDo(item)) {
+    if (cal.isToDo(item)) {
         let initialDatesValue = cal.dateTimeToJsDate(args.initialStartDateValue);
         if (!gNewItemUI) {
             setElementValue("completed-date-picker", initialDatesValue);
             setElementValue("todo-entrydate", initialDatesValue);
             setElementValue("todo-duedate", initialDatesValue);
         }
     }
     loadDialog(window.calendarItem);
@@ -452,21 +452,21 @@ function onCommandCancel() {
     if (gInTab && gTabInfoObject) {
         // Switch to the tab that the prompt refers to.
         gTabmail.switchToTab(gTabInfoObject);
     }
 
     let promptService = Components.interfaces.nsIPromptService;
 
     let promptTitle = cal.calGetString("calendar",
-                                       isEvent(window.calendarItem)
+                                       cal.isEvent(window.calendarItem)
                                           ? "askSaveTitleEvent"
                                           : "askSaveTitleTask");
     let promptMessage = cal.calGetString("calendar",
-                                         isEvent(window.calendarItem)
+                                         cal.isEvent(window.calendarItem)
                                             ? "askSaveMessageEvent"
                                             : "askSaveMessageTask");
 
     let flags = promptService.BUTTON_TITLE_SAVE *
                 promptService.BUTTON_POS_0 +
                 promptService.BUTTON_TITLE_CANCEL *
                 promptService.BUTTON_POS_1 +
                 promptService.BUTTON_TITLE_DONT_SAVE *
@@ -564,20 +564,20 @@ function loadDialog(aItem) {
     if (gNewItemUI) {
         let calendarToUse = aItem.calendar || window.arguments[0].calendar;
         let unfilteredList = sortCalendarArray(cal.getCalendarManager().getCalendars({}));
 
         // filter out calendars that should not be included
         let calendarList = unfilteredList.filter((calendar) =>
            (calendar.id == calendarToUse.id ||
             (calendar &&
-             isCalendarWritable(calendar) &&
-             (userCanAddItemsToCalendar(calendar) ||
-              (calendar == aItem.calendar && userCanModifyItem(aItem))) &&
-             isItemSupported(aItem, calendar))));
+             cal.isCalendarWritable(calendar) &&
+             (cal.userCanAddItemsToCalendar(calendar) ||
+              (calendar == aItem.calendar && cal.userCanModifyItem(aItem))) &&
+             cal.isItemSupported(aItem, calendar))));
 
         itemProps.calendarList = calendarList.map(calendar => [calendar.id, calendar.name]);
 
         if (calendarToUse && calendarToUse.id) {
             let index = itemProps.calendarList.findIndex(
                 calendar => (calendar[0] == calendarToUse.id));
             if (index != -1) {
                 itemProps.initialCalendarId = calendarToUse.id;
@@ -590,17 +590,17 @@ function loadDialog(aItem) {
         if (indexToSelect > -1) {
             calendarList.selectedIndex = indexToSelect;
         }
     }
 
     // Categories
     if (gNewItemUI) {
         // XXX more to do here with localization, see loadCategories.
-        itemProps.initialCategoriesList = cal.sortArrayByLocaleCollator(getPrefCategoriesArray());
+        itemProps.initialCategoriesList = cal.sortArrayByLocaleCollator(cal.getPrefCategoriesArray());
         itemProps.initialCategories = aItem.getCategories({});
 
         // just to demo capsules component
         itemProps.initialCategories = ["Some", "Demo", "Categories"];
     } else {
         loadCategories(aItem);
     }
 
@@ -665,17 +665,17 @@ function loadDialog(aItem) {
         if (aItem.completedDate) {
             updateToDoStatus(aItem.status, cal.dateTimeToJsDate(aItem.completedDate));
         } else {
             updateToDoStatus(aItem.status);
         }
     }
 
     // Task percent complete
-    if (isToDo(aItem)) {
+    if (cal.isToDo(aItem)) {
         let percentCompleteInteger = 0;
         let percentCompleteProperty = aItem.getProperty("PERCENT-COMPLETE");
         if (percentCompleteProperty != null) {
             percentCompleteInteger = parseInt(percentCompleteProperty, 10);
         }
         if (percentCompleteInteger < 0) {
             percentCompleteInteger = 0;
         } else if (percentCompleteInteger > 100) {
@@ -886,18 +886,18 @@ function saveCategories(aItem) {
 }
 
 /**
  * Sets up all date related controls from the passed item
  *
  * @param item      The item to parse information out of.
  */
 function loadDateTime(item) {
-    let kDefaultTimezone = calendarDefaultTimezone();
-    if (isEvent(item)) {
+    let kDefaultTimezone = cal.calendarDefaultTimezone();
+    if (cal.isEvent(item)) {
         let startTime = item.startDate;
         let endTime = item.endDate;
         let duration = endTime.subtractDate(startTime);
 
         // Check if an all-day event has been passed in (to adapt endDate).
         if (startTime.isDate) {
             startTime = startTime.clone();
             endTime = endTime.clone();
@@ -911,17 +911,17 @@ function loadDateTime(item) {
         // separately.
         gStartTimezone = startTime.timezone;
         gEndTimezone = endTime.timezone;
         gStartTime = startTime.getInTimezone(kDefaultTimezone);
         gEndTime = endTime.getInTimezone(kDefaultTimezone);
         gItemDuration = duration;
     }
 
-    if (isToDo(item)) {
+    if (cal.isToDo(item)) {
         let startTime = null;
         let endTime = null;
         let duration = null;
 
         let hasEntryDate = (item.entryDate != null);
         if (hasEntryDate) {
             startTime = item.entryDate;
             gStartTimezone = startTime.timezone;
@@ -987,33 +987,33 @@ function dateTimeControls2State(aStartDa
     if (gIgnoreUpdate) {
         return;
     }
     let keepAttribute = document.getElementById("keepduration-button")
                                 .getAttribute("keep") == "true";
     let allDay = getElementValue("event-all-day", "checked");
     let startWidgetId;
     let endWidgetId;
-    if (isEvent(window.calendarItem)) {
+    if (cal.isEvent(window.calendarItem)) {
         startWidgetId = "event-starttime";
         endWidgetId = "event-endtime";
     } else {
         if (!getElementValue("todo-has-entrydate", "checked")) {
             gItemDuration = null;
         }
         if (!getElementValue("todo-has-duedate", "checked")) {
             gItemDuration = null;
         }
         startWidgetId = "todo-entrydate";
         endWidgetId = "todo-duedate";
     }
 
     let saveStartTime = gStartTime;
     let saveEndTime = gEndTime;
-    let kDefaultTimezone = calendarDefaultTimezone();
+    let kDefaultTimezone = cal.calendarDefaultTimezone();
 
     if (gStartTime) {
         // jsDate is always in OS timezone, thus we create a calIDateTime
         // object from the jsDate representation then we convert the timezone
         // in order to keep gStartTime in default timezone.
         if (gTimezonesEnabled || allDay) {
             gStartTime = cal.jsDateToDateTime(getElementValue(startWidgetId), gStartTimezone);
             gStartTime = gStartTime.getInTimezone(kDefaultTimezone);
@@ -1027,17 +1027,17 @@ function dateTimeControls2State(aStartDa
             // Change the End date in order to keep the duration.
             gEndTime = gStartTime.clone();
             if (gItemDuration) {
                 gEndTime.addDuration(gItemDuration);
             }
         } else {
             let timezone = gEndTimezone;
             if (timezone.isUTC) {
-                if (gStartTime && !compareObjects(gStartTimezone, gEndTimezone)) {
+                if (gStartTime && !cal.compareObjects(gStartTimezone, gEndTimezone)) {
                     timezone = gStartTimezone;
                 }
             }
             if (gTimezonesEnabled || allDay) {
                 gEndTime = cal.jsDateToDateTime(getElementValue(endWidgetId), timezone);
                 gEndTime = gEndTime.getInTimezone(kDefaultTimezone);
             } else {
                 gEndTime = cal.jsDateToDateTime(getElementValue(endWidgetId), kDefaultTimezone);
@@ -1176,17 +1176,17 @@ function updateDueDate() {
  * @param aDateTime         An object implementing the isValid and setDateTime
  *                            methods. XXX explain.
  */
 function updateDateCheckboxes(aDatePickerId, aCheckboxId, aDateTime) {
     if (gIgnoreUpdate) {
         return;
     }
 
-    if (!isToDo(window.calendarItem)) {
+    if (!cal.isToDo(window.calendarItem)) {
         return;
     }
 
     // force something to get set if there was nothing there before
     setElementValue(aDatePickerId, getElementValue(aDatePickerId));
 
     // first of all disable the datetime picker if we don't have a date
     let hasDate = getElementValue(aCheckboxId, "checked");
@@ -1386,64 +1386,64 @@ function updateReminder(aSuppressDialogs
  * Saves all values the user chose on the dialog to the passed item
  *
  * @param item    The item to save to.
  */
 function saveDialog(item) {
     // Calendar
     item.calendar = getCurrentCalendar();
 
-    setItemProperty(item, "title", getElementValue("item-title"));
-    setItemProperty(item, "LOCATION", getElementValue("item-location"));
+    cal.setItemProperty(item, "title", getElementValue("item-title"));
+    cal.setItemProperty(item, "LOCATION", getElementValue("item-location"));
 
     saveDateTime(item);
 
-    if (isToDo(item)) {
+    if (cal.isToDo(item)) {
         let percentCompleteInteger = 0;
         if (getElementValue("percent-complete-textbox") != "") {
             percentCompleteInteger =
                 parseInt(getElementValue("percent-complete-textbox"), 10);
         }
         if (percentCompleteInteger < 0) {
             percentCompleteInteger = 0;
         } else if (percentCompleteInteger > 100) {
             percentCompleteInteger = 100;
         }
-        setItemProperty(item, "PERCENT-COMPLETE", percentCompleteInteger);
+        cal.setItemProperty(item, "PERCENT-COMPLETE", percentCompleteInteger);
     }
 
     // Categories
     saveCategories(item);
 
     // Attachment
     // We want the attachments to be up to date, remove all first.
     item.removeAllAttachments();
 
     // Now add back the new ones
     for (let hashId in gAttachMap) {
         let att = gAttachMap[hashId];
         item.addAttachment(att);
     }
 
     // Description
-    setItemProperty(item, "DESCRIPTION", getElementValue("item-description"));
+    cal.setItemProperty(item, "DESCRIPTION", getElementValue("item-description"));
 
     // Event Status
-    if (isEvent(item)) {
+    if (cal.isEvent(item)) {
         if (gConfig.status && gConfig.status != "NONE") {
             item.setProperty("STATUS", gConfig.status);
         } else {
             item.deleteProperty("STATUS");
         }
     } else {
         let status = getElementValue("todo-status");
         if (status != "COMPLETED") {
             item.completedDate = null;
         }
-        setItemProperty(item, "STATUS", status == "NONE" ? null : status);
+        cal.setItemProperty(item, "STATUS", status == "NONE" ? null : status);
     }
 
     // set the "PRIORITY" property if a valid priority has been
     // specified (any integer value except *null*) OR the item
     // already specifies a priority. in any other case we don't
     // need this property and can safely delete it. we need this special
     // handling since the WCAP provider always includes the priority
     // with value *null* and we don't detect changes to this item if
@@ -1458,73 +1458,73 @@ function saveDialog(item) {
     // Transparency
     if (gConfig.showTimeAs) {
         item.setProperty("TRANSP", gConfig.showTimeAs);
     } else {
         item.deleteProperty("TRANSP");
     }
 
     // Privacy
-    setItemProperty(item, "CLASS", gConfig.privacy, "privacy");
-
-    if (item.status == "COMPLETED" && isToDo(item)) {
+    cal.setItemProperty(item, "CLASS", gConfig.privacy, "privacy");
+
+    if (item.status == "COMPLETED" && cal.isToDo(item)) {
         let elementValue = getElementValue("completed-date-picker");
         item.completedDate = cal.jsDateToDateTime(elementValue);
     }
 
     saveReminder(item);
 }
 
 /**
  * Save date and time related values from the dialog to the passed item.
  *
  * @param item    The item to save to.
  */
 function saveDateTime(item) {
     // Changes to the start date don't have to change the until date.
     untilDateCompensation(item);
 
-    if (isEvent(item)) {
+    if (cal.isEvent(item)) {
         let startTime = gStartTime.getInTimezone(gStartTimezone);
         let endTime = gEndTime.getInTimezone(gEndTimezone);
         let isAllDay = getElementValue("event-all-day", "checked");
         if (isAllDay) {
             startTime = startTime.clone();
             endTime = endTime.clone();
             startTime.isDate = true;
             endTime.isDate = true;
             endTime.day += 1;
         } else {
             startTime = startTime.clone();
             startTime.isDate = false;
             endTime = endTime.clone();
             endTime.isDate = false;
         }
-        setItemProperty(item, "startDate", startTime);
-        setItemProperty(item, "endDate", endTime);
+        cal.setItemProperty(item, "startDate", startTime);
+        cal.setItemProperty(item, "endDate", endTime);
     }
-    if (isToDo(item)) {
+    if (cal.isToDo(item)) {
         let startTime = gStartTime && gStartTime.getInTimezone(gStartTimezone);
         let endTime = gEndTime && gEndTime.getInTimezone(gEndTimezone);
-        setItemProperty(item, "entryDate", startTime);
-        setItemProperty(item, "dueDate", endTime);
+        cal.setItemProperty(item, "entryDate", startTime);
+        cal.setItemProperty(item, "dueDate", endTime);
     }
 }
 
 /**
  * Changes the until date in the rule in order to compensate the automatic
  * correction caused by the function onStartDateChange() when saving the
  * item.
  * It allows to keep the until date set in the dialog irrespective of the
  * changes that the user has done to the start date.
  */
 function untilDateCompensation(aItem) {
     // The current start date in the item is always the date that we get
     // when opening the dialog or after the last save.
-    let startDate = aItem[calGetStartDateProp(aItem)];
+    let startDate = aItem[cal.calGetStartDateProp(aItem)];
 
     if (aItem.recurrenceInfo) {
         let rrules = splitRecurrenceRules(aItem.recurrenceInfo);
         let rule = rrules[0][0];
         if (!rule.isByCount && rule.isFinite && startDate) {
             let compensation = startDate.subtractDate(gStartTime);
             if (compensation != "PT0S") {
                 let untilDate = rule.untilDate.clone();
@@ -1555,17 +1555,17 @@ function updateTitle() {
 
 /**
  * Update the disabled status of the accept button. The button is enabled if all
  * parts of the dialog have options selected that make sense.
  * constraining factors like
  */
 function updateAccept() {
     let enableAccept = true;
-    let kDefaultTimezone = calendarDefaultTimezone();
+    let kDefaultTimezone = cal.calendarDefaultTimezone();
     let startDate;
     let endDate;
     let isEvent = cal.isEvent(window.calendarItem);
 
     // don't allow for end dates to be before start dates
     if (isEvent) {
         startDate = cal.jsDateToDateTime(getElementValue("event-starttime"));
         endDate = cal.jsDateToDateTime(getElementValue("event-endtime"));
@@ -1576,17 +1576,17 @@ function updateAccept() {
             cal.jsDateToDateTime(getElementValue("todo-duedate")) : null;
     }
 
     if (startDate && endDate) {
         if (gTimezonesEnabled) {
             let startTimezone = gStartTimezone;
             let endTimezone = gEndTimezone;
             if (endTimezone.isUTC) {
-                if (!compareObjects(gStartTimezone, gEndTimezone)) {
+                if (!cal.compareObjects(gStartTimezone, gEndTimezone)) {
                     endTimezone = gStartTimezone;
                 }
             }
 
             startDate = startDate.getInTimezone(kDefaultTimezone);
             endDate = endDate.getInTimezone(kDefaultTimezone);
 
             startDate.timezone = startTimezone;
@@ -1640,21 +1640,21 @@ var gOldEndTime = null;
 var gOldStartTimezone = null;
 var gOldEndTimezone = null;
 
 /**
  * Handler function to update controls and state in consequence of the "all
  * day" checkbox being clicked.
  */
 function onUpdateAllDay() {
-    if (!isEvent(window.calendarItem)) {
+    if (!cal.isEvent(window.calendarItem)) {
         return;
     }
     let allDay = getElementValue("event-all-day", "checked");
-    let kDefaultTimezone = calendarDefaultTimezone();
+    let kDefaultTimezone = cal.calendarDefaultTimezone();
 
     if (allDay) {
         // Store date-times and related timezones so we can restore
         // if the user unchecks the "all day" checkbox.
         gOldStartTime = gStartTime.clone();
         gOldEndTime = gEndTime.clone();
         gOldStartTimezone = gStartTimezone;
         gOldEndTimezone = gEndTimezone;
@@ -1671,17 +1671,17 @@ function onUpdateAllDay() {
             }
         }
     } else {
         gStartTime.isDate = false;
         gEndTime.isDate = false;
         if (!gOldStartTime && !gOldEndTime) {
             // The checkbox has been unchecked for the first time, the event
             // was an "All day" type, so we have to set default values.
-            gStartTime.hour = getDefaultStartDate(window.initialStartDateValue).hour;
+            gStartTime.hour = cal.getDefaultStartDate(window.initialStartDateValue).hour;
             gEndTime.hour = gStartTime.hour;
             gEndTime.minute += Preferences.get("calendar.event.defaultlength", 60);
             gOldStartTimezone = kDefaultTimezone;
             gOldEndTimezone = kDefaultTimezone;
         } else {
             // Restore date-times previously stored.
             gStartTime.hour = gOldStartTime.hour;
             gStartTime.minute = gOldStartTime.minute;
@@ -1709,17 +1709,17 @@ function onUpdateAllDay() {
  * - 'timezone-endtime'
  * the state depends on whether or not the event is configured as 'all-day' or not.
  */
 function updateAllDay() {
     if (gIgnoreUpdate) {
         return;
     }
 
-    if (!isEvent(window.calendarItem)) {
+    if (!cal.isEvent(window.calendarItem)) {
         return;
     }
 
     let allDay = getElementValue("event-all-day", "checked");
     setElementValue("event-starttime", allDay, "timepickerdisabled");
     setElementValue("event-endtime", allDay, "timepickerdisabled");
 
     gStartTime.isDate = allDay;
@@ -1792,17 +1792,17 @@ function editAttendees() {
                     organizer.commonName = null;
                 }
             }
             savedWindow.organizer = organizer;
         }
         let duration = endTime.subtractDate(startTime);
         startTime = startTime.clone();
         endTime = endTime.clone();
-        let kDefaultTimezone = calendarDefaultTimezone();
+        let kDefaultTimezone = cal.calendarDefaultTimezone();
         gStartTimezone = startTime.timezone;
         gEndTimezone = endTime.timezone;
         gStartTime = startTime.getInTimezone(kDefaultTimezone);
         gEndTime = endTime.getInTimezone(kDefaultTimezone);
         gItemDuration = duration;
         updateAttendees();
         updateDateTime();
         updateAllDay();
@@ -1946,27 +1946,27 @@ function loadCloudProviders() {
 /**
  * Prompts the user to attach an url to this item.
  */
 function attachURL() {
     if (Services.prompt) {
         // ghost in an example...
         let result = { value: "http://" };
         if (Services.prompt.prompt(window,
-                                   calGetString("calendar-event-dialog",
-                                                "specifyLinkLocation"),
-                                   calGetString("calendar-event-dialog",
-                                                "enterLinkLocation"),
+                                   cal.calGetString("calendar-event-dialog",
+                                                    "specifyLinkLocation"),
+                                   cal.calGetString("calendar-event-dialog",
+                                                    "enterLinkLocation"),
                                    result,
                                    null,
                                    { value: 0 })) {
             try {
-                // If something bogus was entered, makeURL may fail.
-                let attachment = createAttachment();
-                attachment.uri = makeURL(result.value);
+                // If something bogus was entered, cal.makeURL may fail.
+                let attachment = cal.createAttachment();
+                attachment.uri = cal.makeURL(result.value);
                 addAttachment(attachment);
             } catch (e) {
                 // TODO We might want to show a warning instead of just not
                 // adding the file
             }
         }
     }
 }
@@ -1996,17 +1996,17 @@ function attachFile(cloudProvider) {
     }
 
     let files;
     try {
         const nsIFilePicker = Components.interfaces.nsIFilePicker;
         let filePicker = Components.classes["@mozilla.org/filepicker;1"]
                                    .createInstance(nsIFilePicker);
         filePicker.init(window,
-                        calGetString("calendar-event-dialog", "selectAFile"),
+                        cal.calGetString("calendar-event-dialog", "selectAFile"),
                         nsIFilePicker.modeOpenMultiple);
 
         // Check for the last directory
         let lastDir = lastDirectory();
         if (lastDir) {
             filePicker.displayDirectory = lastDir;
         }
 
@@ -2034,17 +2034,17 @@ function attachFile(cloudProvider) {
         if (!(uriSpec in gAttachMap)) {
             // If the attachment hasn't been added, then set the last display
             // directory.
             lastDirectory(uriSpec);
 
             // ... and add the attachment.
             let attachment = cal.createAttachment();
             if (cloudProvider) {
-                attachment.uri = makeURL(uriSpec);
+                attachment.uri = cal.makeURL(uriSpec);
             } else {
                 // TODO read file into attachment
             }
             addAttachment(attachment, cloudProvider);
         }
     }
 }
 
@@ -2054,17 +2054,17 @@ function attachFile(cloudProvider) {
  * @param aFileUri    (optional) If passed, the last directory will be set and
  *                                 returned. If null, the last chosen directory
  *                                 will be returned.
  * @return            The last directory that was set with this function.
  */
 function lastDirectory(aFileUri) {
     if (aFileUri) {
         // Act similar to a setter, save the passed uri.
-        let uri = makeURL(aFileUri);
+        let uri = cal.makeURL(aFileUri);
         let file = uri.QueryInterface(Components.interfaces.nsIFileURL).file;
         lastDirectory.mValue = file.parent.QueryInterface(Components.interfaces.nsILocalFile);
     }
 
     // In any case, return the value
     return (lastDirectory.mValue === undefined ? null : lastDirectory.mValue);
 }
 
@@ -2102,17 +2102,17 @@ function uploadCloudAttachment(attachmen
     cloudProvider.uploadFile(file, {
         onStartRequest: function() {
             listItem.setAttribute("image", "chrome://global/skin/icons/loading.png");
         },
 
         onStopRequest: function(aRequest, aContext, aStatusCode) {
             if (Components.isSuccessCode(aStatusCode)) {
                 delete gAttachMap[attachment.hashId];
-                attachment.uri = makeURL(cloudProvider.urlForFile(file));
+                attachment.uri = cal.makeURL(cloudProvider.urlForFile(file));
                 attachment.setParameter("FILENAME", file.leafName);
                 attachment.setParameter("PROVIDER", cloudProvider.type);
                 listItem.setAttribute("label", file.leafName);
                 gAttachMap[attachment.hashId] = attachment;
                 listItem.setAttribute("image", cloudProvider.iconClass);
                 updateAttachment();
             } else {
                 cal.ERROR("[calendar-event-dialog] Uploading cloud attachment " +
@@ -2537,17 +2537,17 @@ function editRepeat() {
  * @param aItemRepeatCall      True when the function is being called from
  *                               the item-repeat menu list. It allows to detect
  *                               a change from the "custom" option.
  */
 function updateRepeat(aSuppressDialogs, aItemRepeatCall) {
     function setUpEntrydateForTask(item) {
         // if this item is a task, we need to make sure that it has
         // an entry-date, otherwise we can't create a recurrence.
-        if (isToDo(item)) {
+        if (cal.isToDo(item)) {
             // automatically check 'has entrydate' if needed.
             if (!getElementValue("todo-has-entrydate", "checked")) {
                 setElementValue("todo-has-entrydate", "true", "checked");
 
                 // make sure gStartTime is properly initialized
                 updateEntryDate();
             }
 
@@ -2561,17 +2561,17 @@ function updateRepeat(aSuppressDialogs, 
     let repeatMenu = document.getElementById("item-repeat");
     let repeatValue = repeatMenu.selectedItem.getAttribute("value");
     let repeatDeck = document.getElementById("repeat-deck");
 
     if (repeatValue == "none") {
         repeatDeck.selectedIndex = -1;
         window.recurrenceInfo = null;
         let item = window.calendarItem;
-        if (isToDo(item)) {
+        if (cal.isToDo(item)) {
             enableElementWithLock("todo-has-entrydate", "repeat-lock");
         }
     } else if (repeatValue == "custom") {
         let lastRepeatDeck = repeatDeck.selectedIndex;
         repeatDeck.selectedIndex = 1;
         // the user selected custom repeat pattern. we now need to bring
         // up the appropriate dialog in order to let the user specify the
         // new rule. First of all, retrieve the item we want to specify
@@ -2594,33 +2594,33 @@ function updateRepeat(aSuppressDialogs, 
 
         // Assign gUntilDate on the first run or when returning from the
         // edit recurrence dialog.
         if (window.recurrenceInfo) {
             let rrules = splitRecurrenceRules(window.recurrenceInfo);
             let rule = rrules[0][0];
             gUntilDate = null;
             if (!rule.isByCount && rule.isFinite) {
-                gUntilDate = rule.untilDate.clone().getInTimezone(calendarDefaultTimezone());
+                gUntilDate = rule.untilDate.clone().getInTimezone(cal.calendarDefaultTimezone());
             }
         }
 
         // we need to address two separate cases here.
         // 1)- We need to revoke the selection of the repeat
         //     drop down list in case the user didn't specify
         //     a new repeat pattern (i.e. canceled the dialog);
         //   - re-enable the 'has entrydate' option in case
         //     we didn't end up with a recurrence rule.
         // 2)  Check whether the new recurrence rule needs the
         //     recurrence details text or it can be displayed
         //     only with the repeat-until-datepicker.
         if (recurrenceInfo == window.recurrenceInfo) {
             repeatMenu.selectedIndex = gLastRepeatSelection;
             repeatDeck.selectedIndex = lastRepeatDeck;
-            if (isToDo(item)) {
+            if (cal.isToDo(item)) {
                 if (!window.recurrenceInfo) {
                     enableElementWithLock("todo-has-entrydate", "repeat-lock");
                 }
             }
         } else {
             // From the Edit Recurrence dialog, the rules "every day" and
             // "every weekday" don't need the recurrence details text when they
             // have only the until date. The getRepeatTypeAndUntilDate()
@@ -2672,23 +2672,23 @@ function updateRepeat(aSuppressDialogs, 
                 }
                 setElementValue("repeat-until-datepicker", repeatDate);
             }
             if (rrules[0].length > 0) {
                 recurrenceInfo.deleteRecurrenceItem(rule);
             }
         } else {
             // New event proposes "forever" as default until date.
-            recurrenceInfo = createRecurrenceInfo(item);
+            recurrenceInfo = cal.createRecurrenceInfo(item);
             setElementValue("repeat-until-datepicker", "forever");
         }
 
         repeatDeck.selectedIndex = 0;
 
-        let recRule = createRecurrenceRule();
+        let recRule = cal.createRecurrenceRule();
         recRule.interval = 1;
         switch (repeatValue) {
             case "daily":
                 recRule.type = "DAILY";
                 break;
             case "weekly":
                 recRule.type = "WEEKLY";
                 break;
@@ -2709,17 +2709,17 @@ function updateRepeat(aSuppressDialogs, 
         }
 
         setUpEntrydateForTask(item);
         updateUntildateRecRule(recRule);
 
         recurrenceInfo.insertRecurrenceItemAt(recRule, 0);
         window.recurrenceInfo = recurrenceInfo;
 
-        if (isToDo(item)) {
+        if (cal.isToDo(item)) {
             if (!getElementValue("todo-has-entrydate", "checked")) {
                 setElementValue("todo-has-entrydate", "true", "checked");
             }
             disableElementWithLock("todo-has-entrydate", "repeat-lock");
         }
 
         // Preset the until-datepicker's minimonth to the start date.
         let startDate = cal.dateTimeToJsDate(gStartTime.getInTimezone(cal.floating()));
@@ -3036,21 +3036,21 @@ function onCommandSave(aIsClosing) {
  */
 function onCommandDeleteItem() {
     // only ask for confirmation, if the User changed anything on a new item or we modify an existing item
     if (isItemChanged() || window.mode != "new") {
         let promptTitle = "";
         let promptMessage = "";
 
         if (cal.isEvent(window.calendarItem)) {
-            promptTitle = calGetString("calendar", "deleteEventLabel");
-            promptMessage = calGetString("calendar", "deleteEventMessage");
+            promptTitle = cal.calGetString("calendar", "deleteEventLabel");
+            promptMessage = cal.calGetString("calendar", "deleteEventMessage");
         } else if (cal.isToDo(window.calendarItem)) {
-            promptTitle = calGetString("calendar", "deleteTaskLabel");
-            promptMessage = calGetString("calendar", "deleteTaskMessage");
+            promptTitle = cal.calGetString("calendar", "deleteTaskLabel");
+            promptMessage = cal.calGetString("calendar", "deleteTaskMessage");
         }
 
         let answerDelete = Services.prompt.confirm(
                                     null,
                                     promptTitle,
                                     promptMessage);
         if (!answerDelete) {
             return;
@@ -3258,129 +3258,129 @@ function editTimezone(aElementId, aDateT
 function updateDateTime() {
     gIgnoreUpdate = true;
 
     let item = window.calendarItem;
     // Convert to default timezone if the timezone option
     // is *not* checked, otherwise keep the specific timezone
     // and display the labels in order to modify the timezone.
     if (gTimezonesEnabled) {
-        if (isEvent(item)) {
+        if (cal.isEvent(item)) {
             let startTime = gStartTime.getInTimezone(gStartTimezone);
             let endTime = gEndTime.getInTimezone(gEndTimezone);
 
             setElementValue("event-all-day", startTime.isDate, "checked");
 
             // In the case where the timezones are different but
             // the timezone of the endtime is "UTC", we convert
             // the endtime into the timezone of the starttime.
             if (startTime && endTime) {
-                if (!compareObjects(startTime.timezone, endTime.timezone)) {
+                if (!cal.compareObjects(startTime.timezone, endTime.timezone)) {
                     if (endTime.timezone.isUTC) {
                         endTime = endTime.getInTimezone(startTime.timezone);
                     }
                 }
             }
 
             // before feeding the date/time value into the control we need
             // to set the timezone to 'floating' in order to avoid the
             // automatic conversion back into the OS timezone.
-            startTime.timezone = floating();
-            endTime.timezone = floating();
+            startTime.timezone = cal.floating();
+            endTime.timezone = cal.floating();
 
             setElementValue("event-starttime", cal.dateTimeToJsDate(startTime));
             setElementValue("event-endtime", cal.dateTimeToJsDate(endTime));
         }
 
-        if (isToDo(item)) {
+        if (cal.isToDo(item)) {
             let startTime = gStartTime && gStartTime.getInTimezone(gStartTimezone);
             let endTime = gEndTime && gEndTime.getInTimezone(gEndTimezone);
             let hasEntryDate = (startTime != null);
             let hasDueDate = (endTime != null);
 
             if (hasEntryDate && hasDueDate) {
                 setElementValue("todo-has-entrydate", hasEntryDate, "checked");
-                startTime.timezone = floating();
+                startTime.timezone = cal.floating();
                 setElementValue("todo-entrydate", cal.dateTimeToJsDate(startTime));
 
                 setElementValue("todo-has-duedate", hasDueDate, "checked");
-                endTime.timezone = floating();
+                endTime.timezone = cal.floating();
                 setElementValue("todo-duedate", cal.dateTimeToJsDate(endTime));
             } else if (hasEntryDate) {
                 setElementValue("todo-has-entrydate", hasEntryDate, "checked");
-                startTime.timezone = floating();
+                startTime.timezone = cal.floating();
                 setElementValue("todo-entrydate", cal.dateTimeToJsDate(startTime));
 
-                startTime.timezone = floating();
+                startTime.timezone = cal.floating();
                 setElementValue("todo-duedate", cal.dateTimeToJsDate(startTime));
             } else if (hasDueDate) {
-                endTime.timezone = floating();
+                endTime.timezone = cal.floating();
                 setElementValue("todo-entrydate", cal.dateTimeToJsDate(endTime));
 
                 setElementValue("todo-has-duedate", hasDueDate, "checked");
-                endTime.timezone = floating();
+                endTime.timezone = cal.floating();
                 setElementValue("todo-duedate", cal.dateTimeToJsDate(endTime));
             } else {
                 startTime = window.initialStartDateValue;
-                startTime.timezone = floating();
+                startTime.timezone = cal.floating();
                 endTime = startTime.clone();
 
                 setElementValue("todo-entrydate", cal.dateTimeToJsDate(startTime));
                 setElementValue("todo-duedate", cal.dateTimeToJsDate(endTime));
             }
         }
     } else {
-        let kDefaultTimezone = calendarDefaultTimezone();
-
-        if (isEvent(item)) {
+        let kDefaultTimezone = cal.calendarDefaultTimezone();
+
+        if (cal.isEvent(item)) {
             let startTime = gStartTime.getInTimezone(kDefaultTimezone);
             let endTime = gEndTime.getInTimezone(kDefaultTimezone);
             setElementValue("event-all-day", startTime.isDate, "checked");
 
             // before feeding the date/time value into the control we need
             // to set the timezone to 'floating' in order to avoid the
             // automatic conversion back into the OS timezone.
-            startTime.timezone = floating();
-            endTime.timezone = floating();
+            startTime.timezone = cal.floating();
+            endTime.timezone = cal.floating();
             setElementValue("event-starttime", cal.dateTimeToJsDate(startTime));
             setElementValue("event-endtime", cal.dateTimeToJsDate(endTime));
         }
 
-        if (isToDo(item)) {
+        if (cal.isToDo(item)) {
             let startTime = gStartTime &&
                             gStartTime.getInTimezone(kDefaultTimezone);
             let endTime = gEndTime && gEndTime.getInTimezone(kDefaultTimezone);
             let hasEntryDate = (startTime != null);
             let hasDueDate = (endTime != null);
 
             if (hasEntryDate && hasDueDate) {
                 setElementValue("todo-has-entrydate", hasEntryDate, "checked");
-                startTime.timezone = floating();
+                startTime.timezone = cal.floating();
                 setElementValue("todo-entrydate", cal.dateTimeToJsDate(startTime));
 
                 setElementValue("todo-has-duedate", hasDueDate, "checked");
-                endTime.timezone = floating();
+                endTime.timezone = cal.floating();
                 setElementValue("todo-duedate", cal.dateTimeToJsDate(endTime));
             } else if (hasEntryDate) {
                 setElementValue("todo-has-entrydate", hasEntryDate, "checked");
-                startTime.timezone = floating();
+                startTime.timezone = cal.floating();
                 setElementValue("todo-entrydate", cal.dateTimeToJsDate(startTime));
 
-                startTime.timezone = floating();
+                startTime.timezone = cal.floating();
                 setElementValue("todo-duedate", cal.dateTimeToJsDate(startTime));
             } else if (hasDueDate) {
-                endTime.timezone = floating();
+                endTime.timezone = cal.floating();
                 setElementValue("todo-entrydate", cal.dateTimeToJsDate(endTime));
 
                 setElementValue("todo-has-duedate", hasDueDate, "checked");
-                endTime.timezone = floating();
+                endTime.timezone = cal.floating();
                 setElementValue("todo-duedate", cal.dateTimeToJsDate(endTime));
             } else {
                 startTime = window.initialStartDateValue;
-                startTime.timezone = floating();
+                startTime.timezone = cal.floating();
                 endTime = startTime.clone();
 
                 setElementValue("todo-entrydate", cal.dateTimeToJsDate(startTime));
                 setElementValue("todo-duedate", cal.dateTimeToJsDate(endTime));
             }
         }
     }
 
@@ -3480,17 +3480,17 @@ function updateAttachment() {
  * @param {string} aUrl    The url in question
  * @return {boolean}       Returns true for show and false for hide
  */
 function showOrHideItemURL(aShow, aUrl) {
     if (aShow && aUrl.length) {
         let handler;
         let uri;
         try {
-            uri = makeURL(aUrl);
+            uri = cal.makeURL(aUrl);
             handler = Services.io.getProtocolHandler(uri.scheme);
         } catch (e) {
             // No protocol handler for the given protocol, or invalid uri
             // hideOrShow(false);
             return false;
         }
         // Only show if its either an internal protcol handler, or its external
         // and there is an external app for the scheme
@@ -3531,17 +3531,17 @@ function updateItemURL(aShow, aUrl) {
 
 /**
  * This function updates dialog controls related to attendees.
  */
 function updateAttendees() {
     // sending email invitations currently only supported for events
     let attendeeTab = document.getElementById("event-grid-tab-attendees");
     let attendeePanel = document.getElementById("event-grid-tabpanel-attendees");
-    if (isEvent(window.calendarItem)) {
+    if (cal.isEvent(window.calendarItem)) {
         attendeeTab.removeAttribute("collapsed");
         attendeePanel.removeAttribute("collapsed");
 
         if (window.organizer && window.organizer.id) {
             document.getElementById("item-organizer-row").removeAttribute("collapsed");
             let cell = document.querySelector(".item-organizer-cell");
             let icon = cell.querySelector("img:nth-of-type(1)");
             let text = cell.querySelector("label:nth-of-type(1)");
@@ -3591,17 +3591,17 @@ function updateRepeatDetails() {
         // First of all collapse the details text. If we fail to
         // create a details string, we simply don't show anything.
         // this could happen if the repeat rule is something exotic
         // we don't have any strings prepared for.
         let repeatDetails = document.getElementById("repeat-details");
         repeatDetails.setAttribute("collapsed", "true");
 
         // Try to create a descriptive string from the rule(s).
-        let kDefaultTimezone = calendarDefaultTimezone();
+        let kDefaultTimezone = cal.calendarDefaultTimezone();
         let event = cal.isEvent(item);
 
         let startDate = getElementValue(event ? "event-starttime" : "todo-entrydate");
         let endDate = getElementValue(event ? "event-endtime" : "todo-duedate");
         startDate = cal.jsDateToDateTime(startDate, kDefaultTimezone);
         endDate = cal.jsDateToDateTime(endDate, kDefaultTimezone);
 
         let allDay = getElementValue("event-all-day", "checked");
@@ -3753,17 +3753,17 @@ function sendMailToUndecidedAttendees(aA
  *
  * @param aAttendees    The attendees to send mail to.
  */
 function sendMailToAttendees(aAttendees) {
     let toList = cal.getRecipientList(aAttendees);
     let item = saveItem();
     let emailSubject = cal.calGetString("calendar-event-dialog", "emailSubjectReply", [item.title]);
     let identity = window.calendarItem.calendar.getProperty("imip.identity");
-    sendMailTo(toList, emailSubject, null, identity);
+    cal.sendMailTo(toList, emailSubject, null, identity);
 }
 
 /**
  * Make sure all fields that may have calendar specific capabilities are updated
  */
 function updateCapabilities() {
     updateAttachment();
     updateConfigState({
@@ -3782,23 +3782,23 @@ function updateCapabilities() {
 function isItemChanged() {
     let newItem = saveItem();
     let oldItem = window.calendarItem.clone();
 
     // we need to guide the description text through the text-field since
     // newlines are getting converted which would indicate changes to the
     // text.
     setElementValue("item-description", oldItem.getProperty("DESCRIPTION"));
-    setItemProperty(oldItem,
-                    "DESCRIPTION",
-                    getElementValue("item-description"));
+    cal.setItemProperty(oldItem,
+                        "DESCRIPTION",
+                        getElementValue("item-description"));
     setElementValue("item-description", newItem.getProperty("DESCRIPTION"));
 
     if ((newItem.calendar.id == oldItem.calendar.id) &&
-        compareItemContent(newItem, oldItem)) {
+        cal.compareItemContent(newItem, oldItem)) {
         return false;
     }
     return true;
 }
 
 /**
  * Test if a specific capability is supported
  *
@@ -3994,17 +3994,17 @@ function lookupCounterLabel(aProperty) {
  */
 function formatCounterValue(aProperty) {
     const dateProps = ["DTSTART", "DTEND"];
     const stringProps = ["SUMMARY", "LOCATION"];
 
     let val;
     if (dateProps.includes(aProperty.property)) {
         let localTime = aProperty.proposed.getInTimezone(cal.calendarDefaultTimezone());
-        let formatter = getDateFormatter();
+        let formatter = cal.getDateFormatter();
         val = formatter.formatDateTime(localTime);
         if (gTimezonesEnabled) {
             let tzone = localTime.timezone.displayName || localTime.timezone.tzid;
             val += " " + tzone;
         }
     } else if (stringProps.includes(aProperty.property)) {
         val = aProperty.proposed;
     } else {
--- a/calendar/lightning/content/lightning-item-iframe.xul
+++ b/calendar/lightning/content/lightning-item-iframe.xul
@@ -38,18 +38,16 @@
   <!-- Javascript includes -->
   <script type="application/javascript"
           src="chrome://lightning/content/lightning-item-iframe.js"/>
   <script type="application/javascript"
           src="chrome://calendar/content/calendar-dialog-utils.js"/>
   <script type="application/javascript"
           src="chrome://calendar/content/calendar-ui-utils.js"/>
   <script type="application/javascript"
-          src="chrome://calendar/content/calUtils.js"/>
-  <script type="application/javascript"
           src="chrome://calendar/content/calApplicationUtils.js"/>
   <script type="application/javascript"
           src="chrome://global/content/globalOverlay.js"/>
   <script type="application/javascript"
           src="chrome://global/content/printUtils.js"/>
   <script type="application/javascript"
           src="chrome://calendar/content/calendar-statusbar.js"/>
 
--- a/calendar/lightning/content/messenger-overlay-accountCentral.xul
+++ b/calendar/lightning/content/messenger-overlay-accountCentral.xul
@@ -19,13 +19,13 @@
             flex="1"
             insertbefore="AccountsSection.spacer"/>
     <row id="lightning-newCalendar-row"
          class="acctCentralRow"
          insertbefore="AccountsSection.spacer">
       <hbox>
         <label class="acctCentralText acctCentralLinkText"
                value="&lightning.acctCentral.newCalendar.label;"
-               onclick="window.parent.openCalendarWizard();"/>
+               onclick="window.parent.cal.openCalendarWizard(window);"/>
       </hbox>
     </row>
   </rows>
 </overlay>
--- a/calendar/lightning/content/messenger-overlay-preferences.xul
+++ b/calendar/lightning/content/messenger-overlay-preferences.xul
@@ -53,15 +53,13 @@
                     <tabpanel orient="vertical">
                         <vbox id="calPreferencesBoxViews"/>
                     </tabpanel>
                 </tabpanels>
             </tabbox>
         </prefpane>
 
         <script type="application/javascript"
-                src="chrome://calendar/content/calUtils.js"/>
-        <script type="application/javascript"
                 src="chrome://lightning/content/messenger-overlay-preferences.js"/>
 
     </prefwindow>
 
 </overlay>
--- a/calendar/lightning/content/messenger-overlay-sidebar.js
+++ b/calendar/lightning/content/messenger-overlay-sidebar.js
@@ -8,16 +8,17 @@
  *          customizeMailToolbarForTabType
  */
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Promise.jsm");
 Components.utils.import("resource://gre/modules/Task.jsm");
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calAsyncUtils.jsm");
 
 var gLastShownCalendarView = null;
 
 var calendarTabMonitor = {
     monitorName: "lightning",
 
     // Unused, but needed functions
@@ -328,21 +329,21 @@ var calendarItemTabType = {
      * @param {Object} aTabmail  The tabmail interface
      * @param {Object} aState    The state of the tab to restore
      */
     restoreTab: function(aTabmail, aState) {
         // Sometimes restoreTab is called for tabs that were never saved
         // and never meant to be persisted or restored. See persistTab.
         if (aState.args && aState.calendarId && aState.itemId) {
             aState.args.initialStartDateValue = aState.initialStartDate
-                ? cal.createDateTime(aState.initialStartDate) : getDefaultStartDate();
+                ? cal.createDateTime(aState.initialStartDate) : cal.getDefaultStartDate();
 
             aState.args.onOk = doTransaction.bind(null, "modify");
 
-            aState.args.calendar = getCalendarManager().getCalendarById(aState.calendarId);
+            aState.args.calendar = cal.getCalendarManager().getCalendarById(aState.calendarId);
             if (aState.args.calendar) {
                 // using wrappedJSObject is a hack that is needed to prevent a proxy error
                 let pcal = cal.async.promisifyCalendar(aState.args.calendar.wrappedJSObject);
                 pcal.getItem(aState.itemId).then((item) => {
                     if (item[0]) {
                         aState.args.calendarEvent = item[0];
                         aTabmail.openTab(aState.tabType, aState.args);
                     }
@@ -370,17 +371,17 @@ function ltnOnLoad(event) {
     // Take care of common initialization
     commonInitCalendar();
 
     // Add an unload function to the window so we don't leak any listeners
     window.addEventListener("unload", ltnFinish, false);
 
     // Set up invitations manager
     scheduleInvitationsUpdate(FIRST_DELAY_STARTUP);
-    getCalendarManager().addObserver(gInvitationsCalendarManagerObserver);
+    cal.getCalendarManager().addObserver(gInvitationsCalendarManagerObserver);
 
     let filter = document.getElementById("task-tree-filtergroup");
     filter.value = filter.value || "all";
     document.getElementById("modeBroadcaster").setAttribute("mode", gCurrentMode);
     document.getElementById("modeBroadcaster").setAttribute("checked", "true");
 
     let mailContextPopup = document.getElementById("mailContext");
     if (mailContextPopup) {
@@ -548,26 +549,26 @@ function refreshUIBits() {
          "multiweek-view",
          "month-view"].forEach((view) => {
              if (view != currView.id) {
                  document.getElementById(view).mToggleStatus = -1;
              }
          });
 
         if (!TodayPane.showsToday()) {
-            TodayPane.setDay(now());
+            TodayPane.setDay(cal.now());
         }
 
         // update the unifinder
         refreshEventTree();
 
         // update today's date on todaypane button
         document.getElementById("calendar-status-todaypane-button").setUpTodayDate();
     } catch (exc) {
-        ASSERT(false, exc);
+        cal.ASSERT(false, exc);
     }
 
     // schedule our next update...
     scheduleMidnightUpdate(refreshUIBits);
 }
 
 /**
  * Switch the calendar view, and optionally switch to calendar mode.
@@ -620,17 +621,17 @@ function LtnObserveDisplayDeckChange(eve
     if (gCurrentMode != "mail") {
         if (id != "calendar-view-box" && id != "calendar-task-box") {
             ltnSwitch2Mail();
         }
     }
 }
 
 function ltnFinish() {
-    getCalendarManager().removeObserver(gInvitationsCalendarManagerObserver);
+    cal.getCalendarManager().removeObserver(gInvitationsCalendarManagerObserver);
 
     // Remove listener for mailContext.
     let mailContextPopup = document.getElementById("mailContext");
     if (mailContextPopup) {
         mailContextPopup.removeEventListener("popupshowing",
                                              gCalSetupMailContext.popup, false);
     }
 
--- a/calendar/lightning/content/messenger-overlay-sidebar.xul
+++ b/calendar/lightning/content/messenger-overlay-sidebar.xul
@@ -42,17 +42,16 @@
   <!-- NEEDED FOR IMPORT / EXPORT SUPPORT -->
   <script type="application/javascript" src="chrome://calendar/content/import-export.js"/>
 
   <!-- NEEDED FOR PUBLICATION SUPPORT -->
   <script type="application/javascript" src="chrome://calendar/content/publish.js"/>
 
   <script type="application/javascript" src="chrome://calendar/content/calendar-item-editing.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-chrome-startup.js"/>
-  <script type="application/javascript" src="chrome://calendar/content/calUtils.js"/>
   <script type="application/javascript" src="chrome://calendar/content/mouseoverPreviews.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-views.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-ui-utils.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-creation.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-dnd-listener.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-statusbar.js"/>
   <script type="application/javascript" src="chrome://global/content/nsDragAndDrop.js"/>
 
@@ -79,17 +78,17 @@
       <command id="switch2task"
                oncommand="document.getElementById('tabmail').openTab('tasks', { title: document.getElementById('task-tab-button').getAttribute('title') })"/>
       <command id="new_calendar_tab"
                oncommand="document.getElementById('tabmail').openTab('calendar', { title: document.getElementById('calendar-tab-button').getAttribute('title') })"/>
       <command id="new_task_tab"
                oncommand="document.getElementById('tabmail').openTab('tasks', { title: document.getElementById('task-tab-button').getAttribute('title') })"/>
       <command id="calendar_go_to_today_command"
                observes="calendar_mode_calendar"
-               oncommand="document.getElementById('tabmail').openTab('calendar', { title: document.getElementById('calendar-tab-button').getAttribute('title') }); goToDate(now())"/>
+               oncommand="document.getElementById('tabmail').openTab('calendar', { title: document.getElementById('calendar-tab-button').getAttribute('title') }); goToDate(cal.now())"/>
     </commandset>
 
     <commandset id="mailCommands">
       <command id="cmd_CustomizeMailToolbar"
                oncommand="customizeMailToolbarForTabType()"/>
     </commandset>
 
     <keyset id="calendar-keys">
--- a/calendar/lightning/content/suite-overlay-preferences.xul
+++ b/calendar/lightning/content/suite-overlay-preferences.xul
@@ -58,11 +58,9 @@
         </prefpane>
         <prefpane id="paneLightningViews"
                   label="&paneViews.title;"
                   onpaneload="gViewsPane.init();">
             <vbox id="calPreferencesBoxViews"/>
         </prefpane>
     </prefwindow>
 
-    <script type="application/javascript"
-            src="chrome://calendar/content/calUtils.js"/>
 </overlay>
--- a/calendar/providers/caldav/calDavCalendar.js
+++ b/calendar/providers/caldav/calDavCalendar.js
@@ -152,17 +152,17 @@ calDavCalendar.prototype = {
     //
     // calICalendarProvider interface
     //
     get prefChromeOverlay() {
         return null;
     },
 
     get displayName() {
-        return calGetString("calendar", "caldavName");
+        return cal.calGetString("calendar", "caldavName");
     },
 
     createCalendar: function() {
         throw NS_ERROR_NOT_IMPLEMENTED;
     },
 
     deleteCalendar: function(cal, listener) {
         throw NS_ERROR_NOT_IMPLEMENTED;
@@ -635,17 +635,17 @@ calDavCalendar.prototype = {
         }
 
         if (aItem.id == null) {
             notifyListener(Components.results.NS_ERROR_FAILURE,
                            "Can't set ID on non-mutable item to addItem");
             return;
         }
 
-        if (!isItemSupported(aItem, this)) {
+        if (!cal.isItemSupported(aItem, this)) {
             notifyListener(Components.results.NS_ERROR_FAILURE,
                            "Server does not support item type");
             return;
         }
 
         let parentItem = aItem.parentItem;
         parentItem.calendar = this.superCalendar;
 
@@ -1330,17 +1330,17 @@ calDavCalendar.prototype = {
             }
         };
 
         if (!this.mACLEntry) {
             let self = this;
             let opListener = {
                 QueryInterface: XPCOMUtils.generateQI([Components.interfaces.calIOperationListener]),
                 onGetResult: function(calendar, status, itemType, detail, count, items) {
-                    ASSERT(false, "unexpected!");
+                    cal.ASSERT(false, "unexpected!");
                 },
                 onOperationComplete: function(opCalendar, opStatus, opType, opId, opDetail) {
                     self.mACLEntry = opDetail;
                     self.fillACLProperties();
                     self.safeRefresh(aChangeLogListener);
                 }
             };
 
@@ -1468,17 +1468,17 @@ calDavCalendar.prototype = {
         });
     },
 
     refresh: function() {
         this.replayChangesOn(null);
     },
 
     firstInRealm: function() {
-        let calendars = getCalendarManager().getCalendars({});
+        let calendars = cal.getCalendarManager().getCalendars({});
         for (let i = 0; i < calendars.length; i++) {
             if (calendars[i].type != "caldav" || calendars[i].getProperty("disabled")) {
                 continue;
             }
             // XXX We should probably expose the inner calendar via an
             // interface, but for now use wrappedJSObject.
             let calendar = calendars[i].wrappedJSObject;
             if (calendar.mUncachedCalendar) {
@@ -1993,17 +1993,17 @@ calDavCalendar.prototype = {
                 // XXX - we really shouldn't register with the fb service
                 // if another calendar with the same principal-URL has already
                 // done so. We also shouldn't register with the fb service if we
                 // don't have an outbox.
                 if (!self.hasFreeBusy) {
                     // This may have already been set by fetchCachedMetaData,
                     // we only want to add the freebusy provider once.
                     self.hasFreeBusy = true;
-                    getFreeBusyService().addProvider(self);
+                    cal.getFreeBusyService().addProvider(self);
                 }
                 self.findPrincipalNS(aChangeLogListener);
             } else {
                 cal.LOG("CalDAV: Server does not support CalDAV scheduling.");
                 self.completeCheckServerInfo(aChangeLogListener);
             }
         };
 
@@ -2163,17 +2163,17 @@ calDavCalendar.prototype = {
                     "</D:prop>" +
                 "</D:principal-property-search>";
             queryMethod = "REPORT";
             queryDepth = 1;
         }
 
         // We want a trailing slash, ensure it.
         let nextNS = aNameSpaceList.pop().replace(/([^\/])$/, "$1/");
-        let requestUri = makeURL(this.calendarUri.prePath + this.ensureEncodedPath(nextNS));
+        let requestUri = cal.makeURL(this.calendarUri.prePath + this.ensureEncodedPath(nextNS));
 
         if (this.verboseLogging()) {
             cal.LOG("CalDAV: send: " + queryMethod + " " + requestUri.spec + "\n" + queryXml);
         }
 
         let streamListener = {};
         streamListener.onStreamComplete = function(aLoader, aContext, aStatus, aResultLength, aResult) {
             let request = aLoader.request.QueryInterface(Components.interfaces.nsIHttpChannel);
@@ -2412,30 +2412,30 @@ calDavCalendar.prototype = {
             return;
         }
         let mailto_aCalId = aCalIdParts.join(":");
 
         let self = this;
 
         let organizer = this.calendarUserAddress;
 
-        let fbQuery = getIcsService().createIcalComponent("VCALENDAR");
-        calSetProdidVersion(fbQuery);
-        let prop = getIcsService().createIcalProperty("METHOD");
+        let fbQuery = cal.getIcsService().createIcalComponent("VCALENDAR");
+        cal.calSetProdidVersion(fbQuery);
+        let prop = cal.getIcsService().createIcalProperty("METHOD");
         prop.value = "REQUEST";
         fbQuery.addProperty(prop);
-        let fbComp = getIcsService().createIcalComponent("VFREEBUSY");
-        fbComp.stampTime = now().getInTimezone(UTC());
-        prop = getIcsService().createIcalProperty("ORGANIZER");
+        let fbComp = cal.getIcsService().createIcalComponent("VFREEBUSY");
+        fbComp.stampTime = cal.now().getInTimezone(cal.UTC());
+        prop = cal.getIcsService().createIcalProperty("ORGANIZER");
         prop.value = organizer;
         fbComp.addProperty(prop);
-        fbComp.startTime = aRangeStart.getInTimezone(UTC());
-        fbComp.endTime = aRangeEnd.getInTimezone(UTC());
+        fbComp.startTime = aRangeStart.getInTimezone(cal.UTC());
+        fbComp.endTime = aRangeEnd.getInTimezone(cal.UTC());
         fbComp.uid = cal.getUUID();
-        prop = getIcsService().createIcalProperty("ATTENDEE");
+        prop = cal.getIcsService().createIcalProperty("ATTENDEE");
         prop.setParameter("PARTSTAT", "NEEDS-ACTION");
         prop.setParameter("ROLE", "REQ-PARTICIPANT");
         prop.setParameter("CUTYPE", "INDIVIDUAL");
         prop.value = mailto_aCalId;
         fbComp.addProperty(prop);
         fbQuery.addSubcomponent(fbComp);
         fbQuery = fbQuery.serializeToICS();
         if (this.verboseLogging()) {
@@ -2740,17 +2740,17 @@ calDavCalendar.prototype = {
             // work around BUG 351589, the below just removes RSVP:
             aItipItem.setAttendeeStatus(attendee.id, attendee.participationStatus);
         }
 
         for (let item of aItipItem.getItemList({})) {
             let serializer = Components.classes["@mozilla.org/calendar/ics-serializer;1"]
                                        .createInstance(Components.interfaces.calIIcsSerializer);
             serializer.addItems([item], 1);
-            let methodProp = getIcsService().createIcalProperty("METHOD");
+            let methodProp = cal.getIcsService().createIcalProperty("METHOD");
             methodProp.value = aItipItem.responseMethod;
             serializer.addProperty(methodProp);
 
             let self = this;
             let streamListener = {
                 onStreamComplete: function(aLoader, aContext, aStatus, aResultLength, aResult) {
                     let request = aLoader.request.QueryInterface(Components.interfaces.nsIHttpChannel);
                     let status;
@@ -2982,13 +2982,12 @@ calDavObserver.prototype = {
     onError: function(aCalendar, aErrNo, aMessage) {
         this.mCalendar.readOnly = true;
         this.mCalendar.notifyError(aErrNo, aMessage);
     }
 };
 
 /** Module Registration */
 var scriptLoadOrder = [
-    "calUtils.js",
     "calDavRequestHandlers.js"
 ];
 
 this.NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, [calDavCalendar], this);
--- a/calendar/providers/gdata/content/gdata-migration-wizard.xul
+++ b/calendar/providers/gdata/content/gdata-migration-wizard.xul
@@ -15,16 +15,15 @@
         acceptKey="&gdata.migration.upgrade.accesskey;"
         ondialogaccept="migrateSelectedCalendars(); return true;"
         ondialogcancel="window.close()"
         onload="gdata_migration_loader()"
         width="300"
         height="300"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <script type="application/javascript" src="chrome://gdata-provider/content/gdata-migration.js"/>
-  <script type="application/javascript" src="chrome://calendar/content/calUtils.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-views.js"/>
   <script type="application/javascript" src="chrome://calendar/content/calendar-ui-utils.js"/>
 
   <description>&gdata.migration.description;</description>
   <listbox id="calendars-listbox" flex="1"/>
   <checkbox id="showagain-checkbox" label="&gdata.migration.showagain.label;"/>
 </dialog>
--- a/calendar/providers/gdata/content/gdata-migration.js
+++ b/calendar/providers/gdata/content/gdata-migration.js
@@ -58,17 +58,17 @@ function getMigratableCalendars() {
     function isMigratable(c) {
         let re = new RegExp("^http[s]?://www\\.google\\.com/calendar/ical/" +
                             "[^/]+/(private(-[^/]+)?|public)/" +
                             "(full|full-noattendees|composite|" +
                             "attendees-only|free-busy|basic)(\\.ics)?$");
         return c.type == "ics" && c.uri.spec.match(re);
     }
 
-    return getCalendarManager().getCalendars({}).filter(isMigratable);
+    return cal.getCalendarManager().getCalendars({}).filter(isMigratable);
 }
 
 /**
  * Load Handler for both the wizard and the Thunderbird main window.
  */
 function gdata_migration_loader() {
     if (document.documentElement.id == "gdata-migration-wizard") {
         // This is the migration wizard, load the calendars neeeded.
--- a/calendar/providers/ics/calICSCalendar.js
+++ b/calendar/providers/ics/calICSCalendar.js
@@ -77,17 +77,17 @@ calICSCalendar.prototype = {
     //
     // calICalendarProvider interface
     //
     get prefChromeOverlay() {
         return null;
     },
 
     get displayName() {
-        return calGetString("calendar", "icsName");
+        return cal.calGetString("calendar", "icsName");
     },
 
     createCalendar: function() {
         throw NS_ERROR_NOT_IMPLEMENTED;
     },
 
     deleteCalendar: function(cal, listener) {
         throw NS_ERROR_NOT_IMPLEMENTED;
@@ -577,21 +577,21 @@ calICSCalendar.prototype = {
         }
     },
 
     lock: function() {
         this.locked = true;
     },
 
     unlock: function(errCode) {
-        ASSERT(this.locked, "unexpected!");
+        cal.ASSERT(this.locked, "unexpected!");
 
         this.mModificationActions.forEach((action) => {
             let args = action.opCompleteArgs;
-            ASSERT(args, "missing onOperationComplete call!");
+            cal.ASSERT(args, "missing onOperationComplete call!");
             let listener = action.listener;
             if (listener) {
                 if (Components.isSuccessCode(args[1]) &&
                     errCode && !Components.isSuccessCode(errCode)) {
                     listener.onOperationComplete(args[0], errCode, args[2], args[3], null);
                 } else {
                     listener.onOperationComplete(...args);
                 }
@@ -1106,14 +1106,9 @@ fileHooks.prototype = {
     onAfterPut: function(aChannel, aRespFunc) {
         let filechannel = aChannel.QueryInterface(Components.interfaces.nsIFileChannel);
         this.mtime = filechannel.file.lastModifiedTime;
         aRespFunc();
         return true;
     }
 };
 
-/** Module Registration */
-var scriptLoadOrder = [
-    "calUtils.js",
-];
-
-this.NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, [calICSCalendar], this);
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calICSCalendar]);
--- a/calendar/providers/storage/calStorageCalendar.js
+++ b/calendar/providers/storage/calStorageCalendar.js
@@ -766,17 +766,17 @@ calStorageCalendar.prototype = {
                 // If the item is recurring, get all ocurrences that fall in
                 // the range. If the item doesn't fall into the range at all,
                 // this expands to 0 items.
                 expandedItems = item.recurrenceInfo.getOccurrences(aRangeStart, aRangeEnd, 0, {});
                 if (wantUnrespondedInvitations) {
                     expandedItems = expandedItems.filter(checkUnrespondedInvitation);
                 }
             } else if ((!wantUnrespondedInvitations || checkUnrespondedInvitation(item)) &&
-                       checkIfInRange(item, aRangeStart, aRangeEnd)) {
+                       cal.checkIfInRange(item, aRangeStart, aRangeEnd)) {
                 // If no occurrences are wanted, check only the parent item.
                 // This will be changed with bug 416975.
                 expandedItems = [item];
             }
 
             if (expandedItems.length && optionalFilterFunc) {
                 expandedItems = expandedItems.filter(optionalFilterFunc);
             }
@@ -1594,17 +1594,17 @@ calStorageCalendar.prototype = {
         let item;
         if (!isException) { // only parent items are cached
             item = this.mItemCache[row.id];
             if (item) {
                 return item;
             }
         }
 
-        item = createEvent();
+        item = cal.createEvent();
 
         if (row.event_start) {
             item.startDate = newDateTime(row.event_start, row.event_start_tz);
         }
         if (row.event_end) {
             item.endDate = newDateTime(row.event_end, row.event_end_tz);
         }
         if (row.event_stamp) {
@@ -1630,17 +1630,17 @@ calStorageCalendar.prototype = {
         let item;
         if (!isException) { // only parent items are cached
             item = this.mItemCache[row.id];
             if (item) {
                 return item;
             }
         }
 
-        item = createTodo();
+        item = cal.createTodo();
 
         if (row.todo_entry) {
             item.entryDate = newDateTime(row.todo_entry, row.todo_entry_tz);
         }
         if (row.todo_due) {
             item.dueDate = newDateTime(row.todo_due, row.todo_due_tz);
         }
         if (row.todo_stamp) {
@@ -1722,17 +1722,17 @@ calStorageCalendar.prototype = {
                 while (selectItem.executeStep()) {
                     let row = selectItem.row;
                     let name = row.key;
                     switch (name) {
                         case "DURATION":
                             // for events DTEND/DUE is enforced by calEvent/calTodo, so suppress DURATION:
                             break;
                         case "CATEGORIES": {
-                            let cats = categoriesStringToArray(row.value);
+                            let cats = cal.categoriesStringToArray(row.value);
                             item.setCategories(cats.length, cats);
                             break;
                         }
                         default:
                             item.setProperty(name, row.value);
                             break;
                     }
                 }
@@ -1964,17 +1964,17 @@ calStorageCalendar.prototype = {
             }
         } else {
             params[entryname] = null;
             params[entryname + "_tz"] = null;
         }
     },
 
     flushItem: function(item, olditem) {
-        ASSERT(!item.recurrenceId, "no parent item passed!", true);
+        cal.ASSERT(!item.recurrenceId, "no parent item passed!", true);
 
         try {
             this.deleteItemById(olditem ? olditem.id : item.id, true);
             this.acquireTransaction();
             this.writeItem(item, olditem);
         } catch (e) {
             this.releaseTransaction(e);
             throw e;
@@ -2155,17 +2155,17 @@ calStorageCalendar.prototype = {
                 continue;
             }
             this.writeProperty(item, prop.name, prop.value);
         }
 
         let cats = item.getCategories({});
         if (cats.length > 0) {
             ret = CAL_ITEM_FLAG.HAS_PROPERTIES;
-            this.writeProperty(item, "CATEGORIES", categoriesArrayToString(cats));
+            this.writeProperty(item, "CATEGORIES", cal.categoriesArrayToString(cats));
         }
 
         return ret;
     },
 
     writeRecurrence: function(item, olditem) {
         let flags = 0;
 
@@ -2460,14 +2460,9 @@ calStorageCalendar.prototype = {
                         ex.deleteProperty("SEQUENCE");
                     }
                 }
             }
         }
     }
 };
 
-/** Module Registration */
-var scriptLoadOrder = [
-    "calUtils.js",
-];
-
-this.NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, [calStorageCalendar], this);
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calStorageCalendar]);
--- a/calendar/providers/wcap/calWcapCalendarItems.js
+++ b/calendar/providers/wcap/calWcapCalendarItems.js
@@ -1,13 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calAlarmUtils.jsm");
 Components.utils.import("resource://calendar/modules/calIteratorUtils.jsm");
 
 calWcapCalendar.prototype.encodeAttendee = function(att) {
     if (LOG_LEVEL > 2) {
         log("attendee.icalProperty.icalString=" + att.icalProperty.icalString, this);
     }
     function encodeAttr(val, attr, params) {
@@ -49,19 +50,19 @@ calWcapCalendar.prototype.getRecurrenceP
                 if (isNeg) {
                     out_exrules.value.push(rule);
                 } else {
                     out_rrules.value.push(rule);
                 }
             } else if (rDateInstance) {
                 // cs does not accept DATEs here:
                 if (isNeg) {
-                    out_exdates.value.push(getIcalUTC(ensureDateTime(rDateInstance.date)));
+                    out_exdates.value.push(getIcalUTC(cal.ensureDateTime(rDateInstance.date)));
                 } else {
-                    out_rdates.value.push(getIcalUTC(ensureDateTime(rDateInstance.date)));
+                    out_rdates.value.push(getIcalUTC(cal.ensureDateTime(rDateInstance.date)));
                 }
             } else {
                 this.notifyError(NS_ERROR_UNEXPECTED,
                                  "don't know how to handle this recurrence item: " + rItem.valueAsIcalString);
             }
         }
     }
 };
@@ -232,17 +233,17 @@ function equalDatetimes(one, two) {
             (one && two &&
              one.isDate == two.isDate &&
              one.compare(two) == 0);
 }
 
 function identicalDatetimes(one, two) {
     return (!one && !two) ||
             (equalDatetimes(one, two) &&
-             compareObjects(one.timezone, two.timezone));
+             cal.compareObjects(one.timezone, two.timezone));
 }
 
 // @return null if nothing has changed else value to be written
 function diffProperty(newItem, oldItem, propName) {
     let val = newItem.getProperty(propName);
     let oldVal = (oldItem ? oldItem.getProperty(propName) : null);
     if (val === null) {
         // force being set when - no old item, eg when adding new item
@@ -313,17 +314,17 @@ calWcapCalendar.prototype.storeItem = fu
                 }
             }
             strings.sort();
             ret = strings.join(";");
         }
         return ret || "";
     };
 
-    let bIsEvent = isEvent(item);
+    let bIsEvent = cal.isEvent(item);
     let bIsParent = isParent(item);
 
     let method = METHOD_PUBLISH;
     let bNoSmtpNotify = false;
     let params = "";
 
     let calId = this.calId;
     if (!bAddItem && this.isInvitation(item)) { // REPLY
@@ -548,17 +549,17 @@ calWcapCalendar.prototype.storeItem = fu
             params += "&storetype=1";
         } else if (oldItem) {
             params += "&storetype=2";
         } // else we don't know exactly, so don't check
 
         if (bIsParent) {
             params += "&mod=4"; // THIS AND ALL INSTANCES
         } else {
-            params += "&mod=1&rid=" + getIcalUTC(ensureDateTime(item.recurrenceId)); // THIS INSTANCE
+            params += "&mod=1&rid=" + getIcalUTC(cal.ensureDateTime(item.recurrenceId)); // THIS INSTANCE
         }
 
         params += "&method=" + method;
         if (bNoSmtpNotify) {
             params += "&smtp=0&smtpNotify=0&notify=0";
         }
         params += "&replace=1"; // (update) don't append to any lists
         params += "&fetch=1&relativealarm=1&compressed=1&recurring=1";
@@ -708,17 +709,17 @@ calWcapCalendar.prototype.modifyItem = f
                                                  }
                                                  // invalidate cached results:
                                                  delete this.m_cachedResults;
                                                  this.storeItem(false /* bAddItem */, newItem, oldItem_, request);
                                              } finally {
                                                  request.unlockPending();
                                              }
                                          },
-                                         stringToXml, isEvent(newItem) ? "deleteevents_by_id" : "deletetodos_by_id",
+                                         stringToXml, cal.isEvent(newItem) ? "deleteevents_by_id" : "deletetodos_by_id",
                                          params, calIWcapCalendar.AC_COMP_WRITE);
                 return request;
             }
         } else if (oldItem && !oldItem.parentItem.recurrenceInfo.getExceptionFor(newItem.recurrenceId)) {
             // pass null for oldItem when creating new exceptions, write whole item:
             oldItem_ = null;
         }
         this.storeItem(false /* bAddItem */, newItem, oldItem_, request);
@@ -746,17 +747,17 @@ calWcapCalendar.prototype.deleteItem = f
         if (!item.id) {
             throw new Components.Exception("no item id!");
         }
         let params = "&uid=" + encodeURIComponent(item.id);
         if (isParent(item)) { // delete THIS AND ALL:
             params += "&mod=4&rid=0";
         } else { // delete THIS INSTANCE:
             // cs does not accept DATE here:
-            params += "&mod=1&rid=" + getIcalUTC(ensureDateTime(item.recurrenceId));
+            params += "&mod=1&rid=" + getIcalUTC(cal.ensureDateTime(item.recurrenceId));
         }
 
         let orgCalId = getCalId(item.organizer);
         if (!orgCalId || (orgCalId != this.calId)) {
             // item does not belong to this user, so don't notify:
             params += "&smtp=0&smtpNotify=0&notify=0";
         }
 
@@ -768,17 +769,17 @@ calWcapCalendar.prototype.deleteItem = f
                                          throw err;
                                      }
                                      // invalidate cached results:
                                      delete this.m_cachedResults;
                                      if (LOG_LEVEL > 0) {
                                          log("deleteItem(): " + getWcapRequestStatusString(xml), this);
                                      }
                                  },
-                                 stringToXml, isEvent(item) ? "deleteevents_by_id" : "deletetodos_by_id",
+                                 stringToXml, cal.isEvent(item) ? "deleteevents_by_id" : "deletetodos_by_id",
                                  params, calIWcapCalendar.AC_COMP_WRITE);
     } catch (exc) {
         request.execRespFunc(exc);
     }
     return request;
 };
 
 calWcapCalendar.prototype.patchTimezone = function(subComp, attr, xpropOrTz) {
@@ -788,17 +789,17 @@ calWcapCalendar.prototype.patchTimezone 
         if (LOG_LEVEL > 2) {
             log(attr + " is " + date, this);
         }
         let timezone;
         if (typeof xpropOrTz == "string") {
             let tzid = subComp.getFirstProperty(xpropOrTz);
             if (tzid) {
                 timezone = this.session.getTimezone(tzid.value);
-                ASSERT(timezone, "timezone not found: " + tzid);
+                cal.ASSERT(timezone, "timezone not found: " + tzid);
             }
         } else {
             timezone = xpropOrTz;
         }
         if (timezone) {
             if (LOG_LEVEL > 2) {
                 log("patching " + xpropOrTz + ": from " +
                     date + " to " + date.getInTimezone(timezone), this);
@@ -841,23 +842,23 @@ calWcapCalendar.prototype.parseItems = f
         }
 
         let dtstart = this.patchTimezone(subComp, "startTime", "X-NSCP-DTSTART-TZID");
 
         let item = null;
         switch (subComp.componentType) {
             case "VEVENT": {
                 this.patchTimezone(subComp, "endTime", dtstart ? dtstart.timezone : "X-NSCP-DTEND-TZID");
-                item = createEvent();
+                item = cal.createEvent();
                 item.icalComponent = subComp;
                 break;
             }
             case "VTODO": {
                 this.patchTimezone(subComp, "dueTime", dtstart ? dtstart.timezone : "X-NSCP-DUE-TZID");
-                item = createTodo();
+                item = cal.createTodo();
                 item.icalComponent = subComp;
                 switch (itemFilter & calICalendar.ITEM_FILTER_COMPLETED_ALL) {
                     case calICalendar.ITEM_FILTER_COMPLETED_YES:
                         if (!item.isCompleted) {
                             item = null;
                         }
                         break;
                     case calICalendar.ITEM_FILTER_COMPLETED_NO:
@@ -893,39 +894,39 @@ calWcapCalendar.prototype.parseItems = f
                         "\nrid=" + getIcalUTC(rid) +
                         "\nitem.id=" + item.id, this);
                 }
                 excItems.push(item);
             } else if (item.recurrenceInfo) {
                 unexpandedItems.push(item);
                 uid2parent[item.id] = item;
             } else if ((maxResults == 0 || items.length < maxResults) &&
-                       checkIfInRange(item, rangeStart, rangeEnd)) {
+                       cal.checkIfInRange(item, rangeStart, rangeEnd)) {
                 if (LOG_LEVEL > 2) {
                     log("item: " + item.title + "\n" + item.icalString, this);
                 }
                 if (!bLeaveMutable) {
                     item.makeImmutable();
                 }
                 items.push(item);
             }
         }
     }
 
     // tag "exceptions", i.e. items with rid:
     for (let item of excItems) {
         let parent = uid2parent[item.id];
 
         if (!parent) { // a parentless one, fake a master and override it's occurrence
-            parent = isEvent(item) ? createEvent() : createTodo();
+            parent = cal.isEvent(item) ? cal.createEvent() : cal.createTodo();
             parent.id = item.id;
             parent.calendar = this.superCalendar;
             parent.setProperty("DTSTART", item.recurrenceId);
             parent.setProperty("X-MOZ-FAKED-MASTER", "1"); // this tag might be useful in the future
-            parent.recurrenceInfo = createRecurrenceInfo(parent);
+            parent.recurrenceInfo = cal.createRecurrenceInfo(parent);
             fakedParents[item.id] = true;
             uid2parent[item.id] = parent;
             items.push(parent);
         }
         if (item.id in fakedParents) {
             let rdate = Components.classes["@mozilla.org/calendar/recurrence-date;1"]
                                   .createInstance(Components.interfaces.calIRecurrenceDate);
             rdate.date = item.recurrenceId;
@@ -1117,18 +1118,18 @@ function getItemFilterParams(itemFilter)
     //         compstate += ";REQUEST-WAITFORREPLY";
     if (compstate.length > 0) {
         params += "&compstate=" + compstate.substr(1);
     }
     return params;
 }
 
 calWcapCalendar.prototype.getItems = function(itemFilter, maxResults, rangeStart, rangeEnd, listener) {
-    rangeStart = ensureDateTime(rangeStart);
-    rangeEnd = ensureDateTime(rangeEnd);
+    rangeStart = cal.ensureDateTime(rangeStart);
+    rangeEnd = cal.ensureDateTime(rangeEnd);
     let zRangeStart = getIcalUTC(rangeStart);
     let zRangeEnd = getIcalUTC(rangeEnd);
 
     let request = new calWcapRequest(
         (oprequest, err, data) => {
             log("getItems() complete: " + errorToString(err), this);
             this.notifyOperationComplete(listener,
                                          getResultCode(err),
@@ -1193,17 +1194,17 @@ calWcapCalendar.prototype.getItems = fun
                             rangeStart && rangeEnd) {
                             let freeBusyListener = { // calIGenericOperationListener:
                                 onResult: function(oprequest, result) {
                                     if (!Components.isSuccessCode(oprequest.status)) {
                                         throw oprequest.status;
                                     }
                                     let items = [];
                                     for (let entry of result) {
-                                        let item = createEvent();
+                                        let item = cal.createEvent();
                                         item.id = g_busyPhantomItemUuidPrefix + getIcalUTC(entry.interval.start);
                                         item.calendar = this.superCalendar;
                                         item.title = g_busyItemTitle;
                                         item.startDate = entry.interval.start;
                                         item.endDate = entry.interval.end;
                                         item.makeImmutable();
                                         items.push(item);
                                     }
--- a/calendar/providers/wcap/calWcapCalendarModule.js
+++ b/calendar/providers/wcap/calWcapCalendarModule.js
@@ -63,17 +63,16 @@ function initWcapProvider() {
         CACHE_LAST_RESULTS_INVALIDATE = Preferences.get("calendar.wcap.cache_last_results_invalidate", 120);
     } catch (exc) {
         logError(exc, "error in init sequence");
     }
 }
 
 /** Module Registration */
 var scriptLoadOrder = [
-    "calUtils.js",
     "calWcapUtils.js",
     "calWcapErrors.js",
     "calWcapRequest.js",
     "calWcapSession.js",
     "calWcapCalendar.js",
     "calWcapCalendarItems.js"
 ];
 
--- a/calendar/providers/wcap/calWcapErrors.js
+++ b/calendar/providers/wcap/calWcapErrors.js
@@ -1,16 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* exported checkErrorCode, checkWcapXmlErrno, checkWcapIcalErrno,
  *          errorToString
  */
 
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
 var NS_ERROR_INVALID_ARG = Components.results.NS_ERROR_INVALID_ARG;
 
 //
 // Common netwerk errors:
 //
 var NS_ERROR_MODULE_BASE_OFFSET = 0x45;
 var NS_ERROR_MODULE_NETWORK = 6;
 
@@ -121,17 +123,17 @@ function netErrorToString(rc) {
 
 //
 // WCAP error handling helpers
 //
 
 var g_wcapErrorCodes = [
     /* -1 */ NS_OK, "Logout successful.",
     /*  0 */ NS_OK, "Command successful.",
-    /*  1 */ calIWcapErrors.WCAP_LOGIN_FAILED, calGetString("wcap", "loginFailed.text"),
+    /*  1 */ calIWcapErrors.WCAP_LOGIN_FAILED, cal.calGetString("wcap", "loginFailed.text"),
     /*  2 */ calIWcapErrors.WCAP_LOGIN_OK_DEFAULT_CALENDAR_NOT_FOUND, "login.wcap was successful, but the default calendar for this user was not found. A new default calendar set to the userid was created.",
     /*  3 */ NS_ERROR_INVALID_ARG, "No WCAP error code.",
     /*  4 */ NS_ERROR_INVALID_ARG, "No WCAP error code.",
     /*  5 */ NS_ERROR_INVALID_ARG, "No WCAP error code.",
     /*  6 */ calIWcapErrors.WCAP_DELETE_EVENTS_BY_ID_FAILED, "WCAP_DELETE_EVENTS_BY_ID_FAILED",
     /*  7 */ NS_ERROR_INVALID_ARG, "No WCAP error code.",
     /*  8 */ calIWcapErrors.WCAP_SETCALPROPS_FAILED, "WCAP_SETCALPROPS_FAILED",
     /*  9 */ calIWcapErrors.WCAP_FETCH_EVENTS_BY_ID_FAILED, "WCAP_FETCH_EVENTS_BY_ID_FAILED",
@@ -148,17 +150,17 @@ var g_wcapErrorCodes = [
     /* 20 */ calIWcapErrors.WCAP_GET_CALPROPS_FAILED, "WCAP_GET_CALPROPS_FAILED",
     /* 21 */ calIWcapErrors.WCAP_DELETECOMPONENTS_BY_RANGE_FAILED, "WCAP_DELETECOMPONENTS_BY_RANGE_FAILED",
     /* 22 */ calIWcapErrors.WCAP_DELETEEVENTS_BY_RANGE_FAILED, "WCAP_DELETEEVENTS_BY_RANGE_FAILED",
     /* 23 */ calIWcapErrors.WCAP_DELETETODOS_BY_RANGE_FAILED, "WCAP_DELETETODOS_BY_RANGE_FAILED",
     /* 24 */ calIWcapErrors.WCAP_GET_ALL_TIMEZONES_FAILED, "WCAP_GET_ALL_TIMEZONES_FAILED",
     /* 25 */ calIWcapErrors.WCAP_CREATECALENDAR_ALREADY_EXISTS_FAILED, "The command createcalendar.wcap failed. A calendar with that name already exists in the database.",
     /* 26 */ calIWcapErrors.WCAP_SET_USERPREFS_FAILED, "WCAP_SET_USERPREFS_FAILED",
     /* 27 */ calIWcapErrors.WCAP_CHANGE_PASSWORD_FAILED, "WCAP_CHANGE_PASSWORD_FAILED",
-    /* 28 */ calIWcapErrors.WCAP_ACCESS_DENIED_TO_CALENDAR, calGetString("wcap", "accessDenied.text"),
+    /* 28 */ calIWcapErrors.WCAP_ACCESS_DENIED_TO_CALENDAR, cal.calGetString("wcap", "accessDenied.text"),
     /* 29 */ calIWcapErrors.WCAP_CALENDAR_DOES_NOT_EXIST, "Command failed. The requested calendar does not exist in the database.",
     /* 30 */ calIWcapErrors.WCAP_ILLEGAL_CALID_NAME, "createcalendar.wcap failed. Invalid calid passed in.",
     /* 31 */ calIWcapErrors.WCAP_CANNOT_MODIFY_LINKED_EVENTS, "storeevents.wcap failed. The event to modify was a linked event.",
     /* 32 */ calIWcapErrors.WCAP_CANNOT_MODIFY_LINKED_TODOS, "storetodos.wcap failed. The todo to modify was a linked todo.",
     /* 33 */ calIWcapErrors.WCAP_CANNOT_SENT_EMAIL, "Command failed. Email notification failed. Usually caused by the server not being properly configured to send email. This can occur in storeevents.wcap, storetodos.wcap, deleteevents_by_id.wcap, deletetodos_by_id.wcap.",
     /* 34 */ calIWcapErrors.WCAP_CALENDAR_DISABLED, "Command failed. The calendar is disabled in the database.",
     /* 35 */ calIWcapErrors.WCAP_WRITE_IMPORT_FAILED, "Import failed when writing files to the server.",
     /* 36 */ calIWcapErrors.WCAP_FETCH_BY_LAST_MODIFIED_FAILED, "WCAP_FETCH_BY_LAST_MODIFIED_FAILED",
--- a/calendar/providers/wcap/calWcapRequest.js
+++ b/calendar/providers/wcap/calWcapRequest.js
@@ -16,16 +16,17 @@
    - some data (incl null/undefined) which is the result of the async function,
      indicating that there is no further continuation
 */
 
 /* exported issueNetworkRequest, getWcapRequestStatusString, stringToIcal, stringToXml */
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 function generateRequestId() {
     if (!generateRequestId.mRequestPrefix) {
         generateRequestId.mRequestPrefix = cal.getUUID() + "-";
         generateRequestId.mRequestId = 0;
     }
     ++generateRequestId.mRequestId;
     return generateRequestId.mRequestPrefix + generateRequestId.mRequestId;
@@ -433,17 +434,17 @@ function getWcapRequestStatusString(xml)
 
 function stringToIcal(session, data, expectedErrno) {
     if (!data || data.length == 0) { // assuming time-out; WTF.
         throw new Components.Exception(errorToString(calIWcapErrors.WCAP_LOGIN_FAILED),
                                        calIWcapErrors.WCAP_LOGIN_FAILED);
     }
     let icalRootComp;
     try {
-        icalRootComp = getIcsService().parseICS(data, session /* implements calITimezoneProvider */);
+        icalRootComp = cal.getIcsService().parseICS(data, session /* implements calITimezoneProvider */);
     } catch (exc) { // map into more useful error string:
         throw new Components.Exception("error parsing ical data!", calIErrors.ICS_PARSE);
     }
     checkWcapIcalErrno(icalRootComp, expectedErrno);
     return icalRootComp;
 }
 
 function stringToXml(session, data, expectedErrno) {
--- a/calendar/providers/wcap/calWcapSession.js
+++ b/calendar/providers/wcap/calWcapSession.js
@@ -148,32 +148,32 @@ calWcapSession.prototype = {
         let tzids = [];
         for (let tzid in this.m_serverTimezones) {
             tzids.push(tzid);
         }
         return { // nsIUTF8StringEnumerator:
             m_index: 0,
             getNext: function() {
                 if (this.m_index >= tzids) {
-                    ASSERT(false, "calWcapSession::timezoneIds enumerator!");
+                    cal.ASSERT(false, "calWcapSession::timezoneIds enumerator!");
                     throw Components.results.NS_ERROR_UNEXPECTED;
                 }
                 return tzids[this.m_index++];
             },
             hasMore: function() {
                 return (this.m_index < tzids.length);
             }
         };
     },
     getTimezone: function(tzid) {
         switch (tzid) {
             case "floating":
-                return floating();
+                return cal.floating();
             case "UTC":
-                return UTC();
+                return cal.UTC();
             default:
                 if (this.m_serverTimezones) {
                     return this.m_serverTimezones[tzid];
                 }
                 return null;
         }
     },
 
@@ -211,27 +211,27 @@ calWcapSession.prototype = {
             }