Bug 1142261 - Don't split interfaces between libical and ical.js. r=darktrojan
authorPhilipp Kewisch <mozilla@kewis.ch>
Thu, 12 Mar 2015 11:33:03 +0100
changeset 21936 3e65bc7a77583c968b266dfcc92ed2071c45195d
parent 21935 fcf4eb0a177d87c3e246d0d29902527d49ae25f0
child 21937 3e89f70664833d7250cd28f2c5b3dee5e2e009b9
push id1326
push usermbanner@mozilla.com
push dateMon, 30 Mar 2015 20:10:12 +0000
treeherdercomm-beta@69663dd6f687 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdarktrojan
bugs1142261
Bug 1142261 - Don't split interfaces between libical and ical.js. r=darktrojan
calendar/base/backend/icaljs/calIDateTimeJS.idl
calendar/base/backend/icaljs/calIDurationJS.idl
calendar/base/backend/icaljs/calIICSServiceJS.idl
calendar/base/backend/icaljs/calIPeriodJS.idl
calendar/base/backend/icaljs/calRecurrenceRule.js
calendar/base/backend/icaljs/icaljs.manifest
calendar/base/backend/icaljs/moz.build
calendar/base/backend/libical/build/libical.manifest
calendar/base/backend/libical/calDateTime.cpp
calendar/base/backend/libical/calDateTime.h
calendar/base/backend/libical/calDuration.cpp
calendar/base/backend/libical/calDuration.h
calendar/base/backend/libical/calICSService.cpp
calendar/base/backend/libical/calICSService.h
calendar/base/backend/libical/calIDateTime.idl
calendar/base/backend/libical/calIDuration.idl
calendar/base/backend/libical/calIICSService.idl
calendar/base/backend/libical/calIPeriod.idl
calendar/base/backend/libical/calPeriod.cpp
calendar/base/backend/libical/calPeriod.h
calendar/base/backend/libical/calRecurrenceRule.cpp
calendar/base/backend/libical/calUtils.cpp
calendar/base/backend/libical/moz.build
calendar/base/public/calIDateTime.idl
calendar/base/public/calIDuration.idl
calendar/base/public/calIICSService.idl
calendar/base/public/calIPeriod.idl
calendar/base/public/moz.build
calendar/test/unit/test_recur.js
--- a/calendar/base/backend/icaljs/calRecurrenceRule.js
+++ b/calendar/base/backend/icaljs/calRecurrenceRule.js
@@ -124,16 +124,21 @@ calRecurrenceRule.prototype = {
     get untilDate() {
         if (this.innerObject.until) {
             return new calDateTime(this.innerObject.until);
         } else {
             return null;
         }
     },
     set untilDate(val) unwrapSetter(ICAL.Time, val, function(val) {
+        if (val.timezone != ICAL.Timezone.utcTimezone &&
+            val.timezone != ICAL.Timezone.localTimezone) {
+            val = val.convertToZone(ICAL.Timezone.utcTimezone);
+        }
+
         this.innerObject.until = val;
     }, this),
 
     get isByCount() this.innerObject.isByCount(),
 
     get weekStart() this.innerObject.wkst - 1,
     set weekStart(val) this.innerObject.wkst = val + 1,
 
--- a/calendar/base/backend/icaljs/icaljs.manifest
+++ b/calendar/base/backend/icaljs/icaljs.manifest
@@ -10,10 +10,8 @@ contract @mozilla.org/calendar/ics-servi
 component {394a281f-7299-45f7-8b1f-cce21258972f} calICALJSComponents.js
 contract @mozilla.org/calendar/period;1 {394a281f-7299-45f7-8b1f-cce21258972f}
 
 component {df19281a-5389-4146-b941-798cb93a7f0d} calICALJSComponents.js
 contract @mozilla.org/calendar/recurrence-rule;1 {df19281a-5389-4146-b941-798cb93a7f0d}
 
 component {6702eb17-a968-4b43-b562-0d0c5f8e9eb5} calICALJSComponents.js
 contract @mozilla.org/calendar/timezone;1 {6702eb17-a968-4b43-b562-0d0c5f8e9eb5}
-
-interfaces caldatetime_icaljs.xpt
--- a/calendar/base/backend/icaljs/moz.build
+++ b/calendar/base/backend/icaljs/moz.build
@@ -1,17 +1,8 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-XPIDL_SOURCES += [
-    'calIDateTimeJS.idl',
-    'calIDurationJS.idl',
-    'calIICSServiceJS.idl',
-    'calIPeriodJS.idl',
-]
-
-XPIDL_MODULE = 'caldatetime_icaljs'
-
 EXTRA_COMPONENTS += [
     'calICALJSComponents.js',
 ]
--- a/calendar/base/backend/libical/build/libical.manifest
+++ b/calendar/base/backend/libical/build/libical.manifest
@@ -1,2 +1,1 @@
 #expand binary-component __SHARED_LIBRARY__
-interfaces caldatetime_libical.xpt
--- a/calendar/base/backend/libical/calDateTime.cpp
+++ b/calendar/base/backend/libical/calDateTime.cpp
@@ -19,18 +19,18 @@
 extern "C" {
 #include "ical.h"
 }
 
 #define CAL_ATTR_SET_PRE NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE)
 #define CAL_ATTR_SET_POST Normalize()
 #include "calAttributeHelpers.h"
 
-NS_IMPL_CLASSINFO(calDateTime, NULL, 0, CAL_DATETIME_CID)
-NS_IMPL_ISUPPORTS_CI(calDateTime, calIDateTime)
+NS_IMPL_CLASSINFO(calDateTime, nullptr, 0, CAL_DATETIME_CID)
+NS_IMPL_ISUPPORTS_CI(calDateTime, calIDateTime, calIDateTimeLibical)
 
 calDateTime::calDateTime()
     : mImmutable(false)
 {
     Reset();
 }
 
 calDateTime::calDateTime(icaltimetype const* atimeptr, calITimezone *tz)
@@ -163,18 +163,22 @@ calDateTime::SetNativeTime(PRTime aNativ
 
 NS_IMETHODIMP
 calDateTime::AddDuration(calIDuration *aDuration)
 {
     NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
     NS_ENSURE_ARG_POINTER(aDuration);
     ensureTimezone();
 
+    nsresult rv;
+    nsCOMPtr<calIDurationLibical> icaldur = do_QueryInterface(aDuration, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
     icaldurationtype idt;
-    aDuration->ToIcalDuration(&idt);
+    icaldur->ToIcalDuration(&idt);
 
     icaltimetype itt;
     ToIcalTime(&itt);
 
     icaltimetype const newitt = icaltime_add(itt, idt);
     FromIcalTime(&newitt, mTimezone);
 
     return NS_OK;
@@ -563,29 +567,33 @@ void calDateTime::PRTimeToIcaltime(PRTim
 }
 
 NS_IMETHODIMP
 calDateTime::Compare(calIDateTime * aOther, int32_t * aResult)
 {
     NS_ENSURE_ARG_POINTER(aOther);
     NS_ENSURE_ARG_POINTER(aResult);
 
+    nsresult rv;
+    nsCOMPtr<calIDateTimeLibical> icalother = do_QueryInterface(aOther, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
     bool otherIsDate = false;
     aOther->GetIsDate(&otherIsDate);
 
     icaltimetype a, b;
     ToIcalTime(&a);
-    aOther->ToIcalTime(&b);
+    icalother->ToIcalTime(&b);
 
     // If either this or aOther is floating, both objects are treated
     // as floating for the comparison.
     if (!a.zone || !b.zone) {
-        a.zone = NULL;
+        a.zone = nullptr;
         a.is_utc = 0;
-        b.zone = NULL;
+        b.zone = nullptr;
         b.is_utc = 0;
     }
 
     if (mIsDate || otherIsDate) {
         *aResult = icaltime_compare_date_only_tz(a, b, cal::getIcalTimezone(mTimezone));
     } else {
         *aResult = icaltime_compare(a, b);
     }
--- a/calendar/base/backend/libical/calDateTime.h
+++ b/calendar/base/backend/libical/calDateTime.h
@@ -6,25 +6,26 @@
 
 #include "calIDateTime.h"
 #include "calITimezoneProvider.h"
 #include "calUtils.h"
 
 struct icaltimetype;
 typedef struct _icaltimezone icaltimezone;
 
-class calDateTime : public calIDateTime,
+class calDateTime : public calIDateTimeLibical,
                     public cal::XpcomBase
 {
 public:
     calDateTime();
     calDateTime(icaltimetype const* icalt, calITimezone * tz);
 
     NS_DECL_ISUPPORTS
     NS_DECL_CALIDATETIME
+    NS_DECL_CALIDATETIMELIBICAL
 
 protected:
     virtual ~calDateTime() {}
     bool mImmutable;
     bool mIsValid;
     bool mIsDate;
 
     int16_t mYear;
--- a/calendar/base/backend/libical/calDuration.cpp
+++ b/calendar/base/backend/libical/calDuration.cpp
@@ -13,18 +13,18 @@
 
 #include "calUtils.h"
 
 #define SECONDS_PER_WEEK   604800
 #define SECONDS_PER_DAY     86400
 #define SECONDS_PER_HOUR     3600
 #define SECONDS_PER_MINUTE     60
 
-NS_IMPL_CLASSINFO(calDuration, NULL, 0, CAL_DURATION_CID)
-NS_IMPL_ISUPPORTS_CI(calDuration, calIDuration)
+NS_IMPL_CLASSINFO(calDuration, nullptr, 0, CAL_DURATION_CID)
+NS_IMPL_ISUPPORTS_CI(calDuration, calIDuration, calIDurationLibical)
 
 calDuration::calDuration()
     : mImmutable(false)
 {
     Reset();
 }
 
 calDuration::calDuration(const calDuration& cdt)
@@ -214,18 +214,22 @@ NS_IMETHODIMP calDuration::SetInSeconds(
     return NS_OK;
 }
 
 NS_IMETHODIMP calDuration::AddDuration(calIDuration *aDuration)
 {
     if (mImmutable)
         return NS_ERROR_CALENDAR_IMMUTABLE;
 
+    nsresult rv;
+    nsCOMPtr<calIDurationLibical> icaldur = do_QueryInterface(aDuration, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
     struct icaldurationtype idt;
-    aDuration->ToIcalDuration(&idt);
+    icaldur->ToIcalDuration(&idt);
 
     // Calculate the new absolute value of the duration
     // For two negative durations, the abs. value will increase,
     // so use + in that case.
     // Of course, also use + when both durations are positive.
     if (idt.is_neg == mDuration.is_neg) {
         mDuration.weeks   += idt.weeks;
         mDuration.days    += idt.days;
--- a/calendar/base/backend/libical/calDuration.h
+++ b/calendar/base/backend/libical/calDuration.h
@@ -7,28 +7,29 @@
 #define CALDURATION_H_
 
 #include "calIDuration.h"
 
 extern "C" {
     #include "ical.h"
 }
 
-class calDuration MOZ_FINAL : public calIDuration
+class calDuration MOZ_FINAL : public calIDurationLibical
 {
 public:
     calDuration ();
     calDuration (const calDuration& cdt);
     calDuration (const struct icaldurationtype * const aDurationPtr);
 
     // nsISupports interface
     NS_DECL_ISUPPORTS
 
     // calIDateTime interface
     NS_DECL_CALIDURATION
+    NS_DECL_CALIDURATIONLIBICAL
 
 protected:
     ~calDuration() {}
     bool mImmutable;
 
     struct icaldurationtype mDuration;
 
     void FromIcalDuration(const struct icaldurationtype * const icald);
--- a/calendar/base/backend/libical/calICSService.cpp
+++ b/calendar/base/backend/libical/calICSService.cpp
@@ -17,18 +17,18 @@ extern "C" {
 
 calIcalProperty::~calIcalProperty()
 {
     if (!mParent) {
         icalproperty_free(mProperty);
     }
 }
 
-NS_IMPL_CLASSINFO(calIcalProperty, NULL, 0, CAL_ICALPROPERTY_CID)
-NS_IMPL_ISUPPORTS_CI(calIcalProperty, calIIcalProperty)
+NS_IMPL_CLASSINFO(calIcalProperty, nullptr, 0, CAL_ICALPROPERTY_CID)
+NS_IMPL_ISUPPORTS_CI(calIcalProperty, calIIcalProperty, calIIcalPropertyLibical)
 
 NS_IMETHODIMP_(icalproperty *)
 calIcalProperty::GetLibicalProperty()
 {
     return mProperty;
 }
 
 NS_IMETHODIMP_(icalcomponent *)
@@ -107,17 +107,17 @@ calIcalProperty::SetValue(const nsACStri
     if (kind == ICAL_TEXT_VALUE) {
         icalvalue *v = icalvalue_new_text(PromiseFlatCString(str).get());
         icalproperty_set_value(mProperty, v);
     } else if (kind == ICAL_X_VALUE) {
         icalvalue *v = icalvalue_new_x(PromiseFlatCString(str).get());
         icalproperty_set_value(mProperty, v);
     } else if (kind == ICAL_ATTACH_VALUE) {
         const char *strdata = PromiseFlatCString(str).get();
-        icalattach *v = icalattach_new_from_data(strdata, NULL, NULL);
+        icalattach *v = icalattach_new_from_data(strdata, nullptr, nullptr);
         icalproperty_set_attach(mProperty, v);
     } else {
         icalproperty_set_value_from_string(mProperty,
                                            PromiseFlatCString(str).get(),
                                            icalvalue_kind_to_string(kind));
     }
     return NS_OK;
 }
@@ -769,23 +769,27 @@ calIcalProperty::SetValueAsDatetime(calI
 
 nsresult calIcalProperty::setDatetime_(calIcalComponent * parent,
                                        icalproperty * prop,
                                        calIDateTime * dt)
 {
     NS_ENSURE_ARG_POINTER(prop);
     NS_ENSURE_ARG_POINTER(dt);
 
+    nsresult rv;
+    nsCOMPtr<calIDateTimeLibical> icaldt = do_QueryInterface(dt, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
     icaltimetype itt;
-    dt->ToIcalTime(&itt);
+    icaldt->ToIcalTime(&itt);
 
     if (parent) {
         if (!itt.is_utc) {
             nsCOMPtr<calITimezone> tz;
-            nsresult rv = dt->GetTimezone(getter_AddRefs(tz));
+            rv = dt->GetTimezone(getter_AddRefs(tz));
             NS_ENSURE_SUCCESS(rv, rv);
             if (itt.zone) {
                 rv = parent->getParentVCalendarOrThis()->AddTimezoneReference(tz);
                 NS_ENSURE_SUCCESS(rv, rv);
                 icalparameter * const param = icalparameter_new_from_value_string(
                     ICAL_TZID_PARAMETER, icaltimezone_get_tzid(const_cast<icaltimezone *>(itt.zone)));
                 icalproperty_set_parameter(prop, param);
             } else { // either floating or phantom:
@@ -847,20 +851,19 @@ calIcalComponent::Get##Attrname(calIDura
         icalvalue_get_duration(icalproperty_get_value(prop));           \
     *dtp = new calDuration(&idt);                                       \
     CAL_ENSURE_MEMORY(*dtp);                                            \
     NS_ADDREF(*dtp);                                                    \
     return NS_OK;                                                       \
 }
 
 
-NS_IMPL_CLASSINFO(calIcalComponent, NULL, nsIClassInfo::THREADSAFE, CAL_ICALCOMPONENT_CID)
-NS_IMPL_ISUPPORTS(calIcalComponent, calIIcalComponent, nsIClassInfo)
-NS_IMPL_CI_INTERFACE_GETTER(calIcalComponent, calIIcalComponent)
-NS_IMPL_THREADSAFE_CI(calIcalComponent)
+
+NS_IMPL_CLASSINFO(calIcalComponent, nullptr, nsIClassInfo::THREADSAFE, CAL_ICALCOMPONENT_CID)
+NS_IMPL_ISUPPORTS_CI(calIcalComponent, calIIcalComponent, calIIcalComponentLibical)
 
 NS_IMETHODIMP_(icalcomponent *)
 calIcalComponent::GetLibicalComponent()
 {
     return mComponent;
 }
 
 NS_IMETHODIMP_(icaltimezone *)
@@ -1064,34 +1067,39 @@ calIcalComponent::Clone(calIIcalComponen
         icalcomponent_free(cloned);
         return NS_ERROR_OUT_OF_MEMORY;
     }
     NS_ADDREF(*_retval = comp);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-calIcalComponent::AddSubcomponent(calIIcalComponent *comp)
+calIcalComponent::AddSubcomponent(calIIcalComponent *aComp)
 {
-    NS_ENSURE_ARG_POINTER(comp);
+    NS_ENSURE_ARG_POINTER(aComp);
 
     /* XXX mildly unsafe assumption here.
      * To fix it, I will:
      * - check the object's classinfo to find out if I have one of my
      *   own objects, and if not
      * - use comp->serializeToICS and reparse to create a copy.
      *
      * I should probably also return the new/reused component so that the
      * caller has something it can poke at all live-like.
      */
-    calIcalComponent * const ical = toIcalComponent(comp);
+
+    nsresult rv;
+    nsCOMPtr<calIIcalComponentLibical> icalcomp = do_QueryInterface(aComp, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    calIcalComponent * const ical = toIcalComponent(icalcomp);
 
     uint32_t tzCount = 0;
     calITimezone ** timezones = nullptr;
-    nsresult rv = ical->GetReferencedTimezones(&tzCount, &timezones);
+    rv = ical->GetReferencedTimezones(&tzCount, &timezones);
     NS_ENSURE_SUCCESS(rv, rv);
 
     calIcalComponent * const vcal = getParentVCalendarOrThis();
     bool failed = false;
     for (uint32_t i = 0; i < tzCount; i++) {
         if (!failed) {
             rv = vcal->AddTimezoneReference(timezones[i]);
             if (NS_FAILED(rv))
@@ -1194,31 +1202,36 @@ calIcalComponent::GetNextProperty(const 
 
     *prop = new calIcalProperty(icalprop, this);
     CAL_ENSURE_MEMORY(*prop);
     NS_ADDREF(*prop);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-calIcalComponent::AddProperty(calIIcalProperty * prop)
+calIcalComponent::AddProperty(calIIcalProperty * aProp)
 {
-    NS_ENSURE_ARG_POINTER(prop);
+    NS_ENSURE_ARG_POINTER(aProp);
     // We assume a calIcalProperty is passed in (else the cast wouldn't run and
     // we are about to crash), so we assume that this ICS service code has created
     // the property.
-    calIcalProperty * const ical = toIcalProperty(prop);
+
+    nsresult rv;
+    nsCOMPtr<calIIcalPropertyLibical> icalprop = do_QueryInterface(aProp, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    calIcalProperty * const ical = toIcalProperty(icalprop);
     if (ical->mParent) {
         ical->mProperty = icalproperty_new_clone(ical->mProperty);
     }
     ical->mParent = this;
     icalcomponent_add_property(mComponent, ical->mProperty);
 
     nsCOMPtr<calIDateTime> dt;
-    if (NS_SUCCEEDED(prop->GetValueAsDatetime(getter_AddRefs(dt))) && dt) {
+    if (NS_SUCCEEDED(aProp->GetValueAsDatetime(getter_AddRefs(dt))) && dt) {
         // make sure timezone definition will be included:
         nsCOMPtr<calITimezone> tz;
         if (NS_SUCCEEDED(dt->GetTimezone(getter_AddRefs(tz))) && tz) {
             getParentVCalendarOrThis()->AddTimezoneReference(tz);
         }
     }
     return NS_OK;
 }
@@ -1232,20 +1245,18 @@ calIcalComponent::AddProperty(calIIcalPr
 //     NS_ENSURE_ARG_POINTER(prop);
 //     // XXX like AddSubcomponent, this is questionable
 //     calIcalProperty *ical = static_cast<calIcalProperty *>(prop);
 //     icalcomponent_remove_property(mComponent, ical->mProperty);
 //     ical->mParent = nullptr;
 //     return NS_OK;
 // }
 
-NS_IMPL_CLASSINFO(calICSService, NULL, nsIClassInfo::THREADSAFE, CAL_ICSSERVICE_CID)
-NS_IMPL_ISUPPORTS(calICSService, calIICSService, nsIClassInfo)
-NS_IMPL_CI_INTERFACE_GETTER(calICSService, calIICSService)
-NS_IMPL_THREADSAFE_CI(calICSService)
+NS_IMPL_CLASSINFO(calICSService, nullptr, nsIClassInfo::THREADSAFE, CAL_ICSSERVICE_CID)
+NS_IMPL_ISUPPORTS_CI(calICSService, calIICSService)
 
 calICSService::calICSService()
 {
 }
 
 NS_IMETHODIMP
 calICSService::ParseICS(const nsACString& serialized,
                         calITimezoneProvider *tzProvider,
--- a/calendar/base/backend/libical/calICSService.h
+++ b/calendar/base/backend/libical/calICSService.h
@@ -12,17 +12,16 @@
 #include "nsThreadUtils.h"
 #include "calUtils.h"
 
 extern "C" {
 #include "ical.h"
 }
 
 class calICSService : public calIICSService,
-                      public nsIClassInfo,
                       public cal::XpcomBase
 {
 protected:
     virtual ~calICSService() {}
     class ParserWorker : public nsRunnable {
     public:
       ParserWorker(nsIThread *mainThread,
                    nsIThread *workerThread,
@@ -45,106 +44,105 @@ protected:
       nsCOMPtr<nsIThread> mWorkerThread;
 
       class ParserWorkerCompleter : public nsRunnable {
       public:
         ParserWorkerCompleter(nsIThread *workerThread,
                               nsresult status,
                               calIIcalComponent *component,
                               const nsMainThreadPtrHandle<calIIcsComponentParsingListener> &listener) :
-          mListener(listener), mComp(component),
-          mStatus(status), mWorkerThread(workerThread)
+          mWorkerThread(workerThread), mListener(listener),
+          mComp(component), mStatus(status)
         {
         }
 
         NS_DECL_NSIRUNNABLE
       protected:
         nsCOMPtr<nsIThread> mWorkerThread;
         nsMainThreadPtrHandle<calIIcsComponentParsingListener> mListener;
         nsCOMPtr<calIIcalComponent> mComp;
         nsresult mStatus;
       };
     };
 public:
     calICSService();
 
     NS_DECL_THREADSAFE_ISUPPORTS
-    NS_DECL_NSICLASSINFO
     NS_DECL_CALIICSSERVICE
 };
 
 class calIcalComponent;
 
-class calIcalProperty : public calIIcalProperty,
+class calIcalProperty : public calIIcalPropertyLibical,
                         public cal::XpcomBase
 {
     friend class calIcalComponent;
 public:
-    calIcalProperty(icalproperty * prop, calIIcalComponent * parent)
+    calIcalProperty(icalproperty * prop, calIIcalComponentLibical * parent)
         : mProperty(prop), mParent(parent) {}
 
     NS_DECL_ISUPPORTS
     NS_DECL_CALIICALPROPERTY
+    NS_DECL_CALIICALPROPERTYLIBICAL
 
 protected:
     virtual ~calIcalProperty();
 
     static nsresult getDatetime_(calIcalComponent *parent,
                                  icalproperty *prop,
                                  calIDateTime **dtp);
     static nsresult setDatetime_(calIcalComponent *parent,
                                  icalproperty *prop,
                                  calIDateTime *dt);
 
-    icalproperty *              mProperty;
-    nsCOMPtr<calIIcalComponent> mParent;
+    icalproperty *                     mProperty;
+    nsCOMPtr<calIIcalComponentLibical> mParent;
 };
 
-class calIcalComponent : public calIIcalComponent,
-                         public nsIClassInfo,
+class calIcalComponent : public calIIcalComponentLibical,
                          public cal::XpcomBase
 {
     friend class calIcalProperty;
 public:
-    calIcalComponent(icalcomponent *ical, calIIcalComponent *parent,
+    calIcalComponent(icalcomponent *ical, calIIcalComponentLibical *parent,
                      calITimezoneProvider *tzProvider = nullptr)
         : mComponent(ical), mTimezone(nullptr), mTzProvider(tzProvider), mParent(parent)
     {
     }
 
     // VTIMEZONE ctor
     calIcalComponent(icaltimezone * icaltz, icalcomponent * ical) : mComponent(ical), mTimezone(icaltz) {
     }
 
     NS_DECL_THREADSAFE_ISUPPORTS
-    NS_DECL_NSICLASSINFO
     NS_DECL_CALIICALCOMPONENT
+    NS_DECL_CALIICALCOMPONENTLIBICAL
 
 protected:
     virtual ~calIcalComponent();
 
     calITimezoneProvider * getTzProvider() const {
         // walk up the parents to find a tz provider:
         calIcalComponent const * that = this;
         while (that) {
             calITimezoneProvider * const ret = that->mTzProvider;
             if (ret) {
                 return ret;
             }
-            calIIcalComponent * const p = that->mParent;
+            calIIcalComponentLibical * const p = that->mParent;
             that = static_cast<calIcalComponent const *>(p);
         }
         return nullptr;
     }
 
     calIcalComponent * getParentVCalendarOrThis() {
         // walk up the parents to find a VCALENDAR:
         calIcalComponent * that = this;
         while (that && icalcomponent_isa(that->mComponent) != ICAL_VCALENDAR_COMPONENT) {
-            calIIcalComponent * const p = that->mParent;
+            calIIcalComponentLibical * const p = that->mParent;
             that = static_cast<calIcalComponent *>(p);
         }
         if (!that)
             that = this;
         return that;
     }
 
     nsresult GetDateTimeAttribute(icalproperty_kind kind, calIDateTime ** dtp);
@@ -162,19 +160,19 @@ protected:
     void ClearAllProperties(icalproperty_kind kind);
 
     nsresult Serialize(char ** icalstr);
 
     nsInterfaceHashtable<nsCStringHashKey, calITimezone> mReferencedTimezones;
     icalcomponent *                                      mComponent;
     icaltimezone *                                       mTimezone; // set iff VTIMEZONE
     nsCOMPtr<calITimezoneProvider> const                 mTzProvider;
-    nsCOMPtr<calIIcalComponent>                          mParent;
+    nsCOMPtr<calIIcalComponentLibical>                   mParent;
 };
 
-inline calIcalProperty * toIcalProperty(calIIcalProperty * p) {
+inline calIcalProperty * toIcalProperty(calIIcalPropertyLibical * p) {
     return static_cast<calIcalProperty *>(p);
 }
-inline calIcalComponent * toIcalComponent(calIIcalComponent * p) {
+inline calIcalComponent * toIcalComponent(calIIcalComponentLibical * p) {
     return static_cast<calIcalComponent *>(p);
 }
 
 #endif // INCLUDED_CALICSSERVICE_H
deleted file mode 100644
--- a/calendar/base/backend/libical/calIDateTime.idl
+++ /dev/null
@@ -1,226 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-interface calIDuration;
-interface calITimezone;
-[ptr] native icaltimetypeptr(struct icaltimetype);
-
-[scriptable, uuid(04139dff-a6f0-446d-9aec-2062df887ef2)]
-interface calIDateTime : nsISupports
-{
-  /**
-   * isMutable is true if this instance is modifiable.
-   * If isMutable is false, any attempts to modify
-   * the object will throw NS_ERROR_OBJECT_IS_IMMUTABLE.
-   */
-  readonly attribute boolean isMutable;
-
-  /**
-   * Make this calIDateTime instance immutable.
-   */
-  void makeImmutable();
-
-  /**
-   * Clone this calIDateTime instance into a new
-   * mutable object.
-   */
-  calIDateTime clone();
-
-  /**
-   * valid is true if this object contains a valid
-   * time/date.
-   */
-  // true if this thing is set/valid
-  readonly attribute boolean isValid;
-
-  /**
-   * nativeTime contains this instance's PRTime value relative
-   * to the UTC epoch, regardless of the timezone that's set
-   * on this instance.  If nativeTime is set, the given UTC PRTime
-   * value is exploded into year/month/etc, forcing the timezone
-   * setting to UTC.
-   *
-   * @warning: When the timezone is set to 'floating', this will return
-   * the nativeTime as-if the timezone was UTC. Take this into account
-   * when comparing values.
-   *
-   * @note on objects that are pinned to a timezone and have isDate set,
-   * nativeTime will be 00:00:00 in the timezone of that date, not 00:00:00 in
-   * UTC.
-   */
-  attribute PRTime nativeTime;
-
-  /**
-   * Full 4-digit year value (e.g. "1989", "2004")
-   */
-  attribute short year;
-
-  /**
-   * Month, 0-11, 0 = January
-   */
-  attribute short month;
-
-  /**
-   * Day of month, 1-[28,29,30,31]
-   */
-  attribute short day;
-
-  /**
-   * Hour, 0-23
-   */
-  attribute short hour;
-
-  /**
-   * Minute, 0-59
-   */
-  attribute short minute;
-
-  /**
-   * Second, 0-59
-   */
-  attribute short second;
-
-  /**
-   * Gets or sets the timezone of this calIDateTime instance.
-   * Setting the timezone does not change the actual date/time components;
-   * to convert between timezones, use getInTimezone().
-   *
-   * @throws NS_ERROR_INVALID_ARG if null is passed in.
-   */
-  attribute calITimezone timezone;
-
-  /**
-   * Resets the datetime object.
-   *
-   * @param year     full 4-digit year value (e.g. "1989", "2004")
-   * @param month    month, 0-11, 0 = January
-   * @param day      day of month, 1-[28,29,31]
-   * @param hour     hour, 0-23
-   * @param minute   minute, 0-59
-   * @param second   decond, 0-59
-   * @param timezone timezone
-   *
-   * The passed datetime will be normalized, e.g. a minute value of 60 will
-   * increase the hour.
-   *
-   * @throws NS_ERROR_INVALID_ARG if no timezone is passed in.
-   */
-  void resetTo(in short year,
-               in short month,
-               in short day,
-               in short hour,
-               in short minute,
-               in short second,
-               in calITimezone timezone);
-
-  /**
-   * The offset of the timezone this datetime is in, relative to UTC, in
-   * seconds. A positive number means that the timezone is ahead of UTC.
-   */
-  readonly attribute long timezoneOffset;
-
-  /**
-   * isDate indicates that this calIDateTime instance represents a date
-   * (a whole day), and not a specific time on that day.  If isDate is set,
-   * accessing the hour/minute/second fields will return 0, and and setting
-   * them is an illegal operation.
-   */
-  attribute boolean isDate;
-
-  /*
-   * computed values
-   */
-
-  /**
-   * Day of the week. 0-6, with Sunday = 0.
-   */
-  readonly attribute short weekday;
-
-  /**
-   * Day of the year, 1-[365,366].
-   */
-  readonly attribute short yearday;
-
-  /*
-   * Methods
-   */
-
-  /**
-   * Resets this instance to Jan 1, 1970 00:00:00 UTC.
-   */
-  void reset();
-
-  /**
-   * Return a string representation of this instance.
-   */
-  AUTF8String toString();
-
-  /**
-   * Return a new calIDateTime instance that's the result of
-   * converting this one into the given timezone.  Valid values
-   * for aTimezone are the same as the timezone field.  If
-   * the "floating" timezone is given, then this object
-   * is just cloned, and the timezone is set to floating.
-   */
-  calIDateTime getInTimezone(in calITimezone aTimezone);
-
-  // add the given calIDateTime, treating it as a duration, to
-  // this item.
-  // XXX will change
-  void addDuration (in calIDuration aDuration);
-
-  // Subtract two dates and return a duration
-  // returns duration of this - aOtherDate
-  // if aOtherDate is > this the duration will be negative
-  calIDuration subtractDate (in calIDateTime aOtherDate);
-
-  /**
-   * Compare this calIDateTime instance to aOther.  Returns -1, 0, 1 to
-   * indicate if this < aOther, this == aOther, or this > aOther,
-   * respectively.
-   *
-   * This comparison is timezone-aware; the given values are converted
-   * to a common timezone before comparing. If either this or aOther is
-   * floating, both objects are treated as floating for the comparison.
-   *
-   * If either this or aOther has isDate set, then only the date portion is
-   * compared.
-   *
-   * @exception calIErrors.INVALID_TIMEZONE  bad timezone on this object
-   *                                         (not the argument object)
-   */
-  long compare (in calIDateTime aOther);
-
-  //
-  // Some helper getters for calculating useful ranges
-  //
-
-  /**
-   * Returns SUNDAY of the given datetime object's week.
-   */
-  readonly attribute calIDateTime startOfWeek;
-
-  /**
-   * Returns SATURDAY of the datetime object's week.
-   */
-  readonly attribute calIDateTime endOfWeek;
-
-  // the start/end of the current object's month
-  readonly attribute calIDateTime startOfMonth;
-  readonly attribute calIDateTime endOfMonth;
-
-  // the start/end of the current object's year
-  readonly attribute calIDateTime startOfYear;
-  readonly attribute calIDateTime endOfYear;
-
-  [noscript,notxpcom] void toIcalTime(in icaltimetypeptr itt);
-
-  /**
-   * This object as either an iCalendar DATE or DATETIME string, as
-   * appropriate and sets the timezone to either UTC or floating.
-   */
-  attribute ACString icalString;
-};
deleted file mode 100644
--- a/calendar/base/backend/libical/calIDuration.idl
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- Mode: idl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-#include "nsISupports.idl"
-
-[ptr] native icaldurationtypeptr(struct icaldurationtype);
-
-[scriptable, uuid(f5e1c987-e722-4dec-bf91-93d4062b504a)]
-interface calIDuration : nsISupports
-{
-  /**
-   * isMutable is true if this instance is modifiable.
-   * If isMutable is false, any attempts to modify
-   * the object will throw CAL_ERROR_ITEM_IS_MUTABLE.
-   */
-  readonly attribute boolean isMutable;
-
-  /**
-   * Make this calIDuration instance immutable.
-   */
-  void makeImmutable();
-
-  /**
-   * Clone this calIDuration instance into a new
-   * mutable object.
-   */
-  calIDuration clone();
-
-  /**
-   * Is Negative
-   */
-  attribute boolean isNegative;
-
-  /**
-   * Weeks
-   */
-  attribute short weeks;
-
-  /**
-   * Days
-   */
-  attribute short days;
-
-  /**
-   * Hours
-   */
-  attribute short hours;
-
-  /**
-   * Minutes
-   */
-  attribute short minutes;
-
-  /**
-   * Seconds
-   */
-  attribute short seconds;
-
-  /**
-   * total duration in seconds
-   */
-  attribute long inSeconds;
-
-  /*
-   * Methods
-   */
-
-  /**
-   * Add a duration
-   */
-  void addDuration(in calIDuration aDuration);
-
-  /**
-   * Compare with another duration
-   *
-   * @param    aOther     to be compared with this object
-   * 
-   * @return   -1, 0, 1 if this < aOther, this == aOther, or this > aOther,
-   *           respectively.
-   */
-  long compare(in calIDuration aOther);
-
-  /**
-   * Reset this duration to 0
-   */
-  void reset();
-
-  /**
-   * Normalize the duration
-   */
-  void normalize();
-
-  /**
-   * Return a string representation of this instance.
-   */
-  AUTF8String toString();
-
-  [noscript,notxpcom] void toIcalDuration(in icaldurationtypeptr idt);
-  attribute jsval icalDuration;
-
-  /**
-   * This object as an iCalendar DURATION string
-   */
-  attribute ACString icalString;
-};
deleted file mode 100644
--- a/calendar/base/backend/libical/calIICSService.idl
+++ /dev/null
@@ -1,270 +0,0 @@
-/* -*- Mode: idl; 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/. */
-
-// XXX use strings for kind values instead of enumerated constants?
-
-
-#include "nsISupports.idl"
-
-interface calIItemBase;
-interface calIDateTime;
-interface calIDuration;
-interface calITimezone;
-interface calITimezoneProvider;
-
-interface calIIcalProperty;
-interface nsIUTF8StringEnumerator;
-interface nsIInputStream;
-
-[ptr] native icalpropertyptr(struct icalproperty_impl);
-[ptr] native icalcomponentptr(struct icalcomponent_impl);
-[ptr] native icaltimezoneptr(struct _icaltimezone);
-
-/**
- * General notes:
- *
- * As with libical, use of getNextFoo(footype) is only valid if there have been
- * no intervening getNextFoo(otherfootype)s, or removeFoo()s, or addFoo()s. In
- * general, you want to do as little manipulation of your FooContainers as
- * possible while iterating over them.
- */
-[scriptable,uuid(d2fc0264-191e-435e-8ef2-b2ab1fa81ca9)]
-interface calIIcalComponent : nsISupports
-{
-    /**
-     * The parent ical property
-     */
-    readonly attribute calIIcalComponent parent;
-
-    /**
-     * Access to the inner ical.js objects. Only use these if you know what you
-     * are doing.
-     */
-    attribute jsval icalComponent;
-    attribute jsval icalTimezone;
-
-    /**
-     * This is the value that an integer-valued getter will provide if
-     * there is no such property on the wrapped ical structure.
-     */
-    const int32_t INVALID_VALUE = -1;
-
-    /**
-     * @param kind ANY, XROOT, VCALENDAR, VEVENT, etc.
-     */
-    calIIcalComponent getFirstSubcomponent(in AUTF8String componentType);
-    calIIcalComponent getNextSubcomponent(in AUTF8String componentType);
-
-    readonly attribute AUTF8String componentType;
-
-    attribute AUTF8String uid;
-    attribute AUTF8String prodid;
-    attribute AUTF8String version;
-
-    /**
-     * PUBLISH, REQUEST, REPLY, etc.
-     */
-    attribute AUTF8String method;
-
-    /**
-     * TENTATIVE, CONFIRMED, CANCELLED, etc.
-     */
-    attribute AUTF8String status;
-
-    attribute AUTF8String summary;
-    attribute AUTF8String description;
-    attribute AUTF8String location;
-    attribute AUTF8String categories;
-    attribute AUTF8String URL;
-
-    attribute int32_t priority;
-
-    attribute calIDateTime startTime;
-    attribute calIDateTime endTime;
-    readonly attribute calIDuration duration;
-    attribute calIDateTime dueTime;
-    attribute calIDateTime stampTime;
-
-    attribute calIDateTime createdTime;
-    attribute calIDateTime completedTime;
-    attribute calIDateTime lastModified;
-
-    /**
-     * The recurrence ID, a.k.a. DTSTART-of-calculated-occurrence,
-     * or null if this isn't an occurrence.
-     */
-    attribute calIDateTime recurrenceId;
-
-    AUTF8String serializeToICS();
-
-    /**
-     * Return a string representation of this instance.
-     */
-    AUTF8String toString();
-
-    /**
-     * Serializes this component (and subcomponents) directly to an
-     * input stream.  Typically used for performance to avoid
-     * unnecessary conversions and XPConnect traversals.
-     *
-     * @result     an input stream which can be read to get the serialized
-     *             version of this component, encoded in UTF-8.  Implements
-     *             nsISeekableStream so that it can be used with
-     *             nsIUploadChannel.
-     */
-    nsIInputStream serializeToICSStream();
-
-    void addSubcomponent(in calIIcalComponent comp);
-// If you add then remove a property/component, the referenced
-// timezones won't get purged out. There's currently no client code.
-//     void removeSubcomponent(in calIIcalComponent comp);
-
-    /**
-     * @param kind ANY, ATTENDEE, X-WHATEVER, etc.
-     */
-    calIIcalProperty getFirstProperty(in AUTF8String kind);
-    calIIcalProperty getNextProperty(in AUTF8String kind);
-    void addProperty(in calIIcalProperty prop);
-// If you add then remove a property/component, the referenced
-// timezones won't get purged out. There's currently no client code.
-//     void removeProperty(in calIIcalProperty prop);
-
-    /**
-     * Timezones need special handling, as they must be
-     * emitted as children of VCALENDAR, but can be referenced by
-     * any sub component.
-     * Adding a second timezone (of the same TZID) will remove the
-     * first one.
-     */
-    void addTimezoneReference(in calITimezone aTimezone);
-
-    /**
-     * Returns an array of VTIMEZONE components.
-     * These are the timezones that are in use by this
-     * component and its children.
-     */
-    void getReferencedTimezones(out uint32_t aCount,
-                                [array,size_is(aCount),retval] out calITimezone aTimezones);
-
-    /**
-     * Clones the component. The cloned component is decoupled from any parent.
-     * @return cloned component
-     */
-    calIIcalComponent clone();
-
-    [noscript,notxpcom] icalcomponentptr getLibicalComponent();
-    [noscript,notxpcom] icaltimezoneptr getLibicalTimezone();
-};
-
-[scriptable,uuid(e0b9067f-0a53-4724-9c69-63599681877e)]
-interface calIIcalProperty : nsISupports
-{
-    /**
-     * The whole property as an ical string.
-     * @exception Any libical error will be thrown as an calIError::ICS_ error.
-     */
-    readonly attribute AUTF8String icalString;
-
-    /**
-     * Access to the inner ical.js objects. Only use these if you know what you
-     * are doing.
-     */
-    attribute jsval icalProperty;
-
-    /**
-     * The parent component containing this property
-     */
-    readonly attribute calIIcalComponent parent;
-
-    /**
-     * Return a string representation of this instance.
-     */
-    AUTF8String toString();
-
-    /**
-     * The value of the property as string.
-     * The exception for properties of TEXT or X- type, those will be unescaped
-     * when getting, and also expects an unescaped string when setting.
-     * Datetime, numeric and other non-text types are represented as ical string
-     */
-    attribute AUTF8String value;
-
-    /**
-     * The value of the property in (escaped) ical format.
-     */
-    attribute AUTF8String valueAsIcalString;
-
-    /**
-     * The value of the property as date/datetime value, keeping
-     * track of the used timezone referenced in the owning component.
-     */
-    attribute calIDateTime valueAsDatetime;
-
-    // XXX attribute AUTF8String stringValueWithParams; ?
-    readonly attribute AUTF8String propertyName;
-
-    AUTF8String getParameter(in AUTF8String paramname);
-    void setParameter(in AUTF8String paramname, in AUTF8String paramval);
-
-    AUTF8String getFirstParameterName();
-    AUTF8String getNextParameterName();
-
-    void removeParameter(in AUTF8String paramname);
-    void clearXParameters();
-
-    [noscript,notxpcom] icalpropertyptr getLibicalProperty();
-    [noscript,notxpcom] icalcomponentptr getLibicalComponent();
-};
-
-[scriptable,uuid(131b419f-1373-4013-b470-5359aaff4049)]
-interface calIIcsComponentParsingListener : nsISupports
-{
-    /**
-     * Called when the parsing has completed.
-     *
-     * @param rc            The result code of parsing
-     * @param rootComp      The root ical component that was parsed
-     */
-    void onParsingComplete(in nsresult rc, in calIIcalComponent rootComp);
-};
-
-[scriptable,uuid(fea79ff8-07ba-46ae-ac92-7f9d8c49c9d2)]
-interface calIICSService : nsISupports
-{
-    /**
-     * Parses an ICS string and uses the passed tzProvider instance to
-     * resolve timezones not contained withing the VCALENDAR.
-     *
-     * @param serialized     an ICS string
-     * @param tzProvider     timezone provider used to resolve TZIDs
-     *                       not contained within the VCALENDAR;
-     *                       if null is passed, parsing falls back to
-     *                       using the timezone service
-     */
-    calIIcalComponent parseICS(in AUTF8String serialized,
-                               in calITimezoneProvider tzProvider);
-
-    /**
-     * Asynchronously parse an ICS string
-     *
-     * @param serialized     an ICS string
-     * @param tzProvider     timezone provider used to resolve TZIDs
-     *                       not contained within the VCALENDAR;
-     *                       if null is passed, parsing falls back to
-     *                       using the timezone service
-     * @param listener       The listener that notifies the root component
-     */
-    void parseICSAsync(in AUTF8String serialized,
-                       in calITimezoneProvider tzProvider,
-                       in calIIcsComponentParsingListener listener);
-
-    calIIcalComponent createIcalComponent(in AUTF8String kind);
-    calIIcalProperty createIcalProperty(in AUTF8String kind);
-    calIIcalProperty createIcalPropertyFromString(in AUTF8String str);
-    /* I wish I could write this function atop libical!
-    boolean isLegalParameterValue(in AUTF8String paramKind,
-                                  in AUTF8String paramValue);
-    */
-};
deleted file mode 100644
--- a/calendar/base/backend/libical/calIPeriod.idl
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-interface calIDateTime;
-interface calIDuration;
-
-[ptr] native icalperiodtypeptr(struct icalperiodtype);
-
-[scriptable,uuid(04ee525f-96db-4731-8d61-688e754df24f)]
-interface calIPeriod : nsISupports
-{
-  attribute jsval icalPeriod;
-
-  /**
-   * isMutable is true if this instance is modifiable.
-   * If isMutable is false, any attempts to modify
-   * the object will throw NS_ERROR_OBJECT_IS_IMMUTABLE.
-   */
-  readonly attribute boolean isMutable;
-
-  /**
-   * Make this calIPeriod instance immutable.
-   */
-  void makeImmutable();
-
-  /**
-   * Clone this calIPeriod instance into a new
-   * mutable object.
-   */
-  calIPeriod clone();
-
-  /**
-   * The start datetime of this period
-   */
-  attribute calIDateTime start;
-
-  /**
-   * The end datetime of this period
-   */
-  attribute calIDateTime end;
-
-  /**
-   * The duration, equal to end-start
-   */
-  readonly attribute calIDuration duration;
-
-
-  /**
-   * Return a string representation of this instance.
-   */
-  AUTF8String toString();
-
-  [noscript,notxpcom] void toIcalPeriod(in icalperiodtypeptr idt);
-
-  /**
-   * This object as an iCalendar DURATION string
-   */
-  attribute ACString icalString;
-};
--- a/calendar/base/backend/libical/calPeriod.cpp
+++ b/calendar/base/backend/libical/calPeriod.cpp
@@ -5,31 +5,37 @@
 
 #include "calPeriod.h"
 #include "calBaseCID.h"
 
 #include "nsIClassInfoImpl.h"
 
 #include "calUtils.h"
 
-NS_IMPL_CLASSINFO(calPeriod, NULL, 0, CAL_PERIOD_CID)
-NS_IMPL_ISUPPORTS_CI(calPeriod, calIPeriod)
+NS_IMPL_CLASSINFO(calPeriod, nullptr, 0, CAL_PERIOD_CID)
+NS_IMPL_ISUPPORTS_CI(calPeriod, calIPeriod, calIPeriodLibical)
 
 calPeriod::calPeriod()
     : mImmutable(false)
 {
 }
 
 calPeriod::calPeriod(const calPeriod& cpt)
     : mImmutable(false)
 {
-    if (cpt.mStart)
-        cpt.mStart->Clone(getter_AddRefs(mStart));
-    if (cpt.mEnd)
-        cpt.mEnd->Clone(getter_AddRefs(mEnd));
+    if (cpt.mStart) {
+        nsCOMPtr<calIDateTime> start;
+        cpt.mStart->Clone(getter_AddRefs(start));
+        mStart = do_QueryInterface(start);
+    }
+    if (cpt.mEnd) {
+        nsCOMPtr<calIDateTime> end;
+        cpt.mEnd->Clone(getter_AddRefs(end));
+        mEnd = do_QueryInterface(end);
+    }
 }
 
 calPeriod::calPeriod(struct icalperiodtype const* aPeriodPtr)
     : mImmutable(false)
 {
     FromIcalPeriod(aPeriodPtr);
 }
 
@@ -82,34 +88,34 @@ NS_IMETHODIMP calPeriod::GetStart(calIDa
     return NS_OK;
 }
 NS_IMETHODIMP calPeriod::SetStart(calIDateTime *aValue)
 {
     NS_ENSURE_ARG_POINTER(aValue);
     if (mImmutable)
         return NS_ERROR_OBJECT_IS_IMMUTABLE;
 
-    mStart = aValue;
+    mStart = do_QueryInterface(aValue);
     return mStart->MakeImmutable();
 }
 
 NS_IMETHODIMP calPeriod::GetEnd(calIDateTime **_retval)
 {
     NS_ENSURE_ARG_POINTER(_retval);
     *_retval = mEnd;
     NS_IF_ADDREF(*_retval);
     return NS_OK;
 }
 NS_IMETHODIMP calPeriod::SetEnd(calIDateTime *aValue)
 {
     NS_ENSURE_ARG_POINTER(aValue);
     if (mImmutable)
         return NS_ERROR_OBJECT_IS_IMMUTABLE;
 
-    mEnd = aValue;
+    mEnd = do_QueryInterface(aValue);
     return mEnd->MakeImmutable();
 }
 
 NS_IMETHODIMP calPeriod::GetDuration(calIDuration **_retval)
 {
     NS_ENSURE_ARG_POINTER(_retval);
     if (!mStart || !mEnd)
         return NS_ERROR_UNEXPECTED;
--- a/calendar/base/backend/libical/calPeriod.h
+++ b/calendar/base/backend/libical/calPeriod.h
@@ -11,36 +11,37 @@
 #include "calIPeriod.h"
 #include "calDateTime.h"
 #include "calIDuration.h"
 
 extern "C" {
     #include "ical.h"
 }
 
-class calPeriod MOZ_FINAL : public calIPeriod
+class calPeriod MOZ_FINAL : public calIPeriodLibical
 {
 public:
     calPeriod ();
     explicit calPeriod (const calPeriod& cpt);
     explicit calPeriod (struct icalperiodtype const* aPeriodPtr);
 
     // nsISupports interface
     NS_DECL_ISUPPORTS
 
     // calIPeriod interface
     NS_DECL_CALIPERIOD
+    NS_DECL_CALIPERIODLIBICAL
 
 protected:
     ~calPeriod() {}
     calPeriod const& operator=(calPeriod const&);
 
     bool mImmutable;
 
     //struct icaldurationtype mPeriod;
-    nsCOMPtr<calIDateTime> mStart;
-    nsCOMPtr<calIDateTime> mEnd;
+    nsCOMPtr<calIDateTimeLibical> mStart;
+    nsCOMPtr<calIDateTimeLibical> mEnd;
     
     void FromIcalPeriod(struct icalperiodtype const* icalp);
 };
 
 #endif /* CALPERIOD_H_ */
 
--- a/calendar/base/backend/libical/calRecurrenceRule.cpp
+++ b/calendar/base/backend/libical/calRecurrenceRule.cpp
@@ -192,27 +192,35 @@ calRecurrenceRule::GetUntilDate(calIDate
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
 calRecurrenceRule::SetUntilDate(calIDateTime * aRecurEnd)
 {
     if (aRecurEnd) {
-        nsCOMPtr<calIDateTime> dt(aRecurEnd);
+        nsresult rv;
+        bool b;
+        nsCOMPtr<calIDateTimeLibical> icaldt;
         nsCOMPtr<calITimezone> tz;
         aRecurEnd->GetTimezone(getter_AddRefs(tz));
-        bool b;
+
         if (NS_SUCCEEDED(tz->GetIsUTC(&b)) && !b &&
             NS_SUCCEEDED(tz->GetIsFloating(&b)) && !b) {
             // convert to UTC:
+            nsCOMPtr<calIDateTime> dt;
             aRecurEnd->GetInTimezone(cal::UTC(), getter_AddRefs(dt));
+            icaldt = do_QueryInterface(dt, &rv);
+        } else {
+            icaldt = do_QueryInterface(aRecurEnd, &rv);
         }
+
+        NS_ENSURE_SUCCESS(rv, rv);
         struct icaltimetype itt;
-        dt->ToIcalTime(&itt);
+        icaldt->ToIcalTime(&itt);
 
         mIcalRecur.until = itt;
     } else {
         mIcalRecur.until = icaltime_null_time();
     }
 
     mIcalRecur.count = 0;
 
@@ -330,21 +338,29 @@ NS_IMETHODIMP
 calRecurrenceRule::GetNextOccurrence(calIDateTime *aStartTime,
                                      calIDateTime *aOccurrenceTime,
                                      calIDateTime **_retval)
 {
     NS_ENSURE_ARG_POINTER(aStartTime);
     NS_ENSURE_ARG_POINTER(aOccurrenceTime);
     NS_ENSURE_ARG_POINTER(_retval);
 
+    nsresult rv;
+
+    nsCOMPtr<calIDateTimeLibical> icaldtstart = do_QueryInterface(aStartTime, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsCOMPtr<calIDateTimeLibical> icaloccurtime = do_QueryInterface(aOccurrenceTime, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
     struct icaltimetype dtstart;
-    aStartTime->ToIcalTime(&dtstart);
+    icaldtstart->ToIcalTime(&dtstart);
 
     struct icaltimetype occurtime;
-    aOccurrenceTime->ToIcalTime(&occurtime);
+    icaloccurtime->ToIcalTime(&occurtime);
 
     icalrecur_iterator* recur_iter;
     recur_iter = icalrecur_iterator_new(mIcalRecur, dtstart);
     if (!recur_iter)
         return NS_ERROR_OUT_OF_MEMORY;
 
     struct icaltimetype next = icalrecur_iterator_next(recur_iter);
     while (!icaltime_is_null_time(next)) {
@@ -406,25 +422,35 @@ calRecurrenceRule::GetOccurrences(calIDa
         char const * const ss = icalrecurrencetype_as_string(&mIcalRecur);
         nsAutoCString tst, tend;
         aRangeStart->ToString(tst);
         aRangeEnd->ToString(tend);
         printf("RULE: [%s -> %s, %d]: %s\n", tst.get(), tend.get(), mIcalRecur.count, ss);
     }
 #endif
 
+    nsresult rv;
+
+    nsCOMPtr<calIDateTimeLibical> icalrangestart = do_QueryInterface(aRangeStart, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+    nsCOMPtr<calIDateTimeLibical> icaldtstart = do_QueryInterface(aStartTime, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
     struct icaltimetype rangestart, dtstart, dtend;
-    aRangeStart->ToIcalTime(&rangestart);
+    icalrangestart->ToIcalTime(&rangestart);
     rangestart = ensureDateTime(rangestart);
-    aStartTime->ToIcalTime(&dtstart);
+    icaldtstart->ToIcalTime(&dtstart);
     nsCOMPtr<calITimezone> tz;
     aStartTime->GetTimezone(getter_AddRefs(tz));
 
     if (aRangeEnd) {
-        aRangeEnd->ToIcalTime(&dtend);
+        nsCOMPtr<calIDateTimeLibical> icalrangeend = do_QueryInterface(aRangeEnd, &rv);
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        icalrangeend->ToIcalTime(&dtend);
         dtend = ensureDateTime(dtend);
 
         // if the start of the recurrence is past the end,
         // we have no dates
         if (icaltime_compare (dtstart, dtend) >= 0) {
             *aDates = nullptr;
             *aCount = 0;
             return NS_OK;
@@ -507,33 +533,37 @@ calRecurrenceRule::GetIcalProperty(calII
     NS_ADDREF(*prop);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 calRecurrenceRule::SetIcalProperty(calIIcalProperty *aProp)
 {
     NS_ENSURE_ARG_POINTER(aProp);
+    nsresult rv;
+
+    nsCOMPtr<calIIcalPropertyLibical> icalprop = do_QueryInterface(aProp, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
 
     if (mImmutable)
         return NS_ERROR_OBJECT_IS_IMMUTABLE;
 
     nsAutoCString propname;
-    nsresult rv = aProp->GetPropertyName(propname);
+    rv = aProp->GetPropertyName(propname);
     NS_ENSURE_SUCCESS(rv, rv);
     if (propname.EqualsLiteral("RRULE")) {
         mIsNegative = false;
     } else {
         return NS_ERROR_INVALID_ARG;
     }
 
     icalproperty *prop;
     struct icalrecurrencetype icalrecur;
 
-    prop = aProp->GetLibicalProperty();
+    prop = icalprop->GetLibicalProperty();
 
     icalrecur = icalproperty_get_rrule(prop);
 
     // XXX Note that we ignore the dtstart and use the one from the
     // event, though I realize now that we shouldn't.  Ignoring
     // dtstart makes it impossible to have multiple RRULEs on one
     // event that start at different times (e.g. every day starting on
     // jan 1 for 2 weeks, every other day starting on feb 1 for 2
--- a/calendar/base/backend/libical/calUtils.cpp
+++ b/calendar/base/backend/libical/calUtils.cpp
@@ -75,17 +75,18 @@ icaltimezone * getIcalTimezone(calITimez
     bool b;
     tz->GetIsUTC(&b);
     if (b) {
         icaltz = icaltimezone_get_utc_timezone();
     } else {
         nsCOMPtr<calIIcalComponent> tzComp;
         tz->GetIcalComponent(getter_AddRefs(tzComp));
         if (tzComp) {
-            icaltz = tzComp->GetLibicalTimezone();
+            nsCOMPtr<calIIcalComponentLibical> tzCompLibical = do_QueryInterface(tzComp);
+            icaltz = tzCompLibical->GetLibicalTimezone();
         } // else floating or phantom timezone
     }
     return icaltz;
 }
 
 XpcomBase::~XpcomBase() {
 }
 
--- a/calendar/base/backend/libical/moz.build
+++ b/calendar/base/backend/libical/moz.build
@@ -2,25 +2,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/.
 
 DIRS = [
     'build'
 ]
 
-XPIDL_SOURCES += [
-    'calIDateTime.idl',
-    'calIDuration.idl',
-    'calIICSService.idl',
-    'calIPeriod.idl',
-]
-
-XPIDL_MODULE = 'caldatetime_libical'
-
 SOURCES += [
     'calDateTime.cpp',
     'calDuration.cpp',
     'calICSService.cpp',
     'calPeriod.cpp',
     'calRecurrenceRule.cpp',
     'calTimezone.cpp',
     'calUtils.cpp',
rename from calendar/base/backend/icaljs/calIDateTimeJS.idl
rename to calendar/base/public/calIDateTime.idl
--- a/calendar/base/backend/icaljs/calIDateTimeJS.idl
+++ b/calendar/base/public/calIDateTime.idl
@@ -216,8 +216,17 @@ interface calIDateTime : nsISupports
   readonly attribute calIDateTime endOfYear;
 
   /**
    * This object as either an iCalendar DATE or DATETIME string, as
    * appropriate and sets the timezone to either UTC or floating.
    */
   attribute ACString icalString;
 };
+
+/** Libical specific interfaces */
+
+[ptr] native icaltimetypeptr(struct icaltimetype);
+[scriptable, uuid(04139dff-a6f0-446d-9aec-2062df887ef2)]
+interface calIDateTimeLibical : calIDateTime
+{
+  [noscript,notxpcom] void toIcalTime(in icaltimetypeptr itt);
+};
rename from calendar/base/backend/icaljs/calIDurationJS.idl
rename to calendar/base/public/calIDuration.idl
--- a/calendar/base/backend/icaljs/calIDurationJS.idl
+++ b/calendar/base/public/calIDuration.idl
@@ -97,8 +97,17 @@ interface calIDuration : nsISupports
 
   attribute jsval icalDuration;
 
   /**
    * This object as an iCalendar DURATION string
    */
   attribute ACString icalString;
 };
+
+/** Libical specific interfaces */
+
+[ptr] native icaldurationtypeptr(struct icaldurationtype);
+[scriptable, uuid(f5e1c987-e722-4dec-bf91-93d4062b504a)]
+interface calIDurationLibical : calIDuration
+{
+  [noscript,notxpcom] void toIcalDuration(in icaldurationtypeptr idt);
+};
rename from calendar/base/backend/icaljs/calIICSServiceJS.idl
rename to calendar/base/public/calIICSService.idl
--- a/calendar/base/backend/icaljs/calIICSServiceJS.idl
+++ b/calendar/base/public/calIICSService.idl
@@ -253,8 +253,28 @@ interface calIICSService : nsISupports
     calIIcalComponent createIcalComponent(in AUTF8String kind);
     calIIcalProperty createIcalProperty(in AUTF8String kind);
     calIIcalProperty createIcalPropertyFromString(in AUTF8String str);
     /* I wish I could write this function atop libical!
     boolean isLegalParameterValue(in AUTF8String paramKind,
                                   in AUTF8String paramValue);
     */
 };
+
+/** Libical specific interfaces */
+
+[ptr] native icalpropertyptr(struct icalproperty_impl);
+[ptr] native icalcomponentptr(struct icalcomponent_impl);
+[ptr] native icaltimezoneptr(struct _icaltimezone);
+
+[scriptable,uuid(d2fc0264-191e-435e-8ef2-b2ab1fa81ca9)]
+interface calIIcalComponentLibical : calIIcalComponent
+{
+    [noscript,notxpcom] icalcomponentptr getLibicalComponent();
+    [noscript,notxpcom] icaltimezoneptr getLibicalTimezone();
+};
+
+[scriptable,uuid(e0b9067f-0a53-4724-9c69-63599681877e)]
+interface calIIcalPropertyLibical : calIIcalProperty
+{
+    [noscript,notxpcom] icalpropertyptr getLibicalProperty();
+    [noscript,notxpcom] icalcomponentptr getLibicalComponent();
+};
rename from calendar/base/backend/icaljs/calIPeriodJS.idl
rename to calendar/base/public/calIPeriod.idl
--- a/calendar/base/backend/icaljs/calIPeriodJS.idl
+++ b/calendar/base/public/calIPeriod.idl
@@ -51,8 +51,17 @@ interface calIPeriod : nsISupports
    */
   AUTF8String toString();
 
   /**
    * This object as an iCalendar DURATION string
    */
   attribute ACString icalString;
 };
+
+/** Libical specific interfaces */
+
+[ptr] native icalperiodtypeptr(struct icalperiodtype);
+[scriptable,uuid(04ee525f-96db-4731-8d61-688e754df24f)]
+interface calIPeriodLibical : calIPeriod
+{
+  [noscript,notxpcom] void toIcalPeriod(in icalperiodtypeptr idt);
+};
--- a/calendar/base/public/moz.build
+++ b/calendar/base/public/moz.build
@@ -11,28 +11,32 @@ XPIDL_SOURCES += [
     'calICalendar.idl',
     'calICalendarACLManager.idl',
     'calICalendarManager.idl',
     'calICalendarProvider.idl',
     'calICalendarSearchProvider.idl',
     'calICalendarView.idl',
     'calICalendarViewController.idl',
     'calIChangeLog.idl',
+    'calIDateTime.idl',
     'calIDateTimeFormatter.idl',
     'calIDeletedItems.idl',
+    'calIDuration.idl',
     'calIErrors.idl',
     'calIEvent.idl',
     'calIFreeBusyProvider.idl',
     'calIIcsParser.idl',
     'calIIcsSerializer.idl',
+    'calIICSService.idl',
     'calIImportExport.idl',
     'calIItemBase.idl',
     'calIItipItem.idl',
     'calIItipTransport.idl',
     'calIOperation.idl',
+    'calIPeriod.idl',
     'calIPrintFormatter.idl',
     'calIRecurrenceDate.idl',
     'calIRecurrenceInfo.idl',
     'calIRecurrenceItem.idl',
     'calIRecurrenceRule.idl',
     'calIRelation.idl',
     'calISchedulingSupport.idl',
     'calIStartupService.idl',
--- a/calendar/test/unit/test_recur.js
+++ b/calendar/test/unit/test_recur.js
@@ -567,31 +567,47 @@ function test_rrule_interface() {
     // Now start changing things
     rrule.setComponent("BYDAY", 2, [4,5]);
     equal(rrule.icalString.match(/BYDAY=WE,TH/), "BYDAY=WE,TH");
 
     rrule.count = -1;
     ok(!rrule.isByCount);
     ok(!rrule.isFinite);
     equal(rrule.icalString.match(/COUNT=/), null);
-    throws(function() {
-        rrule.count;
-    }, /0x80004005/);
+    throws(() => rrule.count, /0x80004005/);
 
     rrule.interval = 1;
     equal(rrule.interval, 1);
     equal(rrule.icalString.match(/INTERVAL=/), null);
 
     rrule.interval = 3;
     equal(rrule.interval, 3);
     equal(rrule.icalString.match(/INTERVAL=3/), "INTERVAL=3");
 
     rrule.type = "MONTHLY";
     equal(rrule.type, "MONTHLY");
     equal(rrule.icalString.match(/FREQ=MONTHLY/), "FREQ=MONTHLY");
+
+    // untilDate (without UTC)
+    rrule.count = 3;
+    let untilDate = cal.createDateTime();
+    untilDate.timezone = cal.getTimezoneService().getTimezone("Europe/Berlin");
+    rrule.untilDate = untilDate;
+    ok(!rrule.isByCount)
+    throws(() => rrule.count, /0x80004005/);
+    equal(rrule.untilDate.icalString, untilDate.getInTimezone(cal.UTC()).icalString);
+
+    // untilDate (with UTC)
+    rrule.count = 3;
+    untilDate = cal.createDateTime();
+    untilDate.timezone = cal.UTC();
+    rrule.untilDate = untilDate;
+    ok(!rrule.isByCount)
+    throws(() => rrule.count, /0x80004005/);
+    equal(rrule.untilDate.icalString, untilDate.icalString);
 }
 
 function test_startdate_change() {
 
     // Setting a start date if its missing shouldn't throw
     let item = makeEvent("DTEND:20020402T124500Z\r\n" +
                          "RRULE:FREQ=DAILY\r\n");
     item.startDate = cal.createDateTime("20020502T114500Z");