Bug 1280898 - Set up eslint for calendar files - enable no-unused-vars rule. r=MakeMyDay
authoreslint <eslint@bugzilla.kewis.ch>
Fri, 08 Jul 2016 11:19:31 +0200
changeset 25974 377282fc615d97ac51cdc94ed1f52f8e7cc702f1
parent 25973 7063147fed66249f88739ba93466bd58a7ff032f
child 25975 096b191f8462122f21500bd9343d7a66aabe5ab7
push id1771
push userclokep@gmail.com
push dateMon, 14 Nov 2016 17:47:53 +0000
treeherdercomm-beta@399ae9d71595 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMakeMyDay
bugs1280898
Bug 1280898 - Set up eslint for calendar files - enable no-unused-vars rule. r=MakeMyDay MozReview-Commit-ID: 5RE9QCjTKpf
calendar/.eslintrc
calendar/base/backend/calBackendLoader.js
calendar/base/backend/icaljs/calICALJSComponents.js
calendar/base/backend/icaljs/calICSService-worker.js
calendar/base/backend/icaljs/calICSService.js
calendar/base/content/agenda-listbox.js
calendar/base/content/calendar-base-view.xml
calendar/base/content/calendar-chrome-startup.js
calendar/base/content/calendar-clipboard.js
calendar/base/content/calendar-common-sets.js
calendar/base/content/calendar-extract.js
calendar/base/content/calendar-invitations-manager.js
calendar/base/content/calendar-item-editing.js
calendar/base/content/calendar-management.js
calendar/base/content/calendar-multiday-view.xml
calendar/base/content/calendar-statusbar.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-todo.js
calendar/base/content/calendar-unifinder.js
calendar/base/content/calendar-views.js
calendar/base/content/dialogs/calendar-alarm-dialog.js
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-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-reminder.js
calendar/base/content/dialogs/calendar-event-dialog-timezone.js
calendar/base/content/dialogs/calendar-invitations-dialog.js
calendar/base/content/dialogs/calendar-print-dialog.js
calendar/base/content/dialogs/calendar-properties-dialog.js
calendar/base/content/dialogs/calendar-providerUninstall-dialog.js
calendar/base/content/dialogs/calendar-subscriptions-dialog.js
calendar/base/content/dialogs/calendar-summary-dialog.js
calendar/base/content/import-export.js
calendar/base/content/preferences/alarms.js
calendar/base/content/preferences/categories.js
calendar/base/content/preferences/editCategory.js
calendar/base/content/preferences/general.js
calendar/base/content/preferences/views.js
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/modules/calExtract.jsm
calendar/base/modules/calRecurrenceUtils.jsm
calendar/base/src/calAlarm.js
calendar/base/src/calAlarmService.js
calendar/base/src/calApplicationUtils.js
calendar/base/src/calCalendarManager.js
calendar/base/src/calDefaultACLManager.js
calendar/base/src/calIcsParser.js
calendar/base/src/calItemBase.js
calendar/base/src/calItemModule.js
calendar/base/src/calRecurrenceInfo.js
calendar/base/src/calSleepMonitor.js
calendar/base/src/calTimezoneService.js
calendar/base/src/calUtils.js
calendar/import-export/calImportExportModule.js
calendar/import-export/calOutlookCSVImportExport.js
calendar/itip/calItipEmailTransport.js
calendar/lightning/components/calItipProtocolHandler.js
calendar/lightning/components/lightningTextCalendarConverter.js
calendar/lightning/content/html-item-editing/react-code.js
calendar/lightning/content/lightning-item-iframe.js
calendar/lightning/content/lightning-item-panel.js
calendar/lightning/content/lightning-utils.js
calendar/lightning/content/messenger-overlay-preferences.js
calendar/lightning/content/messenger-overlay-sidebar.js
calendar/lightning/modules/ltnUtils.jsm
calendar/providers/caldav/calDavCalendar.js
calendar/providers/composite/calCompositeCalendar.js
calendar/providers/ics/calICSCalendar.js
calendar/providers/memory/calMemoryCalendar.js
calendar/providers/storage/calStorageCalendar.js
calendar/providers/storage/calStorageHelpers.jsm
calendar/providers/storage/calStorageUpgrade.jsm
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/datetimepickers/datetimepickers.xml
calendar/resources/content/mouseoverPreviews.js
calendar/resources/content/publish.js
calendar/resources/content/publishDialog.js
calendar/test/mozmill/.eslintrc
calendar/test/mozmill/eventDialog/testEventDialog.js
calendar/test/mozmill/eventDialog/testEventDialogModificationPrompt.js
calendar/test/mozmill/shared-modules/timezone-utils.js
calendar/test/mozmill/timezoneTests/test10.js
calendar/test/mozmill/timezoneTests/test2.js
calendar/test/mozmill/timezoneTests/test3.js
calendar/test/mozmill/timezoneTests/test4.js
calendar/test/mozmill/timezoneTests/test5.js
calendar/test/mozmill/timezoneTests/test6.js
calendar/test/mozmill/timezoneTests/test7.js
calendar/test/mozmill/timezoneTests/test8.js
calendar/test/mozmill/timezoneTests/test9.js
calendar/test/unit/.eslintrc
calendar/test/unit/head_consts.js
calendar/test/unit/test_alarm.js
calendar/test/unit/test_attendee.js
calendar/test/unit/test_bug1209399.js
calendar/test/unit/test_bug494140.js
calendar/test/unit/test_calmgr.js
calendar/test/unit/test_extract.js
calendar/test/unit/test_freebusy_service.js
calendar/test/unit/test_gdata_provider.js
calendar/test/unit/test_hashedarray.js
calendar/test/unit/test_ics_service.js
calendar/test/unit/test_ltninvitationutils.js
calendar/test/unit/test_recur.js
calendar/test/unit/test_search_service.js
--- a/calendar/.eslintrc
+++ b/calendar/.eslintrc
@@ -200,16 +200,21 @@
     // confused.
     "no-shadow": 2,
 
     // We use var-only-at-top-level instead of no-var as we allow top level
     // vars.
     "no-var": 0,
     "mozilla/var-only-at-top-level": 1,
 
+    // Disallow global and local variables that aren't used, but allow unused function arguments.
+    "no-unused-vars": [2, {"vars": "all", "args": "none", "varsIgnorePattern": "EXPORTED_SYMBOLS"}],
+
+    "mozilla/mark-test-function-used": 1,
+
     // Will enable these rules later
     "block-spacing": 0,
     "no-lonely-if": 0,
     "space-before-blocks": 0,
     "computed-property-spacing": 0,
     "consistent-return": 0,
 
     // The following rules will not be enabled currently, but are kept here for
--- a/calendar/base/backend/calBackendLoader.js
+++ b/calendar/base/backend/calBackendLoader.js
@@ -53,9 +53,9 @@ calBackendLoader.prototype = {
 
         Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar)
                   .autoRegister(file);
         dump("[calBackendLoader] Using " + backend + " backend at " + file.path + "\n");
         this.loaded = true;
     }
 };
 
-var NSGetFactory = XPCOMUtils.generateNSGetFactory([calBackendLoader]);
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calBackendLoader]);
--- a/calendar/base/backend/icaljs/calICALJSComponents.js
+++ b/calendar/base/backend/icaljs/calICALJSComponents.js
@@ -20,9 +20,9 @@ function getComponents() {
         calIcalComponent,
         calIcalProperty,
         calICSService,
         calPeriod,
         calRecurrenceRule,
     ];
 }
 
-var NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, getComponents, this);
+this.NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, getComponents, this);
--- a/calendar/base/backend/icaljs/calICSService-worker.js
+++ b/calendar/base/backend/icaljs/calICSService-worker.js
@@ -3,17 +3,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * ChromeWorker for parseICSAsync method in calICSService.js
  */
 
 var NS_OK = 0;
 var NS_ERROR_FAILURE = 2147500037;
-var ICS_ERROR_BASE = 2152333568;
 
 importScripts("resource://calendar/modules/ical.js");
 
 onmessage = function onmessage(event) {
     try {
         let comp = ICAL.parse(event.data);
         postMessage({ rc: NS_OK, data: comp });
     } catch (e) {
--- a/calendar/base/backend/icaljs/calICSService.js
+++ b/calendar/base/backend/icaljs/calICSService.js
@@ -97,17 +97,16 @@ calIcalProperty.prototype = {
     },
 
     get propertyName() { return this.innerObject.name.toUpperCase(); },
 
     getParameter: function(name) {
         // Unfortuantely getting the "VALUE" parameter won't work, since in
         // jCal it has been translated to the value type id.
         if (name == "VALUE") {
-            let propname = this.innerObject.name.toLowerCase();
             let defaultType = this.innerObject.getDefaultType();
             if (this.innerObject.type != defaultType) {
                 // Default type doesn't match object type, so we have a VALUE
                 // parameter
                 return this.innerObject.type.toUpperCase();
             }
         }
 
@@ -176,17 +175,16 @@ calIcalProperty.prototype = {
         cal.WARN("calIICSService::clearXParameters is no longer implemented, " +
                  "please use removeParameter");
     },
 
     paramIterator: null,
     getFirstParameterName: function() {
         let innerObject = this.innerObject;
         this.paramIterator = (function* () {
-            let propname = innerObject.name.toLowerCase();
             let defaultType = innerObject.getDefaultType();
             if (defaultType != innerObject.type) {
                 yield "VALUE";
             }
 
             let paramNames = Object.keys(innerObject.jCal[1] || {});
             for (let name of paramNames) {
                 yield name.toUpperCase();
@@ -475,17 +473,16 @@ calICSService.prototype = {
         let comp = ICAL.parse(serialized);
         return new calIcalComponent(new ICAL.Component(comp));
     },
 
     parseICSAsync: function parseICSAsync(serialized, tzProvider, listener) {
         // There are way too many error checking messages here, but I had so
         // much pain with this method that I don't want it to break again.
         try {
-            let self = this;
             let worker = new ChromeWorker("resource://calendar/calendar-js/calICSService-worker.js");
             worker.onmessage = function(event) {
                 let rc = Components.results.NS_ERROR_FAILURE;
                 let icalComp = null;
                 try {
                     rc = event.data.rc;
                     icalComp = new calIcalComponent(new ICAL.Component(event.data.data));
                     if (!Components.isSuccessCode(rc)) {
--- a/calendar/base/content/agenda-listbox.js
+++ b/calendar/base/content/agenda-listbox.js
@@ -163,17 +163,16 @@ function onSelect(aListItem) {
     calendarController.onSelectionChanged({detail: agendaListbox.getSelectedItems()});
 };
 
 /**
  * Handler function called when the agenda listbox becomes focused
  */
 agendaListbox.onFocus =
 function onFocus() {
-    let listbox = document.getElementById("agenda-listbox");
     calendarController.onSelectionChanged({detail: agendaListbox.getSelectedItems()});
 };
 
 /**
  * Handler function called when the agenda listbox loses focus.
  */
 agendaListbox.onBlur =
 function onBlur() {
@@ -797,33 +796,31 @@ function showsToday(aStartDate) {
 };
 
 /**
  * Moves the selection. Moves down unless the next item is a period item, in
  * which case the selection moves up.
  */
 agendaListbox.moveSelection =
 function moveSelection() {
-    let selindex = this.agendaListboxControl.selectedIndex;
     if (!this.isEventListItem(this.agendaListboxControl.selectedItem.nextSibling)) {
         this.agendaListboxControl.goUp();
     } else {
         this.agendaListboxControl.goDown();
     }
 };
 
 /**
  * Gets an array of selected items. If a period node is selected, it is not
  * included.
  *
  * @return      An array with all selected items.
  */
 agendaListbox.getSelectedItems =
 function getSelectedItems() {
-    let selindex = this.agendaListboxControl.selectedIndex;
     let items = [];
     if (this.isEventListItem(this.agendaListboxControl.selectedItem)) {
         // If at some point we support selecting multiple items, this array can
         // be expanded.
         items = [this.agendaListboxControl.selectedItem.occurrence];
     }
     return items;
 };
--- a/calendar/base/content/calendar-base-view.xml
+++ b/calendar/base/content/calendar-base-view.xml
@@ -660,17 +660,17 @@
             const weekPrefix = "calendar.week.";
             const prefNames = ["d0sundaysoff", "d1mondaysoff", "d2tuesdaysoff",
                                "d3wednesdaysoff", "d4thursdaysoff",
                                "d5fridaysoff", "d6saturdaysoff"];
             const defaults = ["true", "false", "false", "false",
                               "false", "false", "true"];
             let daysOff = [];
             for (let i in prefNames) {
-                if (Preferences.get(weekPrefix + prefNames[i])) {
+                if (Preferences.get(weekPrefix + prefNames[i], defaults[i])) {
                     daysOff.push(Number(i));
                 }
             }
             this.daysOffArray = daysOff;
         ]]></body>
       </method>
 
       <method name="refreshView">
--- a/calendar/base/content/calendar-chrome-startup.js
+++ b/calendar/base/content/calendar-chrome-startup.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/. */
 
 Components.utils.import("resource://gre/modules/iteratorUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 
+/* exported commonInitCalendar, commonFinishCalendar */
+
 /**
  * Common initialization steps for calendar chrome windows.
  */
 function commonInitCalendar() {
     // Move around toolbarbuttons and whatever is needed in the UI.
     migrateCalendarUI();
 
     // Load the Calendar Manager
--- a/calendar/base/content/calendar-clipboard.js
+++ b/calendar/base/content/calendar-clipboard.js
@@ -1,15 +1,17 @@
 /* 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/Services.jsm");
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
+/* exported cutToClipboard, pasteFromClipboard */
+
 /**
  * Test if a writable calendar is selected, and if the clipboard has items that
  * can be pasted into Calendar. The data must be of type "text/calendar" or
  * "text/unicode".
  *
  * @return          If true, pasting is currently possible.
  */
 function canPaste() {
--- a/calendar/base/content/calendar-common-sets.js
+++ b/calendar/base/content/calendar-common-sets.js
@@ -1,14 +1,19 @@
 /* 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/Services.jsm");
 
+/* exported injectCalendarCommandController, removeCalendarCommandController,
+ *          setupContextItemType, minimonthPick, getSelectedItems,
+ *          deleteSelectedItems, calendarUpdateNewItemsCommand
+ */
+
 var CalendarDeleteCommandEnabled = false;
 var CalendarNewEventsCommandEnabled = false;
 var CalendarNewTasksCommandEnabled = false;
 
 /**
  * Command controller to execute calendar specific commands
  * @see nsICommandController
  */
--- a/calendar/base/content/calendar-extract.js
+++ b/calendar/base/content/calendar-extract.js
@@ -231,17 +231,16 @@ var calendarExtract = {
         let taskButton = document.getElementById("extractTaskButton");
         let hdrEventButton = document.getElementById("hdrExtractEventButton");
         let hdrTaskButton = document.getElementById("hdrExtractTaskButton");
         let contextMenu = document.getElementById("mailContext-calendar-convert-menu");
         let contextMenuEvent = document.getElementById("mailContext-calendar-convert-event-menuitem");
         let contextMenuTask = document.getElementById("mailContext-calendar-convert-task-menuitem");
         let eventDisabled = (gFolderDisplay.selectedCount == 0);
         let taskDisabled = (gFolderDisplay.selectedCount == 0);
-        let contextDisabled = false;
         let contextEventDisabled = false;
         let contextTaskDisabled = false;
         let newEvent = document.getElementById("calendar_new_event_command");
         let newTask = document.getElementById("calendar_new_todo_command");
 
         if (newEvent.getAttribute("disabled") == "true") {
             eventDisabled = true;
             contextEventDisabled = true;
--- a/calendar/base/content/calendar-invitations-manager.js
+++ b/calendar/base/content/calendar-invitations-manager.js
@@ -2,16 +2,18 @@
  * 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/Preferences.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
+/* exported getInvitationsManager */
+
 /**
  * This object contains functions to take care of manipulating requests.
  */
 var gInvitationsRequestManager = {
     mRequestStatusList: {},
 
     /**
      * Add a request to the request manager.
--- a/calendar/base/content/calendar-item-editing.js
+++ b/calendar/base/content/calendar-item-editing.js
@@ -2,16 +2,18 @@
  * 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/calAlarmUtils.jsm");
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 
+/* exported modifyEventWithDialog, undo, redo, setContextPartstat */
+
 /**
  * Takes a job and makes sure the dispose function on it is called. If there is
  * no dispose function or the job is null, ignore it.
  *
  * @param job       The job to dispose.
  */
 function disposeJob(job) {
     if (job && job.dispose) {
@@ -220,18 +222,16 @@ function setDefaultItemValues(aItem, aCa
  * @param startDate     (optional) The event's start date.
  * @param endDate       (optional) The event's end date.
  * @param summary       (optional) The event's title.
  * @param event         (optional) A template event to show in the dialog
  * @param aForceAllDay  (optional) Make sure the event shown in the dialog is an
  *                                   allday event.
  */
 function createEventWithDialog(calendar, startDate, endDate, summary, event, aForceAllday) {
-    const kDefaultTimezone = calendarDefaultTimezone();
-
     let onNewEvent = function(item, opcalendar, originalItem, listener) {
         if (item.id) {
             // If the item already has an id, then this is the result of
             // saving the item without closing, and then saving again.
             doTransaction('modify', item, opcalendar, originalItem, listener);
         } else {
             // Otherwise, this is an addition
             doTransaction('add', item, opcalendar, null, listener);
@@ -277,18 +277,16 @@ function createEventWithDialog(calendar,
  *
  * @param calendar      (optional) The calendar to create the task in
  * @param dueDate       (optional) The task's due date.
  * @param summary       (optional) The task's title.
  * @param todo          (optional) A template task to show in the dialog.
  * @param initialDate   (optional) The initial date for new task datepickers
  */
 function createTodoWithDialog(calendar, dueDate, summary, todo, initialDate) {
-    const kDefaultTimezone = calendarDefaultTimezone();
-
     let onNewItem = function(item, opcalendar, originalItem, listener) {
         if (item.id) {
             // If the item already has an id, then this is the result of
             // saving the item without closing, and then saving again.
             doTransaction('modify', item, opcalendar, originalItem, listener);
         } else {
             // Otherwise, this is an addition
             doTransaction('add', item, opcalendar, null, listener);
@@ -339,19 +337,19 @@ function modifyEventWithDialog(aItem, jo
         return;
     }
 
     let onModifyItem = function(item, calendar, originalItem, listener) {
         doTransaction('modify', item, calendar, originalItem, listener);
     };
 
     let item = aItem;
-    let futureItem, response;
+    let response;
     if (aPromptOccurrence !== false) {
-        [item, futureItem, response] = promptOccurrenceModification(aItem, true, "edit");
+        [item, , response] = promptOccurrenceModification(aItem, true, "edit");
     }
 
     if (item && (response || response === undefined)) {
         openEventDialog(item, item.calendar, "modify", onModifyItem, job, initialDate);
     } else {
         disposeJob(job);
     }
 }
--- a/calendar/base/content/calendar-management.js
+++ b/calendar/base/content/calendar-management.js
@@ -1,12 +1,19 @@
 /* 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 promptDeleteCalendar, loadCalendarManager, unloadCalendarManager,
+ *         updateSortOrderPref, calendarListTooltipShowing,
+ *         calendarListSetupContextMenu, ensureCalendarVisible, toggleCalendarVisible,
+ *         showAllCalendars, showOnlyCalendar, openCalendarSubscriptionsDialog,
+ *         calendarOfflineManager
+ */
+
 Components.utils.import("resource://calendar/modules/calUtils.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");
 
 /**
  * Get this window's currently selected calendar.
  *
--- a/calendar/base/content/calendar-multiday-view.xml
+++ b/calendar/base/content/calendar-multiday-view.xml
@@ -92,18 +92,16 @@
       <property name="pixelsPerMinute"
         onget="return this.mPixPerMin"
         onset="if (this.mPixPerMin != val) { this.mPixPerMin = val; this.relayout(); } return val;"/>
 
       <method name="relayout">
         <body><![CDATA[
           let topbox = document.getAnonymousElementByAttribute(this, "anonid", "topbox");
           let orient = topbox.getAttribute("orient");
-          let otherorient = getOtherOrientation(orient);
-
 
           function makeTimeBox(timestr, size) {
               let box = createXULElement("box");
               box.setAttribute("orient", orient);
 
               if (orient == "horizontal") {
                   box.setAttribute("width", size);
               } else {
@@ -959,27 +957,25 @@
               //       |      |      |
               //       |OPEN! |      |<--Our item's start time might be here
               //       |      |______|
               //       |      |      |
               //
               // Remember that any time we're starting a new blob, colEndArray
               // will be empty, but that's ok.
               for (let ii = 0; ii < colEndArray.length; ++ii) {
-                  let colStart = colEndArray[ii].layoutStart;
                   let colEnd = colEndArray[ii].layoutEnd;
                   if (colEnd.compare(curItemInfo.layoutStart) != 1) {
                       // Yay, we can jump into this column
                       colEndArray[ii] = curItemInfo;
 
                       // Check and see if there are any adjacent columns we can
                       // jump into as well.
                       let lastCol = Number(ii) + 1;
                       while (lastCol < colEndArray.length) {
-                          let nextColStart = colEndArray[lastCol].layoutStart;
                           let nextColEnd = colEndArray[lastCol].layoutEnd;
                           // If the next column's item ends after we start, we
                           // can't expand any further
                           if (nextColEnd.compare(curItemInfo.layoutStart) == 1) {
                               break;
                           }
                           colEndArray[lastCol] = curItemInfo;
                           lastCol++;
@@ -1067,17 +1063,16 @@
               // conflicts with the item we're trying to place, need to have
               // their span extended by 1, since we're adding the new column
               //
               // * Note that there can only be one, because we sorted our
               //   events by start time, so this event must start later than
               //   the start of any possible conflicts.
               let lastColNum = colEndArray.length;
               for (let mm in currentBlob) {
-                  let mmStart = currentBlob[mm].itemInfo.layoutStart;
                   let mmEnd = currentBlob[mm].itemInfo.layoutEnd;
                   if (currentBlob[mm].startCol + currentBlob[mm].colSpan == lastColNum &&
                       mmEnd.compare(curItemInfo.layoutStart) != 1) {
                       currentBlob[mm] = {itemInfo: currentBlob[mm].itemInfo,
                                          startCol: currentBlob[mm].startCol,
                                          colSpan: currentBlob[mm].colSpan + 1};
                   }
               }
@@ -2319,17 +2314,16 @@
                   needsrelayout = true;
               }
           }
 
           // this should be done using lookupMethod(), see bug 286629
           let ret = XULElement.prototype.setAttribute.call(this, aAttr, aVal);
 
           if (needsrelayout) {
-              let otherorient = (val == "vertical" ? "horizontal" : "vertical");
               let eventbox = document.getAnonymousElementByAttribute(this, "anonid", "eventbox");
               eventbox.setAttribute("orient", val);
               let gb1 = document.getAnonymousElementByAttribute(this, "anonid", "gripbar1");
               gb1.parentorient = val;
               let gb2 = document.getAnonymousElementByAttribute(this, "anonid", "gripbar2");
               gb2.parentorient = val;
           }
 
@@ -2527,17 +2521,16 @@
 
         // initially scroll to the day start hour in the view
         this.scrollToMinute(this.mDayStartMin);
 
         // get visible hours from prefs and set on the view
         let visibleMinutes = Preferences.get("calendar.view.visiblehours", 9) * 60;
         this.setVisibleMinutes(visibleMinutes);
 
-        let self = this;
         // set the flex attribute at the scrollbox-innerbox
         // (this can be removed, after Bug 343555 is fixed)
         let scrollbox = document.getAnonymousElementByAttribute(
                        this, "anonid", "scrollbox");
         document.getAnonymousElementByAttribute(
             scrollbox, "class", "box-inherit scrollbox-innerbox").flex = "1";
 
         // set the time interval for the time indicator timer
@@ -2970,17 +2963,16 @@
             if (this.mSelectedDayCol) {
               this.mSelectedDay = this.mSelectedDayCol.date;
               this.mSelectedDayCol.column.selected = true;
               this.mSelectedDayCol.header.setAttribute("selected", "true");
             } else {
               this.mSelectedDay = val;
             }
           }
-          let headerColLabel = this.selectColumnHeader(val);
           this.fireEvent("dayselect", val);
           return val;
         ]]></setter>
       </property>
 
       <method name="getSelectedItems">
         <parameter name="aCount"/>
         <body><![CDATA[
--- a/calendar/base/content/calendar-statusbar.js
+++ b/calendar/base/content/calendar-statusbar.js
@@ -1,14 +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://gre/modules/XPCOMUtils.jsm");
 
+/* exported gCalendarStatusFeedback */
+
 /**
  * This code might change soon if we support Thunderbird's activity manager.
  * NOTE: The naming "Meteors" is historical.
  */
  let gCalendarStatusFeedback = {
      mCalendarStep: 0,
      mCalendarCount: 0,
      mWindow: null,
--- a/calendar/base/content/calendar-task-tree.js
+++ b/calendar/base/content/calendar-task-tree.js
@@ -1,24 +1,29 @@
 /* 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 addCalendarNames, calendars, changeContextMenuForTask,
+ *          contextChangeTaskCalendar, contextChangeTaskPriority,
+ *          contextPostponeTask, modifyTaskFromContext, deleteToDoCommand,
+ *          tasksToMail, tasksToEvents, toggleCompleted,
+ */
+
 /**
  * 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
  */
 function addCalendarNames(aEvent) {
     let calendarMenuPopup = aEvent.target;
-    let calendars = getCalendarManager().getCalendars({});
     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)) {
--- a/calendar/base/content/calendar-task-tree.xml
+++ b/calendar/base/content/calendar-task-tree.xml
@@ -113,17 +113,16 @@
     </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/calItemUtils.jsm");
         Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-        let self = this;
 
         // set up the tree filter
         this.mFilter = new calFilter();
 
         // set up the custom tree view
         let tree = document.getAnonymousElementByAttribute(this, "anonid", "calendar-task-tree");
         this.mTreeView.tree = tree;
         tree.view = this.mTreeView;
@@ -392,17 +391,16 @@
           // they match the currently applied filter.
           modifyItems: function tTV_modifyItems(aNewItems, aOldItems, aDontSort, aSelectNew) {
               let selItem = this.binding.currentTask;
               let selIndex = this.tree.currentIndex;
               let firstHash = null;
               let remIndexes = [];
               aNewItems = aNewItems || [];
               aOldItems = aOldItems || [];
-              let _this = this;
 
               this.treebox.beginUpdateBatch();
 
               let idiff = new itemDiff();
               idiff.load(aOldItems);
               idiff.difference(aNewItems);
               idiff.complete();
               let delItems = idiff.deletedItems;
--- a/calendar/base/content/calendar-task-view.js
+++ b/calendar/base/content/calendar-task-view.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported taskDetailsView, sendMailToOrganizer, taskViewCopyLink */
+
 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
--- a/calendar/base/content/calendar-ui-utils.js
+++ b/calendar/base/content/calendar-ui-utils.js
@@ -1,12 +1,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported getElementValue, setBooleanAttribute, showElement, hideElement,
+ *          uncollapseElement, collapseElement, disableElementWithLock,
+ *          enableElementWithLock, uncheckChildNodes, removeChildren,
+ *          appendCalendarItems, setAttributeToChildren, checkRadioControl,
+ *          processEnableCheckbox, updateListboxDeleteButton,
+ *          updateUnitLabelPlural, updateMenuLabelsPlural, menuListSelectItem,
+ *          getOptimalMinimumWidth, getOptimalMinimumHeight,
+ *          getOtherOrientation, updateSelectedLabel, setupAttendanceMenu
+ */
 
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 Components.utils.import("resource://gre/modules/PluralForm.jsm");
 
 /**
  * Helper function for filling the form,
  * Set the value of a property of a XUL element
--- a/calendar/base/content/calendar-unifinder-todo.js
+++ b/calendar/base/content/calendar-unifinder-todo.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported prepareCalendarToDoUnifinder, finishCalendarToDoUnifinder */
+
 /**
  * Called when the window is loaded to set up the unifinder-todo.
  */
 function prepareCalendarToDoUnifinder() {
     // add listener to update the date filters
     getViewDeck().addEventListener("dayselect", updateCalendarToDoUnifinder, false);
 
     updateCalendarToDoUnifinder();
--- a/calendar/base/content/calendar-unifinder.js
+++ b/calendar/base/content/calendar-unifinder.js
@@ -1,12 +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/. */
 
+/* exported gCalendarEventTreeClicked, unifinderDoubleClick, unifinderKeyPress,
+ *          focusSearch, toggleUnifinder
+ */
+
 /**
  * U N I F I N D E R
  *
  * This is a hacked in interface to the unifinder. We will need to
  * improve this to make it usable in general.
  *
  * NOTE: Including this file will cause a load handler to be added to the
  * window.
--- a/calendar/base/content/calendar-views.js
+++ b/calendar/base/content/calendar-views.js
@@ -1,12 +1,19 @@
 /* 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 switchToView, getSelectedDay, scheduleMidnightUpdate,
+ *          updateStyleSheetForViews, observeViewDaySelect, toggleOrientation,
+ *          toggleWorkdaysOnly, toggleTasksInView, toggleShowCompletedInView,
+ *          goToDate, getLastCalendarView, deleteSelectedEvents,
+ *          editSelectedEvents, selectAllEvents
+ */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calAlarmUtils.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");
 
 /**
  * Controller for the views
@@ -120,17 +127,17 @@ var calendarViewController = {
                 // 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) {
                 // Only give the user the selection if only one occurrence is
                 // selected. Otherwise he will get a dialog for each occurrence
                 // he deletes.
-                let [targetItem, hasFutureItem, response] = promptOccurrenceModification(itemToDelete, false, "delete");
+                let [targetItem, , response] = promptOccurrenceModification(itemToDelete, false, "delete");
                 if (!response) {
                     // The user canceled the dialog, bail out
                     break;
                 }
 
                 itemToDelete = targetItem;
             }
 
--- a/calendar/base/content/dialogs/calendar-alarm-dialog.js
+++ b/calendar/base/content/dialogs/calendar-alarm-dialog.js
@@ -1,12 +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/. */
 
+/* exported onDismissAllAlarms, setupWindow, finishWindow, addWidgetFor,
+ *         removeWidgetFor, onSelectAlarm, ensureCalendarVisible
+ */
+
 Components.utils.import("resource://gre/modules/PluralForm.jsm");
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 
 /**
  * Helper function to get the alarm service and cache it.
  *
  * @return The alarm service component
--- a/calendar/base/content/dialogs/calendar-creation.js
+++ b/calendar/base/content/dialogs/calendar-creation.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported openLocalCalendar */
+
 /**
  * Shows the filepicker and creates a new calendar with a local file using the ICS
  * provider.
  */
 function openLocalCalendar() {
     const nsIFilePicker = Components.interfaces.nsIFilePicker;
     let fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
     fp.init(window, calGetString("calendar", "Open"), nsIFilePicker.modeOpen);
--- a/calendar/base/content/dialogs/calendar-dialog-utils.js
+++ b/calendar/base/content/dialogs/calendar-dialog-utils.js
@@ -1,12 +1,17 @@
 /* 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 gInTab, gMainWindow, gTabmail, intializeTabOrWindowVariables,
+ *          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/calAlarmUtils.jsm");
 Components.utils.import("resource://calendar/modules/calIteratorUtils.jsm");
 Components.utils.import("resource://calendar/modules/calRecurrenceUtils.jsm");
 
@@ -132,17 +137,16 @@ function editReminder() {
     let args = {};
     args.reminders = customItem.reminders;
     args.item = window.calendarItem;
     args.timezone = (window.gStartTimezone ||
                      window.gEndTimezone ||
                      calendarDefaultTimezone());
 
     args.calendar = getCurrentCalendar();
-    let savedWindow = window;
 
     // 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;
     };
     args.onCancel = function() {
         document.getElementById("item-alarm").selectedIndex = gLastAlarmSelection;
@@ -264,17 +268,16 @@ function matchCustomReminderToMenuitem(r
 /**
  * Load an item's reminders into the dialog
  *
  * @param reminders     An array of calIAlarms to load.
  */
 function loadReminders(reminders) {
     // select 'no reminder' by default
     let reminderList = document.getElementById("item-alarm");
-    let reminderPopup = reminderList.firstChild;
     let customItem = document.getElementById("reminder-custom-menuitem");
     reminderList.selectedIndex = 0;
     gLastAlarmSelection = 0;
 
     if (!reminders || !reminders.length) {
         // No reminders selected, we are done
         return;
     }
--- a/calendar/base/content/dialogs/calendar-event-dialog-attendees.js
+++ b/calendar/base/content/dialogs/calendar-event-dialog-attendees.js
@@ -1,12 +1,17 @@
 /* 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, onAccept, onCancel, zoomWithButtons, updateStartTime,
+ *          endWidget, updateEndTime, editStartTimezone, editEndTimezone,
+ *          changeAllDay, onNextSlot, onPreviousSlot
+ */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 
 var gStartDate = null;
 var gEndDate = null;
 var gStartTimezone = null;
 var gEndTimezone = null;
@@ -340,20 +345,18 @@ function updateTimezone() {
  * Updates gStartDate from the start time picker "event-starttime"
  */
 function updateStartTime() {
     if (gIgnoreUpdate) {
         return;
     }
 
     let startWidgetId = "event-starttime";
-    let endWidgetId = "event-endtime";
 
     let startWidget = document.getElementById(startWidgetId);
-    let endWidget = document.getElementById(endWidgetId);
 
     // 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 start = cal.jsDateToDateTime(startWidget.value, timezone);
 
     gStartDate = start.clone();
@@ -609,17 +612,16 @@ function onResize() {
 
 /**
  * Handler function to call when changing the calendar used in this dialog.
  *
  * @param calendar      The calendar to change to.
  */
 function onChangeCalendar(calendar) {
     let args = window.arguments[0];
-    let organizer = args.organizer;
 
     // set 'mIsReadOnly' if the calendar is read-only
     if (calendar && calendar.readOnly) {
         gIsReadOnly = true;
     }
 
     // assume we're the organizer [in case that the calendar
     // does not support the concept of identities].
@@ -703,17 +705,16 @@ function onPreviousSlot() {
     // In case the new starttime happens to be scheduled
     // on a different day, we also need to update the
     // complete freebusy informations and appropriate
     // underlying arrays holding the information.
     let refresh = previousSlot.startTime.day != gStartDate.day;
 
     gStartDate = previousSlot.startTime.clone();
     gEndDate = previousSlot.endTime.clone();
-    let endDate = gEndDate.clone();
 
     propagateDateTime();
 
     // scroll the grid/timebar such that the current time is visible
     scrollToCurrentTime();
 
     updateButtons();
 
--- a/calendar/base/content/dialogs/calendar-event-dialog-attendees.xml
+++ b/calendar/base/content/dialogs/calendar-event-dialog-attendees.xml
@@ -75,23 +75,16 @@
         let load = function loadHandler() {
             self.onLoad();
         };
         window.addEventListener("load", load, true);
       ]]></constructor>
 
       <method name="onLoad">
         <body><![CDATA[
-          let listbox =
-              document.getAnonymousElementByAttribute(
-                  this, "anonid", "listbox");
-          let template =
-              document.getAnonymousElementByAttribute(
-                  this, "anonid", "item");
-
           this.onInitialize();
 
           // this trigger the continous update chain, which
           // effectively calls this.onModify() on predefined
           // time intervals [each second].
           let self = this;
           let callback = function() {
               setTimeout(callback, 1000);
@@ -696,17 +689,18 @@
                 "RESOURCE": "resource",
                 "ROOM": "room",
                 // I've decided UNKNOWN will not be handled.
             };
 
             let cutypeString = "event.attendee.usertype." + (cutype in cutypeMap ? cutypeMap[cutype] : "unknown");
             let tooltip = cal.calGetString("calendar-event-dialog-attendees",
                                            cutypeString,
-                                           (cutypeString in cutypeMap ? null : [cutype]));
+                                           (cutype in cutypeMap ? null : [cutype]));
+            targetIcon.setAttribute("tooltiptext", tooltip);
         }
       ]]></body>
       </method>
 
       <property name="documentSize">
         <getter><![CDATA[
             return this.mRowHeight * this.mMaxAttendees;
         ]]></getter>
@@ -1069,19 +1063,16 @@
               }
           }
         ]]></body>
       </method>
 
       <method name="removeRow">
         <parameter name="aRow"/>
         <body><![CDATA[
-          let listbox =
-              document.getAnonymousElementByAttribute(
-                  this, "anonid", "listbox");
           this.getListItem(aRow).remove();
           this.fitDummyRows();
           this.mMaxAttendees--;
         ]]></body>
       </method>
     </implementation>
 
     <handlers>
@@ -1403,17 +1394,16 @@
       <method name="update">
         <body><![CDATA[
           if (!this.mStartDate || !this.mEndDate) {
               return;
           }
 
           // Calculate the relation of startdate/basedate and enddate/startdate.
           let offset = this.mStartDate.subtractDate(this.mBaseDate);
-          let duration = this.mEndDate.subtractDate(this.mStartDate);
 
           // Calculate how much pixels a single hour and a single day take up.
           let num_hours = this.mEndHour - this.mStartHour;
           let hour_width = this.mContentWidth / num_hours;
 
           // Calculate the offset in fractional hours that corrospond
           // to our start- and end-time.
           let start_offset_in_hours = this.date2offset(this.mStartDate);
--- a/calendar/base/content/dialogs/calendar-event-dialog-freebusy.xml
+++ b/calendar/base/content/dialogs/calendar-event-dialog-freebusy.xml
@@ -469,17 +469,16 @@
         ]]></body>
       </method>
 
       <method name="initialize">
         <body><![CDATA[
           let args = window.arguments[0];
           let startTime = args.startTime;
           let endTime = args.endTime;
-          let calendar = args.calendar;
 
           let kDefaultTimezone = 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
@@ -697,17 +696,16 @@
           let step_in_minutes = Math.floor(60 * this.mZoomFactor / 100);
           let formatter = Components.classes[
               "@mozilla.org/calendar/datetime-formatter;1"]
                   .getService(
                       Components.interfaces.calIDateTimeFormatter);
           let date = cal.jsDateToDateTime(new Date());
           date.hour = this.mStartHour;
           date.minute = 0;
-          let height = this.parentNode.parentNode.boxObject.height - 1;
           let hours =
               document.getAnonymousElementByAttribute(
                   this, "anonid", "hours");
           if (hours.childNodes.length <= 0) {
               let template = createXULElement("text");
               template.className = "freebusy-grid";
               // TODO: hardcoded value
               let num_days = Math.max(2, 4 * this.mZoomFactor / 100);
@@ -1063,18 +1061,16 @@
           listbox.scrollToIndex(Math.floor(rowcount * val));
           return val;
         ]]></setter>
       </property>
 
       <constructor><![CDATA[
         Components.utils.import("resource://gre/modules/Preferences.jsm");
 
-        let args = window.arguments[0];
-
         this.initTimeRange();
 
         this.mRange = Number(this.getAttribute("range"));
 
         this.mMaxFreeBusy = 0;
         this.mPendingRequests = [];
 
         let self = this;
@@ -1139,17 +1135,16 @@
         ]]></body>
       </method>
 
       <method name="onInitialize">
         <body><![CDATA[
           let args = window.arguments[0];
           let startTime = args.startTime;
           let endTime = args.endTime;
-          let calendar = args.calendar;
 
           let kDefaultTimezone = calendarDefaultTimezone();
           this.startDate = startTime.getInTimezone(kDefaultTimezone);
           this.endDate = endTime.getInTimezone(kDefaultTimezone);
 
           let listbox =
               document.getAnonymousElementByAttribute(
                   this, "anonid", "listbox");
@@ -1465,19 +1460,16 @@
               }
           }
         ]]></body>
       </method>
 
       <method name="removeRow">
         <parameter name="aRow"/>
         <body><![CDATA[
-          let listbox =
-              document.getAnonymousElementByAttribute(
-                  this, "anonid", "listbox");
           this.getListItem(aRow).remove();
           this.fitDummyRows();
           this.mMaxFreeBusy--;
         ]]></body>
       </method>
 
       <!-- gets the next row from the top down -->
       <method name="getNextDummyRow">
--- a/calendar/base/content/dialogs/calendar-event-dialog-recurrence-preview.xml
+++ b/calendar/base/content/dialogs/calendar-event-dialog-recurrence-preview.xml
@@ -57,19 +57,16 @@
             if (this.mDateTime == null) {
                 this.mDateTime = now();
             }
             return this.mDateTime;
         ]]></getter>
       </property>
       <method name="onResize">
         <body><![CDATA[
-          let mainbox =
-              document.getAnonymousElementByAttribute(
-                  this, "anonid", "mainbox");
           let minimonth =
               document.getAnonymousElementByAttribute(
                   this, "anonid", "minimonth");
 
           let row =
               document.getAnonymousElementByAttribute(
                   this, "anonid", "row");
           let rows = row.parentNode;
--- a/calendar/base/content/dialogs/calendar-event-dialog-recurrence.js
+++ b/calendar/base/content/dialogs/calendar-event-dialog-recurrence.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported onLoad, onAccept, onCancel */
+
 Components.utils.import("resource://calendar/modules/calRecurrenceUtils.jsm");
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 var gIsReadOnly = false;
 var gStartTime = null;
 var gEndTime = null;
 var gUntilDate = null;
@@ -39,17 +41,16 @@ function onLoad() {
         item = item.parentItem;
     }
     let rule = null;
     if (recinfo) {
         // Split out rules and exceptions
         try {
             let rrules = splitRecurrenceRules(recinfo);
             let rules = rrules[0];
-            let exceptions = rrules[1];
             // Deal with the rules
             if (rules.length > 0) {
                 // We only handle 1 rule currently
                 rule = cal.wrapInstance(rules[0], Components.interfaces.calIRecurrenceRule);
             }
         } catch (ex) {
             Components.utils.reportError(ex);
         }
@@ -550,18 +551,16 @@ function updateRecurrenceRange() {
         document.getElementById("recurrence-range-until");
     let rangeTimesCount =
         document.getElementById("repeat-ntimes-count");
     let rangeUntilDate =
         document.getElementById("repeat-until-date");
     let rangeAppointmentsLabel =
         document.getElementById("repeat-appointments-label");
 
-    let deckNumber = Number(getElementValue("period-list"));
-
     radioRangeForever.removeAttribute("disabled");
     radioRangeFor.removeAttribute("disabled");
     radioRangeUntil.removeAttribute("disabled");
     rangeAppointmentsLabel.removeAttribute("disabled");
 
     let durationSelection = document.getElementById("recurrence-duration")
                                     .selectedItem.value;
 
--- a/calendar/base/content/dialogs/calendar-event-dialog-reminder.js
+++ b/calendar/base/content/dialogs/calendar-event-dialog-reminder.js
@@ -1,12 +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/. */
 
+/* exported onLoad, onReminderSelected, updateReminder, onNewReminder,
+ *          onRemoveReminder, onAccept, onCancel
+ */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calIteratorUtils.jsm");
 Components.utils.import("resource://gre/modules/PluralForm.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 
 var allowedActionsMap = {};
 
 /**
@@ -309,17 +313,16 @@ function updateReminder(event) {
     let relationOrigin = document.getElementById("reminder-relation-origin");
     let [relation, origin] = relationOrigin.value.split("-");
     let absDate = document.getElementById("reminder-absolute-date");
     let action = document.getElementById("reminder-actions-menulist").selectedItem.value;
 
     // Action
     reminder.action = action;
 
-    let relationType;
     if (relationItem.value == "relative") {
         if (origin == "START") {
             reminder.related = Components.interfaces.calIAlarm.ALARM_RELATED_START;
         } else if (origin == "END") {
             reminder.related = Components.interfaces.calIAlarm.ALARM_RELATED_END;
         }
 
         // Set up offset, taking units and before/after into account
--- a/calendar/base/content/dialogs/calendar-event-dialog-timezone.js
+++ b/calendar/base/content/dialogs/calendar-event-dialog-timezone.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported onLoad, onAccept, onCancel */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 /**
  * Sets up the timezone dialog from the window arguments, also setting up all
  * dialog controls from the window's dates.
  */
 function onLoad() {
     let args = window.arguments[0];
--- a/calendar/base/content/dialogs/calendar-invitations-dialog.js
+++ b/calendar/base/content/dialogs/calendar-invitations-dialog.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported onLoad, onUnload, onAccept, onCancel */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calAlarmUtils.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 /**
  * Sets up the invitations dialog from the window arguments, retrieves the
  * invitations from the invitations manager.
  */
--- a/calendar/base/content/dialogs/calendar-print-dialog.js
+++ b/calendar/base/content/dialogs/calendar-print-dialog.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported loadCalendarPrintDialog, printAndClose, onDatePick */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 /**
  * Gets the calendar view from the opening window
  */
 function getCalendarView() {
     let theView = window.opener.currentView();
--- a/calendar/base/content/dialogs/calendar-properties-dialog.js
+++ b/calendar/base/content/dialogs/calendar-properties-dialog.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported onLoad, onAcceptDialog, unsubscribeCalendar */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/PluralForm.jsm");
 
 /**
  * The calendar to modify, is retrieved from window.arguments[0].calendar
  */
 var gCalendar;
 
--- a/calendar/base/content/dialogs/calendar-providerUninstall-dialog.js
+++ b/calendar/base/content/dialogs/calendar-providerUninstall-dialog.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported onLoad, onAccept, onCancel */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 function onLoad() {
     let extension = window.arguments[0].extension;
     document.getElementById("provider-name-label").value = extension.name;
 
     let calendars = cal.getCalendarManager().getCalendars({})
                        .filter(x => x.providerID == extension.id);
--- a/calendar/base/content/dialogs/calendar-subscriptions-dialog.js
+++ b/calendar/base/content/dialogs/calendar-subscriptions-dialog.js
@@ -1,12 +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/. */
 
+/* exported onLoad, onUnload, onKeyPress, onTextBoxKeyPress, onAccept,
+ *          onCancel, onSubscribe, onUnsubscribe
+ */
+
 /**
  * Cancels any pending search operations.
  */
 var gCurrentSearchOperation = null;
 function cancelPendingSearchOperation() {
     if (gCurrentSearchOperation && gCurrentSearchOperation.isPending) {
         gCurrentSearchOperation.cancel(Components.interfaces.calIErrors.OPERATION_CANCELLED);
     }
--- a/calendar/base/content/dialogs/calendar-summary-dialog.js
+++ b/calendar/base/content/dialogs/calendar-summary-dialog.js
@@ -1,12 +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/. */
 
+/* exported onLoad, onAccept, onCancel, updatePartStat, browseDocument,
+ *          sendMailToOrganizer
+ */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calItipUtils.jsm");
 Components.utils.import("resource://calendar/modules/calAlarmUtils.jsm");
 Components.utils.import("resource://calendar/modules/calRecurrenceUtils.jsm");
 
 /**
  * Sets up the summary dialog, setting all needed fields on the dialog from the
  * item received in the window arguments.
--- a/calendar/base/content/import-export.js
+++ b/calendar/base/content/import-export.js
@@ -1,23 +1,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
+/* exported loadEventsFromFile, exportEntireCalendar */
+
 // File constants copied from file-utils.js
 var MODE_RDONLY = 0x01;
 var MODE_WRONLY = 0x02;
-var MODE_RDWR = 0x04;
 var MODE_CREATE = 0x08;
-var MODE_APPEND = 0x10;
 var MODE_TRUNCATE = 0x20;
-var MODE_SYNC = 0x40;
-var MODE_EXCL = 0x80;
 
 /**
  * Shows a file dialog, reads the selected file(s) and tries to parse events from it.
  *
  * @param aCalendar  (optional) If specified, the items will be imported directly
  *                              into the calendar
  */
 function loadEventsFromFile(aCalendar) {
@@ -71,17 +69,16 @@ function loadEventsFromFile(aCalendar) {
             filterIndex = defaultCIDIndex;
         }
 
         let filePath = fp.file.path;
         let importer = Components.classes[contractids[filterIndex]]
                                  .getService(Components.interfaces.calIImporter);
 
         const nsIFileInputStream = Components.interfaces.nsIFileInputStream;
-        const nsIScriptableInputStream = Components.interfaces.nsIScriptableInputStream;
 
         let inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
                                     .createInstance(nsIFileInputStream);
         let items = [];
 
         try {
             inputStream.init(fp.file, MODE_RDONLY, parseInt("0444", 8), {});
             items = importer.importFromStream(inputStream, {});
@@ -256,23 +253,17 @@ function saveEventsToFile(calendarEventA
             contractids.push(contractid);
             currentListLength++;
         }
     }
 
     let rv = fp.show();
 
     // Now find out as what to save, convert the events and save to file.
-    if (rv != nsIFilePicker.returnCancel &&
-        fp.file && fp.file.path.length > 0) {
-        const UTF8 = "UTF-8";
-        let aDataStream;
-        let extension;
-        let charset;
-
+    if (rv != nsIFilePicker.returnCancel && fp.file && fp.file.path.length > 0) {
         let filterIndex = fp.filterIndex;
         if (fp.filterIndex < 0 || fp.filterIndex > contractids.length) {
             // For some reason the wrong filter was selected, assume default extension
             filterIndex = defaultCIDIndex;
         }
 
         let exporter = Components.classes[contractids[filterIndex]]
                                  .getService(Components.interfaces.calIExporter);
--- a/calendar/base/content/preferences/alarms.js
+++ b/calendar/base/content/preferences/alarms.js
@@ -1,13 +1,14 @@
-/**
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* 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/.
- */
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* exported gAlarmsPane */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 /**
  * Global Object to hold methods for the alarms pref pane
  */
 var gAlarmsPane = {
     /**
--- a/calendar/base/content/preferences/categories.js
+++ b/calendar/base/content/preferences/categories.js
@@ -1,13 +1,14 @@
-/**
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* 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/.
- */
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* exported gCategoriesPane */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/AppConstants.jsm");
 
 var gCategoryList;
 var categoryPrefBranch = Services.prefs.getBranch("calendar.category.color.");
 
 /**
--- a/calendar/base/content/preferences/editCategory.js
+++ b/calendar/base/content/preferences/editCategory.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported editCategoryLoad, doOK, categoryNameChanged, clickColor, delay */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 // Global variable, set to true if the user has picked a custom color.
 var customColorSelected = false;
 
 /**
  * Load Handler, called when the edit category dialog is loaded
  */
--- a/calendar/base/content/preferences/general.js
+++ b/calendar/base/content/preferences/general.js
@@ -1,13 +1,13 @@
-/**
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* 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/.
- */
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* exported gCalendarGeneralPane */
 
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 /**
  * Global Object to hold methods for the general pref pane
  */
 var gCalendarGeneralPane = {
     /**
--- a/calendar/base/content/preferences/views.js
+++ b/calendar/base/content/preferences/views.js
@@ -1,13 +1,13 @@
-/**
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* 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/.
- */
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* exported gViewsPane */
 
 /**
  * Global Object to hold methods for the views pref pane
  */
 var gViewsPane = {
     /**
      * Initialize the views pref pane. Sets up dialog controls to match the
      * values set in prefs.
--- a/calendar/base/content/widgets/calendar-alarm-widget.xml
+++ b/calendar/base/content/widgets/calendar-alarm-widget.xml
@@ -80,19 +80,16 @@
           }
 
           let formatter = cal.getDateFormatter();
           let titleLabel = document.getAnonymousElementByAttribute(this, "anonid", "alarm-title-label");
           let locationDescription = document.getAnonymousElementByAttribute(this, "anonid", "alarm-location-description");
           let dateLabel = document.getAnonymousElementByAttribute(this, "anonid", "alarm-date-label");
 
           // Dates
-          let startString = {};
-          let endString = {};
-
           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",
--- a/calendar/base/content/widgets/calendar-list-tree.xml
+++ b/calendar/base/content/widgets/calendar-list-tree.xml
@@ -914,18 +914,16 @@
           return null;
         ]]></body>
       </method>
 
       <method name="getCellText">
         <parameter name="aRow"/>
         <parameter name="aCol"/>
         <body><![CDATA[
-          let calendar = this.getCalendar(aRow);
-
           switch (aCol.element.getAttribute("anonid")) {
               case "calendarname-treecol":
                   return this.getCalendar(aRow).name;
           }
           return "";
         ]]></body>
       </method>
 
--- a/calendar/base/content/widgets/calendar-widgets.xml
+++ b/calendar/base/content/widgets/calendar-widgets.xml
@@ -490,17 +490,17 @@
                   binding: this,
                   handleEvent: function(aEvent, aHandled) {
                       return this.binding.onModeModified(aEvent, this.binding);
                   }
               };
               this.mBroadcaster.addEventListener("DOMAttrModified", this.mModHandler, true);
             }
           }
-          let ret = XULElement.prototype.setAttribute.call(this, aAttr, aVal);
+          return XULElement.prototype.setAttribute.call(this, aAttr, aVal);
         ]]></body>
       </method>
     </implementation>
   </binding>
 
 <!-- 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.
@@ -675,24 +675,18 @@
 
          if (isEvent(item)) {
              transfer.addDataFlavor("application/x-moz-cal-event");
          } else {
              transfer.addDataFlavor("application/x-moz-cal-task");
          }
 
          session.getData(transfer, 0);
-         let flavor = {};
-         let data = {};
-         // nsITransferable sucks when it comes to trying to add extra flavors.
-         // This will throw NS_ERROR_FAILURE, so as a workaround, we use the
-         // sourceNode property and get the event that way
-         //   transfer.getAnyTransferData(flavor, data, {});
+         item = session.sourceNode.sourceObject;
 
-         item = session.sourceNode.sourceObject;
          let newItem = this.onDropItem(item).clone();
          let newStart = newItem.startDate || newItem.entryDate || newItem.dueDate;
          let newEnd = newItem.endDate || newItem.dueDate || newItem.entryDate;
          let offset = this.calendarView.mShadowOffset;
          newStart.addDuration(offset);
          newEnd.addDuration(offset);
          this.calendarView.controller.modifyOccurrence(item, newStart, newEnd);
 
--- a/calendar/base/modules/calExtract.jsm
+++ b/calendar/base/modules/calExtract.jsm
@@ -803,17 +803,16 @@ Extractor.prototype = {
             return guess;
         }
 
         let wDay = startTimes.filter(val => val.day != null && val.start !== undefined);
         let wDayNA = wDay.filter(val => val.ambiguous === undefined);
 
         let wMinute = startTimes.filter(val => val.minute != null && val.start !== undefined);
         let wMinuteNA = wMinute.filter(val => val.ambiguous === undefined);
-        let wMinuteInit = startTimes.filter(val => val.minute != null && val.start === undefined);
 
         if (wMinuteNA.length != 0) {
             guess.hour = wMinuteNA[0].hour;
             guess.minute = wMinuteNA[0].minute;
         } else if (wMinute.length != 0) {
             guess.hour = wMinute[0].hour;
             guess.minute = wMinute[0].minute;
         }
@@ -1072,20 +1071,18 @@ Extractor.prototype = {
                         cal.LOG("[calExtract] Removed " + removals[pattern] + " from " + name);
                     }
                 }
             }
 
             vals.sort(function(one, two) {return two.length - one.length;});
             for (let val in vals) {
                 let pattern = vals[val];
-                let cnt = 1;
-                for (let replaceable in replaceables) {
+                for (let cnt = 1; cnt <= replaceables.length; cnt++) {
                     pattern = pattern.split("#" + cnt).join(replaceables[cnt - 1]);
-                    cnt++;
                 }
                 patterns.push(pattern);
             }
 
             for (let val in vals) {
                 let positions = [];
                 if (replaceables.length == 1) {
                     positions[1] = 1;
--- a/calendar/base/modules/calRecurrenceUtils.jsm
+++ b/calendar/base/modules/calRecurrenceUtils.jsm
@@ -1,14 +1,17 @@
 /* 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 recurrenceRule2String, splitRecurrenceRules, checkRecurrenceRule */
+
 Components.utils.import("resource://gre/modules/PluralForm.jsm");
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
 this.EXPORTED_SYMBOLS = ["recurrenceRule2String", "splitRecurrenceRules", "checkRecurrenceRule"];
 
 /**
  * This function takes the recurrence info passed as argument and creates a
  * literal string representing the repeat pattern in natural language.
  *
  * @param recurrenceInfo    An item's recurrence info to parse.
  * @param startDate         The start date to base rules on.
--- a/calendar/base/src/calAlarm.js
+++ b/calendar/base/src/calAlarm.js
@@ -74,17 +74,16 @@ calAlarm.prototype = {
                 this[member].makeImmutable();
             }
         }
 
         // Properties
         let e = this.mProperties.enumerator;
         while (e.hasMoreElements()) {
             let prop = e.getNext();
-            let val = prop.value;
 
             if (prop.value instanceof Components.interfaces.calIDateTime) {
                 if (prop.value.isMutable) {
                     prop.value.makeImmutable();
                 }
             }
         }
 
--- a/calendar/base/src/calAlarmService.js
+++ b/calendar/base/src/calAlarmService.js
@@ -6,18 +6,16 @@ Components.utils.import("resource://cale
 Components.utils.import("resource://calendar/modules/calAlarmUtils.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");
 Components.utils.import("resource://gre/modules/Promise.jsm");
 Components.utils.import("resource://gre/modules/PromiseUtils.jsm");
 
 var kHoursBetweenUpdates = 6;
-var kSleepMonitorInterval = 60000;
-var kSleepMonitorTolerance = 1000;
 
 function nowUTC() {
     return cal.jsDateToDateTime(new Date()).getInTimezone(cal.UTC());
 }
 
 function newTimerWithCallback(aCallback, aDelay, aRepeating) {
     let timer = Components.classes["@mozilla.org/timer;1"]
                           .createInstance(Components.interfaces.nsITimer);
--- a/calendar/base/src/calApplicationUtils.js
+++ b/calendar/base/src/calApplicationUtils.js
@@ -1,13 +1,14 @@
-/* -*- Mode: javascript; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
+/* 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 launchBrowser */
+
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 /**
  * Launch the given url (string) in the external browser. If an event is passed,
  * then this is only done on left click and the event propagation is stopped.
  *
  * @param url       The URL to open, as a string
  * @param event     (optional) The event that caused the URL to open
--- a/calendar/base/src/calCalendarManager.js
+++ b/calendar/base/src/calCalendarManager.js
@@ -174,21 +174,16 @@ calCalendarManager.prototype = {
         }
     },
 
     //
     // DB migration code begins here
     //
 
     upgradeDB: function(oldVersion, db) {
-        // some common helpers
-        function addColumn(db_, tableName, colName, colType) {
-            db_.executeSimpleSQL("ALTER TABLE " + tableName + " ADD COLUMN " + colName + " " + colType);
-        }
-
         if (oldVersion < 6) {
             dump("**** Upgrading calCalendarManager schema to 6\n");
 
             // Schema changes in v6:
             //
             // - Change all STRING columns to TEXT to avoid SQLite's
             //   "feature" where it will automatically convert strings to
             //   numbers (ex: 10e4 -> 10000). See bug 333688.
@@ -412,25 +407,25 @@ calCalendarManager.prototype = {
         let errorBoxButtonLabel = calGetString("calendar", "tooNewSchemaButtonRestart", [hostAppName]);
 
         let promptSvc = Services.prompt;
 
         let errorBoxButtonFlags = (promptSvc.BUTTON_POS_0 *
                                    promptSvc.BUTTON_TITLE_IS_STRING +
                                    promptSvc.BUTTON_POS_0_DEFAULT);
 
-        let choice = promptSvc.confirmEx(null,
-                                         errorBoxTitle,
-                                         errorBoxText,
-                                         errorBoxButtonFlags,
-                                         errorBoxButtonLabel,
-                                         null, // No second button text
-                                         null, // No third button text
-                                         null, // No checkbox
-                                         { value: false }); // Unnecessary checkbox state
+        promptSvc.confirmEx(null,
+                            errorBoxTitle,
+                            errorBoxText,
+                            errorBoxButtonFlags,
+                            errorBoxButtonLabel,
+                            null, // No second button text
+                            null, // No third button text
+                            null, // No checkbox
+                            { value: false }); // Unnecessary checkbox state
 
         // Disable Lightning
         AddonManager.getAddonByID("{e2fda1a4-762b-4020-b5ad-a41df1933103}", function getLightningExt(aAddon) {
             aAddon.userDisabled = true;
             Services.startup.quit(Components.interfaces.nsIAppStartup.eRestart |
                 Components.interfaces.nsIAppStartup.eForceQuit);
         });
     },
--- a/calendar/base/src/calDefaultACLManager.js
+++ b/calendar/base/src/calDefaultACLManager.js
@@ -114,9 +114,9 @@ calDefaultItemACLEntry.prototype = {
     calendarEntry: null,
     userCanModify: true,
     userCanRespond: true,
     userCanViewAll: true,
     userCanViewDateAndTime: true,
 };
 
 /** Module Registration */
-var NSGetFactory = XPCOMUtils.generateNSGetFactory([calDefaultACLManager]);
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calDefaultACLManager]);
--- a/calendar/base/src/calIcsParser.js
+++ b/calendar/base/src/calIcsParser.js
@@ -114,18 +114,16 @@ calIcsParser.prototype = {
             }
         });
     },
 
     parseString: function ip_parseString(aICSString, aTzProvider, aAsyncParsing) {
         if (aAsyncParsing) {
             let self = this;
 
-            let start = new Date();
-
             // We are using two types of very similar listeners here:
             // aAsyncParsing is a calIcsParsingListener that returns the ics
             //   parser containing the processed items.
             // The listener passed to parseICSAsync is a calICsComponentParsingListener
             //   required by the ics service, that receives the parsed root component.
             cal.getIcsService().parseICSAsync(aICSString, aTzProvider, {
                 onParsingComplete: function(rc, rootComp) {
                     if (Components.isSuccessCode(rc)) {
--- a/calendar/base/src/calItemBase.js
+++ b/calendar/base/src/calItemBase.js
@@ -201,17 +201,17 @@ calItemBase.prototype = {
             this.mOrganizer.makeImmutable();
         }
         if (this.mAttendees) {
             for (let att of this.mAttendees) {
                 att.makeImmutable();
             }
         }
 
-        for (let [propKey, propValue] of this.mProperties) {
+        for (let [, propValue] of this.mProperties) {
             if (propValue instanceof Components.interfaces.calIDateTime &&
                 propValue.isMutable) {
                 propValue.makeImmutable();
             }
         }
 
         if (this.mAlarms) {
             for (let alarm of this.mAlarms) {
--- a/calendar/base/src/calItemModule.js
+++ b/calendar/base/src/calItemModule.js
@@ -59,9 +59,9 @@ function getComponents() {
         calStartupService,
         calTransaction,
         calTransactionManager,
         calTodo,
         calWeekInfoService,
     ];
 }
 
-var NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, getComponents, this);
+this.NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, getComponents, this);
--- a/calendar/base/src/calRecurrenceInfo.js
+++ b/calendar/base/src/calRecurrenceInfo.js
@@ -254,18 +254,16 @@ calRecurrenceInfo.prototype = {
     /*
      * calculations
      */
     getNextOccurrence: function cRI_getNextOccurrence(aTime) {
         this.ensureBaseItem();
         this.ensureSortedRecurrenceRules();
 
         let startDate = this.mBaseItem.recurrenceStartDate;
-        let dates = [];
-
         let nextOccurrences = [];
         let invalidOccurrences;
         let negMap = {};
         let minOccRid;
 
         // Go through all negative rules to create a map of occurrences that
         // should be skipped when going through occurrences.
         for (let ritem of this.mNegativeRules) {
--- a/calendar/base/src/calSleepMonitor.js
+++ b/calendar/base/src/calSleepMonitor.js
@@ -63,9 +63,9 @@ calSleepMonitor.prototype = {
             Services.obs.addObserver(this, "quit-application", false);
         } else if (aTopic == "quit-application") {
             cal.LOG("[calSleepMonitor] Stopping sleep monitor.");
             this.stop();
         }
     }
 };
 
-var NSGetFactory = XPCOMUtils.generateNSGetFactory([calSleepMonitor]);
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calSleepMonitor]);
--- a/calendar/base/src/calTimezoneService.js
+++ b/calendar/base/src/calTimezoneService.js
@@ -7,16 +7,20 @@ Components.utils.import("resource://gre/
 Components.utils.import("resource://calendar/modules/calIteratorUtils.jsm");
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 Components.utils.import("resource://calendar/modules/ical.js");
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
 Components.utils.import("resource://gre/modules/Promise.jsm");
 
+/* exported g_stringBundle */
+
+var g_stringBundle = null;
+
 function calStringEnumerator(stringArray) {
     this.mIndex = 0;
     this.mStringArray = stringArray;
 }
 calStringEnumerator.prototype = {
     // nsIUTF8StringEnumerator:
     hasMore: function calStringEnumerator_hasMore() {
         return (this.mIndex < this.mStringArray.length);
@@ -24,18 +28,16 @@ calStringEnumerator.prototype = {
     getNext: function calStringEnumerator_getNext() {
         if (!this.hasMore()) {
             throw Components.results.NS_ERROR_UNEXPECTED;
         }
         return this.mStringArray[this.mIndex++];
     }
 };
 
-var g_stringBundle = null;
-
 function calTimezoneService() {
     this.wrappedJSObject = this;
 
     this.mZones = new Map();
 
     ICAL.TimezoneService = this.wrappedJSObject;
 }
 var calTimezoneServiceClassID = Components.ID("{e736f2bd-7640-4715-ab35-887dc866c587}");
@@ -809,9 +811,9 @@ function guessSystemTimezone() {
     } catch (ex) { // don't abort if error occurs warning user
         Components.utils.reportError(ex);
     }
 
     // return the guessed timezone
     return probableTZId;
 }
 
-var NSGetFactory = cal.loadingNSGetFactory(["calTimezone.js"], [calTimezoneService], this);
+this.NSGetFactory = cal.loadingNSGetFactory(["calTimezone.js"], [calTimezoneService], this);
--- a/calendar/base/src/calUtils.js
+++ b/calendar/base/src/calUtils.js
@@ -2,16 +2,40 @@
  * 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/. */
 
 /* This file contains commonly used functions in a centralized place so that
  * various components (and other js scopes) don't need to replicate them. Note
  * that loading this file twice in the same scope will throw errors.
  */
 
+
+/* exported createEvent, createTodo, createDateTime, createDuration, createAttendee,
+ *          createAttachment, createAlarm, createRelation,
+ *          createRecurrenceDate, createRecurrenceRule, createRecurrenceInfo,
+ *          getCalendarManager, getIcsService, getCalendarSearchService,
+ *          getFreeBusyService, getWeekInfoService, getDateFormatter, UTC,
+ *          floating, saveRecentTimezone, getCalendarDirectory,
+ *          isCalendarWritable, userCanAddItemsToCalendar,
+ *          userCanDeleteItemsFromCalendar, attendeeMatchesAddresses,
+ *          userCanRespondToInvitation, openCalendarWizard,
+ *          openCalendarProperties, calPrint, makeURL, calRadioGroupSelectItem,
+ *          isItemSupported, calInstanceOf, getPrefSafe, setPref,
+ *          setLocalizedPref, getLocalizedPref, getPrefCategoriesArray,
+ *          setPrefCategoriesFromArray, compareItems, calTryWrappedJSObject,
+ *          compareArrays, doQueryInterface, setDefaultStartEndHour, LOG, WARN,
+ *          ERROR, showError, getContrastingTextColor, calGetEndDateProp,
+ *          checkIfInRange, getProgressAtom, sendMailTo, sameDay,
+ *          calSetProdidVersion, applyAttributeToMenuChildren,
+ *          isPropertyValueSame, getParentNodeOrThis,
+ *          getParentNodeOrThisByAttribute, setItemProperty,
+ *          calIterateEmailIdentities, compareItemContent, binaryInsert,
+ *          getCompositeCalendar, findItemWindow
+ */
+
 Components.utils.import("resource:///modules/mailServices.js");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 Components.utils.import("resource://gre/modules/AppConstants.jsm");
 
 function _calIcalCreator(cid, iid) {
     return function(icalString) {
--- a/calendar/import-export/calImportExportModule.js
+++ b/calendar/import-export/calImportExportModule.js
@@ -23,9 +23,9 @@ function getComponents() {
         calOutlookCSVExporter,
 
         calListFormatter,
         calMonthPrinter,
         calWeekPrinter
     ];
 }
 
-var NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, getComponents, this);
+this.NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, getComponents, this);
--- a/calendar/import-export/calOutlookCSVImportExport.js
+++ b/calendar/import-export/calOutlookCSVImportExport.js
@@ -217,17 +217,16 @@ calOutlookCSVImporter.prototype = {
         if (eventFields == null) {
             aCount.value = 0;
             return [];
         }
 
         args.boolStr = localeEn.valueTrue;
         args.boolIsTrue = true;
 
-        let dateParseConfirmed = false;
         let eventArray = [];
         do {
             // At this point eventFields contains following fields. Position
             // of fields is in args.[fieldname]Index.
             //    subject, start date, start time, end date, end time,
             //    all day, alarm on, alarm date, alarm time,
             //    Description, Categories, Location, Private
             // Unused fields (could maybe be copied to Description):
--- a/calendar/itip/calItipEmailTransport.js
+++ b/calendar/itip/calItipEmailTransport.js
@@ -4,23 +4,16 @@
 
 Components.utils.import("resource:///modules/mailServices.js");
 Components.utils.import("resource://calendar/modules/calUtils.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");
 Components.utils.import("resource://calendar/modules/ltnInvitationUtils.jsm");
 
-function convertFromUnicode(aCharset, aSrc) {
-    let unicodeConverter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
-                                     .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
-    unicodeConverter.charset = aCharset;
-    return unicodeConverter.ConvertFromUnicode(aSrc);
-}
-
 /**
  * Constructor of calItipEmailTransport object
  */
 function calItipEmailTransport() {
     this.wrappedJSObject = this;
     this._initEmailTransport();
 }
 var calItipEmailTransportClassID = Components.ID("{d4d7b59e-c9e0-4a7a-b5e8-5958f85515f0}");
@@ -418,9 +411,9 @@ calItipEmailTransport.prototype = {
             return tempFile;
         } catch (exc) {
             cal.ASSERT(false, exc);
             return null;
         }
     }
 };
 
-var NSGetFactory = XPCOMUtils.generateNSGetFactory([calItipEmailTransport]);
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calItipEmailTransport]);
--- a/calendar/lightning/components/calItipProtocolHandler.js
+++ b/calendar/lightning/components/calItipProtocolHandler.js
@@ -129,9 +129,9 @@ ItipContentHandler.prototype = {
             event.organizer.id + " (" + event.id + ")\n");
         let calMgr = cal.getCalendarManager();
         let cals = calMgr.getCalendars({});
         cals[0].addItem(event, null);
     }
 };
 
 var components = [ItipChannel, ItipProtocolHandler, ItipContentHandler];
-var NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
--- a/calendar/lightning/components/lightningTextCalendarConverter.js
+++ b/calendar/lightning/components/lightningTextCalendarConverter.js
@@ -86,9 +86,9 @@ ltnMimeConverter.prototype = {
             cal.ERROR("[ltnMimeConverter] convertToHTML: " + e);
         }
 
         // Create the HTML string for display
         return msgOverlay;
     }
 };
 
-var NSGetFactory = XPCOMUtils.generateNSGetFactory([ltnMimeConverter]);
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ltnMimeConverter]);
--- a/calendar/lightning/content/html-item-editing/react-code.js
+++ b/calendar/lightning/content/html-item-editing/react-code.js
@@ -1,14 +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/. */
 
 // This file contains code that uses react.js
 
+/* exported gTopComponent, DatePicker, TopComponent */
+
 var gTopComponent = null;
 
 var Tabstrip = React.createClass({
     handleChange: function(index) {
         // The click handler will update the state with
         // the index of the focused menu entry
         this.props.onInput(this.props.keyprop, index);
     },
--- a/calendar/lightning/content/lightning-item-iframe.js
+++ b/calendar/lightning/content/lightning-item-iframe.js
@@ -1,12 +1,22 @@
 /* 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 onEventDialogUnload, changeUndiscloseCheckboxStatus,
+ *          toggleKeepDuration, dateTimeControls2State, onUpdateAllDay,
+ *          openNewEvent, openNewTask, openNewMessage, openNewCardDialog,
+ *          deleteAllAttachments, copyAttachment, attachmentLinkKeyPress,
+ *          attachmentDblClick, attachmentClick, notifyUser,
+ *          removeNotification, chooseRecentTimezone, showTimezonePopup,
+ *          attendeeDblClick, attendeeClick, removeAttendee,
+ *          removeAllAttendees, sendMailToUndecidedAttendees, checkUntilDate
+ */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://calendar/modules/calRecurrenceUtils.jsm");
 Components.utils.import("resource:///modules/mailServices.js");
 Components.utils.import("resource://gre/modules/PluralForm.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
@@ -1455,18 +1465,16 @@ function saveDialog(item) {
 }
 
 /**
  * Save date and time related values from the dialog to the passed item.
  *
  * @param item    The item to save to.
  */
 function saveDateTime(item) {
-    let kDefaultTimezone = calendarDefaultTimezone();
-
     // Changes to the start date don't have to change the until date.
     untilDateCompensation(item);
 
     if (isEvent(item)) {
         let startTime = gStartTime.getInTimezone(gStartTimezone);
         let endTime = gEndTime.getInTimezone(gEndTimezone);
         let isAllDay = getElementValue("event-all-day", "checked");
         if (isAllDay) {
--- a/calendar/lightning/content/lightning-item-panel.js
+++ b/calendar/lightning/content/lightning-item-panel.js
@@ -1,12 +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/. */
 
+/* exported onLoadLightningItemPanel, onAccept, onCancel, onCommandSave,
+ *          onCommandDeleteItem, editAttendees, rotatePrivacy, editPrivacy,
+ *          rotatePriority, editPriority, rotateStatus, editStatus,
+ *          rotateShowTimeAs, editShowTimeAs, updateShowTimeAs, editToDoStatus,
+ *          postponeTask, toggleTimezoneLinks, toggleLink, attachURL,
+ *          onCommandViewToolbar, onCommandCustomize, attachFileByAccountKey,
+ */
+
 // XXX Need to determine which of these we really need here.
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://calendar/modules/calRecurrenceUtils.jsm");
 Components.utils.import("resource:///modules/mailServices.js");
 Components.utils.import("resource://gre/modules/PluralForm.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
@@ -435,18 +443,16 @@ function editPrivacy(aTarget, aEvent) {
  * @param {Object}    aArg                Contains privacy properties
  * @param {string}    aArg.privacy        The new privacy value
  * @param {boolean}   aArg.hasPrivacy     Whether privacy is supported
  * @param {string}    aArg.calendarType   The type of calendar
  * @param {string[]}  aArg.privacyValues  The possible privacy values
  */
 function updatePrivacy(aArg) {
     if (aArg.hasPrivacy) {
-        let numChilds;
-
         // Update privacy capabilities (toolbar)
         let menupopup = document.getElementById("event-privacy-menupopup");
         if (menupopup) {
             // Only update the toolbar if the button is actually there
             for (let node of menupopup.childNodes) {
                 let currentProvider = node.getAttribute("provider");
                 if (node.hasAttribute("privacy")) {
                     let currentPrivacyValue = node.getAttribute("privacy");
--- a/calendar/lightning/content/lightning-utils.js
+++ b/calendar/lightning/content/lightning-utils.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported ltnInitMailIdentitiesRow, ltnSaveMailIdentitySelection */
+
 Components.utils.import("resource:///modules/iteratorUtils.jsm");
 Components.utils.import("resource:///modules/mailServices.js");
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 /**
  * Gets the value of a string in a .properties file from the lightning bundle
  *
  * @param aBundleName  the name of the properties file.  It is assumed that the
--- a/calendar/lightning/content/messenger-overlay-preferences.js
+++ b/calendar/lightning/content/messenger-overlay-preferences.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported gLightningPane */
+
 var gLightningPane = {
     mInitialized: false,
 
     init: function lnPaneInit() {
         let preference = document.getElementById("calendar.preferences.lightning.selectedTabIndex");
         if (preference.value) {
             let ltnPrefs = document.getElementById("calPreferencesTabbox");
             ltnPrefs.selectedIndex = preference.value;
--- a/calendar/lightning/content/messenger-overlay-sidebar.js
+++ b/calendar/lightning/content/messenger-overlay-sidebar.js
@@ -1,12 +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 refreshUIBits, switchCalendarView, rescheduleInvitationsUpdate,
+ *          openInvitationsDialog, onToolbarsPopupShowingWithMode,
+ *          InitViewCalendarPaneMenu, onToolbarsPopupShowingForTabType,
+ *          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/calAsyncUtils.jsm");
 
 var gLastShownCalendarView = null;
--- a/calendar/lightning/modules/ltnUtils.jsm
+++ b/calendar/lightning/modules/ltnUtils.jsm
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported ltn */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 this.EXPORTED_SYMBOLS = ["ltn"];
 var ltn = {
     /**
      * Gets the value of a string in a .properties file from the lightning bundle
      *
      * @param {String} aBundleName  the name of the properties file. It is assumed that the
--- a/calendar/providers/caldav/calDavCalendar.js
+++ b/calendar/providers/caldav/calDavCalendar.js
@@ -25,17 +25,16 @@ Components.utils.import("resource://cale
 var xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>\n';
 
 var davNS = "DAV:";
 var caldavNS = "urn:ietf:params:xml:ns:caldav";
 var calservNS = "http://calendarserver.org/ns/";
 var MIME_TEXT_CALENDAR = "text/calendar; charset=utf-8";
 var MIME_TEXT_XML = "text/xml; charset=utf-8";
 
-var cICL = Components.interfaces.calIChangeLog;
 var cIOL = Components.interfaces.calIOperationListener;
 
 function caldavNSResolver(prefix) {
     const ns = {
         D: davNS,
         C: caldavNS,
         CS: calservNS
     };
@@ -999,17 +998,17 @@ calDavCalendar.prototype = {
                     // The item still exists. We need to ask the user if he
                     // really wants to delete the item. Remember, we only
                     // made this request since the actual delete gave 409/412
                     thisCalendar.promptOverwrite(CALDAV_DELETE_ITEM, aItem, aListener, null);
                     return;
                 }
 
                 // Finally, notify listener.
-                notifyListener(listenerstatus, listenerDetail, true);
+                notifyListener(listenerStatus, listenerDetail, true);
             }
         };
 
         if (this.verboseLogging()) {
             cal.LOG("CalDAV: Deleting " + eventUri.spec);
         }
 
         this.sendHttpRequest(eventUri, null, null, null, (channel) => {
@@ -3008,9 +3007,9 @@ calDavObserver.prototype = {
 };
 
 /** Module Registration */
 var scriptLoadOrder = [
     "calUtils.js",
     "calDavRequestHandlers.js"
 ];
 
-var NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, [calDavCalendar], this);
+this.NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, [calDavCalendar], this);
--- a/calendar/providers/composite/calCompositeCalendar.js
+++ b/calendar/providers/composite/calCompositeCalendar.js
@@ -533,9 +533,9 @@ calCompositeGetListenerHelper.prototype 
         // send GetResults to the real listener
         this.mRealListener.onGetResult(aCalendar, aStatus, aItemType, aDetail, aCount, aItems);
         this.mItemsReceived += aCount;
     }
 
 };
 
 /** Module Registration */
-var NSGetFactory = XPCOMUtils.generateNSGetFactory([calCompositeCalendar]);
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calCompositeCalendar]);
--- a/calendar/providers/ics/calICSCalendar.js
+++ b/calendar/providers/ics/calICSCalendar.js
@@ -15,31 +15,27 @@ Components.utils.import("resource://cale
 //
 // This is a non-sync ics file. It reads the file pointer to by uri when set,
 // then writes it on updates. External changes to the file will be
 // ignored and overwritten.
 //
 // XXX Should do locks, so that external changes are not overwritten.
 
 var CI = Components.interfaces;
-var calIOperationListener = Components.interfaces.calIOperationListener;
 var calICalendar = Components.interfaces.calICalendar;
 var calIErrors = Components.interfaces.calIErrors;
 
 function icsNSResolver(prefix) {
     const ns = {
         D: "DAV:"
     };
 
     return ns[prefix] || null;
 }
 
-function icsXPath(aNode, aExpr, aType) {
-    return cal.xml.evalXPath(aNode, aExpr, icsNSResolver, aType);
-}
 function icsXPathFirst(aNode, aExpr, aType) {
     return cal.xml.evalXPathFirst(aNode, aExpr, icsNSResolver, aType);
 }
 
 function calICSCalendar() {
     this.initProviderBase();
     this.initICSCalendar();
 
@@ -1110,9 +1106,9 @@ fileHooks.prototype = {
     }
 };
 
 /** Module Registration */
 var scriptLoadOrder = [
     "calUtils.js",
 ];
 
-var NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, [calICSCalendar], this);
+this.NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, [calICSCalendar], this);
--- a/calendar/providers/memory/calMemoryCalendar.js
+++ b/calendar/providers/memory/calMemoryCalendar.js
@@ -8,18 +8,16 @@ Components.utils.import("resource://gre/
 Components.utils.import("resource://calendar/modules/calProviderUtils.jsm");
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calIteratorUtils.jsm");
 
 //
 // calMemoryCalendar.js
 //
 
-var calCalendarManagerContractID = "@mozilla.org/calendar/manager;1";
-var calICalendarManager = Components.interfaces.calICalendarManager;
 var cICL = Components.interfaces.calIChangeLog;
 
 function calMemoryCalendar() {
     this.initProviderBase();
     this.initMemoryCalendar();
 }
 var calMemoryCalendarClassID = Components.ID("{bda0dd7f-0a2f-4fcf-ba08-5517e6fbf133}");
 var calMemoryCalendarInterfaces = [
@@ -361,17 +359,16 @@ calMemoryCalendar.prototype = {
     },
     getItems_: function(aItemFilter, aCount,
                          aRangeStart, aRangeEnd, aListener) {
         if (!aListener) {
             return;
         }
 
         const calICalendar = Components.interfaces.calICalendar;
-        const calIRecurrenceInfo = Components.interfaces.calIRecurrenceInfo;
 
         let itemsFound = [];
 
         //
         // filters
         //
 
         let wantUnrespondedInvitations = ((aItemFilter & calICalendar.ITEM_FILTER_REQUEST_NEEDS_ACTION) != 0);
@@ -566,9 +563,9 @@ calMemoryCalendar.prototype = {
                                                    out_ids,
                                                    out_values) {
         this.mMetaData.getAllProperties(out_ids, out_values);
         out_count.value = out_ids.value.length;
     }
 };
 
 /** Module Registration */
-var NSGetFactory = XPCOMUtils.generateNSGetFactory([calMemoryCalendar]);
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([calMemoryCalendar]);
--- a/calendar/providers/storage/calStorageCalendar.js
+++ b/calendar/providers/storage/calStorageCalendar.js
@@ -669,17 +669,16 @@ calStorageCalendar.prototype = {
     getItems_: function cSC_getItems_(aItemFilter, aCount,
                                       aRangeStart, aRangeEnd, aListener) {
         if (!aListener) {
             return;
         }
 
         let self = this;
 
-        let itemsFound = [];
         let startTime = -0x7fffffffffffffff;
         // endTime needs to be the max value a PRTime can be
         let endTime = 0x7fffffffffffffff;
         let count = 0;
         if (aRangeStart) {
             startTime = aRangeStart.nativeTime;
         }
         if (aRangeEnd) {
@@ -1046,17 +1045,16 @@ calStorageCalendar.prototype = {
     deleteOfflineItem: function(aItem, aListener) {
         let this_ = this;
         let opListener = {
             QueryInterface: XPCOMUtils.generateQI([Components.interfaces.calIOperationListener]),
             onGetResult: function(calendar, status, itemType, detail, count, items) {
 
             },
             onOperationComplete: function(calendar, status, opType, id, oldOfflineJournalFlag) {
-                let newOfflineJournalFlag = cICL.OFFLINE_FLAG_DELETED_RECORD;
                 if (oldOfflineJournalFlag) {
                     // Delete item if flag is c
                     if (oldOfflineJournalFlag == cICL.OFFLINE_FLAG_CREATED_RECORD) {
                         this_.deleteItemById(aItem.id);
                     } else if (oldOfflineJournalFlag == cICL.OFFLINE_FLAG_MODIFIED_RECORD) {
                         this_.setOfflineJournalFlag(aItem, cICL.OFFLINE_FLAG_DELETED_RECORD);
                     }
                 } else {
@@ -1558,32 +1556,30 @@ calStorageCalendar.prototype = {
             return;
         }
         // build up recurring event and todo cache with its offline flags,
         // because we need that on every query: for recurring items, we need to
         // query database-wide.. yuck
 
         try {
             this.prepareStatement(this.mSelectEventsWithRecurrence);
-            let sp = this.mSelectEventsWithRecurrence.params;
             while (this.mSelectEventsWithRecurrence.executeStep()) {
                 let row = this.mSelectEventsWithRecurrence.row;
                 let item = this.getEventFromRow(row, {});
                 this.mRecEventCache[item.id] = item;
                 this.mRecEventCacheOfflineFlags[item.id] = row.offline_journal || null;
             }
         } catch (e) {
             this.logError("Error selecting events with recurrence!", e);
         } finally {
             this.mSelectEventsWithRecurrence.reset();
         }
 
         try {
             this.prepareStatement(this.mSelectTodosWithRecurrence);
-            let sp = this.mSelectTodosWithRecurrence.params;
             while (this.mSelectTodosWithRecurrence.executeStep()) {
                 let row = this.mSelectTodosWithRecurrence.row;
                 let item = this.getTodoFromRow(row, {});
                 this.mRecTodoCache[item.id] = item;
                 this.mRecTodoCacheOfflineFlags[item.id] = row.offline_journal || null;
             }
         } catch (e) {
             this.logError("Error selecting todos with recurrence!", e);
@@ -1744,17 +1740,16 @@ calStorageCalendar.prototype = {
             } catch (e) {
                 this.logError("Error getting extra properties for item '" +
                               item.title + "' (" + item.id + ")!", e);
             } finally {
                 selectItem.reset();
             }
         }
 
-        let i;
         if (flags & CAL_ITEM_FLAG.HAS_RECURRENCE) {
             if (item.recurrenceId) {
                 throw Components.results.NS_ERROR_UNEXPECTED;
             }
 
             let recInfo = cal.createRecurrenceInfo(item);
             item.recurrenceInfo = recInfo;
 
@@ -2473,9 +2468,9 @@ calStorageCalendar.prototype = {
     }
 };
 
 /** Module Registration */
 var scriptLoadOrder = [
     "calUtils.js",
 ];
 
-var NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, [calStorageCalendar], this);
+this.NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, [calStorageCalendar], this);
--- a/calendar/providers/storage/calStorageHelpers.jsm
+++ b/calendar/providers/storage/calStorageHelpers.jsm
@@ -1,15 +1,19 @@
 /* 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 EXPORTED_SYMBOLS = [
+/* exported CAL_ITEM_FLAG, getInUtcOrKeepFloating, dateToText, textToDate,
+ *          calStorageTimezone, getTimezone, newDateTime
+ */
+
+this.EXPORTED_SYMBOLS = [
     "CAL_ITEM_FLAG",
     "getInUtcOrKeepFloating",
     "dateToText",
     "textToDate",
     "calStorageTimezone",
     "getTimezone",
     "newDateTime"
 ];
--- a/calendar/providers/storage/calStorageUpgrade.jsm
+++ b/calendar/providers/storage/calStorageUpgrade.jsm
@@ -61,16 +61,18 @@
  *     version (setDbVersionAndCommit also commits the transaction)
  * - If something fails, throw reportErrorAndRollback(db, e) to report the
  *     failure and roll back the transaction.
  *
  * If this documentation isn't sufficient to make upgrading understandable,
  * please file a bug.
  */
 
+/* exported upgradeDB */
+
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calStorageHelpers.jsm");
 
 // The current database version. Be sure to increment this when you create a new
 // updater.
 var DB_SCHEMA_VERSION = 22;
 
@@ -1405,17 +1407,16 @@ upgrade.v21 = function upgrade_v21(db, v
                             '   AND dates != ""';
 
             // Create the statements
             let insertStmt = createStatement(db, insertSQL);
             let updateStmt = createStatement(db, updateSQL);
 
             // Repeat these two statements until the update affects 0 rows
             // (because the dates field on all x-datesets is empty)
-            let insertedRows = 0;
             do {
                 insertStmt.execute();
                 updateStmt.execute();
             } while (db.affectedRows > 0);
 
             // Finally we can delete the x-dateset rows. Note this will leave
             // gaps in recur_index, but thats ok since its only used for
             // ordering anyway and will be overwritten on the next item write.
@@ -1522,16 +1523,17 @@ upgrade.v22 = function upgrade_v22(db, v
                             ["attendee_id", "common_name", "rsvp", "role",
                              "status", "type", "is_organizer", "properties"], db);
 
         // Update recurrence table to using icalString directly
         createFunction(db, "translateRecurrence", 17, {
             onFunctionCall: function translateRecurrence(storArgs) {
                 function parseInt10(x) { return parseInt(x, 10); }
                 try {
+                    // eslint-disable-next-line no-unused-vars
                     let [aIndex, aType, aIsNegative, aDates, aCount,
                          aEndDate, aInterval, aSecond, aMinute, aHour,
                          aDay, aMonthday, aYearday, aWeekno, aMonth,
                          aSetPos, aTmpFlags] = mapStorageArgs(storArgs);
 
                     let ritem;
                     if (aType == "x-date") {
                         ritem = Components.classes["@mozilla.org/calendar/recurrence-date;1"]
--- a/calendar/providers/wcap/calWcapCalendarItems.js
+++ b/calendar/providers/wcap/calWcapCalendarItems.js
@@ -267,21 +267,23 @@ function diffProperty(newItem, oldItem, 
         }
         if (val == oldVal) {
             val = null;
         }
     }
     return val;
 }
 
+/* eslint-disable no-unused-vars */
 var METHOD_PUBLISH = 1;
 var METHOD_REQUEST = 2;
 var METHOD_REPLY = 4;
 var METHOD_CANCEL = 8;
 var METHOD_UPDATE = 256;
+/* eslint-enable no-unused-vars */
 
 calWcapCalendar.prototype.storeItem =
 function calWcapCalendar_storeItem(bAddItem, item, oldItem, request) {
     function getOrgId(orgItem) {
         return (orgItem && orgItem.organizer && orgItem.organizer.id ? orgItem.organizer.id : null);
     }
     function encodeAttendees(atts) {
         function attendeeSort(one, two) {
@@ -842,17 +844,16 @@ calWcapCalendar.prototype.parseItems = f
             break;
         case calICalendar.ITEM_FILTER_TYPE_EVENT:
             componentType = "VEVENT";
             break;
     }
 
     let recurrenceBound = this.session.recurrenceBound;
 
-    let count = 0;
     for (let subComp of cal.ical.calendarComponentIterator(icalRootComp, componentType)) {
         let organizer = subComp.getFirstProperty("ORGANIZER");
         if (organizer && organizer.getParameter("SENT-BY")) { // has SENT-BY
             // &emailorcalid=1 sets wrong email, workaround setting calid...
             let id = organizer.getParameter("X-S1CS-CALID");
             if (id) {
                 organizer.value = id;
             }
--- a/calendar/providers/wcap/calWcapCalendarModule.js
+++ b/calendar/providers/wcap/calWcapCalendarModule.js
@@ -1,24 +1,32 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported NS_OK, NS_ERROR_UNEXPECTED, nsIException, calIWcapSession,
+ *          calIWcapCalendar, calIWcapErrors, calICalendar, calIItemBase,
+ *          calIOperationListener, calIFreeBusyProvider, calIFreeBusyInterval,
+ *          calICalendarSearchProvider, calIErrors, g_privateItemTitle,
+ *          g_confidentialItemTitle, g_busyItemTitle,
+ *          g_busyPhantomItemUuidPrefix, CACHE_LAST_RESULTS,
+ *          CACHE_LAST_RESULTS_INVALIDATE, LOG_LEVEL
+ */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 
 //
 // init code for globals, prefs:
 //
 
 // constants:
 var NS_OK = Components.results.NS_OK;
 var NS_ERROR_UNEXPECTED = Components.results.NS_ERROR_UNEXPECTED;
 var nsIException = Components.interfaces.nsIException;
-var nsISupports = Components.interfaces.nsISupports;
 var calIWcapSession = Components.interfaces.calIWcapSession;
 var calIWcapCalendar = Components.interfaces.calIWcapCalendar;
 var calIWcapErrors = Components.interfaces.calIWcapErrors;
 var calICalendar = Components.interfaces.calICalendar;
 var calIItemBase = Components.interfaces.calIItemBase;
 var calIOperationListener = Components.interfaces.calIOperationListener;
 var calIFreeBusyProvider = Components.interfaces.calIFreeBusyProvider;
 var calIFreeBusyInterval = Components.interfaces.calIFreeBusyInterval;
@@ -74,9 +82,9 @@ function getComponents() {
 
     return [
         calWcapCalendar,
         calWcapNetworkRequest,
         calWcapSession
     ];
 }
 
-var NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, getComponents, this);
+this.NSGetFactory = cal.loadingNSGetFactory(scriptLoadOrder, getComponents, this);
--- a/calendar/providers/wcap/calWcapErrors.js
+++ b/calendar/providers/wcap/calWcapErrors.js
@@ -1,12 +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/. */
 
+/* exported checkErrorCode, checkWcapXmlErrno, checkWcapIcalErrno,
+ *          errorToString
+ */
+
 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;
 
@@ -46,19 +50,16 @@ function checkErrorCode(err, rcBits, mas
 // The following error codes have been adopted from
 // xpcom/base/nsError.h
 // and ought to be defined in IDL. xxx todo
 
 // The requested action could not be completed while the networking
 // is in the offline state.
 var NS_ERROR_OFFLINE = generateNetFailure(16);
 
-// The async request completed successfully.
-var NS_BINDING_SUCCEEDED = NS_OK;
-
 var NS_BINDING_FAILED = generateNetFailure(1);
 var NS_BINDING_ABORTED = generateNetFailure(2);
 var NS_BINDING_REDIRECTED = generateNetFailure(3);
 var NS_BINDING_RETARGETED = generateNetFailure(4);
 
 var g_nsNetErrorCodes = [
     NS_BINDING_FAILED,
     "The async request failed for some unknown reason.",
--- a/calendar/providers/wcap/calWcapRequest.js
+++ b/calendar/providers/wcap/calWcapRequest.js
@@ -12,16 +12,18 @@
    The response function gets the ended request as first parameter to check
    whether the request has been successful and get its data.
    The request function itself may return either
    - a further calIOperation request object, i.e. an async continuation
    - 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");
 
 function generateRequestId() {
     if (!generateRequestId.mRequestPrefix) {
         generateRequestId.mRequestPrefix = (cal.getUUID() + "-");
         generateRequestId.mRequestId = 0;
     }
--- a/calendar/providers/wcap/calWcapSession.js
+++ b/calendar/providers/wcap/calWcapSession.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported getWcapSessionFor */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://calendar/modules/calIteratorUtils.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");
 
 function calWcapTimezone(tzProvider, tzid_, component_) {
     this.wrappedJSObject = this;
--- a/calendar/providers/wcap/calWcapUtils.js
+++ b/calendar/providers/wcap/calWcapUtils.js
@@ -1,12 +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/. */
 
+/* exported getCalendarSearchService, getDomParser, isParent, filterXmlNodes,
+ *          getIcalUTC, getDatetimeFromIcalProp
+ */
+
 Components.utils.import("resource://calendar/modules/calIteratorUtils.jsm");
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 
 var g_bShutdown = false;
 
 function initLogging() {
--- a/calendar/resources/content/calendarCreation.js
+++ b/calendar/resources/content/calendarCreation.js
@@ -1,13 +1,17 @@
 /* -*- Mode: javascript; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 initLocationPage, initCustomizePage, onSelectProvider,
+ *          onInitialAdvance, doCreateCalendar, setCanRewindFalse
+ */
+
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 
 var gCalendar;
 
 var errorConstants = {
     SUCCESS: 0,
     INVALID_URI: 1,
     ALREADY_EXISTS: 2
--- a/calendar/resources/content/datetimepickers/datetimepickers.xml
+++ b/calendar/resources/content/datetimepickers/datetimepickers.xml
@@ -1714,31 +1714,28 @@
 
             let time = null;
             let timePartsArray = this.parseTimeRegExp.exec(aValue);
             const PRE_INDEX = 1, HR_INDEX = 2, MIN_INDEX = 4, SEC_INDEX = 6, POST_INDEX = 8;
 
             if (timePartsArray != null) {
               let hoursString = timePartsArray[HR_INDEX];
               let hours = Number(hoursString);
-              let hoursSuffix = timePartsArray[HR_INDEX + 1];
               if (!(hours >= 0 && hours < 24)) {
                 return null;
               }
 
               let minutesString = timePartsArray[MIN_INDEX];
               let minutes = (minutesString == null ? 0 : Number(minutesString));
-              let minutesSuffix = timePartsArray[MIN_INDEX + 1];
               if (!(minutes >= 0 && minutes < 60)) {
                 return null;
               }
 
               let secondsString = timePartsArray[SEC_INDEX];
               let seconds = (secondsString == null ? 0 : Number(secondsString));
-              let secondsSuffix = timePartsArray[SEC_INDEX + 1];
               if (!(seconds >= 0 && seconds < 60)) {
                 return null;
               }
 
               let ampmCode = null;
               if (timePartsArray[PRE_INDEX] || timePartsArray[POST_INDEX]) {
                 if (this.ampmIndex && timePartsArray[this.ampmIndex]) {
                   // try current format order first
@@ -1874,17 +1871,17 @@
             // Digits         HR       sep      MIN     sep      SEC     sep
             //   Index:       2        3        4       5        6       7
             let digitsExpr = "(\\d?\\d)(\\D)?(?:(\\d\\d)(\\D)?(?:(\\d\\d)(\\D)?)?)?";
             // any letters or '.': non-digit alphanumeric, period (a.m.), or space (P M)
             let anyAmPmExpr = "(?:[^\\d\\W]|[. ])+";
             // digitsExpr has 6 captures, so index of first ampmExpr is 1, of last is 8.
             let probeTimeRegExp =
               new RegExp("^(" + anyAmPmExpr + ")?\\s?" + digitsExpr + "(" + anyAmPmExpr + ")?\\s*$");
-            const PRE_INDEX = 1, HR_INDEX = 2, MIN_INDEX = 4, SEC_INDEX = 6, POST_INDEX = 8;
+            const PRE_INDEX = 1, HR_INDEX = 2, MIN_INDEX = 4, SEC_INDEX = 6, POST_INDEX = 8; // eslint-disable-line no-unused-vars
             let amProbeTime = new Date(2000, 0, 1, 6, 12, 34);
             let amProbeString = amProbeTime.toLocaleFormat("%X");
             let pmProbeTime = new Date(2000, 0, 1, 18, 12, 34);
             let pmProbeString = pmProbeTime.toLocaleFormat("%X");
             let amFormatExpr = null, pmFormatExpr = null;
             if (amProbeString != pmProbeString) {
               let amProbeArray = probeTimeRegExp.exec(amProbeString);
               let pmProbeArray = probeTimeRegExp.exec(pmProbeString);
--- a/calendar/resources/content/mouseoverPreviews.js
+++ b/calendar/resources/content/mouseoverPreviews.js
@@ -6,16 +6,18 @@
  * Code which generates event and task (todo) preview tooltips/titletips
  *  when the mouse hovers over either the event list, the task list, or
  *  an event or task box in one of the grid views.
  *
  *   (Portions of this code were previously in calendar.js and unifinder.js,
  *   some of it duplicated.)
  */
 
+/* exported onMouseOverItem, showToolTip */
+
 /** PUBLIC
  *
  *  This changes the mouseover preview based on the start and end dates
  *  of an occurrence of a (one-time or recurring) calEvent or calToDo.
  *  Used by all grid views.
  */
 
 function onMouseOverItem(occurrenceBoxMouseEvent) {
--- a/calendar/resources/content/publish.js
+++ b/calendar/resources/content/publish.js
@@ -1,13 +1,16 @@
-/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 publishCalendarData, publishCalendarDataDialogResponse,
+ *          publishEntireCalendar, publishEntireCalendarDialogResponse
+ */
+
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://calendar/modules/calUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 /**
  * publishCalendarData
  * Show publish dialog, ask for URL and publish all selected items.
  */
--- a/calendar/resources/content/publishDialog.js
+++ b/calendar/resources/content/publishDialog.js
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported loadCalendarPublishDialog, onOKCommand, closeDialog */
+
 var gOnOkFunction;   // function to be called when user clicks OK
 var gPublishObject;
 
 /**
 *   Called when the dialog is loaded.
 */
 function loadCalendarPublishDialog() {
    // Get arguments, see description at top of file
new file mode 100644
--- /dev/null
+++ b/calendar/test/mozmill/.eslintrc
@@ -0,0 +1,20 @@
+{
+  "globals": {
+    "elementslib": true,
+    "controller": true,
+    "mozmill": true,
+    "utils": true,
+    "require": true,
+    "exports": true,
+    "module": true
+  },
+  "rules": {
+    // Allow mozmill test methods to be used without warning
+    "no-unused-vars": [2, {
+      "vars": "all",
+      "args": "none",
+      "varsIgnorePattern": "(MODULE_NAME|MODULE_REQUIRES|RELATIVE_ROOT|setupModule|teardownTest|^test[A-Z].*)"
+      }
+    ]
+  }
+}
--- a/calendar/test/mozmill/eventDialog/testEventDialog.js
+++ b/calendar/test/mozmill/eventDialog/testEventDialog.js
@@ -8,17 +8,16 @@ var utils = require("../shared-modules/u
 
 var sleep = 500;
 var calendar = "Mozmill";
 var title = "Event";
 var location = "Location";
 var desc = "Event Decription";
 var attendee = "foo@bar.com";
 var url = "http://mozilla.org";
-var tmp;
 
 var setupModule = function(module) {
   controller = mozmill.getMail3PaneController();
   calUtils.createCalendar(controller, calendar);
 };
 
 var testEventDialog = function() {
   // paths
--- a/calendar/test/mozmill/eventDialog/testEventDialogModificationPrompt.js
+++ b/calendar/test/mozmill/eventDialog/testEventDialogModificationPrompt.js
@@ -3,19 +3,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var calUtils = require("../shared-modules/calendar-utils");
 var modalDialog = require("../shared-modules/modal-dialog");
 var prefs = require("../shared-modules/prefs");
 
 var sleep = 500;
 var calendar = "Mozmill";
-var title = "Title";
-var location = "Location";
-var description = "Description\ncontinuing";
 var pass;
 var date1 = new Date(2009, 0, 1, 8, 0);
 var date2 = new Date(2009, 0, 2, 9, 0);
 var date3 = new Date(2009, 0, 3, 10, 0);
 var data = [{title: "title1", location: "location1", description: "description1", allday: false,
              startdate: date1, starttime: date1, enddate: date2, endtime: date2, repeat: "none",
              reminder: 0, priority: "normal", privacy: "public", status: "confirmed",
              freebusy: "busy", timezone: true, attachment: {add: "http://mozilla.org"}},
--- a/calendar/test/mozmill/shared-modules/timezone-utils.js
+++ b/calendar/test/mozmill/shared-modules/timezone-utils.js
@@ -1,17 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var calUtils = require("calendar-utils");
 var prefs = require("prefs");
 
-var sleep = 500;
-
 function switchAppTimezone(timezone) {
   // change directly as Mac has different Lookup & XPath than Windows & Linux, bug 536605
   prefs.preferences.setPref("calendar.timezone.local", timezone);
 }
 
 function verify(controller, dates, timezones, times) {
   let dayView = '/id("messengerWindow")/id("tabmail-container")/id("tabmail")/'
     + 'id("tabpanelcontainer")/id("calendarTabPanel")/id("calendarContent")/'
--- a/calendar/test/mozmill/timezoneTests/test10.js
+++ b/calendar/test/mozmill/timezoneTests/test10.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/. */
 
 var calUtils = require("../shared-modules/calendar-utils");
 var prefs = require("../shared-modules/prefs");
 var timezoneUtils = require("../shared-modules/timezone-utils");
 
-var sleep = 500;
 var calendar = "Mozmill";
 var dates = [[2009, 1, 1], [2009, 4, 2], [2009, 4, 16], [2009, 4, 30],
              [2009, 7, 2], [2009, 10, 15], [2009, 10, 29], [2009, 11, 5]];
 var timezones = ["America/St_Johns", "America/Caracas", "America/Phoenix", "America/Los_Angeles",
                  "America/Argentina/Buenos_Aires", "Europe/Paris", "Asia/Kathmandu", "Australia/Adelaide"];
 /* rows - dates
    columns - correct time for each event */
 var times = [[[18, 30], [19, 30], [20, 30], [21, 30], [22, 30], [23, 30], [0, 30, +1], [1, 30, +1]],
@@ -23,18 +22,16 @@ var times = [[[18, 30], [19, 30], [20, 3
              [[17, 30], [19, 30], [20, 30], [20, 30], [22, 30], [23, 30], [0, 30, +1], [1, 30, +1]],
              [[18, 30], [19, 30], [20, 30], [21, 30], [22, 30], [23, 30], [0, 30, +1], [1, 30, +1]]];
 
 var setupModule = function(module) {
   controller = mozmill.getMail3PaneController();
 };
 
 var testTimezones10_checkAdelaide = function() {
-  let eventPath = '/{"tooltip":"itemTooltip","calendar":"' + calendar.toLowerCase() + '"}';
-
   controller.click(new elementslib.ID(controller.window.document, "calendar-tab-button"));
   calUtils.switchToView(controller, "day");
   calUtils.goToDate(controller, 2009, 1, 1);
 
   timezoneUtils.verify(controller, dates, timezones, times);
 };
 
 var teardownTest = function(module) {
--- a/calendar/test/mozmill/timezoneTests/test2.js
+++ b/calendar/test/mozmill/timezoneTests/test2.js
@@ -2,17 +2,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var calUtils = require("../shared-modules/calendar-utils");
 var modalDialog = require("../shared-modules/modal-dialog");
 var timezoneUtils = require("../shared-modules/timezone-utils");
 
 var sleep = 500;
-var calendar = "Mozmill";
 var timezones = ["America/St_Johns", "America/Caracas", "America/Phoenix", "America/Los_Angeles",
                  "America/Argentina/Buenos_Aires", "Europe/Paris", "Asia/Kathmandu", "Australia/Adelaide"];
 var times = [[4, 30], [4, 30], [3, 0], [3, 0], [9, 0], [14, 0], [19, 45], [1, 30]];
 var gTimezone;
 
 var setupModule = function(module) {
   controller = mozmill.getMail3PaneController();
 };
--- a/calendar/test/mozmill/timezoneTests/test3.js
+++ b/calendar/test/mozmill/timezoneTests/test3.js
@@ -1,17 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var calUtils = require("../shared-modules/calendar-utils");
 var timezoneUtils = require("../shared-modules/timezone-utils");
 
-var sleep = 500;
-var calendar = "Mozmill";
 var dates = [[2009, 1, 1], [2009, 4, 2], [2009, 4, 16], [2009, 4, 30],
              [2009, 7, 2], [2009, 10, 15], [2009, 10, 29], [2009, 11, 5]];
 var timezones = ["America/St_Johns", "America/Caracas", "America/Phoenix", "America/Los_Angeles",
                  "America/Argentina/Buenos_Aires", "Europe/Paris", "Asia/Kathmandu", "Australia/Adelaide"];
 /* rows - dates
    columns - correct time for each event */
 var times = [[[4, 30], [5, 30], [6, 30], [7, 30], [8, 30], [9, 30], [10, 30], [11, 30]],
              [[4, 30], [6, 30], [7, 30], [7, 30], [9, 30], [9, 30], [11, 30], [12, 30]],
@@ -22,18 +20,16 @@ var times = [[[4, 30], [5, 30], [6, 30],
              [[4, 30], [6, 30], [7, 30], [7, 30], [9, 30], [10, 30], [11, 30], [12, 30]],
              [[4, 30], [5, 30], [6, 30], [7, 30], [8, 30], [9, 30], [10, 30], [11, 30]]];
 
 var setupModule = function(module) {
   controller = mozmill.getMail3PaneController();
 };
 
 var testTimezones3_checkStJohns = function() {
-  let eventPath = '/{"tooltip":"itemTooltip","calendar":"' + calendar.toLowerCase() + '"}';
-
   controller.click(new elementslib.ID(controller.window.document, "calendar-tab-button"));
   calUtils.switchToView(controller, "day");
   calUtils.goToDate(controller, 2009, 1, 1);
 
   timezoneUtils.verify(controller, dates, timezones, times);
 };
 
 var teardownTest = function(module) {
--- a/calendar/test/mozmill/timezoneTests/test4.js
+++ b/calendar/test/mozmill/timezoneTests/test4.js
@@ -1,17 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var calUtils = require("../shared-modules/calendar-utils");
 var timezoneUtils = require("../shared-modules/timezone-utils");
 
-var sleep = 500;
-var calendar = "Mozmill";
 var dates = [[2009, 1, 1], [2009, 4, 2], [2009, 4, 16], [2009, 4, 30],
              [2009, 7, 2], [2009, 10, 15], [2009, 10, 29], [2009, 11, 5]];
 var timezones = ["America/St_Johns", "America/Caracas", "America/Phoenix", "America/Los_Angeles",
                  "America/Argentina/Buenos_Aires", "Europe/Paris", "Asia/Kathmandu", "Australia/Adelaide"];
 /* rows - dates
    columns - correct time for each event */
 var times = [[[3, 30], [4, 30], [5, 30], [6, 30], [7, 30], [8, 30], [9, 30], [10, 30]],
              [[2, 30], [4, 30], [5, 30], [5, 30], [7, 30], [7, 30], [9, 30], [10, 30]],
@@ -22,18 +20,16 @@ var times = [[[3, 30], [4, 30], [5, 30],
              [[2, 30], [4, 30], [5, 30], [5, 30], [7, 30], [8, 30], [9, 30], [10, 30]],
              [[3, 30], [4, 30], [5, 30], [6, 30], [7, 30], [8, 30], [9, 30], [10, 30]]];
 
 var setupModule = function(module) {
   controller = mozmill.getMail3PaneController();
 };
 
 var testTimezones4_checkCaracas = function() {
-  let eventPath = '/{"tooltip":"itemTooltip","calendar":"' + calendar.toLowerCase() + '"}';
-
   controller.click(new elementslib.ID(controller.window.document, "calendar-tab-button"));
   calUtils.switchToView(controller, "day");
   calUtils.goToDate(controller, 2009, 1, 1);
 
   timezoneUtils.verify(controller, dates, timezones, times);
 };
 
 var teardownTest = function(module) {
--- a/calendar/test/mozmill/timezoneTests/test5.js
+++ b/calendar/test/mozmill/timezoneTests/test5.js
@@ -1,17 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var calUtils = require("../shared-modules/calendar-utils");
 var timezoneUtils = require("../shared-modules/timezone-utils");
 
-var sleep = 500;
-var calendar = "Mozmill";
 var dates = [[2009, 1, 1], [2009, 4, 2], [2009, 4, 16], [2009, 4, 30],
              [2009, 7, 2], [2009, 10, 15], [2009, 10, 29], [2009, 11, 5]];
 var timezones = ["America/St_Johns", "America/Caracas", "America/Phoenix", "America/Los_Angeles",
                  "America/Argentina/Buenos_Aires", "Europe/Paris", "Asia/Kathmandu", "Australia/Adelaide"];
 /* rows - dates
    columns - correct time for each event */
 var times = [[[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0]],
              [[0, 0], [2, 0], [3, 0], [3, 0], [5, 0], [5, 0], [7, 0], [8, 0]],
@@ -22,18 +20,16 @@ var times = [[[1, 0], [2, 0], [3, 0], [4
              [[0, 0], [2, 0], [3, 0], [3, 0], [5, 0], [6, 0], [7, 0], [8, 0]],
              [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0]]];
 
 var setupModule = function(module) {
   controller = mozmill.getMail3PaneController();
 };
 
 var testTimezones5_checkPhoenix = function() {
-  let eventPath = '/{"tooltip":"itemTooltip","calendar":"' + calendar.toLowerCase() + '"}';
-
   controller.click(new elementslib.ID(controller.window.document, "calendar-tab-button"));
   calUtils.switchToView(controller, "day");
   calUtils.goToDate(controller, 2009, 1, 1);
 
   timezoneUtils.verify(controller, dates, timezones, times);
 };
 
 var teardownTest = function(module) {
--- a/calendar/test/mozmill/timezoneTests/test6.js
+++ b/calendar/test/mozmill/timezoneTests/test6.js
@@ -1,17 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var calUtils = require("../shared-modules/calendar-utils");
 var timezoneUtils = require("../shared-modules/timezone-utils");
 
-var sleep = 500;
-var calendar = "Mozmill";
 var dates = [[2009, 1, 1], [2009, 4, 2], [2009, 4, 16], [2009, 4, 30],
              [2009, 7, 2], [2009, 10, 15], [2009, 10, 29], [2009, 11, 5]];
 var timezones = ["America/St_Johns", "America/Caracas", "America/Phoenix", "America/Los_Angeles",
                  "America/Argentina/Buenos_Aires", "Europe/Paris", "Asia/Kathmandu", "Australia/Adelaide"];
 /* rows - dates
    columns - correct time for each event */
 var times = [[[0, 0], [1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0]],
              [[0, 0], [2, 0], [3, 0], [3, 0], [5, 0], [5, 0], [7, 0], [8, 0]],
@@ -22,18 +20,16 @@ var times = [[[0, 0], [1, 0], [2, 0], [3
              [[0, 0], [2, 0], [3, 0], [3, 0], [5, 0], [6, 0], [7, 0], [8, 0]],
              [[0, 0], [1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0]]];
 
 var setupModule = function(module) {
   controller = mozmill.getMail3PaneController();
 };
 
 var testTimezones6_checkLosAngeles = function() {
-  let eventPath = '/{"tooltip":"itemTooltip","calendar":"' + calendar.toLowerCase() + '"}';
-
   controller.click(new elementslib.ID(controller.window.document, "calendar-tab-button"));
   calUtils.switchToView(controller, "day");
   calUtils.goToDate(controller, 2009, 1, 1);
 
   timezoneUtils.verify(controller, dates, timezones, times);
 };
 
 var teardownTest = function(module) {
--- a/calendar/test/mozmill/timezoneTests/test7.js
+++ b/calendar/test/mozmill/timezoneTests/test7.js
@@ -1,17 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var calUtils = require("../shared-modules/calendar-utils");
 var timezoneUtils = require("../shared-modules/timezone-utils");
 
-var sleep = 500;
-var calendar = "Mozmill";
 var dates = [[2009, 1, 1], [2009, 4, 2], [2009, 4, 16], [2009, 4, 30],
              [2009, 7, 2], [2009, 10, 15], [2009, 10, 29], [2009, 11, 5]];
 var timezones = ["America/St_Johns", "America/Caracas", "America/Phoenix", "America/Los_Angeles",
                  "America/Argentina/Buenos_Aires", "Europe/Paris", "Asia/Kathmandu", "Australia/Adelaide"];
 /* rows - dates
    columns - correct time for each event */
 var times = [[[5, 0], [6, 0], [7, 0], [8, 0], [9, 0], [10, 0], [11, 0], [12, 0]],
              [[4, 0], [6, 0], [7, 0], [7, 0], [9, 0], [9, 0], [11, 0], [12, 0]],
@@ -22,18 +20,16 @@ var times = [[[5, 0], [6, 0], [7, 0], [8
              [[4, 0], [6, 0], [7, 0], [7, 0], [9, 0], [10, 0], [11, 0], [12, 0]],
              [[5, 0], [6, 0], [7, 0], [8, 0], [9, 0], [10, 0], [11, 0], [12, 0]]];
 
 var setupModule = function(module) {
   controller = mozmill.getMail3PaneController();
 };
 
 var testTimezones7_checkBuenosAires = function() {
-  let eventPath = '/{"tooltip":"itemTooltip","calendar":"' + calendar.toLowerCase() + '"}';
-
   controller.click(new elementslib.ID(controller.window.document, "calendar-tab-button"));
   calUtils.switchToView(controller, "day");
   calUtils.goToDate(controller, 2009, 1, 1);
 
   timezoneUtils.verify(controller, dates, timezones, times);
 };
 
 var teardownTest = function(module) {
--- a/calendar/test/mozmill/timezoneTests/test8.js
+++ b/calendar/test/mozmill/timezoneTests/test8.js
@@ -1,17 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var calUtils = require("../shared-modules/calendar-utils");
 var timezoneUtils = require("../shared-modules/timezone-utils");
 
-var sleep = 500;
-var calendar = "Mozmill";
 var dates = [[2009, 1, 1], [2009, 4, 2], [2009, 4, 16], [2009, 4, 30],
              [2009, 7, 2], [2009, 10, 15], [2009, 10, 29], [2009, 11, 5]];
 var timezones = ["America/St_Johns", "America/Caracas", "America/Phoenix", "America/Los_Angeles",
                  "America/Argentina/Buenos_Aires", "Europe/Paris", "Asia/Kathmandu", "Australia/Adelaide"];
 /* rows - dates
    columns - correct time for each event */
 var times = [[[9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [16, 0]],
              [[9, 0], [11, 0], [12, 0], [12, 0], [14, 0], [14, 0], [16, 0], [17, 0]],
@@ -22,18 +20,16 @@ var times = [[[9, 0], [10, 0], [11, 0], 
              [[8, 0], [10, 0], [11, 0], [11, 0], [13, 0], [14, 0], [15, 0], [16, 0]],
              [[9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [16, 0]]];
 
 var setupModule = function(module) {
   controller = mozmill.getMail3PaneController();
 };
 
 var testTimezones8_checkParis = function() {
-  let eventPath = '/{"tooltip":"itemTooltip","calendar":"' + calendar.toLowerCase() + '"}';
-
   controller.click(new elementslib.ID(controller.window.document, "calendar-tab-button"));
   calUtils.switchToView(controller, "day");
   calUtils.goToDate(controller, 2009, 1, 1);
 
   timezoneUtils.verify(controller, dates, timezones, times);
 };
 
 var teardownTest = function(module) {
--- a/calendar/test/mozmill/timezoneTests/test9.js
+++ b/calendar/test/mozmill/timezoneTests/test9.js
@@ -1,17 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var calUtils = require("../shared-modules/calendar-utils");
 var timezoneUtils = require("../shared-modules/timezone-utils");
 
-var sleep = 500;
-var calendar = "Mozmill";
 var dates = [[2009, 1, 1], [2009, 4, 2], [2009, 4, 16], [2009, 4, 30],
              [2009, 7, 2], [2009, 10, 15], [2009, 10, 29], [2009, 11, 5]];
 var timezones = ["America/St_Johns", "America/Caracas", "America/Phoenix", "America/Los_Angeles",
                  "America/Argentina/Buenos_Aires", "Europe/Paris", "Asia/Kathmandu", "Australia/Adelaide"];
 /* rows - dates
    columns - correct time for each event */
 var times = [[[13, 45], [14, 45], [15, 45], [16, 45], [17, 45], [18, 45], [19, 45], [20, 45]],
              [[12, 45], [14, 45], [15, 45], [15, 45], [17, 45], [17, 45], [19, 45], [20, 45]],
@@ -22,18 +20,16 @@ var times = [[[13, 45], [14, 45], [15, 4
              [[12, 45], [14, 45], [15, 45], [15, 45], [17, 45], [18, 45], [19, 45], [20, 45]],
              [[13, 45], [14, 45], [15, 45], [16, 45], [17, 45], [18, 45], [19, 45], [20, 45]]];
 
 var setupModule = function(module) {
   controller = mozmill.getMail3PaneController();
 };
 
 var testTimezones9_checkKathmandu = function() {
-  let eventPath = '/{"tooltip":"itemTooltip","calendar":"' + calendar.toLowerCase() + '"}';
-
   controller.click(new elementslib.ID(controller.window.document, "calendar-tab-button"));
   calUtils.switchToView(controller, "day");
   calUtils.goToDate(controller, 2009, 1, 1);
 
   timezoneUtils.verify(controller, dates, timezones, times);
 };
 
 var teardownTest = function(module) {
new file mode 100644
--- /dev/null
+++ b/calendar/test/unit/.eslintrc
@@ -0,0 +1,18 @@
+{
+  "extends": [
+    "../../../mozilla/testing/xpcshell/xpcshell.eslintrc"
+  ],
+  "rules": {
+    // Allow non-camelcase so that run_test doesn't produce a warning.
+    "camelcase": 0,
+    // Allow using undefined variables so that tests can refer to functions
+    // and variables defined in head.js files, without having to maintain a
+    // list of globals in each .eslintrc file.
+    // Note that bug 1168340 will eventually help auto-registering globals
+    // from head.js files.
+    "no-undef": 0,
+    "block-scoped-var": 0,
+    // Allow run_test to be unused in xpcshell
+    "no-unused-vars": [2, { "vars": "all", "args": "none", "varsIgnorePattern": "run_test" }],
+  }
+}
--- a/calendar/test/unit/head_consts.js
+++ b/calendar/test/unit/head_consts.js
@@ -1,22 +1,26 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+/* exported do_calendar_startup, do_load_calmgr, do_load_timezoneservice,
+ *          readJSONFile, ics_unfoldline, compareItemsSpecific, getStorageCal,
+ *          getMemoryCal, createTodoFromIcalString, createEventFromIcalString,
+ *          createDate, Cc, Ci, Cr, Cu
+ */
+
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/Preferences.jsm");
 Components.utils.import("resource://gre/modules/FileUtils.jsm");
 
 Components.utils.import("resource://testing-common/AppInfo.jsm");
 updateAppInfo();
 
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cr = Components.results;
+var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
 
 (function load_lightning_manifest() {
   let bindir = Services.dirsvc.get("CurProcD", Components.interfaces.nsIFile);
   bindir.append("extensions");
   bindir.append("{e2fda1a4-762b-4020-b5ad-a41df1933103}");
   bindir.append("chrome.manifest");
   dump("Loading" + bindir.path + "\n");
   Components.manager.autoRegister(bindir);
--- a/calendar/test/unit/test_alarm.js
+++ b/calendar/test/unit/test_alarm.js
@@ -245,17 +245,16 @@ function test_custom_alarm() {
     alarm.clearAttachments();
     addedAttachments = alarm.getAttachments({});
     equal(addedAttachments.length, 0);
 }
 
 // Check if any combination of REPEAT and DURATION work as expected.
 function test_repeat() {
     dump("Testing REPEAT and DURATION properties...");
-    let message;
     let alarm = cal.createAlarm();
 
     // Check initial value
     equal(alarm.repeat, 0);
     equal(alarm.repeatOffset, null);
     equal(alarm.repeatDate, null);
 
     // Should not be able to get REPEAT when DURATION is not set
@@ -389,17 +388,16 @@ function test_immutable() {
         alarm[prop] = propMap[prop];
     }
 
     // Set up some extra props
     alarm.setProperty("X-FOO", "X-VAL");
     alarm.setProperty("X-DATEPROP", cal.createDateTime());
     alarm.addAttendee(cal.createAttendee());
 
-    let passed = false;
     // Initial checks
     ok(alarm.isMutable);
     alarm.makeImmutable();
     ok(!alarm.isMutable);
     alarm.makeImmutable();
     ok(!alarm.isMutable);
 
     // Check each attribute
--- a/calendar/test/unit/test_attendee.js
+++ b/calendar/test/unit/test_attendee.js
@@ -42,18 +42,16 @@ function test_values() {
             throws(function() {
                 a[properties[i]] = old + 1;
             }, /Can not modify immutable data container/);
 
             equal(a[properties[i]], old);
         }
     }
 
-    const cIA = Components.interfaces.calIAttendee;
-
     // Create Attendee
     let a1 = cal.createAttendee();
     // Testing attendee set/get.
     let properties = ["id", "commonName", "rsvp", "role", "participationStatus",
                       "userType"];
     let values = ["myid", "mycn", "TRUE", "CHAIR", "DECLINED", "RESOURCE"];
     // Make sure test is valid
     equal(properties.length, values.length);
--- a/calendar/test/unit/test_bug1209399.js
+++ b/calendar/test/unit/test_bug1209399.js
@@ -84,16 +84,15 @@ function test_fromICS() {
         { id: 'mailto:user3@example.net', cn: 'Test3' },
         { id: 'mailto:user4@example.net', cn: '' },
         { id: 'mailto:user5@example.net', cn: '' },
         { id: 'mailto:user6@example.net', cn: null },
         { id: 'mailto:user7@example.net', cn: '' },
         { id: 'mailto:user8@example.net', cn: '' }
     ];
     let event = createEventFromIcalString(ics);
-    let attendees = event.getAttendees({});
 
     equal(event.getAttendees({}).length, expected.length, "Check test consistency");
     for (let exp of expected) {
         let attendee = event.getAttendeeById(exp.id);
         equal(attendee.commonName, exp.cn, "Test for cn matching of " + exp.id);
     }
 }
--- a/calendar/test/unit/test_bug494140.js
+++ b/calendar/test/unit/test_bug494140.js
@@ -49,12 +49,12 @@ function run_test() {
     storageCal.getItem("c1a6cfe7-7fbb-4bfb-a00d-861e07c649a5", {
         onGetResult: function onGetResult(cal, stat, type, detail, count, items) {
             retrievedItem = items[0];
         },
         onOperationComplete: function() {}
     });
 
     // There should still be one alarm, one relation and one attachment
-    equal(item.getAlarms({}).length, 1);
-    equal(item.getRelations({}).length, 1);
-    equal(item.getAttachments({}).length, 1);
+    equal(retrievedItem.getAlarms({}).length, 1);
+    equal(retrievedItem.getRelations({}).length, 1);
+    equal(retrievedItem.getAttachments({}).length, 1);
 }
--- a/calendar/test/unit/test_calmgr.js
+++ b/calendar/test/unit/test_calmgr.js
@@ -128,24 +128,24 @@ add_test(function test_calobserver() {
     // First of all we need a local calendar to work on and some variables
     let calmgr = cal.getCalendarManager();
     let memory = calmgr.createCalendar("memory", Services.io.newURI("moz-memory-calendar://", null, null));
     let memory2 = calmgr.createCalendar("memory", Services.io.newURI("moz-memory-calendar://", null, null));
     let calcounter, allcounter;
 
     // These observers will end up counting calls which we will use later on
     let calobs = cal.createAdapter(Components.interfaces.calIObserver, {
-        onAddItem: itm => calcounter.addItem++,
-        onModifyItem: itm => calcounter.modifyItem++,
-        onDeleteItem: itm => calcounter.deleteItem++
+        onAddItem: () => calcounter.addItem++,
+        onModifyItem: () => calcounter.modifyItem++,
+        onDeleteItem: () => calcounter.deleteItem++
     });
     let allobs = cal.createAdapter(Components.interfaces.calIObserver, {
-        onAddItem: itm => allcounter.addItem++,
-        onModifyItem: itm => allcounter.modifyItem++,
-        onDeleteItem: itm => allcounter.deleteItem++
+        onAddItem: () => allcounter.addItem++,
+        onModifyItem: () => allcounter.modifyItem++,
+        onDeleteItem: () => allcounter.deleteItem++
     });
 
     // Set up counters and observers
     resetCounters();
     calmgr.registerCalendar(memory);
     calmgr.registerCalendar(memory2);
     calmgr.addCalendarObserver(allobs);
     memory.addObserver(calobs);
--- a/calendar/test/unit/test_extract.js
+++ b/calendar/test/unit/test_extract.js
@@ -22,17 +22,17 @@ function run_test() {
     test_event_start_dollar_sign();
 }
 
 function test_event_start_end() {
     let date = new Date(2012, 9, 1, 9, 0);
     let title = "Wednesday meetup";
     let content = "We'll meet at 2 pm and discuss until 3 pm.";
 
-    let collected = extractor.extract(title, content, date, undefined);
+    extractor.extract(title, content, date, undefined);
     let guessed = extractor.guessStart();
     let endGuess = extractor.guessEnd(guessed);
 
     equal(guessed.year, 2012);
     equal(guessed.month, 10);
     equal(guessed.day, 3);
     equal(guessed.hour, 14);
     equal(guessed.minute, 0);
@@ -44,17 +44,17 @@ function test_event_start_end() {
     equal(endGuess.minute, 0);
 }
 
 function test_event_start_duration() {
     let date = new Date(2012, 9, 1, 9, 0);
     let title = "Wednesday meetup";
     let content = "We'll meet at 2 pm and discuss for 30 minutes.";
 
-    let collected = extractor.extract(title, content, date, undefined);
+    extractor.extract(title, content, date, undefined);
     let guessed = extractor.guessStart();
     let endGuess = extractor.guessEnd(guessed);
 
     equal(guessed.year, 2012);
     equal(guessed.month, 10);
     equal(guessed.day, 3);
     equal(guessed.hour, 14);
     equal(guessed.minute, 0);
@@ -66,17 +66,17 @@ function test_event_start_duration() {
     equal(endGuess.minute, 30);
 }
 
 function test_event_start_end_whitespace() {
     let date = new Date(2012, 9, 1, 9, 0);
     let title = "Wednesday meetup";
     let content = "We'll meet at2pm and discuss until\r\n3pm.";
 
-    let collected = extractor.extract(title, content, date, undefined);
+    extractor.extract(title, content, date, undefined);
     let guessed = extractor.guessStart();
     let endGuess = extractor.guessEnd(guessed);
 
     equal(guessed.year, 2012);
     equal(guessed.month, 10);
     equal(guessed.day, 3);
     equal(guessed.hour, 14);
     equal(guessed.minute, 0);
@@ -88,17 +88,17 @@ function test_event_start_end_whitespace
     equal(endGuess.minute, 0);
 }
 
 function test_event_without_date() {
     let date = new Date(2012, 9, 1, 9, 0);
     let title = "Meetup";
     let content = "We'll meet at 2 pm and discuss until 3 pm.";
 
-    let collected = extractor.extract(title, content, date, undefined);
+    extractor.extract(title, content, date, undefined);
     let guessed = extractor.guessStart();
     let endGuess = extractor.guessEnd(guessed);
 
     equal(guessed.year, 2012);
     equal(guessed.month, 10);
     equal(guessed.day, 1);
     equal(guessed.hour, 14);
     equal(guessed.minute, 0);
@@ -110,17 +110,17 @@ function test_event_without_date() {
     equal(endGuess.minute, 0);
 }
 
 function test_event_next_year() {
     let date = new Date(2012, 9, 1, 9, 0);
     let title = "Open day";
     let content = "FYI: Next open day is planned for February 5th.";
 
-    let collected = extractor.extract(title, content, date, undefined);
+    extractor.extract(title, content, date, undefined);
     let guessed = extractor.guessStart();
     let endGuess = extractor.guessEnd(guessed);
 
     equal(guessed.year, 2013);
     equal(guessed.month, 2);
     equal(guessed.day, 5);
     equal(guessed.hour, undefined);
     equal(guessed.minute, undefined);
@@ -132,17 +132,17 @@ function test_event_next_year() {
     equal(endGuess.minute, undefined);
 }
 
 function test_task_due() {
     let date = new Date(2012, 9, 1, 9, 0);
     let title = "Assignment deadline";
     let content = "This is a reminder that all assignments must be sent in by October 5th!.";
 
-    let collected = extractor.extract(title, content, date, undefined);
+    extractor.extract(title, content, date, undefined);
     let guessed = extractor.guessStart(true);
     let endGuess = extractor.guessEnd(guessed, true);
 
     equal(guessed.year, 2012);
     equal(guessed.month, 10);
     equal(guessed.day, 1);
     equal(guessed.hour, 9);
     equal(guessed.minute, 0);
@@ -154,17 +154,17 @@ function test_task_due() {
     equal(endGuess.minute, 0);
 }
 
 function test_overrides() {
     let date = new Date(2012, 9, 1, 9, 0);
     let title = "Event invitation";
     let content = "We'll meet 10:11 worromot";
 
-    let collected = extractor.extract(title, content, date, undefined);
+    extractor.extract(title, content, date, undefined);
     let guessed = extractor.guessStart(false);
     let endGuess = extractor.guessEnd(guessed, true);
 
     equal(guessed.year, 2012);
     equal(guessed.month, 10);
     equal(guessed.day, 1);
     equal(guessed.hour, 10);
     equal(guessed.minute, 11);
@@ -199,18 +199,24 @@ function test_overrides() {
     equal(endGuess.minute, undefined);
 }
 
 function test_event_start_dollar_sign() {
     let date = new Date(2012, 9, 1, 9, 0);
     let title = "Wednesday sale";
     let content = "Sale starts at 3 pm and prices start at 2$.";
 
-    let collected = extractor.extract(title, content, date, undefined);
+    extractor.extract(title, content, date, undefined);
     let guessed = extractor.guessStart();
     let endGuess = extractor.guessEnd(guessed);
 
     equal(guessed.year, 2012);
     equal(guessed.month, 10);
     equal(guessed.day, 3);
     equal(guessed.hour, 15);
     equal(guessed.minute, 0);
+
+    equal(endGuess.year, undefined);
+    equal(endGuess.month, undefined);
+    equal(endGuess.day, undefined);
+    equal(endGuess.hour, undefined);
+    equal(endGuess.minute, undefined);
 }
--- a/calendar/test/unit/test_freebusy_service.js
+++ b/calendar/test/unit/test_freebusy_service.js
@@ -93,21 +93,21 @@ function test_failure() {
             ok(provider.called);
             do_test_finished();
         }
     };
 
     freebusy.addProvider(provider);
 
     do_test_pending();
-    let op = freebusy.getFreeBusyIntervals("email",
-                                           cal.createDateTime("20120101T010101"),
-                                           cal.createDateTime("20120102T010101"),
-                                           cIFI.BUSY_ALL,
-                                           listener);
+    freebusy.getFreeBusyIntervals("email",
+                                  cal.createDateTime("20120101T010101"),
+                                  cal.createDateTime("20120102T010101"),
+                                  cIFI.BUSY_ALL,
+                                  listener);
 }
 
 function test_cancel() {
     _clearProviders();
 
     let provider = {
         QueryInterface: XPCOMUtils.generateQI([Components.interfaces.calIFreeBusyProvider, Components.interfaces.calIOperation]),
         getFreeBusyIntervals: function(aCalId, aStart, aEnd, aTypes, aListener) {
--- a/calendar/test/unit/test_gdata_provider.js
+++ b/calendar/test/unit/test_gdata_provider.js
@@ -346,33 +346,33 @@ GDataServer.prototype = {
             }
         } else if (matchTag == "*") {
             let data = modifyFunc(body, itemId);
             items.push(data);
             response.write(JSON.stringify(data));
         } else if (body.recurringEventId) {
             // Special case for events, won't happen on tasks.  This is an
             // exception that doesn't exist yet. Allow creation in this case.
-            let [foundParentIndex, foundParent] = findKey(items, "id", body.recurringEventId);
+            let [, foundParent] = findKey(items, "id", body.recurringEventId);
             if (!matchTag || foundParent.etag == matchTag) {
                 let data = modifyFunc(body, itemId);
                 items.push(data);
                 response.write(JSON.stringify(data));
             } else {
                 response.setStatusLine(null, 412, "Precondition Failed");
             }
         } else if (matchTag) {
             response.setStatusLine(null, 412, "Precondition Failed");
         } else {
             response.setStatusLine(null, 404, "Not Found");
         }
     },
 
     handleDelete: function(request, response, items, itemId) {
-        let [foundIndex, foundItem] = findKey(items, "id", itemId);
+        let [foundIndex, ] = findKey(items, "id", itemId);
 
         let matchTag = request.hasHeader("If-Match") ?
                        request.getHeader("If-Match") : null;
 
         if (foundIndex != -1) {
             if (!matchTag || matchTag == "*" || items[foundIndex].etag == matchTag) {
                 items.splice(foundIndex, 1);
                 response.setStatusLine(null, 204, "No Content");
@@ -600,18 +600,17 @@ add_task(function* test_dateToJSON() {
 
         let parser = Components.classes["@mozilla.org/calendar/ics-parser;1"]
                                .createInstance(Components.interfaces.calIIcsParser);
         parser.parseString(ics);
         let items = parser.getItems({});
         return items[0].startDate;
     }
 
-    let tzProvider = cal.getTimezoneService();
-    let dt, vtimezone;
+    let dt;
 
     // no timezone
     dt = _createDateTime(cal.floating());
     deepEqual(dateToJSON(dt), { "dateTime": "2015-01-30T12:00:00-00:00" });
 
     // valid non-Olson tz name
     dt = _createDateTime("Eastern Standard Time");
     deepEqual(dateToJSON(dt), {"dateTime": "2015-01-30T12:00:00", "timeZone": "America/New_York"});
@@ -1300,17 +1299,17 @@ add_task(function* test_modify_invitatio
     equal(att.id, "mailto:" + attendee.email);
     equal(att.participationStatus, "NEEDS-ACTION");
 
     newItem.removeAttendee(att);
     att = att.clone();
     att.participationStatus = "ACCEPTED";
     newItem.addAttendee(att);
 
-    let modifiedItem = yield pclient.modifyItem(newItem, items[0]);
+    yield pclient.modifyItem(newItem, items[0]);
     equal(gServer.lastMethod, "PATCH");
 
     // Case #2: User is organizer
     let events = gServer.events;
     gServer.resetClient(client);
     gServer.events = events;
 
     organizer = Object.assign({}, gServer.creator);
@@ -1370,21 +1369,16 @@ add_task(function* test_metadata() {
         "id": "MTEyMDE2MDE5NzE0NjYzMDk4ODI6MDo0MDI1NDg2NjU",
         "etag": "\"2\"",
         "title": "New Task",
         "updated": "2014-09-08T16:30:27.000Z",
         "selfLink": gServer.baseUri + "/tasks/v1/lists/MTEyMDE2MDE5NzE0NjYzMDk4ODI6MDow/tasks/MTEyMDE2MDE5NzE0NjYzMDk4ODI6MDo0MDI1NDg2NjU",
         "notes": "description"
     }];
 
-    let idToEtag = {
-        "go6ijb0b46hlpbu4eeu92njevo@google.com": '"1"',
-        "MTEyMDE2MDE5NzE0NjYzMDk4ODI6MDo0MDI1NDg2NjU": '"2"'
-    };
-
     let client = yield gServer.getClient();
     let offline = client.wrappedJSObject.mCachedCalendar;
     let pclient = cal.async.promisifyCalendar(client.wrappedJSObject);
 
     // Check initial metadata
     let items = yield pclient.getAllItems();
     let meta = getAllMeta(offline);
     let [event, task] = items;
--- a/calendar/test/unit/test_hashedarray.js
+++ b/calendar/test/unit/test_hashedarray.js
@@ -59,26 +59,16 @@ function checkConsistancy(har, testItems
                     ti.title);
         equal(itemAccessor(har.itemById(ti.hashId)).title,
                     ti.title);
         equal(har.indexOf(testItems[idx]), idx);
     }
 }
 
 /**
- * Useful for debugging, in case this test fails. Dumps the array showing the
- * title identifications.
- *
- * @param ar        The array to dump
- */
-function dumpArray(ar) {
-    dump("ARR: " + ar.map(e => e.title).toSource() + "\n");
-}
-
-/**
  * Man, this function is really hard to keep general enough, I'm almost tempted
  * to duplicate the code. It checks if the remove and modify operations work for
  * the given hashed array.
  *
  * @param har               The Hashed Array
  * @param testItems         The js array with the items
  * @param postprocessFunc   (optional) The function to call after each
  *                            operation, but before checking consistancy.
--- a/calendar/test/unit/test_ics_service.js
+++ b/calendar/test/unit/test_ics_service.js
@@ -151,17 +151,16 @@ function test_icalproperty() {
     equal(prop.value, "A\\nB");
     equal(prop.valueAsIcalString, "A\\\\nB");
     equal(prop.valueAsDatetime, null);
 }
 
 function test_icalcomponent() {
     let svc = cal.getIcsService();
     let event = svc.createIcalComponent("VEVENT");
-    let todo = svc.createIcalComponent("VTODO");
     let alarm = svc.createIcalComponent("VALARM");
     event.addSubcomponent(alarm);
 
     // Check that the parent works and does not appear on cloned instances
     let alarm2 = alarm.clone();
     equal(alarm.parent.toString(), event.toString());
     equal(alarm2.parent, null);
 
--- a/calendar/test/unit/test_ltninvitationutils.js
+++ b/calendar/test/unit/test_ltninvitationutils.js
@@ -316,17 +316,16 @@ add_task(function* createInvitationOverl
 
 add_task(function* compareInvitationOverlay_test() {
     // eventually it would make sense to set local timezone to Europe/Berlin to avoid test
     // failures when executing in a different timezone
     function getDom(aInput) {
         let item = getIcs();
         let props = ["attendee", "organizer", "dtstart", "dtend", "summary", "location"];
         for (let prop of props) {
-            let copyItem = item;
             if (Object.keys(aInput).includes(prop)) {
                 let regex = prop.toUpperCase() +
                             (["summary", "location"].includes(prop) ? ":" : ";") +
                             "[^\r]+\r\n";
                 item = item.replace(new RegExp(regex), aInput[prop]);
             }
         }
         let itipItem = Components.classes["@mozilla.org/calendar/itip-item;1"]
@@ -549,26 +548,25 @@ add_task(function* getHeaderSection_test
                   "?w6kp?=\r\n" +
                   "Cc: =?UTF-8?B?UmVuw6k=?= <cc@example.net>\r\n" +
                   "Bcc: =?UTF-8?B?UmVuw6k=?= <bcc@example.net>\r\n"
     }];
     let i = 0;
     for (let test of data) {
         i++;
         let identity = MailServices.accounts.createIdentity();
-        for (let attribute of Object.keys(test.input.identity)) {
-            identity.email = test.input.identity.email || null;
-            identity.fullName = test.input.identity.fullName || null;
-            identity.replyTo = test.input.identity.replyTo || null;
-            identity.organization = test.input.identity.organization || null;
-            identity.doCc = test.input.identity.doCc || (test.input.identity.cc);
-            identity.doCcList = test.input.identity.cc || null;
-            identity.doBcc = test.input.identity.doBcc || (test.input.identity.bcc);
-            identity.doBccList = test.input.identity.bcc || null;
-        }
+        identity.email = test.input.identity.email || null;
+        identity.fullName = test.input.identity.fullName || null;
+        identity.replyTo = test.input.identity.replyTo || null;
+        identity.organization = test.input.identity.organization || null;
+        identity.doCc = test.input.identity.doCc || (test.input.identity.cc);
+        identity.doCcList = test.input.identity.cc || null;
+        identity.doBcc = test.input.identity.doBcc || (test.input.identity.bcc);
+        identity.doBccList = test.input.identity.bcc || null;
+
         let composeUtils = Components.classes["@mozilla.org/messengercompose/computils;1"]
                                      .createInstance(Components.interfaces.nsIMsgCompUtils);
         let messageId = composeUtils.msgGenerateMessageId(identity);
 
         let header = ltn.invitation.getHeaderSection(messageId, identity,
                                                      test.input.toList, test.input.subject);
         // we test Date and Message-ID headers separately to avoid false positives
         ok(!!header.match(/Date\:.+(?:\n|\r\n|\r)/),
--- a/calendar/test/unit/test_recur.js
+++ b/calendar/test/unit/test_recur.js
@@ -14,16 +14,17 @@ function really_run_test() {
     test_interface();
     test_rrule_interface();
     test_rules();
     test_failures();
     test_limit();
     test_startdate_change();
     test_idchange();
     test_rrule_icalstring();
+    test_immutable();
 }
 
 function test_rules() {
     function check_recur(event, expected, ignoreNextOccCheck) {
         dump("Checking '" + event.getProperty("DESCRIPTION") + "'\n");
         // Get recurrence dates
         let start = createDate(1990, 0, 1);
         let end = createDate(2020, 0, 1);
@@ -697,17 +698,17 @@ function test_startdate_change() {
     }
 
     function changeBy(changeItem, dur) {
         let newDate = changeItem.startDate.clone();
         newDate.addDuration(cal.createDuration(dur));
         changeItem.startDate = newDate;
     }
 
-    let dur, ritem;
+    let ritem;
 
     // Changing an existing start date for a recurring item shouldn't either
     item = makeRecEvent("RRULE:FREQ=DAILY\r\n");
     changeBy(item, "PT1H");
 
     // Event with an rdate
     item = makeRecEvent("RDATE:20020403T114500Z\r\n");
     changeBy(item, "PT1H");
@@ -797,24 +798,24 @@ function test_failures() {
 function test_immutable() {
     item = createEventFromIcalString("BEGIN:VCALENDAR\r\n" +
         "BEGIN:VTODO\r\n" +
         "RRULE:FREQ=DAILY\r\n" +
         "END:VTODO\r\n" +
         "END:VCALENDAR\r\n"
     );
     ok(item.recurrenceInfo.isMutable);
-    let rinfo2 = item.recurrenceInfo.clone();
-    rinfo2.makeImmutable();
-    rinfo2.makeImmutable(); // Doing so twice shouldn't throw
-    throws(() => rinfo2.appendRecurrenceItem(ritem), /Can not modify immutable data container/);
-    ok(!rinfo2.isMutable);
+    let rinfo = item.recurrenceInfo.clone();
+    let ritem = cal.createRecurrenceDate();
+    rinfo.makeImmutable();
+    rinfo.makeImmutable(); // Doing so twice shouldn't throw
+    throws(() => rinfo.appendRecurrenceItem(ritem), /Can not modify immutable data container/);
+    ok(!rinfo.isMutable);
 
-    let ritem = cal.createRecurrenceDate();
-    rinfo.appenRecurrenceItem(ritem);
+    item.recurrenceInfo.appendRecurrenceItem(ritem);
 }
 
 function test_rrule_icalstring() {
     let recRule = createRecurrenceRule();
     recRule.type = "DAILY";
     recRule.interval = 4;
     equal(recRule.icalString, "RRULE:FREQ=DAILY;INTERVAL=4\r\n");
 
--- a/calendar/test/unit/test_search_service.js
+++ b/calendar/test/unit/test_search_service.js
@@ -58,17 +58,17 @@ function test_found() {
             ok(!this.called);
             this.called = true;
 
             equal(result.length, 1);
             equal(result[0].id, "test");
         }
     };
 
-    let op = search.searchForCalendars("str", HINT_EXACT_MATCH, 0, listener);
+    search.searchForCalendars("str", HINT_EXACT_MATCH, 0, listener);
     ok(listener.called);
     ok(provider2.called);
 }
 
 function test_failure() {
     search.getProviders({}).forEach(search.removeProvider, search);
 
     let provider = {
@@ -83,17 +83,17 @@ function test_failure() {
             ok(!this.called);
             this.called = true;
             equal(result.length, 0);
         }
     };
 
     search.addProvider(provider);
 
-    let op = search.searchForCalendars("str", HINT_EXACT_MATCH, 0, listener);
+    search.searchForCalendars("str", HINT_EXACT_MATCH, 0, listener);
     ok(listener.called);
 }
 
 function test_cancel() {
     search.getProviders({}).forEach(search.removeProvider, search);
 
     let provider = {
         QueryInterface: XPCOMUtils.generateQI([Components.interfaces.calICalendarSearchProvider, Components.interfaces.calIOperation]),