[evolution-data-server/wip/mcrha/libical-glib] libecal changes



commit 05938fec328bfc6e51cd123c0c2acdbe27eaf7f2
Author: Milan Crha <mcrha redhat com>
Date:   Wed Mar 13 14:38:30 2019 +0100

    libecal changes

 src/calendar/libecal/e-cal-check-timezones.c       |  266 +--
 src/calendar/libecal/e-cal-check-timezones.h       |   19 +-
 src/calendar/libecal/e-cal-client-view.c           |   36 +-
 src/calendar/libecal/e-cal-client-view.h           |    8 +-
 src/calendar/libecal/e-cal-client.c                | 1238 ++++++-------
 src/calendar/libecal/e-cal-client.h                |  112 +-
 .../libecal/e-cal-component-alarm-trigger.c        |    3 +-
 src/calendar/libecal/e-cal-component.c             |   35 +-
 src/calendar/libecal/e-cal-enums.h                 |   19 +
 src/calendar/libecal/e-cal-recur.c                 |  762 ++++----
 src/calendar/libecal/e-cal-recur.h                 |  126 +-
 src/calendar/libecal/e-cal-system-timezone.c       |   20 +-
 src/calendar/libecal/e-cal-time-util.c             |  334 ++--
 src/calendar/libecal/e-cal-time-util.h             |   81 +-
 src/calendar/libecal/e-cal-util.c                  | 1820 +++++++++++---------
 src/calendar/libecal/e-cal-util.h                  |  176 +-
 src/calendar/libecal/e-reminder-watcher.c          |  484 ++++--
 src/calendar/libecal/e-reminder-watcher.h          |   37 +-
 src/calendar/libecal/e-timezone-cache.c            |   31 +-
 src/calendar/libecal/e-timezone-cache.h            |   17 +-
 src/libedataserverui/e-reminders-widget.c          |   10 +-
 21 files changed, 2979 insertions(+), 2655 deletions(-)
---
diff --git a/src/calendar/libecal/e-cal-check-timezones.c b/src/calendar/libecal/e-cal-check-timezones.c
index 8594317e3..8c6898190 100644
--- a/src/calendar/libecal/e-cal-check-timezones.c
+++ b/src/calendar/libecal/e-cal-check-timezones.c
@@ -36,14 +36,14 @@
 static const gchar *
 e_cal_match_location (const gchar *location)
 {
-       icaltimezone *icomp;
+       icaltimezone *zone;
        const gchar *tail;
        gsize len;
        gchar *buffer;
 
-       icomp = icaltimezone_get_builtin_timezone (location);
-       if (icomp) {
-               return icaltimezone_get_tzid (icomp);
+       zone = icaltimezone_get_builtin_timezone (location);
+       if (zone) {
+               return icaltimezone_get_tzid (zone);
        }
 
        /* try a bit harder by stripping trailing suffix */
@@ -54,10 +54,10 @@ e_cal_match_location (const gchar *location)
        if (buffer) {
                memcpy (buffer, location, len);
                buffer[len] = 0;
-               icomp = icaltimezone_get_builtin_timezone (buffer);
+               zone = icaltimezone_get_builtin_timezone (buffer);
                g_free (buffer);
-               if (icomp) {
-                       return icaltimezone_get_tzid (icomp);
+               if (zone) {
+                       return icaltimezone_get_tzid (zone);
                }
        }
 
@@ -144,23 +144,27 @@ e_cal_match_tzid (const gchar *tzid)
 }
 
 static void
-patch_tzids (icalcomponent *subcomp,
+patch_tzids (ICalComponent *subcomp,
              GHashTable *mapping)
 {
        gchar *tzid = NULL;
 
-       if (icalcomponent_isa (subcomp) != ICAL_VTIMEZONE_COMPONENT) {
-               icalproperty *prop = icalcomponent_get_first_property (
-                       subcomp, ICAL_ANY_PROPERTY);
-               while (prop) {
-                       icalparameter *param = icalproperty_get_first_parameter (
-                               prop, ICAL_TZID_PARAMETER);
-                       while (param) {
+       if (i_cal_component_isa (subcomp) != I_CAL_VTIMEZONE_COMPONENT) {
+               ICalProperty *prop;
+
+               for (prop = i_cal_component_get_first_property (subcomp, I_CAL_ANY_PROPERTY);
+                    prop;
+                    g_object_unref (prop), prop = i_cal_component_get_next_property (subcomp, 
I_CAL_ANY_PROPERTY)) {
+                       ICalParameter *param;
+
+                       for (param = i_cal_property_get_first_parameter (prop, I_CAL_TZID_PARAMETER);
+                            param;
+                            g_object_unref (param), param = i_cal_property_get_next_parameter (prop, 
I_CAL_TZID_PARAMETER)) {
                                const gchar *oldtzid;
                                const gchar *newtzid;
 
                                g_free (tzid);
-                               tzid = g_strdup (icalparameter_get_tzid (param));
+                               tzid = g_strdup (i_cal_parameter_get_tzid (param));
 
                                if (!g_hash_table_lookup_extended (
                                        mapping, tzid,
@@ -170,13 +174,9 @@ patch_tzids (icalcomponent *subcomp,
                                        newtzid = e_cal_match_tzid (tzid);
                                }
                                if (newtzid) {
-                                       icalparameter_set_tzid (param, newtzid);
+                                       i_cal_parameter_set_tzid (param, newtzid);
                                }
-                               param = icalproperty_get_next_parameter (
-                                       prop, ICAL_TZID_PARAMETER);
                        }
-                       prop = icalcomponent_get_next_property (
-                               subcomp, ICAL_ANY_PROPERTY);
                }
        }
 
@@ -189,36 +189,38 @@ addsystemtz (gpointer key,
              gpointer user_data)
 {
        const gchar *tzid = key;
-       icalcomponent *comp = user_data;
-       icaltimezone *zone;
+       ICalComponent *vcalendar = user_data;
+       ICalTimezone *zone;
 
-       zone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
+       zone = i_cal_timezone_get_builtin_timezone_from_tzid (tzid);
        if (zone) {
-               icalcomponent_add_component (
-                       comp,
-                       icalcomponent_new_clone (
-                       icaltimezone_get_component (zone)));
+               ICalComponent *zone_comp;
+
+               zone_comp = i_cal_timezone_get_component (zone);
+               if (zone_comp) {
+                       i_cal_component_take_component (vcalendar, i_cal_component_new_clone (zone_comp));
+                       g_object_unref (zone_comp);
+               }
        }
 }
 
 /**
- * e_cal_client_check_timezones:
- * @comp:     a VCALENDAR containing a list of
- *            VTIMEZONE and arbitrary other components, in
- *            arbitrary order: these other components are
- *            modified by this call
- * @comps: (element-type icalcomponent) (allow-none): a list of #icalcomponent
- * instances which also have to be patched; may be %NULL
- * @tzlookup: a callback function which is called to retrieve
- *            a calendar's VTIMEZONE definition; the returned
- *            definition is *not* freed by e_cal_client_check_timezones()
- *            (to be compatible with e_cal_get_timezone());
- *            NULL indicates that no such timezone exists
- *            or an error occurred
- * @ecalclient: an arbitrary pointer which is passed through to
- *            the @tzlookup function
+ * e_cal_client_check_timezones_sync:
+ * @vcalendar: a VCALENDAR containing a list of
+ *    VTIMEZONE and arbitrary other components, in
+ *    arbitrary order: these other components are
+ *    modified by this call
+ * @icalcomps: (element-type ICalComponent) (nullable): a list of #ICalComponent
+ *    instances which also have to be patched; may be %NULL
+ * @tzlookup: (scope call): a callback function which is called to retrieve
+ *    a calendar's VTIMEZONE definition; the returned
+ *    definition is *not* freed by e_cal_client_check_timezones()
+ *    NULL indicates that no such timezone exists
+ *    or an error occurred
+ * @tzlookup_data: (closure tzlookup): an arbitrary pointer which is passed
+ *    through to the @tzlookup function
  * @cancellable: a #GCancellable to use in @tzlookup function
- * @error:    an error description in case of a failure
+ * @error: an error description in case of a failure
  *
  * This function cleans up VEVENT, VJOURNAL, VTODO and VTIMEZONE
  * items which are to be imported into Evolution.
@@ -236,7 +238,7 @@ addsystemtz (gpointer key,
  * Some programs generate broken meeting invitations with TZID, but
  * without including the corresponding VTIMEZONE. Importing such
  * invitations unchanged causes problems later on (meeting displayed
- * incorrectly, e_cal_get_component_as_string() fails). The situation
+ * incorrectly, e_cal_component_get_as_string() fails). The situation
  * where this occurred in the past (found by a SyncEvolution user) is
  * now handled via the location based mapping.
  *
@@ -247,34 +249,31 @@ addsystemtz (gpointer key,
  * displaying of old events, whereas not replacing it breaks the new
  * events (the behavior in Evolution <= 2.22.1).
  *
- * The way this problem is resolved is by renaming the new VTIMEZONE
+ * The way this problem is resolved by renaming the new VTIMEZONE
  * definition until the TZID is unique. A running count is appended to
  * the TZID. All items referencing the renamed TZID are adapted
  * accordingly.
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
- * Since: 3.2
+ * Since: 3.36
  **/
 gboolean
-e_cal_client_check_timezones (icalcomponent *comp,
-                              GList *comps,
-                              icaltimezone *(*tzlookup) (const gchar *tzid,
-                                                         gconstpointer ecalclient,
-                                                         GCancellable *cancellable,
-                                                         GError **error),
-                              gconstpointer ecalclient,
-                              GCancellable *cancellable,
-                              GError **error)
+e_cal_client_check_timezones_sync (ICalComponent *vcalendar,
+                                  GSList *icalcomps,
+                                  ECalRecurResolveTimezoneCb tzlookup,
+                                  gpointer tzlookup_data,
+                                  GCancellable *cancellable,
+                                  GError **error)
 {
        gboolean success = TRUE;
-       icalcomponent *subcomp = NULL;
-       icaltimezone *zone = icaltimezone_new ();
+       ICalComponent *subcomp;
+       ICalTimezone *zone = i_cal_timezone_new ();
        gchar *key = NULL, *value = NULL;
        gchar *buffer = NULL;
        gchar *zonestr = NULL;
        gchar *tzid = NULL;
-       GList *l;
+       GSList *link;
 
        /* a hash from old to new tzid; strings dynamically allocated */
        GHashTable *mapping = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
@@ -282,18 +281,17 @@ e_cal_client_check_timezones (icalcomponent *comp,
        /* a hash of all system time zone IDs which have to be added; strings are shared with mapping hash */
        GHashTable *systemtzids = g_hash_table_new (g_str_hash, g_str_equal);
 
-       *error = NULL;
-
        if (!mapping || !zone) {
                goto nomem;
        }
 
        /* iterate over all VTIMEZONE definitions */
-       subcomp = icalcomponent_get_first_component (comp, ICAL_VTIMEZONE_COMPONENT);
-       while (subcomp) {
-               if (icaltimezone_set_component (zone, subcomp)) {
+       for (subcomp = i_cal_component_get_first_component (vcalendar, I_CAL_VTIMEZONE_COMPONENT);
+            subcomp;
+            g_object_unref (subcomp), subcomp = i_cal_component_get_next_component (vcalendar, 
I_CAL_VTIMEZONE_COMPONENT)) {
+               if (i_cal_timezone_set_component (zone, subcomp)) {
                        g_free (tzid);
-                       tzid = g_strdup (icaltimezone_get_tzid (zone));
+                       tzid = g_strdup (i_cal_timezone_get_tzid (zone));
                        if (tzid) {
                                const gchar *newtzid = e_cal_match_tzid (tzid);
                                if (newtzid) {
@@ -301,12 +299,14 @@ e_cal_client_check_timezones (icalcomponent *comp,
                                        g_free (key);
                                        key = g_strdup (tzid);
                                        if (!key) {
+                                               g_object_unref (subcomp);
                                                goto nomem;
                                        }
 
                                        g_free (value);
                                        value = g_strdup (newtzid);
                                        if (!value) {
+                                               g_object_unref (subcomp);
                                                goto nomem;
                                        }
 
@@ -316,28 +316,38 @@ e_cal_client_check_timezones (icalcomponent *comp,
                                } else {
                                        gint counter;
 
-                                       zonestr = icalcomponent_as_ical_string_r (subcomp);
+                                       zonestr = i_cal_component_as_ical_string_r (subcomp);
 
                                        /* check for collisions with existing timezones */
                                        for (counter = 0;
                                             counter < 100 /* sanity limit */;
                                             counter++) {
-                                               icaltimezone *existing_zone;
+                                               ICalTimezone *existing_zone;
+                                               ICalComponent *zone_comp;
+                                               GError *local_error = NULL;
 
                                                if (counter) {
                                                        g_free (value);
                                                        value = g_strdup_printf ("%s %d", tzid, counter);
                                                }
-                                               existing_zone = tzlookup (counter ? value : tzid, ecalclient, 
cancellable, error);
+                                               existing_zone = tzlookup (counter ? value : tzid, 
tzlookup_data, cancellable, &local_error);
                                                if (!existing_zone) {
-                                                       if (*error) {
+                                                       if (local_error) {
+                                                               g_propagate_error (error, local_error);
+                                                               g_object_unref (subcomp);
                                                                goto failed;
                                                        } else {
                                                                break;
                                                        }
                                                }
                                                g_free (buffer);
-                                               buffer = icalcomponent_as_ical_string_r 
(icaltimezone_get_component (existing_zone));
+                                               zone_comp = i_cal_timezone_get_component (existing_zone);
+                                               buffer = zone_comp ? i_cal_component_as_ical_string_r 
(zone_comp) : NULL;
+                                               g_clear_object (&zone_comp);
+                                               g_clear_object (&existing_zone);
+
+                                               if (!buffer)
+                                                       continue;
 
                                                if (counter) {
                                                        gchar *fulltzid = g_strdup_printf ("TZID:%s", value);
@@ -367,7 +377,7 @@ e_cal_client_check_timezones (icalcomponent *comp,
                                                 * is expected to occur rarely (if at all) in
                                                 * practice.
                                                 */
-                                               if (!strcmp (zonestr, buffer)) {
+                                               if (!g_strcmp0 (zonestr, buffer)) {
                                                        break;
                                                }
                                        }
@@ -376,10 +386,12 @@ e_cal_client_check_timezones (icalcomponent *comp,
                                                /* does not exist, nothing to do */
                                        } else {
                                                /* timezone renamed */
-                                               icalproperty *prop = icalcomponent_get_first_property 
(subcomp, ICAL_TZID_PROPERTY);
-                                               while (prop) {
-                                                       icalproperty_set_value_from_string (prop, value, 
"NO");
-                                                       prop = icalcomponent_get_next_property (subcomp, 
ICAL_ANY_PROPERTY);
+                                               ICalProperty *prop;
+
+                                               for (prop = i_cal_component_get_first_property (subcomp, 
I_CAL_TZID_PROPERTY);
+                                                    prop;
+                                                    g_object_unref (prop), prop = 
i_cal_component_get_next_property (subcomp, I_CAL_TZID_PROPERTY)) {
+                                                       i_cal_property_set_value_from_string (prop, value, 
"NO");
                                                }
                                                g_free (key);
                                                key = g_strdup (tzid);
@@ -389,15 +401,14 @@ e_cal_client_check_timezones (icalcomponent *comp,
                                }
                        }
                }
-
-               subcomp = icalcomponent_get_next_component (comp, ICAL_VTIMEZONE_COMPONENT);
        }
 
        /*
         * now replace all TZID parameters in place
         */
-       subcomp = icalcomponent_get_first_component (comp, ICAL_ANY_COMPONENT);
-       while (subcomp) {
+       for (subcomp = i_cal_component_get_first_component (vcalendar, ICAL_ANY_COMPONENT);
+            subcomp;
+            g_object_unref (subcomp), subcomp = i_cal_component_get_next_component (vcalendar, 
ICAL_ANY_COMPONENT)) {
                /*
                 * Leave VTIMEZONE unchanged, iterate over properties of
                 * everything else.
@@ -408,39 +419,37 @@ e_cal_client_check_timezones (icalcomponent *comp,
                 * added below.
                 */
                patch_tzids (subcomp, mapping);
-               subcomp = icalcomponent_get_next_component (comp, ICAL_ANY_COMPONENT);
        }
 
-       for (l = comps; l; l = l->next) {
-               patch_tzids (l->data, mapping);
+       for (link = icalcomps; link; link = g_slist_next (link)) {
+               ICalComponent *icalcomp = link->data;
+               patch_tzids (icalcomp, mapping);
        }
 
        /*
         * add system time zones that we mapped to: adding them ensures
         * that the VCALENDAR remains consistent
         */
-       g_hash_table_foreach (systemtzids, addsystemtz, comp);
+       g_hash_table_foreach (systemtzids, addsystemtz, vcalendar);
 
        goto done;
  nomem:
        /* set gerror for "out of memory" if possible, otherwise abort via g_error() */
-       *error = g_error_new (E_CLIENT_ERROR, E_CLIENT_ERROR_OTHER_ERROR, "out of memory");
-       if (!*error) {
-               g_error ("e_cal_check_timezones(): out of memory, cannot proceed - sorry!");
+       g_set_error_literal (error, E_CLIENT_ERROR, E_CLIENT_ERROR_OTHER_ERROR, "out of memory");
+       if (error && !*error) {
+               g_error ("%s: out of memory, cannot proceed - sorry!", G_STRFUNC);
        }
  failed:
        /* gerror should have been set already */
        success = FALSE;
  done:
-       if (mapping) {
+       if (mapping)
                g_hash_table_destroy (mapping);
-       }
-       if (systemtzids) {
+
+       if (systemtzids)
                g_hash_table_destroy (systemtzids);
-       }
-       if (zone) {
-               icaltimezone_free (zone, 1);
-       }
+
+       g_clear_object (&zone);
        g_free (tzid);
        g_free (zonestr);
        g_free (buffer);
@@ -451,31 +460,33 @@ e_cal_client_check_timezones (icalcomponent *comp,
 }
 
 /**
- * e_cal_client_tzlookup:
+ * e_cal_client_tzlookup_cb:
  * @tzid: ID of the timezone to lookup
- * @ecalclient: must be a valid #ECalClient pointer
+ * @ecalclient: (type ECalClient): a valid #ECalClient pointer
  * @cancellable: an optional #GCancellable to use, or %NULL
  * @error: an error description in case of a failure
  *
- * An implementation of the tzlookup callback which clients
+ * An implementation of the #ECalRecurResolveTimezoneCb callback which clients
  * can use. Calls e_cal_client_get_timezone_sync().
  *
- * Returns: A timezone object, or %NULL on failure. This object is owned
- *   by the @ecalclient, thus do not free it.
+ * Free a non-NULL returned timezone object with g_object_unref(), when
+ * no longer needed.
  *
- * Since: 3.2
- */
-icaltimezone *
-e_cal_client_tzlookup (const gchar *tzid,
-                       gconstpointer ecalclient,
-                       GCancellable *cancellable,
-                       GError **error)
+ * Returns: (transfer full) (nullable): A timezone object, or %NULL on failure
+ *    or when not found.
+ *
+ * Since: 3.36
+ **/
+ICalTimezone *
+e_cal_client_tzlookup_cb (const gchar *tzid,
+                         gpointer ecalclient,
+                         GCancellable *cancellable,
+                         GError **error)
 {
-       ECalClient *cal_client = (ECalClient *) ecalclient;
-       icaltimezone *zone = NULL;
+       ECalClient *cal_client = ecalclient;
+       ICalTimezone *zone = NULL;
        GError *local_error = NULL;
 
-       g_return_val_if_fail (cal_client != NULL, NULL);
        g_return_val_if_fail (E_IS_CAL_CLIENT (cal_client), NULL);
 
        if (e_cal_client_get_timezone_sync (cal_client, tzid, &zone, cancellable, &local_error)) {
@@ -496,30 +507,33 @@ e_cal_client_tzlookup (const gchar *tzid,
 }
 
 /**
- * e_cal_client_tzlookup_icomp:
+ * e_cal_client_tzlookup_icalcomp_cb:
  * @tzid: ID of the timezone to lookup
- * @custom: must be a icalcomponent pointer which contains
- *          either a VCALENDAR with VTIMEZONEs or VTIMEZONES
- *          directly
+ * @icalcomp: (type ICalComponent): an #ICalComponent pointer, which contains
+ *    either a VCALENDAR with VTIMEZONEs or VTIMEZONES directly
  * @cancellable: an optional #GCancellable to use, or %NULL
  * @error: an error description in case of a failure
  *
- * An implementation of the tzlookup callback which backends
- * like the file backend can use. Searches for the timezone
- * in the component list.
+ * An implementation of the #ECalRecurResolveTimezoneCb callback which
+ * backends can use. Searches for the timezone in the @icalcomp.
  *
- * Returns: A timezone object, or %NULL if not found inside @custom. This object is owned
- *   by the @custom, thus do not free it.
+ * Free a non-NULL returned timezone object with g_object_unref(), when
+ * no longer needed.
  *
- * Since: 3.2
- */
-icaltimezone *
-e_cal_client_tzlookup_icomp (const gchar *tzid,
-                             gconstpointer custom,
-                             GCancellable *cancellable,
-                             GError **error)
+ * Returns: (transfer full) (nullable): A timezone object, or %NULL, if
+ *    not found inside @icalcomp.
+ *
+ * Since: 3.36
+ **/
+ICalTimezone *
+e_cal_client_tzlookup_icalcomp_cb (const gchar *tzid,
+                                  gpointer icalcomp,
+                                  GCancellable *cancellable,
+                                  GError **error)
 {
-       icalcomponent *icomp = (icalcomponent *) custom;
+       ICalComponent *icomp = icalcomp;
+
+       g_return_val_if_fail (I_CAL_IS_COMPONENT (icalcomp), NULL);
 
-       return icalcomponent_get_timezone (icomp, (gchar *) tzid);
+       return i_cal_component_get_timezone (icomp, tzid);
 }
diff --git a/src/calendar/libecal/e-cal-check-timezones.h b/src/calendar/libecal/e-cal-check-timezones.h
index a819dbad1..ba4b3c987 100644
--- a/src/calendar/libecal/e-cal-check-timezones.h
+++ b/src/calendar/libecal/e-cal-check-timezones.h
@@ -27,23 +27,26 @@
 #include <glib.h>
 #include <gio/gio.h>
 
+#include <libecal/e-cal-recur.h>
+
 G_BEGIN_DECLS
 
-gboolean       e_cal_client_check_timezones    (icalcomponent *comp,
-                                                GList *comps,
-                                                icaltimezone *(*tzlookup) (const gchar *tzid, gconstpointer 
ecalclient, GCancellable *cancellable, GError **error),
-                                                gconstpointer ecalclient,
+gboolean       e_cal_client_check_timezones_sync
+                                               (ICalComponent *vcalendar,
+                                                GSList *comps, /* ICalComponent * */
+                                                ECalRecurResolveTimezoneCb tzlookup,
+                                                gpointer tzlookup_data,
                                                 GCancellable *cancellable,
                                                 GError **error);
 
-icaltimezone * e_cal_client_tzlookup           (const gchar *tzid,
-                                                gconstpointer ecalclient,
+ICalTimezone * e_cal_client_tzlookup_cb        (const gchar *tzid,
+                                                gpointer ecalclient, /* ECalClient * */
                                                 GCancellable *cancellable,
                                                 GError **error);
 
-icaltimezone * e_cal_client_tzlookup_icomp
+ICalTimezone * e_cal_client_tzlookup_icalcomp_cb
                                                (const gchar *tzid,
-                                                gconstpointer custom,
+                                                gpointer icalcomp, /* ICalComponent * */
                                                 GCancellable *cancellable,
                                                 GError **error);
 
diff --git a/src/calendar/libecal/e-cal-client-view.c b/src/calendar/libecal/e-cal-client-view.c
index 065d1f8f3..9da88897f 100644
--- a/src/calendar/libecal/e-cal-client-view.c
+++ b/src/calendar/libecal/e-cal-client-view.c
@@ -106,13 +106,8 @@ signal_closure_free (SignalClosure *signal_closure)
 {
        g_weak_ref_clear (&signal_closure->client_view);
 
-       g_slist_free_full (
-               signal_closure->component_list,
-               (GDestroyNotify) icalcomponent_free);
-
-       g_slist_free_full (
-               signal_closure->component_id_list,
-               (GDestroyNotify) e_cal_component_free_id);
+       g_slist_free_full (signal_closure->component_list, g_object_unref);
+       g_slist_free_full (signal_closure->component_id_list, e_cal_component_id_free);
 
        g_free (signal_closure->message);
 
@@ -154,7 +149,7 @@ cal_client_view_set_main_context (ECalClientView *client_view,
        g_mutex_unlock (&client_view->priv->main_context_lock);
 }
 
-static GSList *
+static GSList * /* ICalComponent * */
 build_object_list (const gchar * const *seq)
 {
        GSList *list;
@@ -162,9 +157,9 @@ build_object_list (const gchar * const *seq)
 
        list = NULL;
        for (i = 0; seq[i]; i++) {
-               icalcomponent *comp;
+               ICalComponent *comp;
 
-               comp = icalcomponent_new_from_string ((gchar *) seq[i]);
+               comp = i_cal_component_new_from_string (seq[i]);
                if (!comp)
                        continue;
 
@@ -174,7 +169,7 @@ build_object_list (const gchar * const *seq)
        return g_slist_reverse (list);
 }
 
-static GSList *
+static GSList * /* ECalComponentId * */
 build_id_list (const gchar * const *seq)
 {
        GSList *list;
@@ -184,17 +179,15 @@ build_id_list (const gchar * const *seq)
        list = NULL;
        for (i = 0; seq[i]; i++) {
                ECalComponentId *id;
-               id = g_new (ECalComponentId, 1);
 
                /* match encoding as in notify_remove()
                 * in e-data-cal-view.c: <uid>[\n<rid>] */
                eol = strchr (seq[i], '\n');
                if (eol) {
-                       id->uid = g_strndup (seq[i], eol - seq[i]);
-                       id->rid = g_strdup (eol + 1);
+                       id = e_cal_component_id_new_take (g_strndup (seq[i], eol - seq[i]),
+                                                         g_strdup (eol + 1));
                } else {
-                       id->uid = g_strdup (seq[i]);
-                       id->rid = NULL;
+                       id = e_cal_component_id_new (seq[i], NULL);
                }
 
                list = g_slist_prepend (list, id);
@@ -811,7 +804,8 @@ e_cal_client_view_class_init (ECalClientViewClass *class)
        /**
         * ECalClientView::objects-added:
         * @client_view: the #ECalClientView which emitted the signal
-        * @objects: (type GSList) (transfer none) (element-type long):
+        * @objects: (type GSList) (transfer none) (element-type ICalComponent): a #GSList
+        *    of added #ICalComponent objects into the @client_view.
         */
        signals[OBJECTS_ADDED] = g_signal_new (
                "objects-added",
@@ -825,7 +819,8 @@ e_cal_client_view_class_init (ECalClientViewClass *class)
        /**
         * ECalClientView::objects-modified:
         * @client_view: the #ECalClientView which emitted the signal
-        * @objects: (type GSList) (transfer none) (element-type long):
+        * @objects: (type GSList) (transfer none) (element-type ICalComponent): a #GSList
+        *    of modified #ICalComponent objects within the @client_view
         */
        signals[OBJECTS_MODIFIED] = g_signal_new (
                "objects-modified",
@@ -839,7 +834,8 @@ e_cal_client_view_class_init (ECalClientViewClass *class)
        /**
         * ECalClientView::objects-removed:
         * @client_view: the #ECalClientView which emitted the signal
-        * @objects: (type GSList) (transfer none) (element-type ECalComponentId):
+        * @uids: (type GSList) (transfer none) (element-type ECalComponentId): a #GSList
+        *    of removed objects, described by their UID and eventually RID, as an #ECalComponentId structure.
         */
        signals[OBJECTS_REMOVED] = g_signal_new (
                "objects-removed",
@@ -1028,7 +1024,7 @@ e_cal_client_view_stop (ECalClientView *client_view,
 /**
  * e_cal_client_view_set_fields_of_interest:
  * @client_view: an #ECalClientView
- * @fields_of_interest: (element-type utf8) (allow-none): List of field names
+ * @fields_of_interest: (element-type utf8) (nullable): List of field names
  *                      in which the client is interested, or %NULL to reset
  *                      the fields of interest
  * @error: return location for a #GError, or %NULL
diff --git a/src/calendar/libecal/e-cal-client-view.h b/src/calendar/libecal/e-cal-client-view.h
index effdae783..00cf318c2 100644
--- a/src/calendar/libecal/e-cal-client-view.h
+++ b/src/calendar/libecal/e-cal-client-view.h
@@ -102,11 +102,11 @@ struct _ECalClientViewClass {
        /*< public >*/
        /* Signals */
        void            (*objects_added)        (ECalClientView *client_view,
-                                                const GSList *objects);
+                                                const GSList *objects); /* ICalComponent * */
        void            (*objects_modified)     (ECalClientView *client_view,
-                                                const GSList *objects);
+                                                const GSList *objects); /* ICalComponent * */
        void            (*objects_removed)      (ECalClientView *client_view,
-                                                const GSList *uids);
+                                                const GSList *uids); /* ECalComponentId * */
        void            (*progress)             (ECalClientView *client_view,
                                                 guint percent,
                                                 const gchar *message);
@@ -125,7 +125,7 @@ const gchar *       e_cal_client_view_get_object_path
 gboolean       e_cal_client_view_is_running    (ECalClientView *client_view);
 void           e_cal_client_view_set_fields_of_interest
                                                (ECalClientView *client_view,
-                                                const GSList *fields_of_interest,
+                                                const GSList *fields_of_interest, /* gchar * */
                                                 GError **error);
 void           e_cal_client_view_start         (ECalClientView *client_view,
                                                 GError **error);
diff --git a/src/calendar/libecal/e-cal-client.c b/src/calendar/libecal/e-cal-client.c
index 9cedfef5c..6f5a1e9b8 100644
--- a/src/calendar/libecal/e-cal-client.c
+++ b/src/calendar/libecal/e-cal-client.c
@@ -63,7 +63,7 @@ struct _ECalClientPrivate {
        guint name_watcher_id;
 
        ECalClientSourceType source_type;
-       icaltimezone *default_zone;
+       ICalTimezone *default_zone;
 
        GMutex zone_cache_lock;
        GHashTable *zone_cache;
@@ -75,12 +75,13 @@ struct _ECalClientPrivate {
 
 struct _AsyncContext {
        ECalClientView *client_view;
-       icalcomponent *in_comp;
-       icalcomponent *out_comp;
-       icaltimezone *zone;
+       ICalComponent *in_comp;
+       ICalComponent *out_comp;
+       ICalTimezone *zone;
        GSList *comp_list;
        GSList *object_list;
        GSList *string_list;
+       GSList *ids_list; /* ECalComponentId * */
        gchar *sexp;
        gchar *tzid;
        gchar *uid;
@@ -96,7 +97,7 @@ struct _SignalClosure {
        gchar *property_name;
        gchar *error_message;
        gchar **free_busy_data;
-       icaltimezone *cached_zone;
+       ICalTimezone *cached_zone;
 };
 
 struct _ConnectClosure {
@@ -149,29 +150,15 @@ G_DEFINE_TYPE_WITH_CODE (
 static void
 async_context_free (AsyncContext *async_context)
 {
-       if (async_context->client_view != NULL)
-               g_object_unref (async_context->client_view);
+       g_clear_object (&async_context->client_view);
+       g_clear_object (&async_context->in_comp);
+       g_clear_object (&async_context->out_comp);
+       g_clear_object (&async_context->zone);
 
-       if (async_context->in_comp != NULL)
-               icalcomponent_free (async_context->in_comp);
-
-       if (async_context->out_comp != NULL)
-               icalcomponent_free (async_context->out_comp);
-
-       if (async_context->zone != NULL)
-               icaltimezone_free (async_context->zone, 1);
-
-       g_slist_free_full (
-               async_context->comp_list,
-               (GDestroyNotify) icalcomponent_free);
-
-       g_slist_free_full (
-               async_context->object_list,
-               (GDestroyNotify) g_object_unref);
-
-       g_slist_free_full (
-               async_context->string_list,
-               (GDestroyNotify) g_free);
+       g_slist_free_full (async_context->comp_list, g_object_unref);
+       g_slist_free_full (async_context->object_list, g_object_unref);
+       g_slist_free_full (async_context->string_list, g_free);
+       g_slist_free_full (async_context->ids_list, e_cal_component_id_free);
 
        g_free (async_context->sexp);
        g_free (async_context->tzid);
@@ -191,8 +178,9 @@ signal_closure_free (SignalClosure *signal_closure)
        g_free (signal_closure->error_message);
 
        g_strfreev (signal_closure->free_busy_data);
+       g_clear_object (&signal_closure->cached_zone);
 
-       /* The icaltimezone is cached in ECalClient's internal
+       /* The ICalTimezone is cached in ECalClient's internal
         * "zone_cache" hash table and must not be freed here. */
 
        g_slice_free (SignalClosure, signal_closure);
@@ -222,12 +210,6 @@ run_in_thread_closure_free (RunInThreadClosure *run_in_thread_closure)
        g_slice_free (RunInThreadClosure, run_in_thread_closure);
 }
 
-static void
-free_zone_cb (gpointer zone)
-{
-       icaltimezone_free (zone, 1);
-}
-
 /*
  * Well-known calendar backend properties:
  * @E_CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS: Contains default calendar's email
@@ -235,7 +217,7 @@ free_zone_cb (gpointer zone)
  * @E_CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS: Contains default alarm email
  *   address suggested by the backend.
  * @E_CAL_BACKEND_PROPERTY_DEFAULT_OBJECT: Contains iCal component string
- *   of an #icalcomponent with the default values for properties needed.
+ *   of an #ICalComponent with the default values for properties needed.
  *   Preferred way of retrieving this property is by
  *   calling e_cal_client_get_default_object().
  *
@@ -461,27 +443,22 @@ cal_client_emit_free_busy_data_idle_cb (gpointer user_data)
 
                for (ii = 0; strv[ii] != NULL; ii++) {
                        ECalComponent *comp;
-                       icalcomponent *icalcomp;
-                       icalcomponent_kind kind;
+                       ICalComponent *icalcomp;
+                       ICalComponentKind kind;
 
-                       icalcomp = icalcomponent_new_from_string (strv[ii]);
+                       icalcomp = i_cal_component_new_from_string (strv[ii]);
                        if (icalcomp == NULL)
                                continue;
 
-                       kind = icalcomponent_isa (icalcomp);
-                       if (kind != ICAL_VFREEBUSY_COMPONENT) {
-                               icalcomponent_free (icalcomp);
+                       kind = i_cal_component_isa (icalcomp);
+                       if (kind != I_CAL_VFREEBUSY_COMPONENT) {
+                               i_cal_component_free (icalcomp);
                                continue;
                        }
 
-                       comp = e_cal_component_new ();
-                       if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
-                               icalcomponent_free (icalcomp);
-                               g_object_unref (comp);
-                               continue;
-                       }
-
-                       list = g_slist_prepend (list, comp);
+                       comp = e_cal_component_new_from_icalcomponent (icalcomp);
+                       if (comp)
+                               list = g_slist_prepend (list, comp);
                }
 
                list = g_slist_reverse (list);
@@ -874,8 +851,8 @@ cal_client_finalize (GObject *object)
        if (priv->name_watcher_id > 0)
                g_bus_unwatch_name (priv->name_watcher_id);
 
-       if (priv->default_zone && priv->default_zone != icaltimezone_get_utc_timezone ())
-               icaltimezone_free (priv->default_zone, 1);
+       if (priv->default_zone && priv->default_zone != i_cal_timezone_get_utc_timezone ())
+               g_clear_object (&priv->default_zone);
 
        g_mutex_lock (&priv->zone_cache_lock);
        g_hash_table_destroy (priv->zone_cache);
@@ -1360,7 +1337,7 @@ cal_client_initable_init_finish (GAsyncInitable *initable,
 
 static void
 cal_client_add_cached_timezone (ETimezoneCache *cache,
-                                icaltimezone *zone)
+                                ICalTimezone *zone)
 {
        ECalClientPrivate *priv;
        const gchar *tzid;
@@ -1369,39 +1346,34 @@ cal_client_add_cached_timezone (ETimezoneCache *cache,
 
        /* XXX Apparently this function can sometimes return NULL.
         *     I'm not sure when or why that happens, but we can't
-        *     cache the icaltimezone if it has no tzid string. */
-       tzid = icaltimezone_get_tzid (zone);
+        *     cache the ICalTimezone if it has no tzid string. */
+       tzid = i_cal_timezone_get_tzid (zone);
        if (tzid == NULL)
                return;
 
        g_mutex_lock (&priv->zone_cache_lock);
 
        /* Avoid replacing an existing cache entry.  We don't want to
-        * invalidate any icaltimezone pointers that may have already
+        * invalidate any ICalTimezone pointers that may have already
         * been returned through e_timezone_cache_get_timezone(). */
        if (!g_hash_table_contains (priv->zone_cache, tzid)) {
                GSource *idle_source;
                GMainContext *main_context;
                SignalClosure *signal_closure;
+               ICalTimezone *cached_zone;
 
-               icalcomponent *icalcomp;
-               icaltimezone *cached_zone;
-
-               cached_zone = icaltimezone_new ();
-               icalcomp = icaltimezone_get_component (zone);
-               icalcomp = icalcomponent_new_clone (icalcomp);
-               icaltimezone_set_component (cached_zone, icalcomp);
+               cached_zone = e_cal_util_copy_timezone (zone);
 
                g_hash_table_insert (
                        priv->zone_cache,
                        g_strdup (tzid), cached_zone);
 
                /* The closure's client reference will keep the
-                * internally cached icaltimezone alive for the
+                * internally cached ICalTimezone alive for the
                 * duration of the idle callback. */
                signal_closure = g_slice_new0 (SignalClosure);
                g_weak_ref_init (&signal_closure->client, cache);
-               signal_closure->cached_zone = cached_zone;
+               signal_closure->cached_zone = g_object_ref (cached_zone);
 
                main_context = e_client_ref_main_context (E_CLIENT (cache));
 
@@ -1420,21 +1392,21 @@ cal_client_add_cached_timezone (ETimezoneCache *cache,
        g_mutex_unlock (&priv->zone_cache_lock);
 }
 
-static icaltimezone *
+static ICalTimezone *
 cal_client_get_cached_timezone (ETimezoneCache *cache,
                                 const gchar *tzid)
 {
        ECalClientPrivate *priv;
-       icaltimezone *zone = NULL;
-       icaltimezone *builtin_zone = NULL;
-       icalcomponent *icalcomp;
-       icalproperty *prop;
+       ICalTimezone *zone = NULL;
+       ICalTimezone *builtin_zone = NULL;
+       ICalComponent *icalcomp, *clone;
+       ICalProperty *prop;
        const gchar *builtin_tzid;
 
        priv = E_CAL_CLIENT_GET_PRIVATE (cache);
 
        if (g_str_equal (tzid, "UTC"))
-               return icaltimezone_get_utc_timezone ();
+               return i_cal_timezone_get_utc_timezone ();
 
        g_mutex_lock (&priv->zone_cache_lock);
 
@@ -1447,51 +1419,45 @@ cal_client_get_cached_timezone (ETimezoneCache *cache,
        /* Try to replace the original time zone with a more complete
         * and/or potentially updated built-in time zone.  Note this also
         * applies to TZIDs which match built-in time zones exactly: they
-        * are extracted via icaltimezone_get_builtin_timezone_from_tzid()
+        * are extracted via i_cal_timezone_get_builtin_timezone_from_tzid()
         * below without a roundtrip to the backend. */
 
        builtin_tzid = e_cal_match_tzid (tzid);
 
        if (builtin_tzid != NULL)
-               builtin_zone = icaltimezone_get_builtin_timezone_from_tzid (
-                       builtin_tzid);
+               builtin_zone = i_cal_timezone_get_builtin_timezone_from_tzid (builtin_tzid);
 
        if (builtin_zone == NULL)
                goto exit;
 
        /* Use the built-in time zone *and* rename it.  Likely the caller
         * is asking for a specific TZID because it has an event with such
-        * a TZID.  Returning an icaltimezone with a different TZID would
+        * a TZID.  Returning an ICalTimezone with a different TZID would
         * lead to broken VCALENDARs in the caller. */
 
-       icalcomp = icaltimezone_get_component (builtin_zone);
-       icalcomp = icalcomponent_new_clone (icalcomp);
-
-       prop = icalcomponent_get_first_property (
-               icalcomp, ICAL_ANY_PROPERTY);
-
-       while (prop != NULL) {
-               if (icalproperty_isa (prop) == ICAL_TZID_PROPERTY) {
-                       icalproperty_set_value_from_string (prop, tzid, "NO");
+       icalcomp = i_cal_timezone_get_component (builtin_zone);
+       clone = i_cal_component_new_clone (icalcomp);
+       g_object_unref (icalcomp);
+       icalcomp = clone;
+
+       for (prop = i_cal_component_get_first_property (icalcomp, I_CAL_ANY_PROPERTY);
+            prop;
+            g_object_unref (prop), prop = i_cal_component_get_next_property (icalcomp, I_CAL_ANY_PROPERTY)) {
+               if (i_cal_property_isa (prop) == I_CAL_TZID_PROPERTY) {
+                       i_cal_property_set_value_from_string (prop, tzid, "NO");
+                       g_object_unref (prop);
                        break;
                }
-
-               prop = icalcomponent_get_next_property (
-                       icalcomp, ICAL_ANY_PROPERTY);
        }
 
-       if (icalcomp != NULL) {
-               zone = icaltimezone_new ();
-               if (icaltimezone_set_component (zone, icalcomp)) {
-                       tzid = icaltimezone_get_tzid (zone);
-                       g_hash_table_insert (
-                               priv->zone_cache,
-                               g_strdup (tzid), zone);
-               } else {
-                       icalcomponent_free (icalcomp);
-                       icaltimezone_free (zone, 1);
-                       zone = NULL;
-               }
+       zone = i_cal_timezone_new ();
+       if (i_cal_timezone_set_component (zone, icalcomp)) {
+               tzid = i_cal_timezone_get_tzid (zone);
+               g_hash_table_insert (priv->zone_cache, g_strdup (tzid), zone);
+       } else {
+               g_object_unref (icalcomp);
+               g_object_unref (zone);
+               zone = NULL;
        }
 
 exit:
@@ -1600,15 +1566,11 @@ e_cal_client_init (ECalClient *client)
 {
        GHashTable *zone_cache;
 
-       zone_cache = g_hash_table_new_full (
-               (GHashFunc) g_str_hash,
-               (GEqualFunc) g_str_equal,
-               (GDestroyNotify) g_free,
-               (GDestroyNotify) free_zone_cb);
+       zone_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
 
        client->priv = E_CAL_CLIENT_GET_PRIVATE (client);
        client->priv->source_type = E_CAL_CLIENT_SOURCE_TYPE_LAST;
-       client->priv->default_zone = icaltimezone_get_utc_timezone ();
+       client->priv->default_zone = i_cal_timezone_get_utc_timezone ();
        g_mutex_init (&client->priv->zone_cache_lock);
        client->priv->zone_cache = zone_cache;
 }
@@ -1977,35 +1939,6 @@ e_cal_client_get_local_attachment_store (ECalClient *client)
        return e_dbus_calendar_get_cache_dir (client->priv->dbus_proxy);
 }
 
-/* icaltimezone_copy does a shallow copy while icaltimezone_free tries to
- * free the entire the contents inside the structure with libical 0.43.
- * Use this, till eds allows older libical.
- */
-static icaltimezone *
-copy_timezone (icaltimezone *ozone)
-{
-       icaltimezone *zone = NULL;
-       const gchar *tzid;
-
-       tzid = icaltimezone_get_tzid (ozone);
-
-       if (g_strcmp0 (tzid, "UTC") != 0) {
-               icalcomponent *comp;
-
-               comp = icaltimezone_get_component (ozone);
-               if (comp != NULL) {
-                       zone = icaltimezone_new ();
-                       icaltimezone_set_component (
-                               zone, icalcomponent_new_clone (comp));
-               }
-       }
-
-       if (zone == NULL)
-               zone = icaltimezone_get_utc_timezone ();
-
-       return zone;
-}
-
 /**
  * e_cal_client_set_default_timezone:
  * @client: A calendar client.
@@ -2019,7 +1952,7 @@ copy_timezone (icaltimezone *ozone)
  **/
 void
 e_cal_client_set_default_timezone (ECalClient *client,
-                                   icaltimezone *zone)
+                                   ICalTimezone *zone)
 {
        g_return_if_fail (E_IS_CAL_CLIENT (client));
        g_return_if_fail (zone != NULL);
@@ -2027,13 +1960,13 @@ e_cal_client_set_default_timezone (ECalClient *client,
        if (zone == client->priv->default_zone)
                return;
 
-       if (client->priv->default_zone != icaltimezone_get_utc_timezone ())
-               icaltimezone_free (client->priv->default_zone, 1);
+       if (client->priv->default_zone != i_cal_timezone_get_utc_timezone ())
+               g_clear_object (&client->priv->default_zone);
 
-       if (zone == icaltimezone_get_utc_timezone ())
+       if (zone == i_cal_timezone_get_utc_timezone ())
                client->priv->default_zone = zone;
        else
-               client->priv->default_zone = copy_timezone (zone);
+               client->priv->default_zone = e_cal_util_copy_timezone (zone);
 
        g_object_notify (G_OBJECT (client), "default-timezone");
 }
@@ -2046,11 +1979,11 @@ e_cal_client_set_default_timezone (ECalClient *client,
  * e_cal_client_set_default_timezone().  The returned pointer is owned by
  * the @client and should not be freed.
  *
- * Returns: an #icaltimezone
+ * Returns: (transfer none): an #ICalTimezone
  *
  * Since: 3.2
  **/
-icaltimezone *
+ICalTimezone *
 e_cal_client_get_default_timezone (ECalClient *client)
 {
        g_return_val_if_fail (E_IS_CAL_CLIENT (client), NULL);
@@ -2162,103 +2095,6 @@ e_cal_client_check_recurrences_no_master (ECalClient *client)
                E_CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER);
 }
 
-/**
- * e_cal_client_free_icalcomp_slist:
- * @icalcomps: (element-type icalcomponent): list of icalcomponent objects
- *
- * Frees each element of the @icalcomps list and the list itself.
- * Each element is an object of type #icalcomponent.
- *
- * Since: 3.2
- **/
-void
-e_cal_client_free_icalcomp_slist (GSList *icalcomps)
-{
-       g_slist_foreach (icalcomps, (GFunc) icalcomponent_free, NULL);
-       g_slist_free (icalcomps);
-}
-
-/**
- * e_cal_client_free_ecalcomp_slist:
- * @ecalcomps: (element-type ECalComponent): list of #ECalComponent objects
- *
- * Frees each element of the @ecalcomps list and the list itself.
- * Each element is an object of type #ECalComponent.
- *
- * Since: 3.2
- **/
-void
-e_cal_client_free_ecalcomp_slist (GSList *ecalcomps)
-{
-       g_slist_foreach (ecalcomps, (GFunc) g_object_unref, NULL);
-       g_slist_free (ecalcomps);
-}
-
-/**
- * e_cal_client_resolve_tzid_cb:
- * @tzid: ID of the timezone to resolve.
- * @data: Closure data for the callback, in this case #ECalClient.
- *
- * Resolves TZIDs for the recurrence generator.
- *
- * Returns: The timezone identified by the @tzid argument, or %NULL if
- * it could not be found.
- *
- * Since: 3.2
- */
-icaltimezone *
-e_cal_client_resolve_tzid_cb (const gchar *tzid,
-                              gpointer data)
-{
-       ECalClient *client = data;
-       icaltimezone *zone = NULL;
-       GError *local_error = NULL;
-
-       g_return_val_if_fail (E_IS_CAL_CLIENT (client), NULL);
-
-       e_cal_client_get_timezone_sync (
-               client, tzid, &zone, NULL, &local_error);
-
-       if (local_error != NULL) {
-               g_debug (
-                       "%s: Failed to find '%s' timezone: %s",
-                       G_STRFUNC, tzid, local_error->message);
-               g_error_free (local_error);
-       }
-
-       return zone;
-}
-
-/**
- * e_cal_client_resolve_tzid_sync:
- * @tzid: ID of the timezone to resolve.
- * @cal_client: User data for the callback, in this case #ECalClient.
- * @cancellable: optional #GCancellable object, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Resolves TZIDs for the recurrence generator.
- *
- * Returns: The timezone identified by the @tzid argument, or %NULL if
- * it could not be found.
- *
- * Since: 3.20
- */
-icaltimezone *
-e_cal_client_resolve_tzid_sync (const gchar *tzid,
-                               gpointer cal_client,
-                               GCancellable *cancellable,
-                               GError **error)
-{
-       icaltimezone *zone = NULL;
-
-       g_return_val_if_fail (E_IS_CAL_CLIENT (cal_client), NULL);
-
-       if (!e_cal_client_get_timezone_sync (cal_client, tzid, &zone, cancellable, error))
-               return NULL;
-
-       return zone;
-}
-
 struct comp_instance {
        ECalComponent *comp;
        time_t start;
@@ -2267,113 +2103,118 @@ struct comp_instance {
 
 struct instances_info {
        GSList **instances;
-       icaltimezone *start_zone;
-       icaltimezone *end_zone;
-       icaltimezone *default_zone;
+       ICalTimezone *start_zone;
+       ICalTimezone *end_zone;
+       ICalTimezone *default_zone;
 };
 
 /* Called from cal_recur_generate_instances(); adds an instance to the list */
 static gboolean
-add_instance (ECalComponent *comp,
-              time_t start,
-              time_t end,
-              gpointer data)
+add_instance_cb (ICalComponent *icomp,
+                ICalTimetype *start,
+                ICalTimetype *end,
+                gpointer user_data,
+                GCancellable *cancellable,
+                GError **error)
 {
        GSList **list;
        struct comp_instance *ci;
-       icalcomponent *icalcomp;
        struct instances_info *instances_hold;
 
-       instances_hold = data;
+       instances_hold = user_data;
        list = instances_hold->instances;
 
        ci = g_new (struct comp_instance, 1);
 
-       icalcomp = icalcomponent_new_clone (
-               e_cal_component_get_icalcomponent (comp));
-
        /* add the instance to the list */
-       ci->comp = e_cal_component_new ();
-       e_cal_component_set_icalcomponent (ci->comp, icalcomp);
+       ci->comp = e_cal_component_new_from_icalcomponent (i_cal_component_new_clone (icomp));
+       if (!ci->comp) {
+               g_free (ci);
+               return FALSE;
+       }
 
        /* make sure we return an instance */
-       if (e_cal_util_component_has_recurrences (icalcomp) &&
-           !(icalcomponent_get_first_property (icalcomp, ICAL_RECURRENCEID_PROPERTY))) {
+       if (e_cal_component_has_recurrences (ci->comp) &&
+           !e_cal_component_is_instance (ci->comp)) {
                ECalComponentRange *range;
-               struct icaltimetype itt;
-               ECalComponentDateTime dtstart, dtend;
+               ICalTimetype *itt;
+               ECalComponentDateTime *dtstart, *dtend;
 
-               /* update DTSTART */
-               dtstart.value = NULL;
-               dtstart.tzid = NULL;
-
-               e_cal_component_get_dtstart (comp, &dtstart);
+               dtstart = e_cal_component_get_dtstart (ci->comp);
 
                if (instances_hold->start_zone) {
-                       itt = icaltime_from_timet_with_zone (
-                               start, dtstart.value && dtstart.value->is_date,
+                       itt = i_cal_time_from_timet_with_zone (i_cal_time_as_timet (start),
+                               dtstart && e_cal_component_datetime_get_value (dtstart) && i_cal_time_is_date 
(e_cal_component_datetime_get_value (dtstart)),
                                instances_hold->start_zone);
-                       g_free ((gchar *) dtstart.tzid);
-                       dtstart.tzid = g_strdup (icaltimezone_get_tzid (
-                               instances_hold->start_zone));
-               } else if (dtstart.value && dtstart.value->is_date && !dtstart.tzid && 
instances_hold->default_zone) {
+                       if (dtstart)
+                               e_cal_component_datetime_set_tzid (dtstart, i_cal_timezone_get_tzid 
(instances_hold->start_zone));
+               } else if (dtstart && instances_hold->default_zone &&
+                          e_cal_component_datetime_get_value (dtstart) &&
+                          i_cal_time_is_date (e_cal_component_datetime_get_value (dtstart)) &&
+                          !e_cal_component_datetime_get_tzid (dtstart)) {
                        /* Floating date, set in the default zone */
-                       itt = icaltime_from_timet_with_zone (start, TRUE, instances_hold->default_zone);
+                       itt = i_cal_time_from_timet_with_zone (i_cal_time_as_timet (start), TRUE, 
instances_hold->default_zone);
                } else {
-                       itt = icaltime_from_timet_with_zone (start, dtstart.value && dtstart.value->is_date, 
NULL);
-                       if (dtstart.tzid) {
-                               g_free ((gchar *) dtstart.tzid);
-                               dtstart.tzid = NULL;
-                       }
+                       itt = i_cal_time_from_timet_with_zone (i_cal_time_as_timet (start),
+                               dtstart && e_cal_component_datetime_get_value (dtstart) && i_cal_time_is_date 
(e_cal_component_datetime_get_value (dtstart)),
+                               NULL);
+                       if (dtstart)
+                               e_cal_component_datetime_set_tzid (dtstart, NULL);
                }
 
-               g_free (dtstart.value);
-               dtstart.value = &itt;
-               e_cal_component_set_dtstart (ci->comp, &dtstart);
+               if (dtstart)
+                       e_cal_component_datetime_set_value (dtstart, itt);
+               else
+                       dtstart = e_cal_component_datetime_new (itt, instances_hold->start_zone ? 
i_cal_timezone_get_tzid (instances_hold->start_zone) : NULL);
+
+               e_cal_component_set_dtstart (ci->comp, dtstart);
 
                /* set the RECUR-ID for the instance */
-               range = g_new0 (ECalComponentRange, 1);
-               range->type = E_CAL_COMPONENT_RANGE_SINGLE;
-               range->datetime = dtstart;
+               range = e_cal_component_range_new (E_CAL_COMPONENT_RANGE_SINGLE, dtstart);
 
                e_cal_component_set_recurid (ci->comp, range);
 
-               g_free (range);
-               g_free ((gchar *) dtstart.tzid);
+               e_cal_component_datetime_free (dtstart);
+               e_cal_component_range_free (range);
+               g_clear_object (&itt);
 
                /* Update DTEND */
-               dtend.value = NULL;
-               dtend.tzid = NULL;
 
-               e_cal_component_get_dtend (comp, &dtend);
+               dtend = e_cal_component_get_dtend (ci->comp);
 
                if (instances_hold->end_zone) {
-                       itt = icaltime_from_timet_with_zone (
-                               end, dtend.value && dtend.value->is_date,
+                       itt = i_cal_time_from_timet_with_zone (i_cal_time_as_timet (end),
+                               dtend && e_cal_component_datetime_get_value (dtend) && i_cal_time_is_date 
(e_cal_component_datetime_get_value (dtend)),
                                instances_hold->end_zone);
-                       g_free ((gchar *) dtend.tzid);
-                       dtend.tzid = g_strdup (icaltimezone_get_tzid (
-                               instances_hold->end_zone));
-               } else if (dtend.value && dtend.value->is_date && !dtend.tzid && 
instances_hold->default_zone) {
+                       if (dtend)
+                               e_cal_component_datetime_set_tzid (dtend, i_cal_timezone_get_tzid 
(instances_hold->end_zone));
+               } else if (dtend && instances_hold->default_zone &&
+                          e_cal_component_datetime_get_value (dtend) &&
+                          i_cal_time_is_date (e_cal_component_datetime_get_value (dtend)) &&
+                          !e_cal_component_datetime_get_tzid (dtend)) {
                        /* Floating date, set in the default zone */
-                       itt = icaltime_from_timet_with_zone (end, TRUE, instances_hold->default_zone);
+                       itt = i_cal_time_from_timet_with_zone (i_cal_time_as_timet (end), TRUE, 
instances_hold->default_zone);
                } else {
-                       itt = icaltime_from_timet_with_zone (end, dtend.value && dtend.value->is_date, NULL);
-                       if (dtend.tzid) {
-                               g_free ((gchar *) dtend.tzid);
-                               dtend.tzid = NULL;
-                       }
+                       itt = i_cal_time_from_timet_with_zone (i_cal_time_as_timet (end),
+                               dtend && e_cal_component_datetime_get_value (dtend) && i_cal_time_is_date 
(e_cal_component_datetime_get_value (dtend)),
+                               NULL);
+                       if (dtend)
+                               e_cal_component_datetime_set_tzid (dtend, NULL);
                }
 
-               g_free (dtend.value);
-               dtend.value = &itt;
-               e_cal_component_set_dtend (ci->comp, &dtend);
+               if (dtend)
+                       e_cal_component_datetime_set_value (dtend, itt);
+               else
+                       dtend = e_cal_component_datetime_new (itt, instances_hold->end_zone ? 
i_cal_timezone_get_tzid (instances_hold->end_zone) : NULL);
 
-               g_free ((gchar *) dtend.tzid);
+               e_cal_component_set_dtend (ci->comp, dtend);
+
+               e_cal_component_datetime_free (dtend);
+               g_clear_object (&itt);
        }
 
-       ci->start = start;
-       ci->end = end;
+       ci->start = i_cal_time_as_timet (start);
+       ci->end = i_cal_time_as_timet (end);
 
        *list = g_slist_prepend (*list, ci);
 
@@ -2397,33 +2238,43 @@ compare_comp_instance (gconstpointer a,
 
 static time_t
 convert_to_tt_with_zone (const ECalComponentDateTime *dt,
-                        ECalRecurResolveTimezoneFn tz_cb,
+                        ECalRecurResolveTimezoneCb tz_cb,
                         gpointer tz_cb_data,
-                        icaltimezone *default_timezone)
+                        ICalTimezone *default_timezone)
 {
-       icaltimezone *zone = default_timezone;
+       ICalTimezone *zone = NULL;
+       ICalTimetype *value;
+       time_t tt;
 
-       if (!dt || !dt->value)
-               return (time_t) 0;
+       value = dt ? e_cal_component_datetime_get_value (dt) : NULL;
 
-       if (icaltime_is_utc (*dt->value)) {
-               zone = icaltimezone_get_utc_timezone ();
-       } else if (tz_cb && !dt->value->is_date && dt->tzid) {
-               zone = (*tz_cb) (dt->tzid, tz_cb_data);
+       if (!dt || !value)
+               return (time_t) 0;
 
-               if (!zone)
-                       zone = default_timezone;
+       if (i_cal_time_is_utc (value)) {
+               zone = i_cal_timezone_get_utc_timezone ();
+               if (zone)
+                       g_object_ref (zone);
+       } else if (tz_cb && !i_cal_time_is_date (value) && e_cal_component_datetime_get_tzid (dt)) {
+               zone = (*tz_cb) (e_cal_component_datetime_get_tzid (dt), tz_cb_data, NULL, NULL);
        }
 
-       return icaltime_as_timet_with_zone (*dt->value, zone);
+       if (!zone)
+               zone = default_timezone ? g_object_ref (default_timezone) : NULL;
+
+       tt = i_cal_time_as_timet_with_zone (value, zone);
+
+       g_clear_object (&zone);
+
+       return tt;
 }
 
 static GSList *
 process_detached_instances (GSList *instances,
                            GSList *detached_instances,
-                           ECalRecurResolveTimezoneFn tz_cb,
+                           ECalRecurResolveTimezoneCb tz_cb,
                            gpointer tz_cb_data,
-                           icaltimezone *default_timezone)
+                           ICalTimezone *default_timezone)
 {
        struct comp_instance *ci, *cid;
        GSList *dl, *unprocessed_instances = NULL;
@@ -2432,21 +2283,23 @@ process_detached_instances (GSList *instances,
                GSList *il;
                const gchar *uid;
                gboolean processed;
-               ECalComponentRange recur_id;
+               ECalComponentRange *recur_id;
                time_t d_rid, i_rid;
 
                processed = FALSE;
-               recur_id.type = E_CAL_COMPONENT_RANGE_SINGLE;
-               recur_id.datetime.value = NULL;
 
                cid = dl->data;
-               e_cal_component_get_uid (cid->comp, &uid);
-               e_cal_component_get_recurid (cid->comp, &recur_id);
+               uid = e_cal_component_get_uid (cid->comp);
+               recur_id = e_cal_component_get_recurid (cid->comp);
 
-               if (!recur_id.datetime.value)
+               if (!recur_id ||
+                   !e_cal_component_range_get_datetime (recur_id) ||
+                   !e_cal_component_datetime_get_value (e_cal_component_range_get_datetime (recur_id))) {
+                       e_cal_component_range_free (recur_id);
                        continue;
+               }
 
-               d_rid = convert_to_tt_with_zone (&recur_id.datetime, tz_cb, tz_cb_data, default_timezone);
+               d_rid = convert_to_tt_with_zone (e_cal_component_range_get_datetime (recur_id), tz_cb, 
tz_cb_data, default_timezone);
 
                /* search for coincident instances already expanded */
                for (il = instances; il != NULL; il = il->next) {
@@ -2454,17 +2307,16 @@ process_detached_instances (GSList *instances,
                        gint cmp;
 
                        ci = il->data;
-                       e_cal_component_get_uid (ci->comp, &instance_uid);
-
-                       if (strcmp (uid, instance_uid) == 0) {
-                               ECalComponentRange instance_recur_id;
+                       instance_uid = e_cal_component_get_uid (ci->comp);
 
-                               instance_recur_id.type = E_CAL_COMPONENT_RANGE_SINGLE;
-                               instance_recur_id.datetime.value = NULL;
+                       if (g_strcmp0 (uid, instance_uid) == 0) {
+                               ECalComponentRange *instance_recur_id;
 
-                               e_cal_component_get_recurid (ci->comp, &instance_recur_id);
+                               instance_recur_id = e_cal_component_get_recurid (ci->comp);
 
-                               if (!instance_recur_id.datetime.value) {
+                               if (!instance_recur_id ||
+                                   !e_cal_component_range_get_datetime (instance_recur_id) ||
+                                   !e_cal_component_datetime_get_value (e_cal_component_range_get_datetime 
(instance_recur_id))) {
                                        /*
                                         * Prevent obvious segfault by ignoring missing
                                         * recurrency ids. Real problem might be elsewhere,
@@ -2472,13 +2324,13 @@ process_detached_instances (GSList *instances,
                                         */
                                        g_warning ("UID %s: instance RECURRENCE-ID and detached instance 
RECURRENCE-ID cannot compare", uid);
 
-                                       e_cal_component_free_range (&instance_recur_id);
+                                       e_cal_component_range_free (instance_recur_id);
                                        continue;
                                }
 
-                               i_rid = convert_to_tt_with_zone (&instance_recur_id.datetime, tz_cb, 
tz_cb_data, default_timezone);
+                               i_rid = convert_to_tt_with_zone (e_cal_component_range_get_datetime 
(instance_recur_id), tz_cb, tz_cb_data, default_timezone);
 
-                               if (recur_id.type == E_CAL_COMPONENT_RANGE_SINGLE && i_rid == d_rid) {
+                               if (e_cal_component_range_get_kind (recur_id) == E_CAL_COMPONENT_RANGE_SINGLE 
&& i_rid == d_rid) {
                                        g_object_unref (ci->comp);
                                        ci->comp = g_object_ref (cid->comp);
                                        ci->start = cid->start;
@@ -2487,15 +2339,12 @@ process_detached_instances (GSList *instances,
                                        processed = TRUE;
                                } else {
                                        cmp = i_rid == d_rid ? 0 : i_rid < d_rid ? -1 : 1;
-                                       if ((recur_id.type == E_CAL_COMPONENT_RANGE_THISPRIOR && cmp <= 0) ||
-                                               (recur_id.type == E_CAL_COMPONENT_RANGE_THISFUTURE && cmp >= 
0)) {
+                                       if ((e_cal_component_range_get_kind (recur_id) == 
E_CAL_COMPONENT_RANGE_THISPRIOR && cmp <= 0) ||
+                                           (e_cal_component_range_get_kind (recur_id) == 
E_CAL_COMPONENT_RANGE_THISFUTURE && cmp >= 0)) {
                                                ECalComponent *comp;
 
-                                               comp = e_cal_component_new ();
-                                               e_cal_component_set_icalcomponent (
-                                                       comp,
-                                                       icalcomponent_new_clone 
(e_cal_component_get_icalcomponent (cid->comp)));
-                                               e_cal_component_set_recurid (comp, &instance_recur_id);
+                                               comp = e_cal_component_clone (cid->comp);
+                                               e_cal_component_set_recurid (comp, instance_recur_id);
 
                                                /* replace the generated instances */
                                                g_object_unref (ci->comp);
@@ -2503,11 +2352,11 @@ process_detached_instances (GSList *instances,
                                        }
                                }
 
-                               e_cal_component_free_range (&instance_recur_id);
+                               e_cal_component_range_free (instance_recur_id);
                        }
                }
 
-               e_cal_component_free_datetime (&recur_id.datetime);
+               e_cal_component_range_free (recur_id);
 
                if (!processed)
                        unprocessed_instances = g_slist_prepend (unprocessed_instances, cid);
@@ -2535,13 +2384,13 @@ generate_instances (ECalClient *client,
                     time_t end,
                     GSList *objects,
                     GCancellable *cancellable,
-                    ECalRecurInstanceFn cb,
+                    ECalRecurInstanceCb cb,
                     gpointer cb_data)
 {
        GSList *instances, *detached_instances = NULL;
        GSList *l;
        ECalClientPrivate *priv;
-       icaltimezone *default_zone;
+       ICalTimezone *default_zone;
 
        priv = client->priv;
 
@@ -2550,7 +2399,7 @@ generate_instances (ECalClient *client,
        if (priv->default_zone)
                default_zone = priv->default_zone;
        else
-               default_zone = icaltimezone_get_utc_timezone ();
+               default_zone = i_cal_timezone_get_utc_timezone ();
 
        for (l = objects; l && !g_cancellable_is_cancelled (cancellable); l = l->next) {
                ECalComponent *comp;
@@ -2558,98 +2407,90 @@ generate_instances (ECalClient *client,
                comp = l->data;
                if (e_cal_component_is_instance (comp)) {
                        struct comp_instance *ci;
-                       ECalComponentDateTime dtstart, dtend;
-                       icaltimezone *start_zone = NULL, *end_zone = NULL;
+                       ECalComponentDateTime *dtstart, *dtend;
+                       ICalTimezone *start_zone = NULL, *end_zone = NULL;
 
                        /* keep the detached instances apart */
                        ci = g_new0 (struct comp_instance, 1);
                        ci->comp = g_object_ref (comp);
 
-                       e_cal_component_get_dtstart (comp, &dtstart);
-                       e_cal_component_get_dtend (comp, &dtend);
+                       dtstart = e_cal_component_get_dtstart (comp);
+                       dtend = e_cal_component_get_dtend (comp);
 
                        /* For DATE-TIME values with a TZID, we use
                         * e_cal_resolve_tzid_cb to resolve the TZID.
                         * For DATE values and DATE-TIME values without a
                         * TZID (i.e. floating times) we use the default
                         * timezone. */
-                       if (dtstart.tzid && dtstart.value && !dtstart.value->is_date) {
-                               start_zone = e_cal_client_resolve_tzid_cb (
-                                       dtstart.tzid, client);
+                       if (dtstart && e_cal_component_datetime_get_tzid (dtstart) && 
e_cal_component_datetime_get_value (dtstart) &&
+                           !i_cal_timetype_get_is_date (e_cal_component_datetime_get_value (dtstart))) {
+                               start_zone = e_cal_client_tzlookup_cb (e_cal_component_datetime_get_tzid 
(dtstart), client, cancellable, NULL);
                                if (!start_zone)
                                        start_zone = default_zone;
                        } else {
                                start_zone = default_zone;
                        }
 
-                       if (dtend.tzid && dtend.value && !dtend.value->is_date) {
-                               end_zone = e_cal_client_resolve_tzid_cb (
-                                       dtend.tzid, client);
+                       if (dtend && e_cal_component_datetime_get_tzid (dtend) && 
e_cal_component_datetime_get_value (dtend) &&
+                           !i_cal_timetype_get_is_date (e_cal_component_datetime_get_value (dtend))) {
+                               end_zone = e_cal_client_tzlookup_cb (e_cal_component_datetime_get_tzid 
(dtend), client, cancellable, NULL);
                                if (!end_zone)
                                        end_zone = default_zone;
                        } else {
                                end_zone = default_zone;
                        }
 
-                       if (!dtstart.value) {
+                       if (!dtstart || !e_cal_component_datetime_get_value (dtstart)) {
                                g_warn_if_reached ();
 
-                               e_cal_component_free_datetime (&dtstart);
-                               e_cal_component_free_datetime (&dtend);
+                               e_cal_component_datetime_free (dtstart);
+                               e_cal_component_datetime_free (dtend);
                                g_object_unref (G_OBJECT (ci->comp));
                                g_free (ci);
 
                                continue;
                        }
 
-                       if (dtstart.value) {
-                               ci->start = icaltime_as_timet_with_zone (
-                                       *dtstart.value, start_zone);
-                       }
+                       ci->start = i_cal_time_as_timet_with_zone (e_cal_component_datetime_get_value 
(dtstart), start_zone);
 
-                       if (dtend.value)
-                               ci->end = icaltime_as_timet_with_zone (
-                                       *dtend.value, end_zone);
-                       else if (dtstart.value && icaltime_is_date (*dtstart.value))
+                       if (dtend && e_cal_component_datetime_get_value (dtend))
+                               ci->end = i_cal_time_as_timet_with_zone (e_cal_component_datetime_get_value 
(dtend), end_zone);
+                       else if (i_cal_time_is_date (e_cal_component_datetime_get_value (dtstart)))
                                ci->end = time_day_end (ci->start);
                        else
                                ci->end = ci->start;
 
-                       e_cal_component_free_datetime (&dtstart);
-                       e_cal_component_free_datetime (&dtend);
+                       e_cal_component_datetime_free (dtstart);
+                       e_cal_component_datetime_free (dtend);
 
                        if (ci->start <= end && ci->end >= start) {
-                               detached_instances = g_slist_prepend (
-                                       detached_instances, ci);
+                               detached_instances = g_slist_prepend (detached_instances, ci);
                        } else {
                                /* it doesn't fit to our time range, thus skip it */
                                g_object_unref (G_OBJECT (ci->comp));
                                g_free (ci);
                        }
                } else {
-                       ECalComponentDateTime datetime;
-                       icaltimezone *start_zone = NULL, *end_zone = NULL;
+                       ECalComponentDateTime *datetime;
+                       ICalTimezone *start_zone = NULL, *end_zone = NULL;
+                       ICalTimetype *starttt, *endtt;
                        struct instances_info *instances_hold;
 
                        /* Get the start timezone */
-                       e_cal_component_get_dtstart (comp, &datetime);
-                       if (datetime.tzid)
-                               e_cal_client_get_timezone_sync (
-                                       client, datetime.tzid,
-                                       &start_zone, cancellable, NULL);
+                       datetime = e_cal_component_get_dtstart (comp);
+                       if (datetime && e_cal_component_datetime_get_tzid (datetime))
+                               e_cal_client_get_timezone_sync (client, e_cal_component_datetime_get_tzid 
(datetime), &start_zone, cancellable, NULL);
                        else
                                start_zone = NULL;
-                       e_cal_component_free_datetime (&datetime);
+                       e_cal_component_datetime_free (datetime);
 
                        /* Get the end timezone */
-                       e_cal_component_get_dtend (comp, &datetime);
-                       if (datetime.tzid)
-                               e_cal_client_get_timezone_sync (
-                                       client, datetime.tzid,
-                                       &end_zone, cancellable, NULL);
+                       datetime = e_cal_component_get_dtend (comp);
+                       if (datetime && e_cal_component_datetime_get_tzid (datetime))
+                               e_cal_client_get_timezone_sync (client, e_cal_component_datetime_get_tzid 
(datetime), &end_zone, cancellable, NULL);
                        else
                                end_zone = NULL;
-                       e_cal_component_free_datetime (&datetime);
+                       e_cal_component_datetime_free (datetime);
 
                        instances_hold = g_new0 (struct instances_info, 1);
                        instances_hold->instances = &instances;
@@ -2657,33 +2498,44 @@ generate_instances (ECalClient *client,
                        instances_hold->end_zone = end_zone;
                        instances_hold->default_zone = default_zone;
 
-                       e_cal_recur_generate_instances (
-                               comp, start, end, add_instance, instances_hold,
-                               e_cal_client_resolve_tzid_cb, client,
-                               default_zone);
+                       starttt = i_cal_time_from_timet_with_zone (start, FALSE, NULL);
+                       endtt = i_cal_time_from_timet_with_zone (end, FALSE, NULL);
+
+                       e_cal_recur_generate_instances_sync (
+                               e_cal_component_get_icalcomponent (comp), starttt, endtt, add_instance_cb, 
instances_hold,
+                               e_cal_client_tzlookup_cb, client,
+                               default_zone, cancellable, NULL);
 
+                       g_clear_object (&starttt);
+                       g_clear_object (&endtt);
                        g_free (instances_hold);
                }
        }
 
-       g_slist_foreach (objects, (GFunc) g_object_unref, NULL);
-       g_slist_free (objects);
+       g_slist_free_full (objects, g_object_unref);
 
        /* Generate instances and spew them out */
 
        if (!g_cancellable_is_cancelled (cancellable)) {
                instances = g_slist_sort (instances, compare_comp_instance);
                instances = process_detached_instances (instances, detached_instances,
-                       e_cal_client_resolve_tzid_cb, client, default_zone);
+                       e_cal_client_tzlookup_cb, client, default_zone);
        }
 
        for (l = instances; l && !g_cancellable_is_cancelled (cancellable); l = l->next) {
                struct comp_instance *ci;
+               ICalTimetype *starttt, *endtt;
                gboolean result;
 
                ci = l->data;
 
-               result = (* cb) (ci->comp, ci->start, ci->end, cb_data);
+               starttt = i_cal_time_from_timet_with_zone (ci->start, FALSE, default_zone);
+               endtt = i_cal_time_from_timet_with_zone (ci->end, FALSE, default_zone);
+
+               result = (* cb) (e_cal_component_get_icalcomponent (ci->comp), starttt, endtt, cb_data, 
cancellable, NULL);
+
+               g_clear_object (&starttt);
+               g_clear_object (&endtt);
 
                if (!result)
                        break;
@@ -2770,15 +2622,15 @@ struct get_objects_async_data {
        ECalClient *client;
        time_t start;
        time_t end;
-       ECalRecurInstanceFn cb;
+       ECalRecurInstanceCb cb;
        gpointer cb_data;
        GDestroyNotify destroy_cb_data;
        gchar *uid;
        gchar *query;
        guint tries;
        void (* ready_cb) (struct get_objects_async_data *goad, GSList *objects);
-       icaltimezone *start_zone;
-       icaltimezone *end_zone;
+       ICalTimezone *start_zone;
+       ICalTimezone *end_zone;
        ECalComponent *comp;
 };
 
@@ -2944,7 +2796,7 @@ generate_instances_got_objects_cb (struct get_objects_async_data *goad,
  *                   @cb_data; can be %NULL.
  *
  * Does a combination of e_cal_client_get_object_list() and
- * e_cal_recur_generate_instances(). Unlike
+ * e_cal_recur_generate_instances_sync(). Unlike
  * e_cal_client_generate_instances_sync(), this returns immediately and the
  * @cb callback is called asynchronously.
  *
@@ -2959,7 +2811,7 @@ e_cal_client_generate_instances (ECalClient *client,
                                  time_t start,
                                  time_t end,
                                  GCancellable *cancellable,
-                                 ECalRecurInstanceFn cb,
+                                 ECalRecurInstanceCb cb,
                                  gpointer cb_data,
                                  GDestroyNotify destroy_cb_data)
 {
@@ -3000,7 +2852,7 @@ e_cal_client_generate_instances (ECalClient *client,
  * @cb_data: (closure): Closure data for the callback
  *
  * Does a combination of e_cal_client_get_object_list() and
- * e_cal_recur_generate_instances().
+ * e_cal_recur_generate_instances_sync().
  *
  * The callback function should do a g_object_ref() of the calendar component
  * it gets passed if it intends to keep it around, since it will be unreffed
@@ -3012,7 +2864,7 @@ void
 e_cal_client_generate_instances_sync (ECalClient *client,
                                       time_t start,
                                       time_t end,
-                                      ECalRecurInstanceFn cb,
+                                      ECalRecurInstanceCb cb,
                                       gpointer cb_data)
 {
        GSList *objects = NULL;
@@ -3033,20 +2885,22 @@ e_cal_client_generate_instances_sync (ECalClient *client,
 
 /* also frees 'instances' GSList */
 static void
-process_instances (ECalComponent *comp,
+process_instances (ECalClient *client,
+                  ECalComponent *comp,
                    GSList *instances,
-                   ECalRecurInstanceFn cb,
+                   ECalRecurInstanceCb cb,
                    gpointer cb_data)
 {
        gchar *rid;
        gboolean result;
 
+       g_return_if_fail (E_IS_CAL_CLIENT (client));
        g_return_if_fail (comp != NULL);
        g_return_if_fail (cb != NULL);
 
        rid = e_cal_component_get_recurid_as_string (comp);
 
-       /* Reverse the instances list because the add_instance() function
+       /* Reverse the instances list because the add_instance_cb() function
         * is prepending. */
        instances = g_slist_reverse (instances);
 
@@ -3059,13 +2913,26 @@ process_instances (ECalComponent *comp,
                ci = instances->data;
 
                if (result) {
+                       ICalTimetype *starttt = NULL, *endtt = NULL;
+
                        instance_rid = e_cal_component_get_recurid_as_string (ci->comp);
 
                        if (rid && *rid) {
-                               if (instance_rid && *instance_rid && strcmp (rid, instance_rid) == 0)
-                                       result = (* cb) (ci->comp, ci->start, ci->end, cb_data);
-                       } else
-                               result = (* cb) (ci->comp, ci->start, ci->end, cb_data);
+                               if (instance_rid && *instance_rid && strcmp (rid, instance_rid) == 0) {
+                                       starttt = i_cal_time_from_timet_with_zone (ci->start, FALSE, 
client->priv->default_zone);
+                                       endtt = i_cal_time_from_timet_with_zone (ci->end, FALSE, 
client->priv->default_zone);
+
+                                       result = (* cb) (e_cal_component_get_icalcomponent (ci->comp), 
starttt, endtt, cb_data, NULL, NULL);
+                               }
+                       } else {
+                               starttt = i_cal_time_from_timet_with_zone (ci->start, FALSE, 
client->priv->default_zone);
+                               endtt = i_cal_time_from_timet_with_zone (ci->end, FALSE, 
client->priv->default_zone);
+
+                               result = (* cb) (e_cal_component_get_icalcomponent (ci->comp), starttt, 
endtt, cb_data, NULL, NULL);
+                       }
+
+                       g_clear_object (&starttt);
+                       g_clear_object (&endtt);
                }
 
                /* remove instance from list */
@@ -3097,11 +2964,11 @@ generate_instances_for_object_got_objects_cb (struct get_objects_async_data *goa
        /* generate all instances in the given time range */
        generate_instances (
                goad->client, goad->start, goad->end, objects,
-               goad->cancellable, add_instance, instances_hold);
+               goad->cancellable, add_instance_cb, instances_hold);
 
        /* it also frees 'instances' GSList */
        process_instances (
-               goad->comp, *(instances_hold->instances),
+               goad->client, goad->comp, *(instances_hold->instances),
                goad->cb, goad->cb_data);
 
        /* clean up */
@@ -3122,7 +2989,7 @@ generate_instances_for_object_got_objects_cb (struct get_objects_async_data *goa
  *                   free @cb_data; can be %NULL.
  *
  * Does a combination of e_cal_client_get_object_list() and
- * e_cal_recur_generate_instances(), like
+ * e_cal_recur_generate_instances_sync(), like
  * e_cal_client_generate_instances(), but for a single object. Unlike
  * e_cal_client_generate_instances_for_object_sync(), this returns immediately
  * and the @cb callback is called asynchronously.
@@ -3135,19 +3002,18 @@ generate_instances_for_object_got_objects_cb (struct get_objects_async_data *goa
  **/
 void
 e_cal_client_generate_instances_for_object (ECalClient *client,
-                                            icalcomponent *icalcomp,
+                                            ICalComponent *icalcomp,
                                             time_t start,
                                             time_t end,
                                             GCancellable *cancellable,
-                                            ECalRecurInstanceFn cb,
+                                            ECalRecurInstanceCb cb,
                                             gpointer cb_data,
                                             GDestroyNotify destroy_cb_data)
 {
        ECalComponent *comp;
        const gchar *uid;
-       ECalComponentDateTime datetime;
-       icaltimezone *start_zone = NULL, *end_zone = NULL;
-       gboolean is_single_instance = FALSE;
+       ECalComponentDateTime *datetime;
+       ICalTimezone *start_zone = NULL, *end_zone = NULL;
        struct get_objects_async_data *goad;
        GCancellable *use_cancellable;
 
@@ -3157,50 +3023,47 @@ e_cal_client_generate_instances_for_object (ECalClient *client,
        g_return_if_fail (end >= 0);
        g_return_if_fail (cb != NULL);
 
-       comp = e_cal_component_new ();
-       e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
-
-       if (!e_cal_component_has_recurrences (comp))
-               is_single_instance = TRUE;
-
        /* If the backend stores it as individual instances and does not
         * have a master object - do not expand */
-       if (is_single_instance || e_client_check_capability (E_CLIENT (client), 
E_CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER)) {
+       if (!e_cal_util_component_has_recurrences (icalcomp) || e_client_check_capability (E_CLIENT (client), 
E_CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER)) {
+               ICalTimetype *dtstart, *dtend;
+
+               dtstart = i_cal_component_get_dtstart (icalcomp);
+               dtend = i_cal_component_get_dtend (icalcomp);
+
                /* return the same instance */
-               (* cb)  (comp,
-                       icaltime_as_timet_with_zone (
-                               icalcomponent_get_dtstart (icalcomp),
-                               client->priv->default_zone),
-                       icaltime_as_timet_with_zone (
-                               icalcomponent_get_dtend (icalcomp),
-                               client->priv->default_zone),
-                       cb_data);
-               g_object_unref (comp);
+               (* cb)  (icalcomp, dtstart, dtend, cb_data, NULL, NULL);
+
+               g_clear_object (&dtstart);
+               g_clear_object (&dtend);
 
                if (destroy_cb_data)
                        destroy_cb_data (cb_data);
                return;
        }
 
-       e_cal_component_get_uid (comp, &uid);
+       comp = e_cal_component_new_from_icalcomponent (i_cal_component_new_clone (icalcomp));
+       g_return_if_fail (comp != NULL);
+
+       uid = e_cal_component_get_uid (comp);
 
        /* Get the start timezone */
-       e_cal_component_get_dtstart (comp, &datetime);
-       if (datetime.tzid)
+       datetime = e_cal_component_get_dtstart (comp);
+       if (datetime && e_cal_component_datetime_get_tzid (datetime))
                e_cal_client_get_timezone_sync (
-                       client, datetime.tzid, &start_zone, NULL, NULL);
+                       client, e_cal_component_datetime_get_tzid (datetime), &start_zone, cancellable, NULL);
        else
                start_zone = NULL;
-       e_cal_component_free_datetime (&datetime);
+       e_cal_component_datetime_free (datetime);
 
        /* Get the end timezone */
-       e_cal_component_get_dtend (comp, &datetime);
-       if (datetime.tzid)
+       datetime = e_cal_component_get_dtend (comp);
+       if (datetime && e_cal_component_datetime_get_tzid (datetime))
                e_cal_client_get_timezone_sync (
-                       client, datetime.tzid, &end_zone, NULL, NULL);
+                       client, e_cal_component_datetime_get_tzid (datetime), &end_zone, cancellable, NULL);
        else
                end_zone = NULL;
-       e_cal_component_free_datetime (&datetime);
+       e_cal_component_datetime_free (datetime);
 
        use_cancellable = cancellable;
        if (!use_cancellable)
@@ -3235,7 +3098,7 @@ e_cal_client_generate_instances_for_object (ECalClient *client,
  * @cb_data: (closure): Closure data for the callback
  *
  * Does a combination of e_cal_client_get_object_list() and
- * e_cal_recur_generate_instances(), like
+ * e_cal_recur_generate_instances_sync(), like
  * e_cal_client_generate_instances_sync(), but for a single object.
  *
  * The callback function should do a g_object_ref() of the calendar component
@@ -3246,19 +3109,18 @@ e_cal_client_generate_instances_for_object (ECalClient *client,
  **/
 void
 e_cal_client_generate_instances_for_object_sync (ECalClient *client,
-                                                 icalcomponent *icalcomp,
+                                                 ICalComponent *icalcomp,
                                                  time_t start,
                                                  time_t end,
-                                                 ECalRecurInstanceFn cb,
+                                                 ECalRecurInstanceCb cb,
                                                  gpointer cb_data)
 {
        ECalComponent *comp;
        const gchar *uid;
        GSList *instances = NULL;
-       ECalComponentDateTime datetime;
-       icaltimezone *start_zone = NULL, *end_zone = NULL;
+       ECalComponentDateTime *datetime;
+       ICalTimezone *start_zone = NULL, *end_zone = NULL;
        struct instances_info *instances_hold;
-       gboolean is_single_instance = FALSE;
 
        g_return_if_fail (E_IS_CAL_CLIENT (client));
 
@@ -3266,47 +3128,43 @@ e_cal_client_generate_instances_for_object_sync (ECalClient *client,
        g_return_if_fail (end >= 0);
        g_return_if_fail (cb != NULL);
 
-       comp = e_cal_component_new ();
-       e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
-
-       if (!e_cal_component_has_recurrences (comp))
-               is_single_instance = TRUE;
-
        /* If the backend stores it as individual instances and does not
         * have a master object - do not expand */
-       if (is_single_instance || e_client_check_capability (E_CLIENT (client), 
E_CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER)) {
+       if (!e_cal_util_component_has_recurrences (icalcomp) || e_client_check_capability (E_CLIENT (client), 
E_CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER)) {
+               ICalTimetype *dtstart, *dtend;
+
+               dtstart = i_cal_component_get_dtstart (icalcomp);
+               dtend = i_cal_component_get_dtend (icalcomp);
+
                /* return the same instance */
-               (* cb)  (comp,
-                       icaltime_as_timet_with_zone (
-                               icalcomponent_get_dtstart (icalcomp),
-                               client->priv->default_zone),
-                       icaltime_as_timet_with_zone (
-                               icalcomponent_get_dtend (icalcomp),
-                               client->priv->default_zone),
-                       cb_data);
-               g_object_unref (comp);
+               (* cb)  (icalcomp, dtstart, dtend, cb_data, NULL, NULL);
+
+               g_clear_object (&dtstart);
+               g_clear_object (&dtend);
+
                return;
        }
 
-       e_cal_component_get_uid (comp, &uid);
+       comp = e_cal_component_new_from_icalcomponent (i_cal_component_new_clone (icalcomp));
+       g_return_if_fail (comp != NULL);
+
+       uid = e_cal_component_get_uid (comp);
 
        /* Get the start timezone */
-       e_cal_component_get_dtstart (comp, &datetime);
-       if (datetime.tzid)
-               e_cal_client_get_timezone_sync (
-                       client, datetime.tzid, &start_zone, NULL, NULL);
+       datetime = e_cal_component_get_dtstart (comp);
+       if (datetime && e_cal_component_datetime_get_tzid (datetime))
+               e_cal_client_get_timezone_sync (client, e_cal_component_datetime_get_tzid (datetime), 
&start_zone, NULL, NULL);
        else
                start_zone = NULL;
-       e_cal_component_free_datetime (&datetime);
+       e_cal_component_datetime_free (datetime);
 
        /* Get the end timezone */
-       e_cal_component_get_dtend (comp, &datetime);
-       if (datetime.tzid)
-               e_cal_client_get_timezone_sync (
-                       client, datetime.tzid, &end_zone, NULL, NULL);
+       datetime = e_cal_component_get_dtend (comp);
+       if (datetime && e_cal_component_datetime_get_tzid (datetime))
+               e_cal_client_get_timezone_sync (client, e_cal_component_datetime_get_tzid (datetime), 
&end_zone, NULL, NULL);
        else
                end_zone = NULL;
-       e_cal_component_free_datetime (&datetime);
+       e_cal_component_datetime_free (datetime);
 
        instances_hold = g_new0 (struct instances_info, 1);
        instances_hold->instances = &instances;
@@ -3318,10 +3176,10 @@ e_cal_client_generate_instances_for_object_sync (ECalClient *client,
        generate_instances (
                client, start, end,
                get_objects_sync (client, start, end, uid),
-               NULL, add_instance, instances_hold);
+               NULL, add_instance_cb, instances_hold);
 
        /* it also frees 'instances' GSList */
-       process_instances (comp, *(instances_hold->instances), cb, cb_data);
+       process_instances (client, comp, *(instances_hold->instances), cb, cb_data);
 
        /* clean up */
        g_object_unref (comp);
@@ -3338,17 +3196,17 @@ struct _ForeachTZIDCallbackData {
 /* This adds the VTIMEZONE given by the TZID parameter to the GHashTable in
  * data. */
 static void
-foreach_tzid_callback (icalparameter *param,
+foreach_tzid_callback (ICalParameter *param,
                        gpointer cbdata)
 {
        ForeachTZIDCallbackData *data = cbdata;
        const gchar *tzid;
-       icaltimezone *zone = NULL;
-       icalcomponent *vtimezone_comp;
+       ICalTimezone *zone = NULL;
+       ICalComponent *vtimezone_comp;
        gchar *vtimezone_as_string;
 
        /* Get the TZID string from the parameter. */
-       tzid = icalparameter_get_tzid (param);
+       tzid = i_cal_parameter_get_tzid (param);
        if (!tzid)
                return;
 
@@ -3362,11 +3220,11 @@ foreach_tzid_callback (icalparameter *param,
        }
 
        /* Convert it to a string and add it to the hash. */
-       vtimezone_comp = icaltimezone_get_component (zone);
+       vtimezone_comp = i_cal_timezone_get_component (zone);
        if (!vtimezone_comp)
                return;
 
-       vtimezone_as_string = icalcomponent_as_ical_string_r (vtimezone_comp);
+       vtimezone_as_string = i_cal_component_as_ical_string_r (vtimezone_comp);
 
        g_hash_table_insert (data->timezone_hash, (gchar *) tzid, vtimezone_as_string);
 }
@@ -3407,7 +3265,7 @@ free_timezone_string (gpointer key,
  **/
 gchar *
 e_cal_client_get_component_as_string (ECalClient *client,
-                                      icalcomponent *icalcomp)
+                                      ICalComponent *icalcomp)
 {
        GHashTable *timezone_hash;
        GString *vcal_string;
@@ -3424,7 +3282,7 @@ e_cal_client_get_component_as_string (ECalClient *client,
        cbdata.client = client;
        cbdata.timezone_hash = timezone_hash;
        cbdata.success = TRUE;
-       icalcomponent_foreach_tzid (icalcomp, foreach_tzid_callback, &cbdata);
+       i_cal_component_foreach_tzid (icalcomp, foreach_tzid_callback, &cbdata);
        if (!cbdata.success) {
                g_hash_table_foreach (timezone_hash, free_timezone_string, NULL);
                return NULL;
@@ -3445,7 +3303,7 @@ e_cal_client_get_component_as_string (ECalClient *client,
        g_hash_table_foreach (timezone_hash, append_timezone_string, vcal_string);
 
        /* Get the string for the VEVENT/VTODO. */
-       obj_string = icalcomponent_as_ical_string_r (icalcomp);
+       obj_string = i_cal_component_as_ical_string_r (icalcomp);
 
        /* If there were any timezones to send, create a complete VCALENDAR,
         * else just send the VEVENT/VTODO string. */
@@ -3494,7 +3352,7 @@ cal_client_get_default_object_thread (GSimpleAsyncResult *simple,
  * @callback: callback to call when a result is ready
  * @user_data: user data for the @callback
  *
- * Retrives an #icalcomponent from the backend that contains the default
+ * Retrives an #ICalComponent from the backend that contains the default
  * values for properties needed. The call is finished
  * by e_cal_client_get_default_object_finish() from the @callback.
  *
@@ -3533,13 +3391,13 @@ e_cal_client_get_default_object (ECalClient *client,
  * e_cal_client_get_default_object_finish:
  * @client: an #ECalClient
  * @result: a #GAsyncResult
- * @out_icalcomp: (out): Return value for the default calendar object.
+ * @out_icalcomp: (out) (transfer full): Return value for the default calendar object.
  * @error: (out): a #GError to set an error, if any
  *
  * Finishes previous call of e_cal_client_get_default_object() and
- * sets @out_icalcomp to an #icalcomponent from the backend that contains
+ * sets @out_icalcomp to an #ICalComponent from the backend that contains
  * the default values for properties needed. This @out_icalcomp should be
- * freed with icalcomponent_free().
+ * freed with g_object_unref(), when no longer needed.
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
@@ -3548,7 +3406,7 @@ e_cal_client_get_default_object (ECalClient *client,
 gboolean
 e_cal_client_get_default_object_finish (ECalClient *client,
                                         GAsyncResult *result,
-                                        icalcomponent **out_icalcomp,
+                                        ICalComponent **out_icalcomp,
                                         GError **error)
 {
        GSimpleAsyncResult *simple;
@@ -3578,13 +3436,13 @@ e_cal_client_get_default_object_finish (ECalClient *client,
 /**
  * e_cal_client_get_default_object_sync:
  * @client: an #ECalClient
- * @out_icalcomp: (out): Return value for the default calendar object.
+ * @out_icalcomp: (out) (transfer full): Return value for the default calendar object.
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
- * Retrives an #icalcomponent from the backend that contains the default
+ * Retrives an #ICalComponent from the backend that contains the default
  * values for properties needed. This @out_icalcomp should be freed with
- * icalcomponent_free().
+ * g_object_unref(), when no longer needed.
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
@@ -3592,11 +3450,11 @@ e_cal_client_get_default_object_finish (ECalClient *client,
  **/
 gboolean
 e_cal_client_get_default_object_sync (ECalClient *client,
-                                      icalcomponent **out_icalcomp,
+                                      ICalComponent **out_icalcomp,
                                       GCancellable *cancellable,
                                       GError **error)
 {
-       icalcomponent *icalcomp = NULL;
+       ICalComponent *icalcomp = NULL;
        gchar *string;
 
        g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
@@ -3604,7 +3462,7 @@ e_cal_client_get_default_object_sync (ECalClient *client,
 
        string = e_dbus_calendar_dup_default_object (client->priv->dbus_proxy);
        if (string != NULL) {
-               icalcomp = icalparser_parse_string (string);
+               icalcomp = i_cal_parser_parse_string (string);
                g_free (string);
        }
 
@@ -3617,12 +3475,12 @@ e_cal_client_get_default_object_sync (ECalClient *client,
                return FALSE;
        }
 
-       if (icalcomponent_get_uid (icalcomp) != NULL) {
+       if (i_cal_component_get_uid (icalcomp) != NULL) {
                gchar *new_uid;
 
                /* Make sure the UID is always unique. */
                new_uid = e_util_generate_uid ();
-               icalcomponent_set_uid (icalcomp, new_uid);
+               i_cal_component_set_uid (icalcomp, new_uid);
                g_free (new_uid);
        }
 
@@ -3718,13 +3576,13 @@ e_cal_client_get_object (ECalClient *client,
  * e_cal_client_get_object_finish:
  * @client: an #ECalClient
  * @result: a #GAsyncResult
- * @out_icalcomp: (out): Return value for the calendar component object.
+ * @out_icalcomp: (out) (transfer full): Return value for the calendar component object.
  * @error: (out): a #GError to set an error, if any
  *
  * Finishes previous call of e_cal_client_get_object() and
  * sets @out_icalcomp to queried component. This function always returns
  * master object for a case of @rid being NULL or an empty string.
- * This component should be freed with icalcomponent_free().
+ * This component should be freed with g_object_unref(), when no longer needed.
  *
  * Use e_cal_client_get_objects_for_uid() to get list of all
  * objects for the given uid, which includes master object and
@@ -3737,7 +3595,7 @@ e_cal_client_get_object (ECalClient *client,
 gboolean
 e_cal_client_get_object_finish (ECalClient *client,
                                 GAsyncResult *result,
-                                icalcomponent **out_icalcomp,
+                                ICalComponent **out_icalcomp,
                                 GError **error)
 {
        GSimpleAsyncResult *simple;
@@ -3769,14 +3627,15 @@ e_cal_client_get_object_finish (ECalClient *client,
  * @client: an #ECalClient
  * @uid: Unique identifier for a calendar component.
  * @rid: Recurrence identifier.
- * @out_icalcomp: (out): Return value for the calendar component object.
+ * @out_icalcomp: (out) (transfer full): Return value for the calendar component object.
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
  * Queries a calendar for a calendar component object based
  * on its unique identifier. This function always returns
  * master object for a case of @rid being NULL or an empty string.
- * This component should be freed with icalcomponent_free().
+ * This component should be freed with g_object_unref(),
+ * when no longer needed.
  *
  * Use e_cal_client_get_objects_for_uid_sync() to get list of all
  * objects for the given uid, which includes master object and
@@ -3790,12 +3649,12 @@ gboolean
 e_cal_client_get_object_sync (ECalClient *client,
                               const gchar *uid,
                               const gchar *rid,
-                              icalcomponent **out_icalcomp,
+                              ICalComponent **out_icalcomp,
                               GCancellable *cancellable,
                               GError **error)
 {
-       icalcomponent *icalcomp = NULL;
-       icalcomponent_kind kind;
+       ICalComponent *icalcomp = NULL;
+       ICalComponentKind kind;
        gchar *utf8_uid;
        gchar *utf8_rid;
        gchar *string = NULL;
@@ -3805,6 +3664,8 @@ e_cal_client_get_object_sync (ECalClient *client,
        g_return_val_if_fail (uid != NULL, FALSE);
        g_return_val_if_fail (out_icalcomp != NULL, FALSE);
 
+       *out_icalcomp = NULL;
+
        if (rid == NULL)
                rid = "";
 
@@ -3829,7 +3690,7 @@ e_cal_client_get_object_sync (ECalClient *client,
                return FALSE;
        }
 
-       icalcomp = icalparser_parse_string (string);
+       icalcomp = i_cal_parser_parse_string (string);
 
        g_free (string);
 
@@ -3844,55 +3705,61 @@ e_cal_client_get_object_sync (ECalClient *client,
 
        switch (e_cal_client_get_source_type (client)) {
                case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
-                       kind = ICAL_VEVENT_COMPONENT;
+                       kind = I_CAL_VEVENT_COMPONENT;
                        break;
                case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
-                       kind = ICAL_VTODO_COMPONENT;
+                       kind = I_CAL_VTODO_COMPONENT;
                        break;
                case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
-                       kind = ICAL_VJOURNAL_COMPONENT;
+                       kind = I_CAL_VJOURNAL_COMPONENT;
                        break;
                default:
                        g_warn_if_reached ();
-                       kind = ICAL_VEVENT_COMPONENT;
+                       kind = I_CAL_VEVENT_COMPONENT;
                        break;
        }
 
-       if (icalcomponent_isa (icalcomp) == kind) {
+       if (i_cal_component_isa (icalcomp) == kind) {
                *out_icalcomp = icalcomp;
+               icalcomp = NULL;
 
-       } else if (icalcomponent_isa (icalcomp) == ICAL_VCALENDAR_COMPONENT) {
-               icalcomponent *subcomponent;
+       } else if (i_cal_component_isa (icalcomp) == I_CAL_VCALENDAR_COMPONENT) {
+               ICalComponent *subcomponent;
 
-               for (subcomponent = icalcomponent_get_first_component (icalcomp, kind);
-                       subcomponent != NULL;
-                       subcomponent = icalcomponent_get_next_component (icalcomp, kind)) {
-                       struct icaltimetype recurrenceid;
+               for (subcomponent = i_cal_component_get_first_component (icalcomp, kind);
+                    subcomponent != NULL;
+                    g_object_unref (subcomponent), subcomponent = i_cal_component_get_next_component 
(icalcomp, kind)) {
+                       ICalTimetype *recurrenceid;
 
-                       if (icalcomponent_get_uid (subcomponent) == NULL)
+                       if (i_cal_component_get_uid (subcomponent) == NULL)
                                continue;
 
-                       recurrenceid =
-                               icalcomponent_get_recurrenceid (subcomponent);
-
-                       if (icaltime_is_null_time (recurrenceid))
-                               break;
+                       recurrenceid = i_cal_component_get_recurrenceid (subcomponent);
 
-                       if (!icaltime_is_valid_time (recurrenceid))
+                       if (!recurrenceid ||
+                           i_cal_time_is_null_time (recurrenceid) ||
+                           !i_cal_time_is_valid_time (recurrenceid)) {
+                               g_clear_object (&recurrenceid);
                                break;
+                       }
                }
 
                if (subcomponent == NULL)
-                       subcomponent = icalcomponent_get_first_component (icalcomp, kind);
-               if (subcomponent != NULL)
-                       subcomponent = icalcomponent_new_clone (subcomponent);
+                       subcomponent = i_cal_component_get_first_component (icalcomp, kind);
+               if (subcomponent != NULL) {
+                       ICalComponent *clone;
 
-               /* XXX Shouldn't we set an error is this is still NULL? */
-               *out_icalcomp = subcomponent;
+                       clone = i_cal_component_new_clone (subcomponent);
+                       g_object_unref (subcomponent);
+                       subcomponent = clone;
+               }
 
-               icalcomponent_free (icalcomp);
+               /* XXX Shouldn't we set an error if this is still NULL? */
+               *out_icalcomp = subcomponent;
        }
 
+       g_clear_object (&icalcomp);
+
        return TRUE;
 }
 
@@ -3984,7 +3851,7 @@ e_cal_client_get_objects_for_uid (ECalClient *client,
  * Finishes previous call of e_cal_client_get_objects_for_uid() and
  * sets @out_ecalcomps to a list of #ECalComponent<!-- -->s corresponding to
  * found components for a given uid of the same type as this client.
- * This list should be freed with e_cal_client_free_ecalcomp_slist().
+ * This list should be freed with e_client_util_free_object_slist().
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
@@ -4031,7 +3898,7 @@ e_cal_client_get_objects_for_uid_finish (ECalClient *client,
  * Queries a calendar for all calendar components with the given unique
  * ID. This will return any recurring event and all its detached recurrences.
  * For non-recurring events, it will just return the object with that ID.
- * This list should be freed with e_cal_client_free_ecalcomp_slist().
+ * This list should be freed with e_client_util_free_object_slist().
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
@@ -4044,8 +3911,8 @@ e_cal_client_get_objects_for_uid_sync (ECalClient *client,
                                        GCancellable *cancellable,
                                        GError **error)
 {
-       icalcomponent *icalcomp;
-       icalcomponent_kind kind;
+       ICalComponent *icalcomp;
+       ICalComponentKind kind;
        gchar *utf8_uid;
        gchar *string = NULL;
        GError *local_error = NULL;
@@ -4054,6 +3921,8 @@ e_cal_client_get_objects_for_uid_sync (ECalClient *client,
        g_return_val_if_fail (uid != NULL, FALSE);
        g_return_val_if_fail (out_ecalcomps != NULL, FALSE);
 
+       *out_ecalcomps = NULL;
+
        utf8_uid = e_util_utf8_make_valid (uid);
 
        e_dbus_calendar_call_get_object_sync (
@@ -4073,7 +3942,7 @@ e_cal_client_get_objects_for_uid_sync (ECalClient *client,
                return FALSE;
        }
 
-       icalcomp = icalparser_parse_string (string);
+       icalcomp = i_cal_parser_parse_string (string);
 
        g_free (string);
 
@@ -4088,52 +3957,47 @@ e_cal_client_get_objects_for_uid_sync (ECalClient *client,
 
        switch (e_cal_client_get_source_type (client)) {
                case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
-                       kind = ICAL_VEVENT_COMPONENT;
+                       kind = I_CAL_VEVENT_COMPONENT;
                        break;
                case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
-                       kind = ICAL_VTODO_COMPONENT;
+                       kind = I_CAL_VTODO_COMPONENT;
                        break;
                case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
-                       kind = ICAL_VJOURNAL_COMPONENT;
+                       kind = I_CAL_VJOURNAL_COMPONENT;
                        break;
                default:
                        g_warn_if_reached ();
-                       kind = ICAL_VEVENT_COMPONENT;
+                       kind = I_CAL_VEVENT_COMPONENT;
                        break;
        }
 
-       if (icalcomponent_isa (icalcomp) == kind) {
+       if (i_cal_component_isa (icalcomp) == kind) {
                ECalComponent *comp;
 
-               comp = e_cal_component_new ();
-               e_cal_component_set_icalcomponent (comp, icalcomp);
+               comp = e_cal_component_new_from_icalcomponent (icalcomp);
+               icalcomp = NULL;
+
                *out_ecalcomps = g_slist_append (NULL, comp);
 
-       } else if (icalcomponent_isa (icalcomp) == ICAL_VCALENDAR_COMPONENT) {
+       } else if (i_cal_component_isa (icalcomp) == I_CAL_VCALENDAR_COMPONENT) {
                GSList *tmp = NULL;
-               icalcomponent *subcomponent;
-
-               subcomponent = icalcomponent_get_first_component (
-                       icalcomp, kind);
+               ICalComponent *subcomponent;
 
-               while (subcomponent != NULL) {
+               for (subcomponent = i_cal_component_get_first_component (icalcomp, kind);
+                    subcomponent;
+                    g_object_unref (subcomponent), subcomponent = i_cal_component_get_next_component 
(icalcomp, kind)) {
                        ECalComponent *comp;
-                       icalcomponent *clone;
 
-                       comp = e_cal_component_new ();
-                       clone = icalcomponent_new_clone (subcomponent);
-                       e_cal_component_set_icalcomponent (comp, clone);
-                       tmp = g_slist_prepend (tmp, comp);
-
-                       subcomponent = icalcomponent_get_next_component (
-                               icalcomp, kind);
+                       comp = e_cal_component_new_from_icalcomponent (i_cal_component_new_clone 
(subcomponent));
+                       if (comp)
+                               tmp = g_slist_prepend (tmp, comp);
                }
 
                *out_ecalcomps = g_slist_reverse (tmp);
-
-               icalcomponent_free (icalcomp);
        }
 
+       g_clear_object (&icalcomp);
+
        return TRUE;
 }
 
@@ -4174,7 +4038,7 @@ cal_client_get_object_list_thread (GSimpleAsyncResult *simple,
  * @user_data: user data for the @callback
  *
  * Gets a list of objects from the calendar that match the query specified
- * by the @sexp argument, returning matching objects as a list of #icalcomponent-s.
+ * by the @sexp argument, returning matching objects as a list of #ICalComponent-s.
  * The call is finished by e_cal_client_get_object_list_finish() from
  * the @callback.
  *
@@ -4216,13 +4080,13 @@ e_cal_client_get_object_list (ECalClient *client,
  * e_cal_client_get_object_list_finish:
  * @client: an #ECalClient
  * @result: a #GAsyncResult
- * @out_icalcomps: (out) (element-type icalcomponent): list of matching
- *                 #icalcomponent<!-- -->s
+ * @out_icalcomps: (out) (element-type ICalComponent): list of matching
+ *                 #ICalComponent<!-- -->s
  * @error: (out): a #GError to set an error, if any
  *
  * Finishes previous call of e_cal_client_get_object_list() and
- * sets @out_icalcomps to a matching list of #icalcomponent-s.
- * This list should be freed with e_cal_client_free_icalcomp_slist().
+ * sets @out_icalcomps to a matching list of #ICalComponent-s.
+ * This list should be freed with e_client_util_free_object_slist().
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
@@ -4260,15 +4124,15 @@ e_cal_client_get_object_list_finish (ECalClient *client,
  * e_cal_client_get_object_list_sync:
  * @client: an #ECalClient
  * @sexp: an S-expression representing the query
- * @out_icalcomps: (out) (element-type icalcomponent): list of matching
- *                 #icalcomponent<!-- -->s
+ * @out_icalcomps: (out) (element-type ICalComponent): list of matching
+ *                 #ICalComponent<!-- -->s
  * @cancellable: (allow-none): a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
  * Gets a list of objects from the calendar that match the query specified
  * by the @sexp argument. The objects will be returned in the @out_icalcomps
- * argument, which is a list of #icalcomponent.
- * This list should be freed with e_cal_client_free_icalcomp_slist().
+ * argument, which is a list of #ICalComponent.
+ * This list should be freed with e_client_util_free_object_slist().
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
@@ -4291,6 +4155,8 @@ e_cal_client_get_object_list_sync (ECalClient *client,
        g_return_val_if_fail (sexp != NULL, FALSE);
        g_return_val_if_fail (out_icalcomps != NULL, FALSE);
 
+       *out_icalcomps = NULL;
+
        utf8_sexp = e_util_utf8_make_valid (sexp);
 
        e_dbus_calendar_call_get_object_list_sync (
@@ -4311,9 +4177,9 @@ e_cal_client_get_object_list_sync (ECalClient *client,
        }
 
        for (ii = 0; strv[ii] != NULL; ii++) {
-               icalcomponent *icalcomp;
+               ICalComponent *icalcomp;
 
-               icalcomp = icalcomponent_new_from_string (strv[ii]);
+               icalcomp = i_cal_component_new_from_string (strv[ii]);
                if (icalcomp == NULL)
                        continue;
 
@@ -4412,7 +4278,7 @@ e_cal_client_get_object_list_as_comps (ECalClient *client,
  *
  * Finishes previous call of e_cal_client_get_object_list_as_comps() and
  * sets @out_ecalcomps to a matching list of #ECalComponent-s.
- * This list should be freed with e_cal_client_free_ecalcomp_slist().
+ * This list should be freed with e_client_util_free_object_slist().
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
@@ -4458,7 +4324,7 @@ e_cal_client_get_object_list_as_comps_finish (ECalClient *client,
  * Gets a list of objects from the calendar that match the query specified
  * by the @sexp argument. The objects will be returned in the @out_ecalcomps
  * argument, which is a list of #ECalComponent.
- * This list should be freed with e_cal_client_free_ecalcomp_slist().
+ * This list should be freed with e_client_util_free_object_slist().
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
@@ -4473,13 +4339,14 @@ e_cal_client_get_object_list_as_comps_sync (ECalClient *client,
 {
        GSList *list = NULL;
        GSList *link;
-       GQueue trash = G_QUEUE_INIT;
        gboolean success;
 
        g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
        g_return_val_if_fail (sexp != NULL, FALSE);
        g_return_val_if_fail (out_ecalcomps != NULL, FALSE);
 
+       *out_ecalcomps = NULL;
+
        success = e_cal_client_get_object_list_sync (
                client, sexp, &list, cancellable, error);
 
@@ -4488,32 +4355,21 @@ e_cal_client_get_object_list_as_comps_sync (ECalClient *client,
                return FALSE;
        }
 
-       /* Convert the icalcomponent list to an ECalComponent list. */
+       /* Convert the ICalComponent list to an ECalComponent list. */
        for (link = list; link != NULL; link = g_slist_next (link)) {
                ECalComponent *comp;
-               icalcomponent *icalcomp = link->data;
-
-               comp = e_cal_component_new ();
+               ICalComponent *icalcomp = link->data;
 
-               /* This takes ownership of the icalcomponent, if it works. */
-               if (e_cal_component_set_icalcomponent (comp, icalcomp)) {
-                       link->data = g_object_ref (comp);
-               } else {
-                       /* On failure, free resources and add
-                        * the GSList link to the trash queue. */
-                       icalcomponent_free (icalcomp);
-                       g_queue_push_tail (&trash, link);
-                       link->data = NULL;
-               }
+               /* This takes ownership of the ICalComponent. */
+               comp = e_cal_component_new_from_icalcomponent (icalcomp);
+               if (comp)
+                       *out_ecalcomps = g_slist_prepend (*out_ecalcomps, comp);
 
-               g_object_unref (comp);
        }
 
-       /* Delete GSList links we failed to convert. */
-       while ((link = g_queue_pop_head (&trash)) != NULL)
-               list = g_slist_delete_link (list, link);
+       g_slist_free (list);
 
-       *out_ecalcomps = list;
+       *out_ecalcomps = g_slist_reverse (*out_ecalcomps);
 
        return TRUE;
 }
@@ -4715,10 +4571,8 @@ e_cal_client_get_free_busy_sync (ECalClient *client,
                        ECalComponent *comp;
 
                        comp = e_cal_component_new_from_string (freebusy_strv[ii]);
-                       if (!comp)
-                               continue;
-
-                       *out_freebusy = g_slist_prepend (*out_freebusy, comp);
+                       if (comp)
+                               *out_freebusy = g_slist_prepend (*out_freebusy, comp);
                }
 
                *out_freebusy = g_slist_reverse (*out_freebusy);
@@ -4775,7 +4629,7 @@ cal_client_create_object_thread (GSimpleAsyncResult *simple,
  **/
 void
 e_cal_client_create_object (ECalClient *client,
-                            icalcomponent *icalcomp,
+                            ICalComponent *icalcomp,
                             GCancellable *cancellable,
                             GAsyncReadyCallback callback,
                             gpointer user_data)
@@ -4787,7 +4641,7 @@ e_cal_client_create_object (ECalClient *client,
        g_return_if_fail (icalcomp != NULL);
 
        async_context = g_slice_new0 (AsyncContext);
-       async_context->in_comp = icalcomponent_new_clone (icalcomp);
+       async_context->in_comp = i_cal_component_new_clone (icalcomp);
 
        simple = g_simple_async_result_new (
                G_OBJECT (client), callback, user_data,
@@ -4807,7 +4661,7 @@ e_cal_client_create_object (ECalClient *client,
  * e_cal_client_create_object_finish:
  * @client: an #ECalClient
  * @result: a #GAsyncResult
- * @out_uid: (out): Return value for the UID assigned to the new component
+ * @out_uid: (out) (nullable): Return value for the UID assigned to the new component
  *           by the calendar backend
  * @error: (out): a #GError to set an error, if any
  *
@@ -4853,7 +4707,7 @@ e_cal_client_create_object_finish (ECalClient *client,
  * e_cal_client_create_object_sync:
  * @client: an #ECalClient
  * @icalcomp: The component to create
- * @out_uid: (out): Return value for the UID assigned to the new component
+ * @out_uid: (out) (nullable): Return value for the UID assigned to the new component
  *           by the calendar backend
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
@@ -4870,7 +4724,7 @@ e_cal_client_create_object_finish (ECalClient *client,
  **/
 gboolean
 e_cal_client_create_object_sync (ECalClient *client,
-                                 icalcomponent *icalcomp,
+                                 ICalComponent *icalcomp,
                                  gchar **out_uid,
                                  GCancellable *cancellable,
                                  GError **error)
@@ -4892,6 +4746,8 @@ e_cal_client_create_object_sync (ECalClient *client,
 
        if (out_uid != NULL && string_list != NULL)
                *out_uid = g_strdup (string_list->data);
+       else if (out_uid)
+               *out_uid = NULL;
 
        g_slist_free_full (string_list, (GDestroyNotify) g_free);
 
@@ -4929,7 +4785,7 @@ cal_client_create_objects_thread (GSimpleAsyncResult *simple,
 /**
  * e_cal_client_create_objects:
  * @client: an #ECalClient
- * @icalcomps: (element-type icalcomponent): The components to create
+ * @icalcomps: (element-type ICalComponent): The components to create
  * @cancellable: (allow-none): a #GCancellable; can be %NULL
  * @callback: callback to call when a result is ready
  * @user_data: user data for the @callback
@@ -4957,7 +4813,7 @@ e_cal_client_create_objects (ECalClient *client,
 
        async_context = g_slice_new0 (AsyncContext);
        async_context->comp_list = g_slist_copy_deep (
-               icalcomps, (GCopyFunc) icalcomponent_new_clone, NULL);
+               icalcomps, (GCopyFunc) i_cal_component_new_clone, NULL);
 
        simple = g_simple_async_result_new (
                G_OBJECT (client), callback, user_data,
@@ -4979,7 +4835,7 @@ e_cal_client_create_objects (ECalClient *client,
  * e_cal_client_create_objects_finish:
  * @client: an #ECalClient
  * @result: a #GAsyncResult
- * @out_uids: (out) (element-type utf8): Return value for the UIDs assigned
+ * @out_uids: (out) (nullable) (element-type utf8): Return value for the UIDs assigned
  *            to the new components by the calendar backend
  * @error: (out): a #GError to set an error, if any
  *
@@ -5022,8 +4878,8 @@ e_cal_client_create_objects_finish (ECalClient *client,
 /**
  * e_cal_client_create_objects_sync:
  * @client: an #ECalClient
- * @icalcomps: (element-type icalcomponent): The components to create
- * @out_uids: (out) (element-type utf8): Return value for the UIDs assigned
+ * @icalcomps: (element-type ICalComponent): The components to create
+ * @out_uids: (out) (nullable) (element-type utf8): Return value for the UIDs assigned
  *            to the new components by the calendar backend
  * @cancellable: (allow-none): a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
@@ -5059,7 +4915,7 @@ e_cal_client_create_objects_sync (ECalClient *client,
        while (icalcomps != NULL) {
                gchar *ical_string;
 
-               ical_string = icalcomponent_as_ical_string_r (icalcomps->data);
+               ical_string = i_cal_component_as_ical_string_r (icalcomps->data);
                strv[ii++] = e_util_utf8_make_valid (ical_string);
                g_free (ical_string);
 
@@ -5078,7 +4934,7 @@ e_cal_client_create_objects_sync (ECalClient *client,
                ((uids != NULL) && (local_error == NULL)) ||
                ((uids == NULL) && (local_error != NULL)), FALSE);
 
-       if (uids != NULL) {
+       if (uids && out_uids) {
                GSList *tmp = NULL;
 
                /* Steal the string array elements. */
@@ -5088,6 +4944,8 @@ e_cal_client_create_objects_sync (ECalClient *client,
                }
 
                *out_uids = g_slist_reverse (tmp);
+       } else if (out_uids) {
+               *out_uids = NULL;
        }
 
        g_strfreev (uids);
@@ -5153,7 +5011,7 @@ cal_client_modify_object_thread (GSimpleAsyncResult *simple,
  **/
 void
 e_cal_client_modify_object (ECalClient *client,
-                            icalcomponent *icalcomp,
+                            ICalComponent *icalcomp,
                             ECalObjModType mod,
                             GCancellable *cancellable,
                             GAsyncReadyCallback callback,
@@ -5166,7 +5024,7 @@ e_cal_client_modify_object (ECalClient *client,
        g_return_if_fail (icalcomp != NULL);
 
        async_context = g_slice_new0 (AsyncContext);
-       async_context->in_comp = icalcomponent_new_clone (icalcomp);
+       async_context->in_comp = i_cal_component_new_clone (icalcomp);
        async_context->mod = mod;
 
        simple = g_simple_async_result_new (
@@ -5237,7 +5095,7 @@ e_cal_client_modify_object_finish (ECalClient *client,
  **/
 gboolean
 e_cal_client_modify_object_sync (ECalClient *client,
-                                 icalcomponent *icalcomp,
+                                 ICalComponent *icalcomp,
                                  ECalObjModType mod,
                                  GCancellable *cancellable,
                                  GError **error)
@@ -5282,7 +5140,7 @@ cal_client_modify_objects_thread (GSimpleAsyncResult *simple,
 /**
  * e_cal_client_modify_objects:
  * @client: an #ECalClient
- * @comps: (element-type icalcomponent): Components to modify
+ * @icalcomps: (element-type ICalComponent): Components to modify
  * @mod: Type of modification
  * @cancellable: (allow-none): a #GCancellable; can be %NULL
  * @callback: callback to call when a result is ready
@@ -5303,7 +5161,7 @@ cal_client_modify_objects_thread (GSimpleAsyncResult *simple,
  **/
 void
 e_cal_client_modify_objects (ECalClient *client,
-                             GSList *comps,
+                             GSList *icalcomps,
                              ECalObjModType mod,
                              GCancellable *cancellable,
                              GAsyncReadyCallback callback,
@@ -5313,11 +5171,11 @@ e_cal_client_modify_objects (ECalClient *client,
        AsyncContext *async_context;
 
        g_return_if_fail (E_IS_CAL_CLIENT (client));
-       g_return_if_fail (comps != NULL);
+       g_return_if_fail (icalcomps != NULL);
 
        async_context = g_slice_new0 (AsyncContext);
        async_context->comp_list = g_slist_copy_deep (
-               comps, (GCopyFunc) icalcomponent_new_clone, NULL);
+               icalcomps, (GCopyFunc) i_cal_component_new_clone, NULL);
        async_context->mod = mod;
 
        simple = g_simple_async_result_new (
@@ -5369,7 +5227,7 @@ e_cal_client_modify_objects_finish (ECalClient *client,
 /**
  * e_cal_client_modify_objects_sync:
  * @client: an #ECalClient
- * @comps: (element-type icalcomponent): Components to modify
+ * @icalcomps: (element-type ICalComponent): Components to modify
  * @mod: Type of modification
  * @cancellable: (allow-none): a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
@@ -5388,7 +5246,7 @@ e_cal_client_modify_objects_finish (ECalClient *client,
  **/
 gboolean
 e_cal_client_modify_objects_sync (ECalClient *client,
-                                  GSList *comps,
+                                  GSList *icalcomps,
                                   ECalObjModType mod,
                                   GCancellable *cancellable,
                                   GError **error)
@@ -5401,7 +5259,7 @@ e_cal_client_modify_objects_sync (ECalClient *client,
        GError *local_error = NULL;
 
        g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
-       g_return_val_if_fail (comps != NULL, FALSE);
+       g_return_val_if_fail (icalcomps != NULL, FALSE);
 
        flags = g_string_new (NULL);
        flags_class = g_type_class_ref (E_TYPE_CAL_OBJ_MOD_TYPE);
@@ -5414,15 +5272,15 @@ e_cal_client_modify_objects_sync (ECalClient *client,
                flags_value = g_flags_get_first_value (flags_class, mod);
        }
 
-       strv = g_new0 (gchar *, g_slist_length (comps) + 1);
-       while (comps != NULL) {
+       strv = g_new0 (gchar *, g_slist_length (icalcomps) + 1);
+       while (icalcomps != NULL) {
                gchar *ical_string;
 
-               ical_string = icalcomponent_as_ical_string_r (comps->data);
+               ical_string = i_cal_component_as_ical_string_r (icalcomps->data);
                strv[ii++] = e_util_utf8_make_valid (ical_string);
                g_free (ical_string);
 
-               comps = g_slist_next (comps);
+               icalcomps = g_slist_next (icalcomps);
        }
 
        e_dbus_calendar_call_modify_objects_sync (
@@ -5588,14 +5446,21 @@ e_cal_client_remove_object_sync (ECalClient *client,
                                  GCancellable *cancellable,
                                  GError **error)
 {
-       ECalComponentId id = { (gchar *) uid, (gchar *) rid };
-       GSList link = { &id, NULL };
+       ECalComponentId *id;
+       GSList *link;
+       gboolean success;
 
        g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
        g_return_val_if_fail (uid != NULL, FALSE);
 
-       return e_cal_client_remove_objects_sync (
-               client, &link, mod, cancellable, error);
+       id = e_cal_component_id_new (uid, rid);
+       link = g_slist_prepend (NULL, id);
+
+       success = e_cal_client_remove_objects_sync (client, link, mod, cancellable, error);
+
+       g_slist_free_full (link, e_cal_component_id_free);
+
+       return success;
 }
 
 /* Helper for e_cal_client_remove_objects() */
@@ -5611,7 +5476,7 @@ cal_client_remove_objects_thread (GSimpleAsyncResult *simple,
 
        if (!e_cal_client_remove_objects_sync (
                E_CAL_CLIENT (source_object),
-               async_context->string_list,
+               async_context->ids_list,
                async_context->mod,
                cancellable, &local_error)) {
 
@@ -5661,8 +5526,8 @@ e_cal_client_remove_objects (ECalClient *client,
        g_return_if_fail (ids != NULL);
 
        async_context = g_slice_new0 (AsyncContext);
-       async_context->string_list = g_slist_copy_deep (
-               (GSList *) ids, (GCopyFunc) g_strdup, NULL);
+       async_context->ids_list = g_slist_copy_deep (
+               (GSList *) ids, (GCopyFunc) e_cal_component_id_copy, NULL);
        async_context->mod = mod;
 
        simple = g_simple_async_result_new (
@@ -5760,18 +5625,22 @@ e_cal_client_remove_objects_sync (ECalClient *client,
        g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)"));
        while (ids != NULL) {
                ECalComponentId *id = ids->data;
+               const gchar *uid, *rid;
                gchar *utf8_uid;
                gchar *utf8_rid;
 
                ids = g_slist_next (ids);
 
-               if (id->uid == NULL)
+               uid = e_cal_component_id_get_uid (id);
+               rid = e_cal_component_id_get_rid (id);
+
+               if (!uid)
                        continue;
 
                /* Reject empty UIDs with an OBJECT_NOT_FOUND error for
                 * backward-compatibility, even though INVALID_ARG might
                 * be more appropriate. */
-               if (*id->uid == '\0') {
+               if (!*uid) {
                        local_error = g_error_new_literal (
                                E_CAL_CLIENT_ERROR,
                                E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND,
@@ -5781,9 +5650,9 @@ e_cal_client_remove_objects_sync (ECalClient *client,
                        break;
                }
 
-               utf8_uid = e_util_utf8_make_valid (id->uid);
-               if (id->rid != NULL)
-                       utf8_rid = e_util_utf8_make_valid (id->rid);
+               utf8_uid = e_util_utf8_make_valid (uid);
+               if (rid)
+                       utf8_rid = e_util_utf8_make_valid (rid);
                else
                        utf8_rid = g_strdup ("");
 
@@ -5846,7 +5715,7 @@ cal_client_receive_objects_thread (GSimpleAsyncResult *simple,
 /**
  * e_cal_client_receive_objects:
  * @client: an #ECalClient
- * @icalcomp: An #icalcomponent
+ * @icalcomp: An #ICalComponent
  * @cancellable: a #GCancellable; can be %NULL
  * @callback: callback to call when a result is ready
  * @user_data: user data for the @callback
@@ -5862,7 +5731,7 @@ cal_client_receive_objects_thread (GSimpleAsyncResult *simple,
  **/
 void
 e_cal_client_receive_objects (ECalClient *client,
-                              icalcomponent *icalcomp,
+                              ICalComponent *icalcomp,
                               GCancellable *cancellable,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
@@ -5874,7 +5743,7 @@ e_cal_client_receive_objects (ECalClient *client,
        g_return_if_fail (icalcomp != NULL);
 
        async_context = g_slice_new0 (AsyncContext);
-       async_context->in_comp = icalcomponent_new_clone (icalcomp);
+       async_context->in_comp = i_cal_component_new_clone (icalcomp);
 
        simple = g_simple_async_result_new (
                G_OBJECT (client), callback, user_data,
@@ -5925,7 +5794,7 @@ e_cal_client_receive_objects_finish (ECalClient *client,
 /**
  * e_cal_client_receive_objects_sync:
  * @client: an #ECalClient
- * @icalcomp: An #icalcomponent
+ * @icalcomp: An #ICalComponent
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
@@ -5939,7 +5808,7 @@ e_cal_client_receive_objects_finish (ECalClient *client,
  **/
 gboolean
 e_cal_client_receive_objects_sync (ECalClient *client,
-                                   icalcomponent *icalcomp,
+                                   ICalComponent *icalcomp,
                                    GCancellable *cancellable,
                                    GError **error)
 {
@@ -5949,7 +5818,7 @@ e_cal_client_receive_objects_sync (ECalClient *client,
 
        g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
 
-       ical_string = icalcomponent_as_ical_string_r (icalcomp);
+       ical_string = i_cal_component_as_ical_string_r (icalcomp);
        utf8_ical_string = e_util_utf8_make_valid (ical_string);
 
        e_dbus_calendar_call_receive_objects_sync (
@@ -6000,7 +5869,7 @@ cal_client_send_objects_thread (GSimpleAsyncResult *simple,
 /**
  * e_cal_client_send_objects:
  * @client: an #ECalClient
- * @icalcomp: An icalcomponent to be sent
+ * @icalcomp: An #ICalComponent to be sent
  * @cancellable: a #GCancellable; can be %NULL
  * @callback: callback to call when a result is ready
  * @user_data: user data for the @callback
@@ -6014,7 +5883,7 @@ cal_client_send_objects_thread (GSimpleAsyncResult *simple,
  **/
 void
 e_cal_client_send_objects (ECalClient *client,
-                           icalcomponent *icalcomp,
+                           ICalComponent *icalcomp,
                            GCancellable *cancellable,
                            GAsyncReadyCallback callback,
                            gpointer user_data)
@@ -6026,7 +5895,7 @@ e_cal_client_send_objects (ECalClient *client,
        g_return_if_fail (icalcomp != NULL);
 
        async_context = g_slice_new0 (AsyncContext);
-       async_context->in_comp = icalcomponent_new_clone (icalcomp);
+       async_context->in_comp = i_cal_component_new_clone (icalcomp);
 
        simple = g_simple_async_result_new (
                G_OBJECT (client), callback, user_data,
@@ -6048,16 +5917,16 @@ e_cal_client_send_objects (ECalClient *client,
  * e_cal_client_send_objects_finish:
  * @client: an #ECalClient
  * @result: a #GAsyncResult
- * @out_users: (out) (element-type utf8): List of users to send
+ * @out_users: (out) (transfer full) (element-type utf8): List of users to send
  *             the @out_modified_icalcomp to
- * @out_modified_icalcomp: (out): Return value for the icalcomponent to be sent
+ * @out_modified_icalcomp: (out) (transfer full): Return value for the #ICalComponent to be sent
  * @error: (out): a #GError to set an error, if any
  *
  * Finishes previous call of e_cal_client_send_objects() and
  * populates @out_users with a list of users to send @out_modified_icalcomp to.
  *
  * The @out_users list should be freed with e_client_util_free_string_slist()
- * and the @out_modified_icalcomp should be freed with icalcomponent_free().
+ * and the @out_modified_icalcomp should be freed with g_object_unref().
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
@@ -6067,7 +5936,7 @@ gboolean
 e_cal_client_send_objects_finish (ECalClient *client,
                                   GAsyncResult *result,
                                   GSList **out_users,
-                                  icalcomponent **out_modified_icalcomp,
+                                  ICalComponent **out_modified_icalcomp,
                                   GError **error)
 {
        GSimpleAsyncResult *simple;
@@ -6102,10 +5971,10 @@ e_cal_client_send_objects_finish (ECalClient *client,
 /**
  * e_cal_client_send_objects_sync:
  * @client: an #ECalClient
- * @icalcomp: An icalcomponent to be sent
- * @out_users: (out) (element-type utf8): List of users to send the
+ * @icalcomp: An #ICalComponent to be sent
+ * @out_users: (out) (transfer full) (element-type utf8): List of users to send the
  *             @out_modified_icalcomp to
- * @out_modified_icalcomp: (out): Return value for the icalcomponent to be sent
+ * @out_modified_icalcomp: (out) (transfer full): Return value for the #ICalComponent to be sent
  * @cancellable: (allow-none): a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
@@ -6114,7 +5983,7 @@ e_cal_client_send_objects_finish (ECalClient *client,
  * @out_users list.
  *
  * The @out_users list should be freed with e_client_util_free_string_slist()
- * and the @out_modified_icalcomp should be freed with icalcomponent_free().
+ * and the @out_modified_icalcomp should be freed with g_object_unref().
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
@@ -6122,9 +5991,9 @@ e_cal_client_send_objects_finish (ECalClient *client,
  **/
 gboolean
 e_cal_client_send_objects_sync (ECalClient *client,
-                                icalcomponent *icalcomp,
+                                ICalComponent *icalcomp,
                                 GSList **out_users,
-                                icalcomponent **out_modified_icalcomp,
+                                ICalComponent **out_modified_icalcomp,
                                 GCancellable *cancellable,
                                 GError **error)
 {
@@ -6139,7 +6008,7 @@ e_cal_client_send_objects_sync (ECalClient *client,
        g_return_val_if_fail (out_users != NULL, FALSE);
        g_return_val_if_fail (out_modified_icalcomp != NULL, FALSE);
 
-       ical_string = icalcomponent_as_ical_string_r (icalcomp);
+       ical_string = i_cal_component_as_ical_string_r (icalcomp);
        utf8_ical_string = e_util_utf8_make_valid (ical_string);
 
        e_dbus_calendar_call_send_objects_sync (
@@ -6161,7 +6030,7 @@ e_cal_client_send_objects_sync (ECalClient *client,
                return FALSE;
        }
 
-       icalcomp = icalparser_parse_string (out_ical_string);
+       icalcomp = i_cal_parser_parse_string (out_ical_string);
 
        g_free (out_ical_string);
 
@@ -6424,12 +6293,12 @@ cal_client_discard_alarm_thread (GSimpleAsyncResult *simple,
  * @client: an #ECalClient
  * @uid: Unique identifier for a calendar component
  * @rid: Recurrence identifier
- * @auid: Alarm identifier to remove
+ * @auid: Alarm identifier to discard
  * @cancellable: a #GCancellable; can be %NULL
  * @callback: callback to call when a result is ready
  * @user_data: user data for the @callback
  *
- * Removes alarm @auid from a given component identified by @uid and @rid.
+ * Discards alarm @auid from a given component identified by @uid and @rid.
  * The call is finished by e_cal_client_discard_alarm_finish() from
  * the @callback.
  *
@@ -6454,7 +6323,7 @@ e_cal_client_discard_alarm (ECalClient *client,
 
        async_context = g_slice_new0 (AsyncContext);
        async_context->uid = g_strdup (uid);
-       async_context->rid = NULL;
+       async_context->rid = g_strdup (rid);
        async_context->auid = g_strdup (auid);
 
        simple = g_simple_async_result_new (
@@ -6508,11 +6377,11 @@ e_cal_client_discard_alarm_finish (ECalClient *client,
  * @client: an #ECalClient
  * @uid: Unique identifier for a calendar component
  * @rid: Recurrence identifier
- * @auid: Alarm identifier to remove
+ * @auid: Alarm identifier to discard
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
- * Removes alarm @auid from a given component identified by @uid and @rid.
+ * Discards alarm @auid from a given component identified by @uid and @rid.
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
@@ -6832,7 +6701,7 @@ e_cal_client_get_timezone (ECalClient *client,
  * e_cal_client_get_timezone_finish:
  * @client: an #ECalClient
  * @result: a #GAsyncResult
- * @out_zone: (out): Return value for the timezone
+ * @out_zone: (out) (transfer none): Return value for the timezone
  * @error: (out): a #GError to set an error, if any
  *
  * Finishes previous call of e_cal_client_get_timezone() and
@@ -6846,7 +6715,7 @@ e_cal_client_get_timezone (ECalClient *client,
 gboolean
 e_cal_client_get_timezone_finish (ECalClient *client,
                                   GAsyncResult *result,
-                                  icaltimezone **out_zone,
+                                  ICalTimezone **out_zone,
                                   GError **error)
 {
        GSimpleAsyncResult *simple;
@@ -6877,7 +6746,7 @@ e_cal_client_get_timezone_finish (ECalClient *client,
  * e_cal_client_get_timezone_sync:
  * @client: an #ECalClient
  * @tzid: ID of the timezone to retrieve
- * @out_zone: (out): Return value for the timezone
+ * @out_zone: (out) (transfer none): Return value for the timezone
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
@@ -6891,12 +6760,12 @@ e_cal_client_get_timezone_finish (ECalClient *client,
 gboolean
 e_cal_client_get_timezone_sync (ECalClient *client,
                                 const gchar *tzid,
-                                icaltimezone **out_zone,
+                                ICalTimezone **out_zone,
                                 GCancellable *cancellable,
                                 GError **error)
 {
-       icalcomponent *icalcomp;
-       icaltimezone *zone;
+       ICalComponent *icalcomp;
+       ICalTimezone *zone;
        gchar *utf8_tzid;
        gchar *string = NULL;
        GError *local_error = NULL;
@@ -6931,7 +6800,7 @@ e_cal_client_get_timezone_sync (ECalClient *client,
                return FALSE;
        }
 
-       icalcomp = icalparser_parse_string (string);
+       icalcomp = i_cal_parser_parse_string (string);
 
        g_free (string);
 
@@ -6944,15 +6813,15 @@ e_cal_client_get_timezone_sync (ECalClient *client,
                return FALSE;
        }
 
-       zone = icaltimezone_new ();
-       if (!icaltimezone_set_component (zone, icalcomp)) {
+       zone = i_cal_timezone_new ();
+       if (!i_cal_timezone_set_component (zone, icalcomp)) {
                g_set_error_literal (
                        error, E_CAL_CLIENT_ERROR,
                        E_CAL_CLIENT_ERROR_INVALID_OBJECT,
                        e_cal_client_error_to_string (
                        E_CAL_CLIENT_ERROR_INVALID_OBJECT));
-               icalcomponent_free (icalcomp);
-               icaltimezone_free (zone, 1);
+               g_object_unref (icalcomp);
+               g_object_unref (zone);
                return FALSE;
        }
 
@@ -6964,7 +6833,7 @@ e_cal_client_get_timezone_sync (ECalClient *client,
                /* It can be that another thread already filled the zone into the cache,
                   thus deal with it properly, because that other zone can be used by that
                   other thread. */
-               icaltimezone_free (zone, 1);
+               g_object_unref (zone);
                zone = g_hash_table_lookup (client->priv->zone_cache, tzid);
        } else {
                g_hash_table_insert (
@@ -6972,6 +6841,8 @@ e_cal_client_get_timezone_sync (ECalClient *client,
        }
        g_mutex_unlock (&client->priv->zone_cache_lock);
 
+       g_object_unref (icalcomp);
+
        *out_zone = zone;
 
        return TRUE;
@@ -7020,26 +6891,28 @@ cal_client_add_timezone_thread (GSimpleAsyncResult *simple,
  **/
 void
 e_cal_client_add_timezone (ECalClient *client,
-                           icaltimezone *zone,
+                           ICalTimezone *zone,
                            GCancellable *cancellable,
                            GAsyncReadyCallback callback,
                            gpointer user_data)
 {
        GSimpleAsyncResult *simple;
        AsyncContext *async_context;
-       icalcomponent *icalcomp;
+       ICalComponent *icalcomp, *clone;
 
        g_return_if_fail (E_IS_CAL_CLIENT (client));
        g_return_if_fail (zone != NULL);
 
-       icalcomp = icaltimezone_get_component (zone);
+       icalcomp = i_cal_timezone_get_component (zone);
        g_return_if_fail (icalcomp != NULL);
 
        async_context = g_slice_new0 (AsyncContext);
-       async_context->zone = icaltimezone_new ();
+       async_context->zone = i_cal_timezone_new ();
 
-       icalcomp = icalcomponent_new_clone (icalcomp);
-       icaltimezone_set_component (async_context->zone, icalcomp);
+       clone = i_cal_component_new_clone (icalcomp);
+       i_cal_timezone_set_component (async_context->zone, clone);
+       g_object_unref (icalcomp);
+       g_object_unref (clone);
 
        simple = g_simple_async_result_new (
                G_OBJECT (client), callback, user_data,
@@ -7050,7 +6923,7 @@ e_cal_client_add_timezone (ECalClient *client,
        g_simple_async_result_set_op_res_gpointer (
                simple, async_context, (GDestroyNotify) async_context_free);
 
-       if (zone == icaltimezone_get_utc_timezone ())
+       if (zone == i_cal_timezone_get_utc_timezone ())
                g_simple_async_result_complete_in_idle (simple);
        else
                g_simple_async_result_run_in_thread (
@@ -7105,11 +6978,11 @@ e_cal_client_add_timezone_finish (ECalClient *client,
  **/
 gboolean
 e_cal_client_add_timezone_sync (ECalClient *client,
-                                icaltimezone *zone,
+                                ICalTimezone *zone,
                                 GCancellable *cancellable,
                                 GError **error)
 {
-       icalcomponent *icalcomp;
+       ICalComponent *icalcomp;
        gchar *zone_str;
        gchar *utf8_zone_str;
        GError *local_error = NULL;
@@ -7117,10 +6990,10 @@ e_cal_client_add_timezone_sync (ECalClient *client,
        g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
        g_return_val_if_fail (zone != NULL, FALSE);
 
-       if (zone == icaltimezone_get_utc_timezone ())
+       if (zone == i_cal_timezone_get_utc_timezone ())
                return TRUE;
 
-       icalcomp = icaltimezone_get_component (zone);
+       icalcomp = i_cal_timezone_get_component (zone);
        if (icalcomp == NULL) {
                g_propagate_error (
                        error, e_client_error_create (
@@ -7128,7 +7001,7 @@ e_cal_client_add_timezone_sync (ECalClient *client,
                return FALSE;
        }
 
-       zone_str = icalcomponent_as_ical_string_r (icalcomp);
+       zone_str = i_cal_component_as_ical_string_r (icalcomp);
        utf8_zone_str = e_util_utf8_make_valid (zone_str);
 
        e_dbus_calendar_call_add_timezone_sync (
@@ -7137,6 +7010,7 @@ e_cal_client_add_timezone_sync (ECalClient *client,
 
        g_free (zone_str);
        g_free (utf8_zone_str);
+       g_object_unref (icalcomp);
 
        if (local_error != NULL) {
                g_dbus_error_strip_remote_error (local_error);
diff --git a/src/calendar/libecal/e-cal-client.h b/src/calendar/libecal/e-cal-client.h
index 0913ddd4d..ca7678922 100644
--- a/src/calendar/libecal/e-cal-client.h
+++ b/src/calendar/libecal/e-cal-client.h
@@ -27,8 +27,8 @@
 #include <libedataserver/libedataserver.h>
 
 #include <libecal/e-cal-client-view.h>
-#include <libecal/e-cal-recur.h>
 #include <libecal/e-cal-enums.h>
+#include <libecal/e-cal-recur.h>
 #include <libecal/e-cal-util.h>
 
 /* Standard GObject macros */
@@ -153,7 +153,7 @@ struct _ECalClientClass {
        /*< public >*/
        /* Signals */
        void            (*free_busy_data)       (ECalClient *client,
-                                                const GSList *free_busy_ecalcomps);
+                                                const GSList *free_busy_ecalcomps); /* ECalComponent * */
 };
 
 GQuark         e_cal_client_error_quark        (void) G_GNUC_CONST;
@@ -179,8 +179,8 @@ const gchar *       e_cal_client_get_local_attachment_store
                                                (ECalClient *client);
 void           e_cal_client_set_default_timezone
                                                (ECalClient *client,
-                                                icaltimezone *zone);
-icaltimezone * e_cal_client_get_default_timezone
+                                                ICalTimezone *zone);
+ICalTimezone * e_cal_client_get_default_timezone
                                                (ECalClient *client);
 gboolean       e_cal_client_check_one_alarm_only
                                                (ECalClient *client);
@@ -192,49 +192,39 @@ gboolean  e_cal_client_check_organizer_must_accept
                                                (ECalClient *client);
 gboolean       e_cal_client_check_recurrences_no_master
                                                (ECalClient *client);
-void           e_cal_client_free_icalcomp_slist
-                                               (GSList *icalcomps);
-void           e_cal_client_free_ecalcomp_slist
-                                               (GSList *ecalcomps);
 
-icaltimezone * e_cal_client_resolve_tzid_cb    (const gchar *tzid,
-                                                gpointer data);
-icaltimezone * e_cal_client_resolve_tzid_sync  (const gchar *tzid,
-                                                gpointer cal_client,
-                                                GCancellable *cancellable,
-                                                GError **error);
 void           e_cal_client_generate_instances (ECalClient *client,
                                                 time_t start,
                                                 time_t end,
                                                 GCancellable *cancellable,
-                                                ECalRecurInstanceFn cb,
+                                                ECalRecurInstanceCb cb,
                                                 gpointer cb_data,
                                                 GDestroyNotify destroy_cb_data);
 void           e_cal_client_generate_instances_sync
                                                (ECalClient *client,
                                                 time_t start,
                                                 time_t end,
-                                                ECalRecurInstanceFn cb,
+                                                ECalRecurInstanceCb cb,
                                                 gpointer cb_data);
 void           e_cal_client_generate_instances_for_object
                                                (ECalClient *client,
-                                                icalcomponent *icalcomp,
+                                                ICalComponent *icalcomp,
                                                 time_t start,
                                                 time_t end,
                                                 GCancellable *cancellable,
-                                                ECalRecurInstanceFn cb,
+                                                ECalRecurInstanceCb cb,
                                                 gpointer cb_data,
                                                 GDestroyNotify destroy_cb_data);
 void           e_cal_client_generate_instances_for_object_sync
                                                (ECalClient *client,
-                                                icalcomponent *icalcomp,
+                                                ICalComponent *icalcomp,
                                                 time_t start,
                                                 time_t end,
-                                                ECalRecurInstanceFn cb,
+                                                ECalRecurInstanceCb cb,
                                                 gpointer cb_data);
 gchar *                e_cal_client_get_component_as_string
                                                (ECalClient *client,
-                                                icalcomponent *icalcomp);
+                                                ICalComponent *icalcomp);
 void           e_cal_client_get_default_object (ECalClient *client,
                                                 GCancellable *cancellable,
                                                 GAsyncReadyCallback callback,
@@ -242,11 +232,11 @@ void              e_cal_client_get_default_object (ECalClient *client,
 gboolean       e_cal_client_get_default_object_finish
                                                (ECalClient *client,
                                                 GAsyncResult *result,
-                                                icalcomponent **out_icalcomp,
+                                                ICalComponent **out_icalcomp,
                                                 GError **error);
 gboolean       e_cal_client_get_default_object_sync
                                                (ECalClient *client,
-                                                icalcomponent **out_icalcomp,
+                                                ICalComponent **out_icalcomp,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_get_object         (ECalClient *client,
@@ -257,12 +247,12 @@ void              e_cal_client_get_object         (ECalClient *client,
                                                 gpointer user_data);
 gboolean       e_cal_client_get_object_finish  (ECalClient *client,
                                                 GAsyncResult *result,
-                                                icalcomponent **out_icalcomp,
+                                                ICalComponent **out_icalcomp,
                                                 GError **error);
 gboolean       e_cal_client_get_object_sync    (ECalClient *client,
                                                 const gchar *uid,
                                                 const gchar *rid,
-                                                icalcomponent **out_icalcomp,
+                                                ICalComponent **out_icalcomp,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_get_objects_for_uid
@@ -274,12 +264,12 @@ void              e_cal_client_get_objects_for_uid
 gboolean       e_cal_client_get_objects_for_uid_finish
                                                (ECalClient *client,
                                                 GAsyncResult *result,
-                                                GSList **out_ecalcomps,
+                                                GSList **out_ecalcomps, /* ECalComponent * */
                                                 GError **error);
 gboolean       e_cal_client_get_objects_for_uid_sync
                                                (ECalClient *client,
                                                 const gchar *uid,
-                                                GSList **out_ecalcomps,
+                                                GSList **out_ecalcomps, /* ECalComponent * */
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_get_object_list    (ECalClient *client,
@@ -290,12 +280,12 @@ void              e_cal_client_get_object_list    (ECalClient *client,
 gboolean       e_cal_client_get_object_list_finish
                                                (ECalClient *client,
                                                 GAsyncResult *result,
-                                                GSList **out_icalcomps,
+                                                GSList **out_icalcomps, /* ICalComponent * */
                                                 GError **error);
 gboolean       e_cal_client_get_object_list_sync
                                                (ECalClient *client,
                                                 const gchar *sexp,
-                                                GSList **out_icalcomps,
+                                                GSList **out_icalcomps, /* ICalComponent * */
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_get_object_list_as_comps
@@ -307,35 +297,35 @@ void              e_cal_client_get_object_list_as_comps
 gboolean       e_cal_client_get_object_list_as_comps_finish
                                                (ECalClient *client,
                                                 GAsyncResult *result,
-                                                GSList **out_ecalcomps,
+                                                GSList **out_ecalcomps, /* ECalComponent * */
                                                 GError **error);
 gboolean       e_cal_client_get_object_list_as_comps_sync
                                                (ECalClient *client,
                                                 const gchar *sexp,
-                                                GSList **out_ecalcomps,
+                                                GSList **out_ecalcomps, /* ECalComponent * */
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_get_free_busy      (ECalClient *client,
                                                 time_t start,
                                                 time_t end,
-                                                const GSList *users,
+                                                const GSList *users, /* gchar * */
                                                 GCancellable *cancellable,
                                                 GAsyncReadyCallback callback,
                                                 gpointer user_data);
 gboolean       e_cal_client_get_free_busy_finish
                                                (ECalClient *client,
                                                 GAsyncResult *result,
-                                                GSList **out_freebusy,
+                                                GSList **out_freebusy, /* ECalComponent * */
                                                 GError **error);
 gboolean       e_cal_client_get_free_busy_sync (ECalClient *client,
                                                 time_t start,
                                                 time_t end,
-                                                const GSList *users,
-                                                GSList **out_freebusy,
+                                                const GSList *users, /* gchar * */
+                                                GSList **out_freebusy, /* ECalComponent * */
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_create_object      (ECalClient *client,
-                                                icalcomponent *icalcomp,
+                                                ICalComponent *icalcomp,
                                                 GCancellable *cancellable,
                                                 GAsyncReadyCallback callback,
                                                 gpointer user_data);
@@ -345,28 +335,28 @@ gboolean  e_cal_client_create_object_finish
                                                 gchar **out_uid,
                                                 GError **error);
 gboolean       e_cal_client_create_object_sync (ECalClient *client,
-                                                icalcomponent *icalcomp,
+                                                ICalComponent *icalcomp,
                                                 gchar **out_uid,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_create_objects     (ECalClient *client,
-                                                GSList *icalcomps,
+                                                GSList *icalcomps, /* ICalComponent * */
                                                 GCancellable *cancellable,
                                                 GAsyncReadyCallback callback,
                                                 gpointer user_data);
 gboolean       e_cal_client_create_objects_finish
                                                (ECalClient *client,
                                                 GAsyncResult *result,
-                                                GSList **out_uids,
+                                                GSList **out_uids, /* gchar * */
                                                 GError **error);
 gboolean       e_cal_client_create_objects_sync
                                                (ECalClient *client,
-                                                GSList *icalcomps,
-                                                GSList **out_uids,
+                                                GSList *icalcomps, /* ICalComponent * */
+                                                GSList **out_uids, /* gchar * */
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_modify_object      (ECalClient *client,
-                                                icalcomponent *icalcomp,
+                                                ICalComponent *icalcomp,
                                                 ECalObjModType mod,
                                                 GCancellable *cancellable,
                                                 GAsyncReadyCallback callback,
@@ -376,12 +366,12 @@ gboolean  e_cal_client_modify_object_finish
                                                 GAsyncResult *result,
                                                 GError **error);
 gboolean       e_cal_client_modify_object_sync (ECalClient *client,
-                                                icalcomponent *icalcomp,
+                                                ICalComponent *icalcomp,
                                                 ECalObjModType mod,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_modify_objects     (ECalClient *client,
-                                                GSList *comps,
+                                                GSList *icalcomps, /* ICalComponent * */
                                                 ECalObjModType mod,
                                                 GCancellable *cancellable,
                                                 GAsyncReadyCallback callback,
@@ -392,7 +382,7 @@ gboolean    e_cal_client_modify_objects_finish
                                                 GError **error);
 gboolean       e_cal_client_modify_objects_sync
                                                (ECalClient *client,
-                                                GSList *comps,
+                                                GSList *icalcomps, /* ICalComponent * */
                                                 ECalObjModType mod,
                                                 GCancellable *cancellable,
                                                 GError **error);
@@ -414,7 +404,7 @@ gboolean    e_cal_client_remove_object_sync (ECalClient *client,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_remove_objects     (ECalClient *client,
-                                                const GSList *ids,
+                                                const GSList *ids, /* ECalComponentId * */
                                                 ECalObjModType mod,
                                                 GCancellable *cancellable,
                                                 GAsyncReadyCallback callback,
@@ -425,12 +415,12 @@ gboolean  e_cal_client_remove_objects_finish
                                                 GError **error);
 gboolean       e_cal_client_remove_objects_sync
                                                (ECalClient *client,
-                                                const GSList *ids,
+                                                const GSList *ids, /* ECalComponentId * */
                                                 ECalObjModType mod,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_receive_objects    (ECalClient *client,
-                                                icalcomponent *icalcomp,
+                                                ICalComponent *icalcomp,
                                                 GCancellable *cancellable,
                                                 GAsyncReadyCallback callback,
                                                 gpointer user_data);
@@ -440,24 +430,24 @@ gboolean  e_cal_client_receive_objects_finish
                                                 GError **error);
 gboolean       e_cal_client_receive_objects_sync
                                                (ECalClient *client,
-                                                icalcomponent *icalcomp,
+                                                ICalComponent *icalcomp,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_send_objects       (ECalClient *client,
-                                                icalcomponent *icalcomp,
+                                                ICalComponent *icalcomp,
                                                 GCancellable *cancellable,
                                                 GAsyncReadyCallback callback,
                                                 gpointer user_data);
 gboolean       e_cal_client_send_objects_finish
                                                (ECalClient *client,
                                                 GAsyncResult *result,
-                                                GSList **out_users,
-                                                icalcomponent **out_modified_icalcomp,
+                                                GSList **out_users, /* gchar * */
+                                                ICalComponent **out_modified_icalcomp,
                                                 GError **error);
 gboolean       e_cal_client_send_objects_sync  (ECalClient *client,
-                                                icalcomponent *icalcomp,
-                                                GSList **out_users,
-                                                icalcomponent **out_modified_icalcomp,
+                                                ICalComponent *icalcomp,
+                                                GSList **out_users, /* gchar * */
+                                                ICalComponent **out_modified_icalcomp,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_get_attachment_uris
@@ -470,13 +460,13 @@ void              e_cal_client_get_attachment_uris
 gboolean       e_cal_client_get_attachment_uris_finish
                                                (ECalClient *client,
                                                 GAsyncResult *result,
-                                                GSList **out_attachment_uris,
+                                                GSList **out_attachment_uris, /* gchar * */
                                                 GError **error);
 gboolean       e_cal_client_get_attachment_uris_sync
                                                (ECalClient *client,
                                                 const gchar *uid,
                                                 const gchar *rid,
-                                                GSList **out_attachment_uris,
+                                                GSList **out_attachment_uris, /* gchar * */
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_discard_alarm      (ECalClient *client,
@@ -518,15 +508,15 @@ void              e_cal_client_get_timezone       (ECalClient *client,
 gboolean       e_cal_client_get_timezone_finish
                                                (ECalClient *client,
                                                 GAsyncResult *result,
-                                                icaltimezone **out_zone,
+                                                ICalTimezone **out_zone,
                                                 GError **error);
 gboolean       e_cal_client_get_timezone_sync  (ECalClient *client,
                                                 const gchar *tzid,
-                                                icaltimezone **out_zone,
+                                                ICalTimezone **out_zone,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_cal_client_add_timezone       (ECalClient *client,
-                                                icaltimezone *zone,
+                                                ICalTimezone *zone,
                                                 GCancellable *cancellable,
                                                 GAsyncReadyCallback callback,
                                                 gpointer user_data);
@@ -535,7 +525,7 @@ gboolean    e_cal_client_add_timezone_finish
                                                 GAsyncResult *result,
                                                 GError **error);
 gboolean       e_cal_client_add_timezone_sync  (ECalClient *client,
-                                                icaltimezone *zone,
+                                                ICalTimezone *zone,
                                                 GCancellable *cancellable,
                                                 GError **error);
 
diff --git a/src/calendar/libecal/e-cal-component-alarm-trigger.c 
b/src/calendar/libecal/e-cal-component-alarm-trigger.c
index 0864e2594..3ff4d3c3b 100644
--- a/src/calendar/libecal/e-cal-component-alarm-trigger.c
+++ b/src/calendar/libecal/e-cal-component-alarm-trigger.c
@@ -305,7 +305,7 @@ e_cal_component_alarm_trigger_fill_property (const ECalComponentAlarmTrigger *tr
                                             ICalProperty *property)
 {
        ICalParameter *param;
-       ICalParameterValue value_type;
+       ICalParameterValue value_type = I_CAL_VALUE_DATETIME;
        ICalParameterRelated related;
        ICalTriggerType *trgtype;
 
@@ -333,6 +333,7 @@ e_cal_component_alarm_trigger_fill_property (const ECalComponentAlarmTrigger *tr
                i_cal_trigger_type_set_time (trgtype, trigger->abs_time);
                value_type = I_CAL_VALUE_DATETIME;
                break;
+
        case E_CAL_COMPONENT_ALARM_TRIGGER_NONE:
                g_object_unref (trgtype);
                return;
diff --git a/src/calendar/libecal/e-cal-component.c b/src/calendar/libecal/e-cal-component.c
index ca7569d4c..9a77c9492 100644
--- a/src/calendar/libecal/e-cal-component.c
+++ b/src/calendar/libecal/e-cal-component.c
@@ -38,6 +38,7 @@
 
 #include "e-cal-component.h"
 #include "e-cal-time-util.h"
+#include "e-cal-util.h"
 
 #ifdef G_OS_WIN32
 #define getgid() 0
@@ -74,24 +75,6 @@ free_icalcomponent (ECalComponent *comp,
        comp->priv->need_sequence_inc = FALSE;
 }
 
-static gboolean
-ecc_property_exists (ICalComponent *icalcomp,
-                    ICalPropertyKind prop_kind)
-{
-       ICalProperty *prop;
-
-       g_return_val_if_fail (I_CAL_IS_COMPONENT (icalcomp), FALSE);
-
-       prop = i_cal_component_get_first_property (icalcomp, prop_kind);
-       if (!prop)
-               return FALSE;
-
-       g_object_unref (prop);
-
-       return TRUE;
-}
-
-
 /* The 'func' returns TRUE to continue */
 static void
 foreach_subcomponent (ICalComponent *icalcomp,
@@ -955,7 +938,7 @@ e_cal_component_has_attachments (ECalComponent *comp)
        g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
        g_return_val_if_fail (comp->priv->icalcomp != NULL, FALSE);
 
-       return ecc_property_exists (comp->priv->icalcomp, I_CAL_ATTACH_PROPERTY);
+       return e_cal_util_component_has_property (comp->priv->icalcomp, I_CAL_ATTACH_PROPERTY);
 }
 
 /* Creates a comma-delimited string of categories */
@@ -2266,7 +2249,7 @@ e_cal_component_has_exdates (ECalComponent *comp)
        g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
        g_return_val_if_fail (comp->priv->icalcomp != NULL, FALSE);
 
-       return ecc_property_exists (comp->priv->icalcomp, I_CAL_EXDATE_PROPERTY);
+       return e_cal_util_component_has_property (comp->priv->icalcomp, I_CAL_EXDATE_PROPERTY);
 }
 
 /* Gets a list of recurrence rules */
@@ -2404,7 +2387,7 @@ e_cal_component_has_exrules (ECalComponent *comp)
        g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
        g_return_val_if_fail (comp->priv->icalcomp != NULL, FALSE);
 
-       return ecc_property_exists (comp->priv->icalcomp, I_CAL_EXRULE_PROPERTY);
+       return e_cal_util_component_has_property (comp->priv->icalcomp, I_CAL_EXRULE_PROPERTY);
 }
 
 /**
@@ -2627,7 +2610,7 @@ e_cal_component_has_organizer (ECalComponent *comp)
 {
        g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
 
-       return ecc_property_exists (comp->priv->icalcomp, I_CAL_ORGANIZER_PROPERTY);
+       return e_cal_util_component_has_property (comp->priv->icalcomp, I_CAL_ORGANIZER_PROPERTY);
 }
 
 /**
@@ -2928,7 +2911,7 @@ e_cal_component_has_rdates (ECalComponent *comp)
        g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
        g_return_val_if_fail (comp->priv->icalcomp != NULL, FALSE);
 
-       return ecc_property_exists (comp->priv->icalcomp, I_CAL_RDATE_PROPERTY);
+       return e_cal_util_component_has_property (comp->priv->icalcomp, I_CAL_RDATE_PROPERTY);
 }
 
 /**
@@ -3013,7 +2996,7 @@ e_cal_component_has_rrules (ECalComponent *comp)
        g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
        g_return_val_if_fail (comp->priv->icalcomp != NULL, FALSE);
 
-       return ecc_property_exists (comp->priv->icalcomp, I_CAL_RRULE_PROPERTY);
+       return e_cal_util_component_has_property (comp->priv->icalcomp, I_CAL_RRULE_PROPERTY);
 }
 
 /**
@@ -3243,7 +3226,7 @@ e_cal_component_is_instance (ECalComponent *comp)
 {
        g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
 
-       return ecc_property_exists (comp->priv->icalcomp, I_CAL_RECURRENCEID_PROPERTY);
+       return e_cal_util_component_has_property (comp->priv->icalcomp, I_CAL_RECURRENCEID_PROPERTY);
 }
 
 /**
@@ -3799,7 +3782,7 @@ e_cal_component_has_attendees (ECalComponent *comp)
 {
        g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
 
-       return ecc_property_exists (comp->priv->icalcomp, I_CAL_ATTENDEE_PROPERTY);
+       return e_cal_util_component_has_property (comp->priv->icalcomp, I_CAL_ATTENDEE_PROPERTY);
 }
 
 /**
diff --git a/src/calendar/libecal/e-cal-enums.h b/src/calendar/libecal/e-cal-enums.h
index afa350142..d1ea0226d 100644
--- a/src/calendar/libecal/e-cal-enums.h
+++ b/src/calendar/libecal/e-cal-enums.h
@@ -183,6 +183,25 @@ typedef enum {
        E_CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE
 } ECalComponentAlarmTriggerKind;
 
+/**
+ * ECalRecurDescribeRecurrenceFlags:
+ * @E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_NONE: no extra flags, either returns %NULL or the recurrence 
description,
+ *    something like "Every 2 weeks..."
+ * @E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_PREFIXED: either returns %NULL or the recurrence description 
prefixed
+ *    with text like "The meeting recurs", forming something like "The meeting recurs every 2 weeks..."
+ * @E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_FALLBACK: returns %NULL only if the component doesn't recur,
+ *    otherwise returns either the recurrence description or at least text like "The meeting recurs"
+ *
+ * Influences behaviour of e_cal_recur_describe_recurrence().
+ *
+ * Since: 3.30
+ **/
+typedef enum {
+       E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_NONE       = 0,
+       E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_PREFIXED   = (1 << 0),
+       E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_FALLBACK   = (1 << 1)
+} ECalRecurDescribeRecurrenceFlags;
+
 G_END_DECLS
 
 #endif /* E_CAL_ENUMS_H */
diff --git a/src/calendar/libecal/e-cal-recur.c b/src/calendar/libecal/e-cal-recur.c
index dc8112807..77c0ec9f1 100644
--- a/src/calendar/libecal/e-cal-recur.c
+++ b/src/calendar/libecal/e-cal-recur.c
@@ -178,6 +178,7 @@ ensure_timezone (icalcomponent *comp,
                 ECalRecurResolveTimezoneCb get_tz_callback,
                 gpointer get_tz_callback_user_data,
                 icaltimezone *default_timezone,
+                GHashTable **pcached_zones,
                 GCancellable *cancellable,
                 GError **error)
 {
@@ -217,9 +218,24 @@ ensure_timezone (icalcomponent *comp,
        if (!tzid || !*tzid)
                return TRUE;
 
-       if (get_tz_callback)
-               tt->zone = get_tz_callback (tzid, get_tz_callback_user_data, cancellable, &local_error);
-       else
+       if (get_tz_callback) {
+               ICalTimezone *zone = NULL;
+
+               if (*pcached_zones)
+                       zone = g_hash_table_lookup (*pcached_zones, tzid);
+
+               if (!zone) {
+                       zone = get_tz_callback (tzid, get_tz_callback_user_data, cancellable, &local_error);
+                       if (zone) {
+                               if (!*pcached_zones)
+                                       *pcached_zones = g_hash_table_new_full (g_str_hash, g_str_equal, 
g_free, g_object_unref);
+
+                               g_hash_table_insert (*pcached_zones, g_strdup (tzid), zone);
+                       }
+               }
+
+               tt->zone = zone ? i_cal_object_get_native (I_CAL_OBJECT (zone)) : NULL;
+       } else
                tt->zone = NULL;
 
        if (!tt->zone)
@@ -296,14 +312,14 @@ intersects_interval (const struct icaltimetype *tt,
 
 /**
  * e_cal_recur_generate_instances_sync:
- * @comp: an icalcomponent
+ * @icalcomp: an #ICalComponent
  * @interval_start: an interval start, for which generate instances
  * @interval_end: an interval end, for which generate instances
  * @callback: (scope call): a callback to be called for each instance
  * @callback_user_data: (closure callback): user data for @callback
  * @get_tz_callback: (scope call): a callback to call when resolving timezone
  * @get_tz_callback_user_data: (closure get_tz_callback): user data for @get_tz_callback
- * @default_timezone: a default icaltimezone
+ * @default_timezone: a default #ICalTimezone
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
@@ -317,7 +333,7 @@ intersects_interval (const struct icaltimetype *tt,
  * The start and end times are required valid times, start before end time.
  *
  * The @get_tz_callback is used to resolve references to timezones. It is passed
- * a TZID and should return the icaltimezone * corresponding to that TZID. We need to
+ * a TZID and should return the ICalTimezone * corresponding to that TZID. We need to
  * do this as we access timezones in different ways on the client & server.
  *
  * The default_timezone argument is used for DTSTART or DTEND properties that
@@ -328,35 +344,54 @@ intersects_interval (const struct icaltimetype *tt,
  * Since: 3.20
  **/
 gboolean
-e_cal_recur_generate_instances_sync (icalcomponent *comp,
-                                    struct icaltimetype interval_start,
-                                    struct icaltimetype interval_end,
+e_cal_recur_generate_instances_sync (ICalComponent *icalcomp,
+                                    ICalTimetype *interval_start,
+                                    ICalTimetype *interval_end,
                                     ECalRecurInstanceCb callback,
                                     gpointer callback_user_data,
                                     ECalRecurResolveTimezoneCb get_tz_callback,
                                     gpointer get_tz_callback_user_data,
-                                    icaltimezone *default_timezone,
+                                    ICalTimezone *default_timezone,
                                     GCancellable *cancellable,
                                     GError **error)
 {
-       struct icaltimetype dtstart, dtend, next;
-       gint64 duration_days, duration_seconds;
+       struct icaltimetype dtstart, dtend, next, interval_start_tt, interval_end_tt, *native_tt;
+       icalcomponent *comp;
        icalproperty *prop;
-       GHashTable *times;
+       icaltimezone *default_zone;
+       gint64 duration_days, duration_seconds;
+       GHashTable *times, *cached_zones = NULL;
        gboolean success = TRUE;
 
-       g_return_val_if_fail (comp != NULL, FALSE);
+       g_return_val_if_fail (icalcomp != NULL, FALSE);
        g_return_val_if_fail (callback != NULL, FALSE);
-       g_return_val_if_fail (icaltime_compare (interval_start, interval_end) < 0, FALSE);
+       g_return_val_if_fail (interval_start != NULL, FALSE);
+       g_return_val_if_fail (interval_end != NULL, FALSE);
+       g_return_val_if_fail (i_cal_time_compare (interval_start, interval_end) < 0, FALSE);
 
        if (g_cancellable_set_error_if_cancelled (cancellable, error))
                return FALSE;
 
+       /* Keep the public API using libical-glib, but internally use libical,
+          for its memory management simplicity. */
+       comp = i_cal_object_get_native (I_CAL_OBJECT (icalcomp));
+       g_return_val_if_fail (comp != NULL, FALSE);
+
+       native_tt = i_cal_object_get_native (I_CAL_OBJECT (interval_start));
+       g_return_val_if_fail (native_tt != NULL, FALSE);
+       interval_start_tt = *native_tt;
+
+       native_tt = i_cal_object_get_native (I_CAL_OBJECT (interval_end));
+       g_return_val_if_fail (native_tt != NULL, FALSE);
+       interval_end_tt = *native_tt;
+
+       default_zone = default_timezone ? i_cal_object_get_native (I_CAL_OBJECT (default_timezone)) : NULL;
+
        times = g_hash_table_new_full (e_instance_time_hash, e_instance_time_equal, g_free, NULL);
 
        dtstart = icalcomponent_get_dtstart (comp);
        success = ensure_timezone (comp, &dtstart, ICAL_DTSTART_PROPERTY, NULL,
-               get_tz_callback, get_tz_callback_user_data, default_timezone, cancellable, error);
+               get_tz_callback, get_tz_callback_user_data, default_zone, &cached_zones, cancellable, error);
 
        duration_seconds = 0;
        dtend = icalcomponent_get_dtend (comp);
@@ -398,7 +433,7 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
 
        if (success && !icaltime_is_null_time (dtend)) {
                success = ensure_timezone (comp, &dtend, ICAL_DTEND_PROPERTY, NULL,
-                       get_tz_callback, get_tz_callback_user_data, default_timezone, cancellable, error);
+                       get_tz_callback, get_tz_callback_user_data, default_zone, &cached_zones, cancellable, 
error);
                duration_seconds = (gint64) icaltime_as_timet_with_zone (dtend, dtend.zone) -
                        (gint64) icaltime_as_timet_with_zone (dtstart, dtstart.zone);
                if (duration_seconds < 0)
@@ -408,7 +443,7 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
        duration_days = duration_seconds / (24 * 60 * 60);
        duration_seconds = duration_seconds % (24 * 60 * 60);
 
-       if (success && intersects_interval (&dtstart, NULL, duration_days, duration_seconds, &interval_start, 
&interval_end)) {
+       if (success && intersects_interval (&dtstart, NULL, duration_days, duration_seconds, 
&interval_start_tt, &interval_end_tt)) {
                g_hash_table_insert (times, e_instance_time_new (&dtstart, NULL), NULL);
        }
 
@@ -423,7 +458,7 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                        if (!icaltime_is_null_time (rrule.until)) {
                                success = ensure_timezone (comp, &rrule.until, 0, prop,
                                        get_tz_callback, get_tz_callback_user_data, (icaltimezone *) 
dtstart.zone,
-                                       cancellable, error);
+                                       &cached_zones, cancellable, error);
                                if (!success)
                                        break;
                        }
@@ -445,14 +480,14 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                                struct icaltimetype prev = icaltime_null_time ();
 
                                for (next = icalrecur_iterator_next (riter);
-                                    !icaltime_is_null_time (next) && icaltime_compare (next, interval_end) 
<= 0;
+                                    !icaltime_is_null_time (next) && icaltime_compare (next, 
interval_end_tt) <= 0;
                                     next = icalrecur_iterator_next (riter)) {
                                        if (!icaltime_is_null_time (prev) &&
                                            icaltime_compare (next, prev) == 0)
                                                break;
                                        prev = next;
 
-                                       if (intersects_interval (&next, NULL, duration_days, 
duration_seconds, &interval_start, &interval_end)) {
+                                       if (intersects_interval (&next, NULL, duration_days, 
duration_seconds, &interval_start_tt, &interval_end_tt)) {
                                                g_hash_table_insert (times, e_instance_time_new (&next, 
NULL), NULL);
                                        }
                                }
@@ -511,11 +546,11 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                        if (!icaltime_is_null_time (tt)) {
                                success = ensure_timezone (comp, &tt, 0, prop,
                                        get_tz_callback, get_tz_callback_user_data, (icaltimezone *) 
dtstart.zone,
-                                       cancellable, error);
+                                       &cached_zones, cancellable, error);
                                if (!success)
                                        break;
 
-                               if (intersects_interval (&tt, &duration, duration_days, duration_seconds, 
&interval_start, &interval_end)) {
+                               if (intersects_interval (&tt, &duration, duration_days, duration_seconds, 
&interval_start_tt, &interval_end_tt)) {
                                        g_hash_table_insert (times, e_instance_time_new (&tt, &duration), 
NULL);
                                }
                        }
@@ -530,7 +565,7 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                        if (!icaltime_is_null_time (exrule.until)) {
                                success = ensure_timezone (comp, &exrule.until, 0, prop,
                                        get_tz_callback, get_tz_callback_user_data, (icaltimezone *) 
dtstart.zone,
-                                       cancellable, error);
+                                       &cached_zones, cancellable, error);
                                if (!success)
                                        break;
                        }
@@ -552,14 +587,14 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                                struct icaltimetype prev = icaltime_null_time ();
 
                                for (next = icalrecur_iterator_next (riter);
-                                    !icaltime_is_null_time (next) && icaltime_compare (next, interval_end) 
<= 0;
+                                    !icaltime_is_null_time (next) && icaltime_compare (next, 
interval_end_tt) <= 0;
                                     next = icalrecur_iterator_next (riter)) {
                                        if (!icaltime_is_null_time (prev) &&
                                            icaltime_compare (next, prev) == 0)
                                                break;
                                        prev = next;
 
-                                       if (intersects_interval (&next, NULL, duration_days, 
duration_seconds, &interval_start, &interval_end)) {
+                                       if (intersects_interval (&next, NULL, duration_days, 
duration_seconds, &interval_start_tt, &interval_end_tt)) {
                                                EInstanceTime it;
 
                                                it.tt = next;
@@ -583,14 +618,14 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
 
                        success = ensure_timezone (comp, &exdate, 0, prop,
                                get_tz_callback, get_tz_callback_user_data, (icaltimezone *) dtstart.zone,
-                               cancellable, error);
+                               &cached_zones, cancellable, error);
                        if (!success)
                                break;
 
                        if (!exdate.zone && !icaltime_is_utc (exdate))
                                exdate.zone = dtstart.zone;
 
-                       if (intersects_interval (&exdate, NULL, duration_days, duration_seconds, 
&interval_start, &interval_end)) {
+                       if (intersects_interval (&exdate, NULL, duration_days, duration_seconds, 
&interval_start_tt, &interval_end_tt)) {
                                EInstanceTime it;
 
                                it.tt = exdate;
@@ -624,6 +659,7 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                for (ii = 0; ii < times_array->len; ii++) {
                        EInstanceTime *it = g_ptr_array_index (times_array, ii);
                        struct icaltimetype ttend;
+                       ICalTimetype *gttstart, *gttend;
                        gint dur_days = duration_days, dur_seconds = duration_seconds;
 
                        if (!it)
@@ -646,7 +682,14 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                                break;
                        }
 
-                       success = callback (comp, it->tt, ttend, callback_user_data, cancellable, error);
+                       gttstart = i_cal_object_construct (I_CAL_TYPE_TIMETYPE, &(it->tt), NULL, FALSE, NULL);
+                       gttend = i_cal_object_construct (I_CAL_TYPE_TIMETYPE, &ttend, NULL, FALSE, NULL);
+
+                       success = callback (icalcomp, gttstart, gttend, callback_user_data, cancellable, 
error);
+
+                       g_clear_object (&gttstart);
+                       g_clear_object (&gttend);
+
                        if (!success)
                                break;
                }
@@ -656,6 +699,9 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
 
        g_hash_table_destroy (times);
 
+       if (cached_zones)
+               g_hash_table_destroy (cached_zones);
+
        return success;
 }
 
@@ -849,9 +895,6 @@ struct _CalObjRecurrenceDate {
        ECalComponentPeriod *period;
 };
 
-/* The paramter we use to store the enddate in RRULE and EXRULE properties. */
-#define EVOLUTION_END_DATE_PARAMETER   "X-EVOLUTION-ENDDATE"
-
 typedef gboolean (*CalObjFindStartFn) (CalObjTime *event_start,
                                       CalObjTime *event_end,
                                       RecurData  *recur_data,
@@ -895,13 +938,13 @@ static void e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
                                                  icalproperty  *prop,
                                                  time_t         start,
                                                  time_t         end,
-                                                 ECalRecurInstanceFn cb,
+                                                 ECalRecurInstanceCb cb,
                                                  gpointer       cb_data,
-                                                 ECalRecurResolveTimezoneFn  tz_cb,
+                                                 ECalRecurResolveTimezoneCb  tz_cb,
                                                  gpointer       tz_cb_data,
                                                  icaltimezone  *default_timezone);
 
-static ECalRecurrence * e_cal_recur_from_icalproperty (icalproperty *prop,
+static ECalRecurrence * e_cal_recur_from_icalproperty (ICalProperty *prop,
                                                    gboolean exception,
                                                    icaltimezone *zone,
                                                    gboolean convert_end_date);
@@ -931,7 +974,7 @@ static gboolean generate_instances_for_chunk        (ECalComponent          *comp,
                                                 gint                    duration_days,
                                                 gint                    duration_seconds,
                                                 gboolean                convert_end_date,
-                                                ECalRecurInstanceFn     cb,
+                                                ECalRecurInstanceCb     cb,
                                                 gpointer                cb_data);
 
 static GArray * cal_obj_expand_recurrence      (CalObjTime       *event_start,
@@ -1107,18 +1150,22 @@ static void cal_object_time_from_time           (CalObjTime *cotime,
 static gint cal_obj_date_only_compare_func     (gconstpointer arg1,
                                                 gconstpointer arg2);
 static gboolean e_cal_recur_ensure_rule_end_date       (ECalComponent  *comp,
-                                                icalproperty   *prop,
+                                                ICalProperty   *prop,
                                                 gboolean        exception,
                                                 gboolean        refresh,
-                                                ECalRecurResolveTimezoneFn tz_cb,
-                                                gpointer        tz_cb_data);
-static gboolean e_cal_recur_ensure_rule_end_date_cb    (ECalComponent  *comp,
-                                                        time_t          instance_start,
-                                                        time_t          instance_end,
-                                                        gpointer        data);
-static time_t e_cal_recur_get_rule_end_date    (icalproperty   *prop,
-                                                icaltimezone   *default_timezone);
-static void e_cal_recur_set_rule_end_date              (icalproperty   *prop,
+                                                ECalRecurResolveTimezoneCb tz_cb,
+                                                gpointer        tz_cb_data,
+                                                GCancellable *cancellable,
+                                                GError **error);
+static gboolean e_cal_recur_ensure_rule_end_date_cb    (ICalComponent  *comp,
+                                                        ICalTimetype *instance_start,
+                                                        ICalTimetype *instance_end,
+                                                        gpointer user_data,
+                                                        GCancellable *cancellable,
+                                                        GError **error);
+static time_t e_cal_recur_get_rule_end_date    (ICalProperty   *prop,
+                                                ICalTimezone   *default_timezone);
+static void e_cal_recur_set_rule_end_date      (ICalProperty   *prop,
                                                 time_t          end_date);
 
 #ifdef CAL_OBJ_DEBUG
@@ -1223,115 +1270,29 @@ static ECalRecurVTable cal_obj_secondly_vtable = {
        cal_obj_bysecond_filter
 };
 
-struct BackwardCompatibilityData
-{
-       ECalComponent *comp;
-       ECalRecurInstanceFn cb;
-       gpointer cb_data;
-       ECalRecurResolveTimezoneFn tz_cb;
-       gpointer tz_cb_data;
-};
-
-static icaltimezone *
-backward_compatibility_resolve_timezone_cb (const gchar *tzid,
-                                           gpointer user_data,
-                                           GCancellable *cancellable,
-                                           GError **error)
-{
-       struct BackwardCompatibilityData *bcd = user_data;
-
-       if (bcd && bcd->tz_cb)
-               return bcd->tz_cb (tzid, bcd->tz_cb_data);
-
-       return NULL;
-}
-
 static gboolean
-backward_compatibility_instance_cb (icalcomponent *comp,
-                                   struct icaltimetype instance_start,
-                                   struct icaltimetype instance_end,
-                                   gpointer user_data,
-                                   GCancellable *cancellable,
-                                   GError **error)
+call_instance_callback (ECalRecurInstanceCb cb,
+                       ECalComponent *comp,
+                       time_t dtstart_time,
+                       time_t dtend_time,
+                       gpointer cb_data)
 {
-       struct BackwardCompatibilityData *bcd = user_data;
+       ICalTimetype *start, *end;
+       ICalTimezone *utc_zone;
+       gboolean res;
 
-       if (bcd && bcd->cb) {
-               time_t istart, iend;
+       g_return_val_if_fail (cb != NULL, FALSE);
 
-               if (instance_start.zone)
-                       istart = icaltime_as_timet_with_zone (instance_start, instance_start.zone);
-               else
-                       istart = icaltime_as_timet (instance_start);
+       utc_zone = i_cal_timezone_get_utc_timezone ();
+       start = i_cal_time_from_timet_with_zone (dtstart_time, FALSE, utc_zone);
+       end = i_cal_time_from_timet_with_zone (dtend_time, FALSE, utc_zone);
 
-               if (instance_end.zone)
-                       iend = icaltime_as_timet_with_zone (instance_end, instance_end.zone);
-               else
-                       iend = icaltime_as_timet (instance_end);
+       res = cb (e_cal_component_get_icalcomponent (comp), start, end, cb_data, NULL, NULL);
 
-               return bcd->cb (bcd->comp, istart, iend, bcd->cb_data);
-       }
+       g_clear_object (&start);
+       g_clear_object (&end);
 
-       return FALSE;
-}
-
-/**
- * e_cal_recur_generate_instances:
- * @comp: A calendar component object
- * @start: Range start time
- * @end: Range end time
- * @cb: (closure cb_data) (scope call): Callback function
- * @cb_data: (closure): Closure data for the callback function
- * @tz_cb: (closure tz_cb_data) (scope call): Callback for retrieving timezones
- * @tz_cb_data: (closure): Closure data for the timezone callback
- * @default_timezone: Default timezone to use when a timezone cannot be
- * found
- *
- * Calls the given callback function for each occurrence of the event that
- * intersects the range between the given @start and @end times (the end time is
- * not included). Note that the occurrences may start before the given start
- * time.
- *
- * If the callback routine returns FALSE the occurrence generation stops.
- *
- * Both start and end can be -1, in which case we start at the events first
- * instance and continue until it ends, or forever if it has no enddate.
- *
- * The tz_cb is used to resolve references to timezones. It is passed a TZID
- * and should return the icaltimezone* corresponding to that TZID. We need to
- * do this as we access timezones in different ways on the client & server.
- *
- * The default_timezone argument is used for DTSTART or DTEND properties that
- * are DATE values or do not have a TZID (i.e. floating times).
- *
- * Note: This will be replaced by e_cal_recur_generate_instances_sync().
- */
-void
-e_cal_recur_generate_instances (ECalComponent *comp,
-                                time_t start,
-                                time_t end,
-                                ECalRecurInstanceFn cb,
-                                gpointer cb_data,
-                                ECalRecurResolveTimezoneFn tz_cb,
-                                gpointer tz_cb_data,
-                                icaltimezone *default_timezone)
-{
-       struct icaltimetype istart, iend;
-       struct BackwardCompatibilityData bcd;
-
-       bcd.comp = comp;
-       bcd.cb = cb;
-       bcd.cb_data = cb_data;
-       bcd.tz_cb = tz_cb;
-       bcd.tz_cb_data = tz_cb_data;
-
-       istart = icaltime_from_timet_with_zone (start, FALSE, icaltimezone_get_utc_timezone ());
-       iend = icaltime_from_timet_with_zone (end, FALSE, icaltimezone_get_utc_timezone ());
-
-       e_cal_recur_generate_instances_sync (e_cal_component_get_icalcomponent (comp), istart, iend,
-               backward_compatibility_instance_cb, &bcd,
-               backward_compatibility_resolve_timezone_cb, &bcd,
-               default_timezone, NULL, NULL);
+       return res;
 }
 
 /*
@@ -1353,21 +1314,23 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
                                         icalproperty *prop,
                                         time_t start,
                                         time_t end,
-                                        ECalRecurInstanceFn cb,
+                                        ECalRecurInstanceCb cb,
                                         gpointer cb_data,
-                                        ECalRecurResolveTimezoneFn tz_cb,
+                                        ECalRecurResolveTimezoneCb tz_cb,
                                         gpointer tz_cb_data,
                                         icaltimezone *default_timezone)
 {
-       ECalComponentDateTime dtstart, dtend;
+       ECalComponentDateTime *dtstart, *dtend;
        time_t dtstart_time, dtend_time;
-       GSList *rrules = NULL, *rdates = NULL, elem;
+       GSList *rrules = NULL, *rdates = NULL;
        GSList *exrules = NULL, *exdates = NULL;
        CalObjTime interval_start, interval_end, event_start, event_end;
        CalObjTime chunk_start, chunk_end;
        gint days, seconds, year;
        gboolean single_rule, convert_end_date = FALSE;
        icaltimezone *start_zone = NULL, *end_zone = NULL;
+       ICalTimezone *gstart_zone = NULL, *gend_zone = NULL;
+       struct icaltimetype *dtstarttt, *dtendtt;
 
        g_return_if_fail (comp != NULL);
        g_return_if_fail (cb != NULL);
@@ -1379,10 +1342,15 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
         * cal_component_get_dtend () will convert a DURATION property to a
         * DTEND so we don't need to worry about that. */
 
-       e_cal_component_get_dtstart (comp, &dtstart);
-       e_cal_component_get_dtend (comp, &dtend);
+       dtstart = e_cal_component_get_dtstart (comp);
+       dtend = e_cal_component_get_dtend (comp);
+
+       dtstarttt = (dtstart && e_cal_component_datetime_get_value (dtstart)) ?
+               i_cal_object_get_native (I_CAL_OBJECT (e_cal_component_datetime_get_value (dtstart))) : NULL;
+       dtendtt = (dtend && e_cal_component_datetime_get_value (dtend)) ?
+               i_cal_object_get_native (I_CAL_OBJECT (e_cal_component_datetime_get_value (dtend))) : NULL;
 
-       if (!dtstart.value) {
+       if (!dtstart || !dtstarttt) {
                g_message (
                        "e_cal_recur_generate_instances_of_rule(): bogus "
                        "component, does not have DTSTART.  Skipping...");
@@ -1392,8 +1360,10 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
        /* For DATE-TIME values with a TZID, we use the supplied callback to
         * resolve the TZID. For DATE values and DATE-TIME values without a
         * TZID (i.e. floating times) we use the default timezone. */
-       if (dtstart.tzid && !dtstart.value->is_date) {
-               start_zone = (*tz_cb) (dtstart.tzid, tz_cb_data);
+       if (e_cal_component_datetime_get_tzid (dtstart) && !dtstarttt->is_date) {
+               gstart_zone = (*tz_cb) (e_cal_component_datetime_get_tzid (dtstart), tz_cb_data, NULL, NULL);
+               if (gstart_zone)
+                       start_zone = i_cal_object_get_native (I_CAL_OBJECT (gstart_zone));
                if (!start_zone)
                        start_zone = default_timezone;
        } else {
@@ -1404,37 +1374,41 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
                convert_end_date = TRUE;
        }
 
-       dtstart_time = icaltime_as_timet_with_zone (
-               *dtstart.value,
-               start_zone);
+       dtstart_time = icaltime_as_timet_with_zone (*dtstarttt, start_zone);
        if (start == -1)
                start = dtstart_time;
 
-       if (dtend.value) {
+       if (dtendtt) {
                /* If both DTSTART and DTEND are DATE values, and they are the
                 * same day, we add 1 day to DTEND. This means that most
                 * events created with the old Evolution behavior will still
                 * work OK. I'm not sure what Outlook does in this case. */
-               if (dtstart.value->is_date && dtend.value->is_date) {
-                       if (icaltime_compare_date_only (*dtstart.value,
-                                                       *dtend.value) == 0) {
-                               icaltime_adjust (dtend.value, 1, 0, 0, 0);
+               if (dtstarttt->is_date && dtendtt->is_date) {
+                       if (icaltime_compare_date_only (*dtstarttt, *dtendtt) == 0) {
+                               icaltime_adjust (dtendtt, 1, 0, 0, 0);
                        }
                }
        } else {
                /* If there is no DTEND, then if DTSTART is a DATE-TIME value
                 * we use the same time (so we have a single point in time).
                 * If DTSTART is a DATE value we add 1 day. */
-               dtend.value = g_new (struct icaltimetype, 1);
-               *dtend.value = *dtstart.value;
+               e_cal_component_datetime_free (dtend);
 
-               if (dtstart.value->is_date) {
-                       icaltime_adjust (dtend.value, 1, 0, 0, 0);
+               dtend = e_cal_component_datetime_copy (dtstart);
+               dtendtt = (dtend && e_cal_component_datetime_get_value (dtend)) ?
+                       i_cal_object_get_native (I_CAL_OBJECT (e_cal_component_datetime_get_value (dtend))) : 
NULL;
+
+               g_warn_if_fail (dtendtt != NULL);
+
+               if (dtstarttt->is_date) {
+                       icaltime_adjust (dtendtt, 1, 0, 0, 0);
                }
        }
 
-       if (dtend.tzid && !dtend.value->is_date) {
-               end_zone = (*tz_cb) (dtend.tzid, tz_cb_data);
+       if (e_cal_component_datetime_get_tzid (dtend) && dtendtt && !dtendtt->is_date) {
+               gend_zone = (*tz_cb) (e_cal_component_datetime_get_tzid (dtend), tz_cb_data, NULL, NULL);
+               if (gend_zone)
+                       end_zone = i_cal_object_get_native (I_CAL_OBJECT (gend_zone));
                if (!end_zone)
                        end_zone = default_timezone;
        } else {
@@ -1446,14 +1420,14 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
 #if 0
        /* If DTEND is a DATE value, we add 1 day to it so that it includes
         * the entire day. */
-       if (dtend.value->is_date) {
-               dtend.value->hour = 0;
-               dtend.value->minute = 0;
-               dtend.value->second = 0;
-               icaltime_adjust (dtend.value, 1, 0, 0, 0);
+       if (dtendtt->is_date) {
+               dtendtt->hour = 0;
+               dtendtt->minute = 0;
+               dtendtt->second = 0;
+               icaltime_adjust (dtendtt, 1, 0, 0, 0);
        }
 #endif
-       dtend_time = icaltime_as_timet_with_zone (*dtend.value, end_zone);
+       dtend_time = icaltime_as_timet_with_zone (*dtendtt, end_zone);
 
        /* If there is no recurrence, just call the callback if the event
         * intersects the given interval. */
@@ -1463,10 +1437,10 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
                        icaltimetype start_t = icaltime_from_timet_with_zone (start, FALSE, default_timezone);
                        icaltimetype end_t = icaltime_from_timet_with_zone (end, FALSE, default_timezone);
 
-                       if ((icaltime_compare_date_only (*dtstart.value, start_t) >= 0) && 
((icaltime_compare_date_only (*dtstart.value, end_t) < 0)))
-                               (* cb) (comp, dtstart_time, dtend_time, cb_data);
+                       if ((icaltime_compare_date_only (*dtstarttt, start_t) >= 0) && 
((icaltime_compare_date_only (*dtstarttt, end_t) < 0)))
+                               call_instance_callback (cb, comp, dtstart_time, dtend_time, cb_data);
                } else if  ((end == -1 || dtstart_time < end) && dtend_time > start) {
-                       (* cb) (comp, dtstart_time, dtend_time, cb_data);
+                       call_instance_callback (cb, comp, dtstart_time, dtend_time, cb_data);
                }
 
                goto out;
@@ -1477,21 +1451,19 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
        if (prop) {
                single_rule = TRUE;
 
-               elem.data = prop;
-               elem.next = NULL;
-               rrules = &elem;
+               rrules = g_slist_prepend (NULL, i_cal_object_construct (I_CAL_TYPE_PROPERTY, prop, NULL, 
FALSE, NULL));
        } else if (e_cal_component_is_instance (comp)) {
                single_rule = FALSE;
        } else {
                single_rule = FALSE;
 
                /* Make sure all the enddates for the rules are set. */
-               e_cal_recur_ensure_end_dates (comp, FALSE, tz_cb, tz_cb_data);
+               e_cal_recur_ensure_end_dates (comp, FALSE, tz_cb, tz_cb_data, NULL, NULL);
 
-               e_cal_component_get_rrule_property_list (comp, &rrules);
-               e_cal_component_get_rdate_list (comp, &rdates);
-               e_cal_component_get_exrule_property_list (comp, &exrules);
-               e_cal_component_get_exdate_list (comp, &exdates);
+               rrules = e_cal_component_get_rrule_properties (comp);
+               rdates = e_cal_component_get_rdates (comp);
+               exrules = e_cal_component_get_exrule_properties (comp);
+               exdates = e_cal_component_get_exdates (comp);
        }
 
        /* Convert the interval start & end to CalObjTime. Note that if end
@@ -1570,14 +1542,16 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
                        break;
        }
 
-       if (!prop) {
-               e_cal_component_free_period_list (rdates);
-               e_cal_component_free_exdate_list (exdates);
-       }
+       g_slist_free_full (rdates, e_cal_component_period_free);
+       g_slist_free_full (exdates, e_cal_component_datetime_free);
+       g_slist_free_full (rrules, g_object_unref);
+       g_slist_free_full (exrules, g_object_unref);
 
  out:
-       e_cal_component_free_datetime (&dtstart);
-       e_cal_component_free_datetime (&dtend);
+       e_cal_component_datetime_free (dtstart);
+       e_cal_component_datetime_free (dtend);
+       g_clear_object (&gstart_zone);
+       g_clear_object (&gend_zone);
 }
 
 /* Builds a list of GINT_TO_POINTER() elements out of a short array from a
@@ -1600,12 +1574,12 @@ array_to_list (gshort *array,
 /**
  * e_cal_recur_get_enddate:
  * @ir: RRULE or EXRULE recurrence 
- * @prop: An RRULE or EXRULE #icalproperty. 
+ * @prop: An RRULE or EXRULE #ICalProperty.
  * @zone: The DTSTART timezone, used for converting the UNTIL property if it
- * is given as a DATE value.
+ *    is given as a DATE value.
  * @convert_end_date: TRUE if the saved end date needs to be converted to the
- * given @zone timezone. This is needed if the DTSTART is a DATE or floating
- * time.
+ *    given @zone timezone. This is needed if the DTSTART is a DATE or floating
+ *    time.
  * 
  * Finds out end time of (reccurent) event.
  *
@@ -1614,54 +1588,54 @@ array_to_list (gshort *array,
  * Since: 2.32
  */
 time_t
-e_cal_recur_obtain_enddate (struct icalrecurrencetype *ir,
-                            icalproperty *prop,
-          icaltimezone *zone,
-                            gboolean convert_end_date)
+e_cal_recur_obtain_enddate (ICalRecurrenceType *ir,
+                           ICalProperty *prop,
+                           ICalTimezone *zone,
+                           gboolean convert_end_date)
 {
        time_t enddate = -1;
 
        g_return_val_if_fail (prop != NULL, 0);
        g_return_val_if_fail (ir != NULL, 0);
 
-       if (ir->count != 0) {
+       if (i_cal_recurrence_type_get_count (ir) != 0) {
                /* If COUNT is set, we use the pre-calculated enddate.
                Note that this can be 0 if the RULE doesn't actually
                generate COUNT instances. */
                enddate = e_cal_recur_get_rule_end_date (prop, convert_end_date ? zone : NULL);
        } else {
-               if (icaltime_is_null_time (ir->until)) {
+               ICalTimetype *until;
+
+               until = i_cal_recurrence_type_get_until (ir);
+
+               if (!until || i_cal_time_is_null_time (until)) {
                        /* If neither COUNT or UNTIL is set, the event
                        recurs forever. */
-               } else if (ir->until.is_date) {
+               } else if (i_cal_timetype_get_is_date (until)) {
                        /* If UNTIL is a DATE, we stop at the end of
                        the day, in local time (with the DTSTART timezone).
                        Note that UNTIL is inclusive so we stop before
                        midnight. */
-                       ir->until.hour = 23;
-                       ir->until.minute = 59;
-                       ir->until.second = 59;
-                       ir->until.is_date = FALSE;
-
-                       enddate = icaltime_as_timet_with_zone (ir->until, zone);
-#if 0
-       g_print ("  until: %li - %s", r->enddate, ctime (&r->enddate));
-#endif
+                       i_cal_timetype_set_hour (until, 23);
+                       i_cal_timetype_set_minute (until, 59);
+                       i_cal_timetype_set_second (until, 59);
+                       i_cal_timetype_set_is_date (until, FALSE);
 
+                       enddate = i_cal_time_as_timet_with_zone (until, zone);
                } else {
-               /* If UNTIL is a DATE-TIME, it must be in UTC. */
-               icaltimezone *utc_zone;
-               utc_zone = icaltimezone_get_utc_timezone ();
-               enddate = icaltime_as_timet_with_zone (ir->until, utc_zone);
+                       /* If UNTIL is a DATE-TIME, it must be in UTC. */
+                       enddate = i_cal_time_as_timet_with_zone (until, i_cal_timezone_get_utc_timezone ());
                }
+
+               g_clear_object (&until);
        }
 
        return enddate;
 }
 
-/**
+/*
  * e_cal_recur_from_icalproperty:
- * @prop: An RRULE or EXRULE #icalproperty.
+ * @prop: An RRULE or EXRULE #ICalProperty.
  * @exception: TRUE if this is an EXRULE rather than an RRULE.
  * @zone: The DTSTART timezone, used for converting the UNTIL property if it
  * is given as a DATE value.
@@ -1669,30 +1643,39 @@ e_cal_recur_obtain_enddate (struct icalrecurrencetype *ir,
  * given @zone timezone. This is needed if the DTSTART is a DATE or floating
  * time.
  *
- * Converts an #icalproperty to a #ECalRecurrence.  This should be
+ * Converts an #ICalProperty to a #ECalRecurrence.  This should be
  * freed using the e_cal_recur_free() function.
  *
  * Returns: #ECalRecurrence structure.
- **/
+ */
 static ECalRecurrence *
-e_cal_recur_from_icalproperty (icalproperty *prop,
+e_cal_recur_from_icalproperty (ICalProperty *gprop,
                                gboolean exception,
                                icaltimezone *zone,
                                gboolean convert_end_date)
 {
        struct icalrecurrencetype ir;
+       ICalRecurrenceType *gir;
+       ICalTimezone *gzone;
+       icalproperty *prop;
        ECalRecurrence *r;
        gint max_elements, i;
        GList *elem;
 
+       g_return_val_if_fail (gprop != NULL, NULL);
+
+       prop = i_cal_object_get_native (I_CAL_OBJECT (gprop));
        g_return_val_if_fail (prop != NULL, NULL);
 
        r = g_new (ECalRecurrence, 1);
 
-       if (exception)
+       if (exception) {
                ir = icalproperty_get_exrule (prop);
-       else
+               gir = i_cal_property_get_exrule (gprop);
+       } else {
                ir = icalproperty_get_rrule (prop);
+               gir = i_cal_property_get_rrule (gprop);
+       }
 
        r->freq = ir.freq;
 
@@ -1705,7 +1688,11 @@ e_cal_recur_from_icalproperty (icalproperty *prop,
                r->interval = ir.interval;
        }
 
-  r->enddate = e_cal_recur_obtain_enddate (&ir, prop, zone, convert_end_date);
+       gzone = zone ? i_cal_object_construct (I_CAL_TYPE_TIMEZONE, zone, NULL, FALSE, NULL) : NULL;
+
+       r->enddate = e_cal_recur_obtain_enddate (gir, gprop, gzone, convert_end_date);
+
+       g_clear_object (&gzone);
 
        r->week_start_day = e_cal_recur_ical_weekday_to_weekday (ir.week_start);
 
@@ -1750,6 +1737,8 @@ e_cal_recur_from_icalproperty (icalproperty *prop,
 
        r->bysetpos = array_to_list (ir.by_set_pos, G_N_ELEMENTS (ir.by_set_pos));
 
+       g_clear_object (&gir);
+
        return r;
 }
 
@@ -1832,7 +1821,7 @@ static gboolean
 generate_instances_for_chunk (ECalComponent *comp,
                               time_t comp_dtstart,
                               icaltimezone *zone,
-                              GSList *rrules,
+                              GSList *rrules, /* ICalProperty * */
                               GSList *rdates,
                               GSList *exrules,
                               GSList *exdates,
@@ -1844,7 +1833,7 @@ generate_instances_for_chunk (ECalComponent *comp,
                               gint duration_days,
                               gint duration_seconds,
                               gboolean convert_end_date,
-                              ECalRecurInstanceFn cb,
+                              ECalRecurInstanceCb cb,
                               gpointer cb_data)
 {
        GArray *occs, *ex_occs, *tmp_occs, *rdate_periods;
@@ -1888,7 +1877,7 @@ generate_instances_for_chunk (ECalComponent *comp,
 
        /* Expand each of the recurrence rules. */
        for (elem = rrules; elem; elem = elem->next) {
-               icalproperty *prop;
+               ICalProperty *prop;
                ECalRecurrence *r;
 
                prop = elem->data;
@@ -1917,13 +1906,20 @@ generate_instances_for_chunk (ECalComponent *comp,
         * period in the rdate_periods array. Otherwise we can just treat them
         * as normal occurrences. */
        for (elem = rdates; elem; elem = elem->next) {
-               ECalComponentPeriod *p;
+               ECalComponentPeriod *period = elem->data;
                CalObjRecurrenceDate rdate;
-               struct icaltimetype tt;
+               ICalTimetype *gtt;
+               struct icaltimetype tt, *pstart;
+
+               gtt = e_cal_component_period_get_start (period);
+               if (!gtt)
+                       continue;
 
-               p = elem->data;
+               pstart = i_cal_object_get_native (I_CAL_OBJECT (gtt));
+               if (!pstart)
+                       continue;
 
-               tt = icaltime_convert_to_zone (p->start, zone);
+               tt = icaltime_convert_to_zone (*pstart, zone);
                cotime.year = tt.year;
                cotime.month = tt.month - 1;
                cotime.day = tt.day;
@@ -1943,12 +1939,13 @@ generate_instances_for_chunk (ECalComponent *comp,
                 * to store it so we can get it later. (libical seems to set
                 * second to -1 to denote an unset time. See icalvalue.c)
                 * FIXME. */
-               if (p->type != E_CAL_COMPONENT_PERIOD_DATETIME
-                   || p->u.end.second != -1) {
+               if (e_cal_component_period_get_kind (period) != E_CAL_COMPONENT_PERIOD_DATETIME ||
+                   !e_cal_component_period_get_end (period) ||
+                   i_cal_timetype_get_second (e_cal_component_period_get_end (period)) != -1) {
                        cotime.flags = TRUE;
 
                        rdate.start = cotime;
-                       rdate.period = p;
+                       rdate.period = period;
                        g_array_append_val (rdate_periods, rdate);
                }
 
@@ -1957,7 +1954,7 @@ generate_instances_for_chunk (ECalComponent *comp,
 
        /* Expand each of the exception rules. */
        for (elem = exrules; elem; elem = elem->next) {
-               icalproperty *prop;
+               ICalProperty *prop;
                ECalRecurrence *r;
 
                prop = elem->data;
@@ -1979,10 +1976,18 @@ generate_instances_for_chunk (ECalComponent *comp,
        /* Add on specific exception dates. */
        for (elem = exdates; elem; elem = elem->next) {
                ECalComponentDateTime *cdt;
-               struct icaltimetype tt;
+               struct icaltimetype tt, *value;
 
                cdt = elem->data;
-               tt = icaltime_convert_to_zone (*cdt->value, zone);
+
+               if (!e_cal_component_datetime_get_value (cdt))
+                       continue;
+
+               value = i_cal_object_get_native (I_CAL_OBJECT (e_cal_component_datetime_get_value (cdt)));
+               if (!value)
+                       continue;
+
+               tt = icaltime_convert_to_zone (*value, zone);
 
                cotime.year = tt.year;
                cotime.month = tt.month - 1;
@@ -1991,7 +1996,7 @@ generate_instances_for_chunk (ECalComponent *comp,
                /* If the EXDATE has a DATE value, set the time to the start
                 * of the day and set flags to TRUE so we know to skip all
                 * occurrences on that date. */
-               if (cdt->value->is_date) {
+               if (value->is_date) {
                        cotime.hour = 0;
                        cotime.minute = 0;
                        cotime.second = 0;
@@ -2098,7 +2103,7 @@ generate_instances_for_chunk (ECalComponent *comp,
                        continue;
                }
 
-               cb_status = (*cb) (comp, start_time, end_time, cb_data);
+               cb_status = call_instance_callback (cb, comp, start_time, end_time, cb_data);
                if (!cb_status)
                        break;
        }
@@ -2122,7 +2127,7 @@ cal_object_get_rdate_end (CalObjTime *occ,
                           icaltimezone *zone)
 {
        CalObjRecurrenceDate *rdate = NULL;
-       ECalComponentPeriod *p;
+       ECalComponentPeriod *period;
        gint lower, upper, middle, cmp = 0;
 
        lower = 0;
@@ -2152,25 +2157,36 @@ cal_object_get_rdate_end (CalObjTime *occ,
                return FALSE;
        }
 
-       p = rdate->period;
-       if (p->type == E_CAL_COMPONENT_PERIOD_DATETIME) {
-               struct icaltimetype tt =
-                       icaltime_convert_to_zone (p->u.end, zone);
-               occ->year = tt.year;
-               occ->month = tt.month - 1;
-               occ->day = tt.day;
-               occ->hour = tt.hour;
-               occ->minute = tt.minute;
-               occ->second = tt.second;
-               occ->flags = FALSE;
+       period = rdate->period;
+       if (e_cal_component_period_get_kind (period) == E_CAL_COMPONENT_PERIOD_DATETIME) {
+               ICalTimetype *end;
+               struct icaltimetype *endtt, tt;
+
+               end = e_cal_component_period_get_end (period);
+               endtt = end ? i_cal_object_get_native (I_CAL_OBJECT (end)) : NULL;
+               g_warn_if_fail (endtt != NULL);
+               if (endtt) {
+                       tt = icaltime_convert_to_zone (*endtt, zone);
+                       occ->year = tt.year;
+                       occ->month = tt.month - 1;
+                       occ->day = tt.day;
+                       occ->hour = tt.hour;
+                       occ->minute = tt.minute;
+                       occ->second = tt.second;
+                       occ->flags = FALSE;
+               }
        } else {
+               ICalDurationType *duration;
+
+               duration = e_cal_component_period_get_duration (period);
+
                cal_obj_time_add_days (
                        occ,
-                       p->u.duration.weeks * 7 +
-                       p->u.duration.days);
-               cal_obj_time_add_hours (occ, p->u.duration.hours);
-               cal_obj_time_add_minutes (occ, p->u.duration.minutes);
-               cal_obj_time_add_seconds (occ, p->u.duration.seconds);
+                       i_cal_duration_type_get_weeks (duration) * 7 +
+                       i_cal_duration_type_get_days (duration));
+               cal_obj_time_add_hours (occ, i_cal_duration_type_get_hours (duration));
+               cal_obj_time_add_minutes (occ, i_cal_duration_type_get_minutes (duration));
+               cal_obj_time_add_seconds (occ, i_cal_duration_type_get_seconds (duration));
        }
 
        return TRUE;
@@ -4523,16 +4539,17 @@ cal_obj_time_to_string (CalObjTime *cotime)
  * e_cal_recur_ensure_end_dates:
  * @comp: an #ECalComponent
  * @refresh: %TRUE to recalculate all end dates
- * @tz_cb: (closure tz_cb_data) (scope call): function to call to resolve
- * timezones
- * @tz_cb_data: (closure): data to pass to @tz_cb
+ * @tz_cb: (scope call): function to call to resolve timezones
+ * @tz_cb_data: (closure tz_cb_data): user data to pass to @tz_cb
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
  *
  * This recalculates the end dates for recurrence & exception rules which use
  * the COUNT property. If @refresh is %TRUE it will recalculate all enddates
  * for rules which use COUNT. If @refresh is %FALSE, it will only calculate
  * the enddate if it hasn't already been set. It returns %TRUE if the component
  * was changed, i.e. if the component should be saved at some point.
- * We store the enddate in the "X-EVOLUTION-ENDDATE" parameter of the RRULE
+ * We store the enddate in the %E_CAL_EVOLUTION_ENDDATE_PARAMETER parameter of the RRULE
  * or EXRULE.
  *
  * Returns: %TRUE if the component was changed, %FALSE otherwise
@@ -4541,29 +4558,32 @@ cal_obj_time_to_string (CalObjTime *cotime)
  **/
 gboolean
 e_cal_recur_ensure_end_dates (ECalComponent *comp,
-                              gboolean refresh,
-                              ECalRecurResolveTimezoneFn tz_cb,
-                              gpointer tz_cb_data)
+                             gboolean refresh,
+                             ECalRecurResolveTimezoneCb tz_cb,
+                             gpointer tz_cb_data,
+                             GCancellable *cancellable,
+                             GError **error)
 {
        GSList *rrules, *exrules, *elem;
        gboolean changed = FALSE;
 
        /* Do the RRULEs. */
-       e_cal_component_get_rrule_property_list (comp, &rrules);
-       for (elem = rrules; elem; elem = elem->next) {
+       rrules = e_cal_component_get_rrule_properties (comp);
+       for (elem = rrules; elem && !g_cancellable_is_cancelled (cancellable); elem = elem->next) {
                changed |= e_cal_recur_ensure_rule_end_date (comp, elem->data,
-                                                          FALSE, refresh,
-                                                          tz_cb, tz_cb_data);
+                       FALSE, refresh, tz_cb, tz_cb_data, cancellable, error);
        }
 
        /* Do the EXRULEs. */
-       e_cal_component_get_exrule_property_list (comp, &exrules);
-       for (elem = exrules; elem; elem = elem->next) {
+       exrules = e_cal_component_get_exrule_properties (comp);
+       for (elem = exrules; elem && !g_cancellable_is_cancelled (cancellable); elem = elem->next) {
                changed |= e_cal_recur_ensure_rule_end_date (comp, elem->data,
-                                                          TRUE, refresh,
-                                                          tz_cb, tz_cb_data);
+                       TRUE, refresh, tz_cb, tz_cb_data, cancellable, error);
        }
 
+       g_slist_free_full (rrules, g_object_unref);
+       g_slist_free_full (exrules, g_object_unref);
+
        return changed;
 }
 
@@ -4576,32 +4596,41 @@ struct _ECalRecurEnsureEndDateData {
 
 static gboolean
 e_cal_recur_ensure_rule_end_date (ECalComponent *comp,
-                                  icalproperty *prop,
+                                  ICalProperty *prop,
                                   gboolean exception,
                                   gboolean refresh,
-                                  ECalRecurResolveTimezoneFn tz_cb,
-                                  gpointer tz_cb_data)
+                                  ECalRecurResolveTimezoneCb tz_cb,
+                                  gpointer tz_cb_data,
+                                 GCancellable *cancellable,
+                                 GError **error)
 {
-       struct icalrecurrencetype rule;
+       ICalRecurrenceType *rule;
        ECalRecurEnsureEndDateData cb_data;
 
+       if (!prop)
+               return FALSE;
+
        if (exception)
-               rule = icalproperty_get_exrule (prop);
+               rule = i_cal_property_get_exrule (prop);
        else
-               rule = icalproperty_get_rrule (prop);
+               rule = i_cal_property_get_rrule (prop);
 
        /* If the rule doesn't use COUNT just return. */
-       if (rule.count == 0)
+       if (!rule || !i_cal_recurrence_type_get_count (rule)) {
+               g_clear_object (&rule);
                return FALSE;
+       }
 
        /* If refresh is FALSE, we check if the enddate is already set, and
         * if it is we just return. */
        if (!refresh) {
-               if (e_cal_recur_get_rule_end_date (prop, NULL) != -1)
+               if (e_cal_recur_get_rule_end_date (prop, NULL) != -1) {
+                       g_clear_object (&rule);
                        return FALSE;
+               }
        } else {
                /* Remove the property parameter, thus it'll not influence the regeneration */
-               icalproperty_remove_parameter_by_name (prop, EVOLUTION_END_DATE_PARAMETER);
+               i_cal_property_remove_parameter_by_name (prop, E_CAL_EVOLUTION_ENDDATE_PARAMETER);
        }
 
        /* Calculate the end date. Note that we initialize end_date to 0, so
@@ -4609,36 +4638,37 @@ e_cal_recur_ensure_rule_end_date (ECalComponent *comp,
         * Also note that we use the UTC timezone as the default timezone.
         * In get_end_date () if the DTSTART is a DATE or floating time, we will
         * convert the ENDDATE to the current timezone. */
-       cb_data.count = rule.count;
+       cb_data.count = i_cal_recurrence_type_get_count (rule);
        cb_data.instances = 0;
        cb_data.end_date = 0;
        e_cal_recur_generate_instances_of_rule (
-               comp, prop, -1, -1,
+               comp, i_cal_object_get_native (I_CAL_OBJECT (prop)), -1, -1,
                e_cal_recur_ensure_rule_end_date_cb,
                &cb_data, tz_cb, tz_cb_data,
                icaltimezone_get_utc_timezone ());
 
-       /* Store the end date in the "X-EVOLUTION-ENDDATE" parameter of the
-        * rule. */
+       /* Store the end date in the E_CAL_EVOLUTION_ENDDATE_PARAMETER parameter of the rule. */
        e_cal_recur_set_rule_end_date (prop, cb_data.end_date);
 
+       g_clear_object (&rule);
+
        return TRUE;
 }
 
 static gboolean
-e_cal_recur_ensure_rule_end_date_cb (ECalComponent *comp,
-                                     time_t instance_start,
-                                     time_t instance_end,
-                                     gpointer data)
+e_cal_recur_ensure_rule_end_date_cb (ICalComponent *comp,
+                                    ICalTimetype *instance_start,
+                                    ICalTimetype *instance_end,
+                                    gpointer user_data,
+                                    GCancellable *cancellable,
+                                    GError **error)
 {
-       ECalRecurEnsureEndDateData *cb_data;
-
-       cb_data = (ECalRecurEnsureEndDateData *) data;
+       ECalRecurEnsureEndDateData *cb_data = user_data;
 
        cb_data->instances++;
 
        if (cb_data->instances == cb_data->count) {
-               cb_data->end_date = instance_start;
+               cb_data->end_date = i_cal_time_as_timet (instance_start);
                return FALSE;
        }
 
@@ -4650,77 +4680,79 @@ e_cal_recur_ensure_rule_end_date_cb (ECalComponent *comp,
  * value, since the RRULE end date will change depending on the timezone that
  * it is evaluated in. */
 static time_t
-e_cal_recur_get_rule_end_date (icalproperty *prop,
-                               icaltimezone *default_timezone)
+e_cal_recur_get_rule_end_date (ICalProperty *prop,
+                               ICalTimezone *default_timezone)
 {
-       icalparameter *param;
+       ICalParameter *param;
        const gchar *xname, *xvalue;
-       icalvalue *value;
-       struct icaltimetype icaltime;
-       icaltimezone *zone;
-
-       param = icalproperty_get_first_parameter (prop, ICAL_X_PARAMETER);
-       while (param) {
-               xname = icalparameter_get_xname (param);
-               if (xname && !strcmp (xname, EVOLUTION_END_DATE_PARAMETER)) {
-                       xvalue = icalparameter_get_x (param);
-                       value = icalvalue_new_from_string (
-                               ICAL_DATETIME_VALUE,
-                               xvalue);
+
+       for (param = i_cal_property_get_first_parameter (prop, I_CAL_X_PARAMETER);
+            param;
+            g_object_unref (param), param = i_cal_property_get_next_parameter (prop, I_CAL_X_PARAMETER)) {
+               xname = i_cal_parameter_get_xname (param);
+               if (xname && !strcmp (xname, E_CAL_EVOLUTION_ENDDATE_PARAMETER)) {
+                       icalvalue *value;
+
+                       xvalue = i_cal_parameter_get_x (param);
+                       value = icalvalue_new_from_string (ICAL_DATETIME_VALUE, xvalue);
                        if (value) {
+                               struct icaltimetype icaltime;
+                               icaltimezone *zone;
+
                                icaltime = icalvalue_get_datetime (value);
                                icalvalue_free (value);
 
-                               zone = default_timezone ? default_timezone :
-                                       icaltimezone_get_utc_timezone ();
-                               return icaltime_as_timet_with_zone (
-                                       icaltime,
-                                       zone);
+                               zone = default_timezone ? i_cal_object_get_native (I_CAL_OBJECT 
(default_timezone)) : NULL;
+                               if (!zone)
+                                       zone = icaltimezone_get_utc_timezone ();
+
+                               g_object_unref (param);
+
+                               return icaltime_as_timet_with_zone (icaltime, zone);
                        }
                }
-
-               param = icalproperty_get_next_parameter (
-                       prop,
-                       ICAL_X_PARAMETER);
        }
 
        return -1;
 }
 
 static void
-e_cal_recur_set_rule_end_date (icalproperty *prop,
+e_cal_recur_set_rule_end_date (ICalProperty *prop,
                                time_t end_date)
 {
-       icalparameter *param;
-       icalvalue *value;
-       icaltimezone *utc_zone;
-       struct icaltimetype icaltime;
+       ICalParameter *param;
+       ICalValue *value;
+       ICalTimezone *utc_zone;
+       ICalTimetype *icaltime;
        const gchar *xname;
        gchar *end_date_string;
 
        /* We save the value as a UTC DATE-TIME. */
-       utc_zone = icaltimezone_get_utc_timezone ();
-       icaltime = icaltime_from_timet_with_zone (end_date, FALSE, utc_zone);
-       value = icalvalue_new_datetime (icaltime);
-       end_date_string = icalvalue_as_ical_string_r (value);
-       icalvalue_free (value);
+       utc_zone = i_cal_timezone_get_utc_timezone ();
+       icaltime = i_cal_time_from_timet_with_zone (end_date, FALSE, utc_zone);
+       value = i_cal_value_new_datetime (icaltime);
+       end_date_string = i_cal_value_as_ical_string_r (value);
+       g_object_unref (value);
+       g_object_unref (icaltime);
 
        /* If we already have an X-EVOLUTION-ENDDATE parameter, set the value
         * to the new date-time. */
-       param = icalproperty_get_first_parameter (prop, ICAL_X_PARAMETER);
-       while (param) {
-               xname = icalparameter_get_xname (param);
-               if (xname && !strcmp (xname, EVOLUTION_END_DATE_PARAMETER)) {
-                       icalparameter_set_x (param, end_date_string);
+       for (param = i_cal_property_get_first_parameter (prop, I_CAL_X_PARAMETER);
+            param;
+            g_object_unref (param), param = i_cal_property_get_next_parameter (prop, I_CAL_X_PARAMETER)) {
+               xname = i_cal_parameter_get_xname (param);
+               if (xname && !strcmp (xname, E_CAL_EVOLUTION_ENDDATE_PARAMETER)) {
+                       i_cal_parameter_set_x (param, end_date_string);
+                       g_free (end_date_string);
+                       g_object_unref (param);
                        return;
                }
-               param = icalproperty_get_next_parameter (prop, ICAL_X_PARAMETER);
        }
 
        /* Create a new X-EVOLUTION-ENDDATE and add it to the property. */
-       param = icalparameter_new_x (end_date_string);
-       icalparameter_set_xname (param, EVOLUTION_END_DATE_PARAMETER);
-       icalproperty_add_parameter (prop, param);
+       param = i_cal_parameter_new_x (end_date_string);
+       i_cal_parameter_set_xname (param, E_CAL_EVOLUTION_ENDDATE_PARAMETER);
+       i_cal_property_take_parameter (prop, param);
 
        g_free (end_date_string);
 }
@@ -4792,13 +4824,13 @@ cal_comp_util_recurrence_count_by_xxx (gshort *field,
 
 /**
  * e_cal_recur_describe_recurrence:
- * @icalcomp: an icalcomponent
+ * @icalcomp: an #ICalComponent
  * @week_start_day: a day when the week starts
  * @flags: bit-or of #ECalRecurDescribeRecurrenceFlags
  *
  * Describes some simple types of recurrences in a human-readable and localized way.
- * The @flags influence the output output format and what to do when the @icalcomp
- * contain more complicated recurrence, some which the function cannot describe.
+ * The @flags influence the output format and what to do when the @icalcomp
+ * contains more complicated recurrence, some which the function cannot describe.
  *
  * The @week_start_day is used for weekly recurrences, to start the list of selected
  * days at that day.
@@ -4813,11 +4845,12 @@ cal_comp_util_recurrence_count_by_xxx (gshort *field,
  * Since: 3.30
  **/
 gchar *
-e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
+e_cal_recur_describe_recurrence (ICalComponent *icalcomp,
                                 GDateWeekday week_start_day,
                                 guint32 flags)
 {
        gchar *prefix = NULL, *mid = NULL, *suffix = NULL, *result = NULL;
+       icalcomponent *comp;
        icalproperty *prop;
        struct icalrecurrencetype rrule;
        gint n_by_second, n_by_minute, n_by_hour;
@@ -4827,14 +4860,17 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
 
        g_return_val_if_fail (icalcomp != NULL, NULL);
 
+       comp = i_cal_object_get_native (I_CAL_OBJECT (icalcomp));
+       g_return_val_if_fail (comp != NULL, NULL);
+
        prefixed = (flags & E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_PREFIXED) != 0;
        fallback = (flags & E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_FALLBACK) != 0;
 
-       prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
+       prop = icalcomponent_get_first_property (comp, ICAL_RRULE_PROPERTY);
        if (!prop)
                return NULL;
 
-       switch (icalcomponent_isa (icalcomp)) {
+       switch (icalcomponent_isa (comp)) {
        case ICAL_VEVENT_COMPONENT:
        case ICAL_VTODO_COMPONENT:
        case ICAL_VJOURNAL_COMPONENT:
@@ -4843,9 +4879,9 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                return NULL;
        }
 
-       if (icalcomponent_count_properties (icalcomp, ICAL_RRULE_PROPERTY) != 1 ||
-           icalcomponent_count_properties (icalcomp, ICAL_RDATE_PROPERTY) != 0 ||
-           icalcomponent_count_properties (icalcomp, ICAL_EXRULE_PROPERTY) != 0)
+       if (icalcomponent_count_properties (comp, ICAL_RRULE_PROPERTY) != 1 ||
+           icalcomponent_count_properties (comp, ICAL_RDATE_PROPERTY) != 0 ||
+           icalcomponent_count_properties (comp, ICAL_EXRULE_PROPERTY) != 0)
                goto custom;
 
        rrule = icalproperty_get_rrule (prop);
@@ -4988,7 +5024,7 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                if (ii == 0) {
                        struct icaltimetype dtstart;
 
-                       dtstart = icalcomponent_get_dtstart (icalcomp);
+                       dtstart = icalcomponent_get_dtstart (comp);
 
                        ii = icaltime_day_of_week (dtstart);
                        if (ii >= 1)
@@ -5134,7 +5170,7 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                        if (nth == -1) {
                                struct icaltimetype dtstart;
 
-                               dtstart = icalcomponent_get_dtstart (icalcomp);
+                               dtstart = icalcomponent_get_dtstart (comp);
 
                                month_index = dtstart.day;
                                month_num = MONTH_NUM_LAST;
@@ -5614,6 +5650,7 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                                        rrule.count), rrule.count);
                } else if (rrule.until.year) {
                        struct tm tm;
+                       ICalTimetype *tt;
                        gchar dt_str[256];
 
                        dt_str[0] = 0;
@@ -5622,7 +5659,7 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                                icaltimezone *from_zone, *to_zone;
                                struct icaltimetype dtstart;
 
-                               dtstart = icalcomponent_get_dtstart (icalcomp);
+                               dtstart = icalcomponent_get_dtstart (comp);
 
                                from_zone = icaltimezone_get_utc_timezone ();
                                to_zone = (icaltimezone *) dtstart.zone;
@@ -5636,7 +5673,10 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                                rrule.until.is_date = TRUE;
                        }
 
-                       tm = icaltimetype_to_tm (&rrule.until);
+                       tt = i_cal_object_construct (I_CAL_TYPE_TIMETYPE, &rrule.until, NULL, FALSE, NULL);
+                       tm = icaltimetype_to_tm (tt);
+                       g_clear_object (&tt);
+
                        e_time_format_date_and_time (&tm, FALSE, FALSE, FALSE, dt_str, 255);
 
                        if (*dt_str) {
@@ -5673,7 +5713,7 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                gint n_exdates;
                gchar *tmp;
 
-               n_exdates = icalcomponent_count_properties (icalcomp, ICAL_EXDATE_PROPERTY);
+               n_exdates = icalcomponent_count_properties (comp, ICAL_EXDATE_PROPERTY);
                if (n_exdates > 0) {
                        gchar *exdates_str;
 
@@ -5698,16 +5738,16 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                if (prefixed) {
                        const gchar *comp_prefix;
 
-                       if (icalcomponent_isa (icalcomp) == ICAL_VEVENT_COMPONENT) {
-                               if (icalcomponent_count_properties (icalcomp, ICAL_ORGANIZER_PROPERTY) > 0 &&
-                                   icalcomponent_count_properties (icalcomp, ICAL_ATTENDEE_PROPERTY) > 0) {
+                       if (icalcomponent_isa (comp) == ICAL_VEVENT_COMPONENT) {
+                               if (icalcomponent_count_properties (comp, ICAL_ORGANIZER_PROPERTY) > 0 &&
+                                   icalcomponent_count_properties (comp, ICAL_ATTENDEE_PROPERTY) > 0) {
                                        comp_prefix = C_("recur-description", "The meeting recurs");
                                } else {
                                        comp_prefix = C_("recur-description", "The appointment recurs");
                                }
-                       } else if (icalcomponent_isa (icalcomp) == ICAL_VTODO_COMPONENT) {
+                       } else if (icalcomponent_isa (comp) == ICAL_VTODO_COMPONENT) {
                                comp_prefix = C_("recur-description", "The task recurs");
-                       } else /* if (icalcomponent_isa (icalcomp) == ICAL_VJOURNAL_COMPONENT) */ {
+                       } else /* if (icalcomponent_isa (comp) == ICAL_VJOURNAL_COMPONENT) */ {
                                comp_prefix = C_("recur-description", "The memo recurs");
                        }
 
@@ -5721,16 +5761,16 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                        result = tmp;
                }
        } else if (fallback) {
-               if (icalcomponent_isa (icalcomp) == ICAL_VEVENT_COMPONENT) {
-                       if (icalcomponent_count_properties (icalcomp, ICAL_ORGANIZER_PROPERTY) > 0 &&
-                           icalcomponent_count_properties (icalcomp, ICAL_ATTENDEE_PROPERTY) > 0) {
+               if (icalcomponent_isa (comp) == ICAL_VEVENT_COMPONENT) {
+                       if (icalcomponent_count_properties (comp, ICAL_ORGANIZER_PROPERTY) > 0 &&
+                           icalcomponent_count_properties (comp, ICAL_ATTENDEE_PROPERTY) > 0) {
                                result = g_strdup (C_("recur-description", "The meeting recurs"));
                        } else {
                                result = g_strdup (C_("recur-description", "The appointment recurs"));
                        }
-               } else if (icalcomponent_isa (icalcomp) == ICAL_VTODO_COMPONENT) {
+               } else if (icalcomponent_isa (comp) == ICAL_VTODO_COMPONENT) {
                        result = g_strdup (C_("recur-description", "The task recurs"));
-               } else if (icalcomponent_isa (icalcomp) == ICAL_VJOURNAL_COMPONENT) {
+               } else if (icalcomponent_isa (comp) == ICAL_VJOURNAL_COMPONENT) {
                        result = g_strdup (C_("recur-description", "The memo recurs"));
                }
        }
diff --git a/src/calendar/libecal/e-cal-recur.h b/src/calendar/libecal/e-cal-recur.h
index 1cbeef787..286aeb0c8 100644
--- a/src/calendar/libecal/e-cal-recur.h
+++ b/src/calendar/libecal/e-cal-recur.h
@@ -30,86 +30,92 @@
 #include <gio/gio.h>
 
 #include <libical-glib/libical-glib.h>
+
 #include <libecal/e-cal-component.h>
+#include <libecal/e-cal-enums.h>
 
 G_BEGIN_DECLS
 
-typedef icaltimezone * (* ECalRecurResolveTimezoneCb)  (const gchar *tzid,
+/**
+ * E_CAL_EVOLUTION_ENDDATE_PARAMETER:
+ *
+ * The X parameter name being used to store the enddate in RRULE and EXRULE properties.
+ *
+ * Since: 3.36
+ **/
+#define E_CAL_EVOLUTION_ENDDATE_PARAMETER      "X-EVOLUTION-ENDDATE"
+
+/**
+ * ECalRecurResolveTimezoneCb:
+ * @tzid: timezone ID to resolve
+ * @user_data: user data used for this callback
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Resolve timezone by its ID provided as @tzid. Free the returned object,
+ * if not %NULL, with g_object_unref(), when no longer needed.
+ *
+ * Returns: (transfer full) (nullable): a new #ICalTimezone object for @tzid,
+ *    or %NULL, on error or if not found.
+ *
+ * Since: 3.36
+ **/
+typedef ICalTimezone * (* ECalRecurResolveTimezoneCb)  (const gchar *tzid,
                                                         gpointer user_data,
                                                         GCancellable *cancellable,
                                                         GError **error);
 
-typedef gboolean (* ECalRecurInstanceCb)               (icalcomponent *comp,
-                                                        struct icaltimetype instance_start,
-                                                        struct icaltimetype instance_end,
+/**
+ * ECalRecurInstanceCb:
+ * @comp: an #ICalComponent
+ * @instance_start: start time of an instance
+ * @instance_end: end time of an instance
+ * @user_data: user data used for this callback in e_cal_recur_generate_instances_sync()
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Callback used by e_cal_recur_generate_instances_sync(), called
+ * for each instance of a (recurring) component within given time range.
+ *
+ * Returns: %TRUE, to continue recurrence generation, %FALSE to stop
+ *
+ * Since: 3.36
+ **/
+typedef gboolean (* ECalRecurInstanceCb)               (ICalComponent *comp,
+                                                        ICalTimetype *instance_start,
+                                                        ICalTimetype *instance_end,
                                                         gpointer user_data,
                                                         GCancellable *cancellable,
                                                         GError **error);
 
-gboolean       e_cal_recur_generate_instances_sync     (icalcomponent *comp,
-                                                        struct icaltimetype interval_start,
-                                                        struct icaltimetype interval_end,
+gboolean       e_cal_recur_generate_instances_sync     (ICalComponent *icalcomp,
+                                                        ICalTimetype *interval_start,
+                                                        ICalTimetype *interval_end,
                                                         ECalRecurInstanceCb callback,
                                                         gpointer callback_user_data,
                                                         ECalRecurResolveTimezoneCb get_tz_callback,
                                                         gpointer get_tz_callback_user_data,
-                                                        icaltimezone *default_timezone,
+                                                        ICalTimezone *default_timezone,
                                                         GCancellable *cancellable,
                                                         GError **error);
 
-typedef gboolean (* ECalRecurInstanceFn) (ECalComponent *comp,
-                                        time_t        instance_start,
-                                        time_t        instance_end,
-                                        gpointer      user_data);
-
-typedef icaltimezone * (* ECalRecurResolveTimezoneFn)  (const gchar   *tzid,
-                                                        gpointer      data);
-
-void   e_cal_recur_generate_instances  (ECalComponent          *comp,
-                                        time_t                  start,
-                                        time_t                  end,
-                                        ECalRecurInstanceFn     cb,
-                                        gpointer                cb_data,
-                                        ECalRecurResolveTimezoneFn tz_cb,
-                                        gpointer                  tz_cb_data,
-                                        icaltimezone           *default_timezone);
-
-time_t
-e_cal_recur_obtain_enddate (struct icalrecurrencetype *ir,
-                            icalproperty *prop,
-                            icaltimezone *zone,
-                            gboolean convert_end_date);
-
-gboolean
-e_cal_recur_ensure_end_dates (ECalComponent    *comp,
-                           gboolean             refresh,
-                           ECalRecurResolveTimezoneFn  tz_cb,
-                           gpointer             tz_cb_data);
-
-const gchar *          e_cal_recur_get_localized_nth           (gint nth);
+time_t         e_cal_recur_obtain_enddate              (ICalRecurrenceType *ir,
+                                                        ICalProperty *prop,
+                                                        ICalTimezone *zone,
+                                                        gboolean convert_end_date);
 
-/**
- * ECalRecurDescribeRecurrenceFlags:
- * @E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_NONE: no extra flags, either returns %NULL or the recurrence 
description,
- *    something like "Every 2 weeks..."
- * @E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_PREFIXED: either returns %NULL or the recurrence description 
prefixed
- *    with text like "The meeting recurs", forming something like "The meeting recurs every 2 weeks..."
- * @E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_FALLBACK: returns %NULL only if the component doesn't recur,
- *    otherwise returns either the recurrence description or at least text like "The meeting recurs"
- *
- * Influences behaviour of e_cal_recur_describe_recurrence().
- *
- * Since: 3.30
- **/
-typedef enum {
-       E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_NONE       = 0,
-       E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_PREFIXED   = (1 << 0),
-       E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_FALLBACK   = (1 << 1)
-} ECalRecurDescribeRecurrenceFlags;
-
-gchar *                        e_cal_recur_describe_recurrence         (icalcomponent *icalcomp,
-                                                                GDateWeekday week_start_day,
-                                                                guint32 flags);
+gboolean       e_cal_recur_ensure_end_dates            (ECalComponent *comp,
+                                                        gboolean refresh,
+                                                        ECalRecurResolveTimezoneCb tz_cb,
+                                                        gpointer tz_cb_data,
+                                                        GCancellable *cancellable,
+                                                        GError **error);
+
+const gchar *  e_cal_recur_get_localized_nth           (gint nth);
+
+gchar *                e_cal_recur_describe_recurrence         (ICalComponent *icalcomp,
+                                                        GDateWeekday week_start_day,
+                                                        guint32 flags); /* bit-or of 
ECalRecurDescribeRecurrenceFlags */
 
 G_END_DECLS
 
diff --git a/src/calendar/libecal/e-cal-system-timezone.c b/src/calendar/libecal/e-cal-system-timezone.c
index 25bbb6713..09da13973 100644
--- a/src/calendar/libecal/e-cal-system-timezone.c
+++ b/src/calendar/libecal/e-cal-system-timezone.c
@@ -543,27 +543,29 @@ static gchar *
 system_timezone_find (void)
 {
        GHashTable *ical_zones;
-       icalarray *builtin_timezones;
-       gint ii;
+       ICalArray *builtin_timezones;
+       gint ii, nelems;
        gchar *tz, *config_tz = NULL;
 
        /* return only timezones known to libical */
        ical_zones = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
        g_hash_table_add (ical_zones, g_strdup ("UTC"));
 
-       builtin_timezones = icaltimezone_get_builtin_timezones ();
-       for (ii = 0; ii < builtin_timezones->num_elements; ii++) {
-               icaltimezone *zone;
+       builtin_timezones = i_cal_timezone_get_builtin_timezones ();
+       nelems = i_cal_array_size (builtin_timezones);
+
+       for (ii = 0; ii < nelems; ii++) {
+               ICalTimezone *zone;
                const gchar *location;
 
-               zone = icalarray_element_at (builtin_timezones, ii);
+               zone = i_cal_timezone_array_element_at (builtin_timezones, ii);
                if (!zone)
                        continue;
 
-               location = icaltimezone_get_location (zone);
+               location = i_cal_timezone_get_location (zone);
                if (location)
-                       g_hash_table_add (
-                               ical_zones, g_strdup (location));
+                       g_hash_table_add (ical_zones, g_strdup (location));
+               g_object_unref (zone);
        }
 
        /* softlink is the best option, it points to the correct file */
diff --git a/src/calendar/libecal/e-cal-time-util.c b/src/calendar/libecal/e-cal-time-util.c
index 22649c588..7aae2d1a5 100644
--- a/src/calendar/libecal/e-cal-time-util.c
+++ b/src/calendar/libecal/e-cal-time-util.c
@@ -23,7 +23,6 @@
 #include <ctype.h>
 #include "e-cal-time-util.h"
 
-
 #ifdef G_OS_WIN32
 #ifdef gmtime_r
 #undef gmtime_r
@@ -50,7 +49,7 @@ static const gint days_in_month[12] = {
  *
  * NOTE: these use the Unix timezone functions like mktime() and localtime()
  * and so should not be used in Evolution. New Evolution code should use
- * icaltimetype values rather than time_t values wherever possible.
+ * ICalTimetype values rather than time_t values wherever possible.
  **************************************************************************/
 
 /**
@@ -142,7 +141,7 @@ time_day_end (time_t t)
  * time_t manipulation functions, using timezones in libical.
  *
  * NOTE: these are only here to make the transition to the timezone
- * functions easier. New code should use icaltimetype values rather than
+ * functions easier. New code should use ICalTimetype values rather than
  * time_t values wherever possible.
  **************************************************************************/
 
@@ -155,26 +154,31 @@ time_day_end (time_t t)
  * Adds or subtracts a number of days to/from the given time_t value, using
  * the given timezone.
  * NOTE: this function is only here to make the transition to the timezone
- * functions easier. New code should use icaltimetype values and
- * icaltime_adjust() to add or subtract days, hours, minutes & seconds.
+ * functions easier. New code should use ICalTimetype values and
+ * i_cal_time_adjust() to add or subtract days, hours, minutes & seconds.
  *
  * Returns: a time_t value containing @time plus the days added.
  */
 time_t
 time_add_day_with_zone (time_t time,
-                        gint days,
-                        icaltimezone *zone)
+                       gint days,
+                       const ICalTimezone *zone)
 {
-       struct icaltimetype tt;
+       ICalTimetype *tt;
+       time_t res;
 
        /* Convert to an icaltimetype. */
-       tt = icaltime_from_timet_with_zone (time, FALSE, zone);
+       tt = i_cal_time_from_timet_with_zone (time, FALSE, (ICalTimezone *) zone);
 
        /* Add/subtract the number of days. */
-       icaltime_adjust (&tt, days, 0, 0, 0);
+       i_cal_time_adjust (tt, days, 0, 0, 0);
 
        /* Convert back to a time_t. */
-       return icaltime_as_timet_with_zone (tt, zone);
+       res = i_cal_time_as_timet_with_zone (tt, (ICalTimezone *) zone);
+
+       g_object_unref (tt);
+
+       return res;
 }
 
 /**
@@ -186,15 +190,15 @@ time_add_day_with_zone (time_t time,
  * Adds or subtracts a number of weeks to/from the given time_t value, using
  * the given timezone.
  * NOTE: this function is only here to make the transition to the timezone
- * functions easier. New code should use icaltimetype values and
- * icaltime_adjust() to add or subtract days, hours, minutes & seconds.
+ * functions easier. New code should use ICalTimetype values and
+ * i_cal_time_adjust() to add or subtract days, hours, minutes & seconds.
  *
  * Returns: a time_t value containing @time plus the weeks added.
  */
 time_t
 time_add_week_with_zone (time_t time,
-                         gint weeks,
-                         icaltimezone *zone)
+                        gint weeks,
+                        const ICalTimezone *zone)
 {
        return time_add_day_with_zone (time, weeks * 7, zone);
 }
@@ -213,42 +217,49 @@ time_add_week_with_zone (time_t time,
  * down to the last day in the month, e.g. 28th Feb (or 29th in a leap year.)
  *
  * NOTE: this function is only here to make the transition to the timezone
- * functions easier. New code should use icaltimetype values and
- * icaltime_adjust() to add or subtract days, hours, minutes & seconds.
+ * functions easier. New code should use ICalTimetype values and
+ * i_cal_time_adjust() to add or subtract days, hours, minutes & seconds.
  *
  * Returns: a time_t value containing @time plus the months added.
  */
 time_t
 time_add_month_with_zone (time_t time,
-                          gint months,
-                          icaltimezone *zone)
+                         gint months,
+                         const ICalTimezone *zone)
 {
-       struct icaltimetype tt;
+       ICalTimetype *tt, *normtt;
        gint day, days_in_month;
+       time_t res;
 
        /* Convert to an icaltimetype. */
-       tt = icaltime_from_timet_with_zone (time, FALSE, zone);
+       tt = i_cal_time_from_timet_with_zone (time, FALSE, (ICalTimezone *) zone);
 
        /* Add on the number of months. */
-       tt.month += months;
+       i_cal_timetype_set_month (tt, i_cal_timetype_get_month (tt) + months);
 
        /* Save the day, and set it to 1, so we don't overflow into the next
         * month. */
-       day = tt.day;
-       tt.day = 1;
+       day = i_cal_timetype_get_day (tt);
+       i_cal_timetype_set_day (tt, 1);
 
        /* Normalize it, fixing any month overflow. */
-       tt = icaltime_normalize (tt);
+       normtt = i_cal_time_normalize (tt);
+       g_object_unref (tt);
+       tt = normtt;
 
        /* If we go past the end of a month, set it to the last day. */
-       days_in_month = time_days_in_month (tt.year, tt.month - 1);
+       days_in_month = time_days_in_month (i_cal_timetype_get_year (tt), i_cal_timetype_get_month (tt) - 1);
        if (day > days_in_month)
                day = days_in_month;
 
-       tt.day = day;
+       i_cal_timetype_set_day (tt, day);
 
        /* Convert back to a time_t. */
-       return icaltime_as_timet_with_zone (tt, zone);
+       res = i_cal_time_as_timet_with_zone (tt, (ICalTimezone *) zone);
+
+       g_object_unref (tt);
+
+       return res;
 }
 
 /**
@@ -259,29 +270,34 @@ time_add_month_with_zone (time_t time,
  * Returns the start of the year containing the given time_t, using the given
  * timezone.
  * NOTE: this function is only here to make the transition to the timezone
- * functions easier. New code should use icaltimetype values and
- * icaltime_adjust() to add or subtract days, hours, minutes & seconds.
+ * functions easier. New code should use ICalTimetype values and
+ * i_cal_time_adjust() to add or subtract days, hours, minutes & seconds.
  *
  * Returns: the beginning of the year.
  */
 time_t
 time_year_begin_with_zone (time_t time,
-                           icaltimezone *zone)
+                          const ICalTimezone *zone)
 {
-       struct icaltimetype tt;
+       ICalTimetype *tt;
+       time_t res;
 
        /* Convert to an icaltimetype. */
-       tt = icaltime_from_timet_with_zone (time, FALSE, zone);
+       tt = i_cal_time_from_timet_with_zone (time, FALSE, (ICalTimezone *) zone);
 
        /* Set it to the start of the year. */
-       tt.month = 1;
-       tt.day = 1;
-       tt.hour = 0;
-       tt.minute = 0;
-       tt.second = 0;
+       i_cal_timetype_set_month (tt, 1);
+       i_cal_timetype_set_day (tt, 1);
+       i_cal_timetype_set_hour (tt, 0);
+       i_cal_timetype_set_minute (tt, 0);
+       i_cal_timetype_set_second (tt, 0);
 
        /* Convert back to a time_t. */
-       return icaltime_as_timet_with_zone (tt, zone);
+       res = i_cal_time_as_timet_with_zone (tt, (ICalTimezone *) zone);
+
+       g_object_unref (tt);
+
+       return res;
 }
 
 /**
@@ -292,28 +308,33 @@ time_year_begin_with_zone (time_t time,
  * Returns the start of the month containing the given time_t, using the given
  * timezone.
  * NOTE: this function is only here to make the transition to the timezone
- * functions easier. New code should use icaltimetype values and
- * icaltime_adjust() to add or subtract days, hours, minutes & seconds.
+ * functions easier. New code should use ICalTimetype values and
+ * i_cal_time_adjust() to add or subtract days, hours, minutes & seconds.
  *
  * Returns: the beginning of the month.
  */
 time_t
 time_month_begin_with_zone (time_t time,
-                            icaltimezone *zone)
+                           const ICalTimezone *zone)
 {
-       struct icaltimetype tt;
+       ICalTimetype *tt;
+       time_t res;
 
        /* Convert to an icaltimetype. */
-       tt = icaltime_from_timet_with_zone (time, FALSE, zone);
+       tt = i_cal_time_from_timet_with_zone (time, FALSE, (ICalTimezone *) zone);
 
        /* Set it to the start of the month. */
-       tt.day = 1;
-       tt.hour = 0;
-       tt.minute = 0;
-       tt.second = 0;
+       i_cal_timetype_set_day (tt, 1);
+       i_cal_timetype_set_hour (tt, 0);
+       i_cal_timetype_set_minute (tt, 0);
+       i_cal_timetype_set_second (tt, 0);
 
        /* Convert back to a time_t. */
-       return icaltime_as_timet_with_zone (tt, zone);
+       res = i_cal_time_as_timet_with_zone (tt, (ICalTimezone *) zone);
+
+       g_object_unref (tt);
+
+       return res;
 }
 
 /**
@@ -326,39 +347,47 @@ time_month_begin_with_zone (time_t time,
  * timezone. week_start_day should use the same values as mktime(),
  * i.e. 0 (Sun) to 6 (Sat).
  * NOTE: this function is only here to make the transition to the timezone
- * functions easier. New code should use icaltimetype values and
- * icaltime_adjust() to add or subtract days, hours, minutes & seconds.
+ * functions easier. New code should use ICalTimetype values and
+ * i_cal_time_adjust() to add or subtract days, hours, minutes & seconds.
  *
  * Returns: the beginning of the week.
  */
 time_t
 time_week_begin_with_zone (time_t time,
-                           gint week_start_day,
-                           icaltimezone *zone)
+                          gint week_start_day,
+                          const ICalTimezone *zone)
 {
-       struct icaltimetype tt;
+       ICalTimetype *tt, *normtt;
        gint weekday, offset;
+       time_t res;
 
        /* Convert to an icaltimetype. */
-       tt = icaltime_from_timet_with_zone (time, FALSE, zone);
+       tt = i_cal_time_from_timet_with_zone (time, FALSE, (ICalTimezone *) zone);
 
        /* Get the weekday. */
-       weekday = time_day_of_week (tt.day, tt.month - 1, tt.year);
+       weekday = time_day_of_week (i_cal_timetype_get_day (tt), i_cal_timetype_get_month (tt) - 1, 
i_cal_timetype_get_year (tt));
 
        /* Calculate the current offset from the week start day. */
        offset = (weekday + 7 - week_start_day) % 7;
 
        /* Set it to the start of the month. */
-       tt.day -= offset;
-       tt.hour = 0;
-       tt.minute = 0;
-       tt.second = 0;
+       i_cal_timetype_set_day (tt, i_cal_timetype_get_day (tt) - offset);
+       i_cal_timetype_set_hour (tt, 0);
+       i_cal_timetype_set_minute (tt, 0);
+       i_cal_timetype_set_second (tt, 0);
 
        /* Normalize it, to fix any overflow. */
-       tt = icaltime_normalize (tt);
+       normtt = i_cal_time_normalize (tt);
+
+       g_object_unref (tt);
+       tt = normtt;
 
        /* Convert back to a time_t. */
-       return icaltime_as_timet_with_zone (tt, zone);
+       res = i_cal_time_as_timet_with_zone (tt, (ICalTimezone *) zone);
+
+       g_object_unref (tt);
+
+       return res;
 }
 
 /**
@@ -369,31 +398,33 @@ time_week_begin_with_zone (time_t time,
  * Returns the start of the day containing the given time_t, using the given
  * timezone.
  * NOTE: this function is only here to make the transition to the timezone
- * functions easier. New code should use icaltimetype values and
- * icaltime_adjust() to add or subtract days, hours, minutes & seconds.
+ * functions easier. New code should use ICalTimetype values and
+ * i_cal_time_adjust() to add or subtract days, hours, minutes & seconds.
  *
  * Returns: the beginning of the day.
  */
 time_t
 time_day_begin_with_zone (time_t time,
-                          icaltimezone *zone)
+                         const ICalTimezone *zone)
 {
-       struct icaltimetype tt;
+       ICalTimetype *tt;
        time_t new_time;
 
        /* Convert to an icaltimetype. */
-       tt = icaltime_from_timet_with_zone (time, FALSE, zone);
+       tt = i_cal_time_from_timet_with_zone (time, FALSE, (ICalTimezone *) zone);
 
        /* Set it to the start of the day. */
-       tt.hour = 0;
-       tt.minute = 0;
-       tt.second = 0;
+       i_cal_timetype_set_hour (tt, 0);
+       i_cal_timetype_set_minute (tt, 0);
+       i_cal_timetype_set_second (tt, 0);
 
        /* Convert back to a time_t and make sure the time is in the past. */
-       while (new_time = icaltime_as_timet_with_zone (tt, zone), new_time > time) {
-               icaltime_adjust (&tt, 0, -1, 0, 0);
+       while (new_time = i_cal_time_as_timet_with_zone (tt, (ICalTimezone *) zone), new_time > time) {
+               i_cal_time_adjust (tt, 0, -1, 0, 0);
        }
 
+       g_object_unref (tt);
+
        return new_time;
 }
 
@@ -405,33 +436,35 @@ time_day_begin_with_zone (time_t time,
  * Returns the end of the day containing the given time_t, using the given
  * timezone. (The end of the day is the start of the next day.)
  * NOTE: this function is only here to make the transition to the timezone
- * functions easier. New code should use icaltimetype values and
- * icaltime_adjust() to add or subtract days, hours, minutes & seconds.
+ * functions easier. New code should use ICalTimetype values and
+ * i_cal_time_adjust() to add or subtract days, hours, minutes & seconds.
  *
  * Returns: the end of the day.
  */
 time_t
 time_day_end_with_zone (time_t time,
-                        icaltimezone *zone)
+                       const ICalTimezone *zone)
 {
-       struct icaltimetype tt;
+       ICalTimetype *tt;
        time_t new_time;
 
        /* Convert to an icaltimetype. */
-       tt = icaltime_from_timet_with_zone (time, FALSE, zone);
+       tt = i_cal_time_from_timet_with_zone (time, FALSE, (ICalTimezone *) zone);
 
        /* Set it to the start of the next day. */
-       tt.hour = 0;
-       tt.minute = 0;
-       tt.second = 0;
+       i_cal_timetype_set_hour (tt, 0);
+       i_cal_timetype_set_minute (tt, 0);
+       i_cal_timetype_set_second (tt, 0);
 
-       icaltime_adjust (&tt, 1, 0, 0, 0);
+       i_cal_time_adjust (tt, 1, 0, 0, 0);
 
        /* Convert back to a time_t and make sure the time is in the future. */
-       while (new_time = icaltime_as_timet_with_zone (tt, zone), new_time <= time) {
-               icaltime_adjust (&tt, 0, 1, 0, 0);
+       while (new_time = i_cal_time_as_timet_with_zone (tt, (ICalTimezone *) zone), new_time <= time) {
+               i_cal_time_adjust (tt, 0, 1, 0, 0);
        }
 
+       g_object_unref (tt);
+
        return new_time;
 }
 
@@ -439,27 +472,29 @@ time_day_end_with_zone (time_t time,
  * time_to_gdate_with_zone:
  * @date: Destination #GDate value.
  * @time: A time value.
- * @zone: Desired timezone for destination @date, or NULL if the UTC timezone
- * is desired.
+ * @zone: (nullable): Desired timezone for destination @date, or %NULL if
+ *    the UTC timezone is desired.
  *
  * Converts a time_t value to a #GDate structure using the specified timezone.
  * This is analogous to g_date_set_time() but takes the timezone into account.
  **/
 void
 time_to_gdate_with_zone (GDate *date,
-                         time_t time,
-                         icaltimezone *zone)
+                        time_t time,
+                        const ICalTimezone *zone)
 {
-       struct icaltimetype tt;
+       ICalTimetype *tt;
 
        g_return_if_fail (date != NULL);
        g_return_if_fail (time != -1);
 
-       tt = icaltime_from_timet_with_zone (
+       tt = i_cal_time_from_timet_with_zone (
                time, FALSE,
-               zone ? zone : icaltimezone_get_utc_timezone ());
+               zone ? (ICalTimezone *) zone : i_cal_timezone_get_utc_timezone ());
+
+       g_date_set_dmy (date, i_cal_timetype_get_day (tt), i_cal_timetype_get_month (tt), 
i_cal_timetype_get_year (tt));
 
-       g_date_set_dmy (date, tt.day, tt.month, tt.year);
+       g_object_unref (tt);
 }
 
 /**************************************************************************
@@ -630,9 +665,10 @@ isodate_from_time_t (time_t t)
 time_t
 time_from_isodate (const gchar *str)
 {
-       struct icaltimetype tt = icaltime_null_time ();
-       icaltimezone *utc_zone;
+       ICalTimetype *tt;
+       ICalTimezone *utc_zone;
        gint len, i;
+       time_t res;
 
        g_return_val_if_fail (str != NULL, -1);
 
@@ -651,59 +687,68 @@ time_from_isodate (const gchar *str)
 
 #define digit_at(x,y) (x[y] - '0')
 
-       tt.year = digit_at (str, 0) * 1000
-               + digit_at (str, 1) * 100
-               + digit_at (str, 2) * 10
-               + digit_at (str, 3);
+       tt = i_cal_time_null_time ();
 
-       tt.month = digit_at (str, 4) * 10
-                + digit_at (str, 5);
+       i_cal_timetype_set_year (tt, digit_at (str, 0) * 1000 +
+                                    digit_at (str, 1) * 100 +
+                                    digit_at (str, 2) * 10 +
+                                    digit_at (str, 3));
 
-       tt.day = digit_at (str, 6) * 10
-              + digit_at (str, 7);
+       i_cal_timetype_set_month (tt, digit_at (str, 4) * 10 +
+                                     digit_at (str, 5));
+
+       i_cal_timetype_set_day (tt, digit_at (str, 6) * 10 +
+                                   digit_at (str, 7));
 
        if (len > 8) {
-               tt.hour = digit_at (str, 9) * 10
-                       + digit_at (str, 10);
-               tt.minute = digit_at (str, 11) * 10
-                          + digit_at (str, 12);
-               tt.second = digit_at (str, 13) * 10
-                          + digit_at (str, 14);
+               i_cal_timetype_set_hour (tt, digit_at (str, 9) * 10 +
+                                            digit_at (str, 10));
+               i_cal_timetype_set_minute (tt, digit_at (str, 11) * 10 +
+                                              digit_at (str, 12));
+               i_cal_timetype_set_second (tt, digit_at (str, 13) * 10 +
+                                              digit_at (str, 14));
        }
 
-       utc_zone = icaltimezone_get_utc_timezone ();
+       utc_zone = i_cal_timezone_get_utc_timezone ();
+
+       res = i_cal_time_as_timet_with_zone (tt, utc_zone);
 
-       return icaltime_as_timet_with_zone (tt, utc_zone);
+       g_object_unref (tt);
+
+       return res;
 }
 
 /**
  * icaltimetype_to_tm:
- * @itt: An icaltimetype structure.
+ * @itt: An #ICalTimetype
  *
- * Convers an icaltimetype structure into a GLibc's struct tm.
+ * Converts an #ICalTimetype into a GLibc's struct tm.
  *
- * Returns: (transfer full): The converted time as a struct tm. All fields will be
- * set properly except for tm.tm_yday.
+ * Returns: The converted time as a struct tm. All fields will be
+ *    set properly except for tm.tm_yday.
  *
  * Since: 2.22
  */
 struct tm
-icaltimetype_to_tm (struct icaltimetype *itt)
+icaltimetype_to_tm (const ICalTimetype *itt)
 {
        struct tm tm;
+       ICalTimetype *tt = (ICalTimetype *) itt;
 
        memset (&tm, 0, sizeof (struct tm));
 
-       if (!itt->is_date) {
-               tm.tm_sec = itt->second;
-               tm.tm_min = itt->minute;
-               tm.tm_hour = itt->hour;
+       g_return_val_if_fail (itt != NULL, tm);
+
+       if (!i_cal_timetype_get_is_date (tt)) {
+               tm.tm_sec = i_cal_timetype_get_second (tt);
+               tm.tm_min = i_cal_timetype_get_minute (tt);
+               tm.tm_hour = i_cal_timetype_get_hour (tt);
        }
 
-       tm.tm_mday = itt->day;
-       tm.tm_mon = itt->month - 1;
-       tm.tm_year = itt->year - 1900;
-       tm.tm_wday = time_day_of_week (itt->day, itt->month - 1, itt->year);
+       tm.tm_mday = i_cal_timetype_get_day (tt);
+       tm.tm_mon = i_cal_timetype_get_month (tt) - 1;
+       tm.tm_year = i_cal_timetype_get_year (tt) - 1900;
+       tm.tm_wday = time_day_of_week (i_cal_timetype_get_day (tt), i_cal_timetype_get_month (tt) - 1, 
i_cal_timetype_get_year (tt));
        tm.tm_isdst = -1;
 
        return tm;
@@ -718,28 +763,29 @@ icaltimetype_to_tm (struct icaltimetype *itt)
  * Converts a time value from one timezone to another, and returns a struct tm
  * representation of the time.
  *
- * Returns: (transfer full): The converted time as a struct tm. All fields will be
- * set properly except for tm.tm_yday.
+ * Returns: The converted time as a struct tm. All fields will be
+ *    set properly except for tm.tm_yday.
  *
  * Since: 2.22
  **/
 struct tm
-icaltimetype_to_tm_with_zone (struct icaltimetype *itt,
-                              icaltimezone *from_zone,
-                              icaltimezone *to_zone)
+icaltimetype_to_tm_with_zone (const ICalTimetype *itt,
+                             const ICalTimezone *from_zone,
+                             const ICalTimezone *to_zone)
 {
        struct tm tm;
-       struct icaltimetype itt_copy;
+       ICalTimetype *itt_copy;
 
        memset (&tm, 0, sizeof (tm));
        tm.tm_isdst = -1;
 
        g_return_val_if_fail (itt != NULL, tm);
 
-       itt_copy = *itt;
+       itt_copy = i_cal_timetype_new_clone (itt);
 
-       icaltimezone_convert_time (&itt_copy, from_zone, to_zone);
-       tm = icaltimetype_to_tm (&itt_copy);
+       i_cal_timezone_convert_time (itt_copy, (ICalTimezone *) from_zone, (ICalTimezone *) to_zone);
+       tm = icaltimetype_to_tm (itt_copy);
+       g_object_unref (itt_copy);
 
        return tm;
 }
@@ -749,32 +795,28 @@ icaltimetype_to_tm_with_zone (struct icaltimetype *itt,
  * @tm: A struct tm.
  * @is_date: Whether the given time is a date only or not.
  *
- * Converts a struct tm into an icaltimetype.
+ * Converts a struct tm into an #ICalTimetype. Free the returned object
+ * with g_object_unref(), when no longe needed.
  *
- * Returns: (transfer full): The converted time as an icaltimetype.
+ * Returns: (transfer full): The converted time as an #ICalTimetype.
  *
  * Since: 2.22
  */
-struct icaltimetype
+ICalTimetype *
 tm_to_icaltimetype (struct tm *tm,
                     gboolean is_date)
 {
-       struct icaltimetype itt;
+       ICalTimetype *itt;
 
-       memset (&itt, 0, sizeof (struct icaltimetype));
+       g_return_val_if_fail (tm != NULL, NULL);
 
-       if (!is_date) {
-               itt.second = tm->tm_sec;
-               itt.minute = tm->tm_min;
-               itt.hour = tm->tm_hour;
-       }
+       itt = i_cal_time_null_time ();
 
-       itt.day = tm->tm_mday;
-       itt.month = tm->tm_mon + 1;
-       itt.year = tm->tm_year + 1900;
+       if (!is_date)
+               i_cal_timetype_set_time (itt, tm->tm_hour, tm->tm_min, tm->tm_sec);
 
-       itt.is_date = is_date;
+       i_cal_timetype_set_date (itt, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
+       i_cal_timetype_set_is_date (itt, is_date);
 
        return itt;
 }
-
diff --git a/src/calendar/libecal/e-cal-time-util.h b/src/calendar/libecal/e-cal-time-util.h
index df665226f..37f93180d 100644
--- a/src/calendar/libecal/e-cal-time-util.h
+++ b/src/calendar/libecal/e-cal-time-util.h
@@ -39,99 +39,124 @@ G_BEGIN_DECLS
 
 /* Returns the number of days in the month. Year is the normal year, e.g. 2001.
  * Month is 0 (Jan) to 11 (Dec). */
-gint   time_days_in_month      (gint year, gint month);
+gint           time_days_in_month      (gint year,
+                                        gint month);
 
 /* Returns the 1-based day number within the year of the specified date.
  * Year is the normal year, e.g. 2001. Month is 0 to 11. */
-gint   time_day_of_year        (gint day, gint month, gint year);
+gint           time_day_of_year        (gint day,
+                                        gint month,
+                                        gint year);
 
 /* Returns the day of the week for the specified date, 0 (Sun) to 6 (Sat).
  * For the days that were removed on the Gregorian reformation, it returns
  * Thursday. Year is the normal year, e.g. 2001. Month is 0 to 11. */
-gint   time_day_of_week        (gint day, gint month, gint year);
+gint           time_day_of_week        (gint day,
+                                        gint month,
+                                        gint year);
 
 /* Returns whether the specified year is a leap year. Year is the normal year,
  * e.g. 2001. */
-gboolean time_is_leap_year     (gint year);
+gboolean       time_is_leap_year       (gint year);
 
 /* Returns the number of leap years since year 1 up to (but not including) the
  * specified year. Year is the normal year, e.g. 2001. */
-gint   time_leap_years_up_to   (gint year);
+gint           time_leap_years_up_to   (gint year);
 
 /* Convert to or from an ISO 8601 representation of a time, in UTC,
  * e.g. "20010708T183000Z". */
-gchar   *isodate_from_time_t     (time_t t);
-time_t time_from_isodate       (const gchar *str);
+gchar *                isodate_from_time_t     (time_t t);
+time_t         time_from_isodate       (const gchar *str);
 
 /**************************************************************************
  * time_t manipulation functions.
  *
  * NOTE: these use the Unix timezone functions like mktime() and localtime()
  * and so should not be used in Evolution. New Evolution code should use
- * icaltimetype values rather than time_t values wherever possible.
+ * ICalTimetype values rather than time_t values wherever possible.
  **************************************************************************/
 
 /* Add or subtract a number of days, weeks or months. */
-time_t time_add_day            (time_t time, gint days);
-time_t time_add_week           (time_t time, gint weeks);
+time_t         time_add_day            (time_t time,
+                                        gint days);
+time_t         time_add_week           (time_t time,
+                                        gint weeks);
 
 /* Returns the beginning or end of the day. */
-time_t time_day_begin          (time_t t);
-time_t time_day_end            (time_t t);
+time_t         time_day_begin          (time_t t);
+time_t         time_day_end            (time_t t);
 
 /**************************************************************************
  * time_t manipulation functions, using timezones in libical.
  *
  * NOTE: these are only here to make the transition to the timezone
- * functions easier. New code should use icaltimetype values rather than
+ * functions easier. New code should use ICalTimetype values rather than
  * time_t values wherever possible.
  **************************************************************************/
 
 /* Adds or subtracts a number of days to/from the given time_t value, using
  * the given timezone. */
-time_t time_add_day_with_zone (time_t time, gint days, icaltimezone *zone);
+time_t         time_add_day_with_zone  (time_t time,
+                                        gint days,
+                                        const ICalTimezone *zone);
 
 /* Adds or subtracts a number of weeks to/from the given time_t value, using
  * the given timezone. */
-time_t time_add_week_with_zone (time_t time, gint weeks, icaltimezone *zone);
+time_t         time_add_week_with_zone (time_t time,
+                                        gint weeks,
+                                        const ICalTimezone *zone);
 
 /* Adds or subtracts a number of months to/from the given time_t value, using
  * the given timezone. */
-time_t time_add_month_with_zone (time_t time, gint months, icaltimezone *zone);
+time_t         time_add_month_with_zone(time_t time,
+                                        gint months,
+                                        const ICalTimezone *zone);
 
 /* Returns the start of the year containing the given time_t, using the given
  * timezone. */
-time_t time_year_begin_with_zone (time_t time, icaltimezone *zone);
+time_t         time_year_begin_with_zone
+                                       (time_t time,
+                                        const ICalTimezone *zone);
 
 /* Returns the start of the month containing the given time_t, using the given
  * timezone. */
-time_t time_month_begin_with_zone (time_t time, icaltimezone *zone);
+time_t         time_month_begin_with_zone
+                                       (time_t time,
+                                        const ICalTimezone *zone);
 
 /* Returns the start of the week containing the given time_t, using the given
  * timezone. week_start_day should use the same values as mktime (),
  * i.e. 0 (Sun) to 6 (Sat). */
-time_t time_week_begin_with_zone (time_t time, gint week_start_day,
-                                  icaltimezone *zone);
+time_t         time_week_begin_with_zone
+                                       (time_t time,
+                                        gint week_start_day,
+                                        const ICalTimezone *zone);
 
 /* Returns the start of the day containing the given time_t, using the given
  * timezone. */
-time_t time_day_begin_with_zone (time_t time, icaltimezone *zone);
+time_t         time_day_begin_with_zone(time_t time,
+                                        const ICalTimezone *zone);
 
 /* Returns the end of the day containing the given time_t, using the given
  * timezone. (The end of the day is the start of the next day.) */
-time_t time_day_end_with_zone (time_t time, icaltimezone *zone);
+time_t         time_day_end_with_zone  (time_t time,
+                                        const ICalTimezone *zone);
 
-void time_to_gdate_with_zone (GDate *date, time_t time, icaltimezone *zone);
+void           time_to_gdate_with_zone (GDate *date,
+                                        time_t time,
+                                        const ICalTimezone *zone);
 
 /**************************************************************************
  * struct tm manipulation
  **************************************************************************/
 
-struct tm icaltimetype_to_tm (struct icaltimetype *itt);
-struct tm icaltimetype_to_tm_with_zone (struct icaltimetype *itt,
-                                       icaltimezone *from_zone,
-                                       icaltimezone *to_zone);
-struct icaltimetype tm_to_icaltimetype (struct tm *tm, gboolean is_date);
+struct tm      icaltimetype_to_tm      (const ICalTimetype *itt);
+struct tm      icaltimetype_to_tm_with_zone
+                                       (const ICalTimetype *itt,
+                                        const ICalTimezone *from_zone,
+                                        const ICalTimezone *to_zone);
+ICalTimetype * tm_to_icaltimetype      (struct tm *tm,
+                                        gboolean is_date);
 
 G_END_DECLS
 
diff --git a/src/calendar/libecal/e-cal-util.c b/src/calendar/libecal/e-cal-util.c
index 28c8a52a0..b6f3897ac 100644
--- a/src/calendar/libecal/e-cal-util.c
+++ b/src/calendar/libecal/e-cal-util.c
@@ -26,106 +26,111 @@
 
 #include <libedataserver/libedataserver.h>
 
-#include "e-cal-util.h"
+#include "e-cal-check-timezones.h"
 #include "e-cal-client.h"
 #include "e-cal-system-timezone.h"
+#include "e-cal-recur.h"
+
+#include "e-cal-util.h"
 
 #define _TIME_MIN      ((time_t) 0)            /* Min valid time_t     */
 #define _TIME_MAX      ((time_t) INT_MAX)
 
-/**
- * cal_obj_instance_list_free:
- * @list: (element-type CalObjInstance): List of #CalObjInstance structures.
- *
- * Frees a list of #CalObjInstance structures.
- **/
-void
-cal_obj_instance_list_free (GList *list)
-{
-       CalObjInstance *i;
-       GList *l;
-
-       for (l = list; l; l = l->next) {
-               i = l->data;
-
-               if (i != NULL && i->uid != NULL) {
-                       g_free (i->uid);
-                       g_free (i);
-               } else
-                       g_warn_if_reached ();
-       }
-
-       g_list_free (list);
-}
-
-/**
- * cal_obj_uid_list_free:
- * @list: (element-type utf8): List of strings with unique identifiers.
- *
- * Frees a list of unique identifiers for calendar objects.
- **/
-void
-cal_obj_uid_list_free (GList *list)
-{
-       g_list_foreach (list, (GFunc) g_free, NULL);
-       g_list_free (list);
-}
-
 /**
  * e_cal_util_new_top_level:
  *
- * Creates a new VCALENDAR component.
+ * Creates a new VCALENDAR component. Free it with g_object_unref(),
+ * when no longer needed.
  *
- * Returns: the newly created top level component.
+ * Returns: (transfer full): the newly created top level component.
  */
-icalcomponent *
+ICalComponent *
 e_cal_util_new_top_level (void)
 {
-       icalcomponent *icalcomp;
-       icalproperty *prop;
+       ICalComponent *icalcomp;
+       ICalProperty *prop;
 
-       icalcomp = icalcomponent_new (ICAL_VCALENDAR_COMPONENT);
+       icalcomp = i_cal_component_new (I_CAL_VCALENDAR_COMPONENT);
 
        /* RFC 2445, section 4.7.1 */
-       prop = icalproperty_new_calscale ("GREGORIAN");
-       icalcomponent_add_property (icalcomp, prop);
+       prop = i_cal_property_new_calscale ("GREGORIAN");
+       i_cal_component_take_property (icalcomp, prop);
 
        /* RFC 2445, section 4.7.3 */
-       prop = icalproperty_new_prodid ("-//Ximian//NONSGML Evolution Calendar//EN");
-       icalcomponent_add_property (icalcomp, prop);
+       prop = i_cal_property_new_prodid ("-//Ximian//NONSGML Evolution Calendar//EN");
+       i_cal_component_take_property (icalcomp, prop);
 
        /* RFC 2445, section 4.7.4.  This is the iCalendar spec version, *NOT*
         * the product version!  Do not change this!
         */
-       prop = icalproperty_new_version ("2.0");
-       icalcomponent_add_property (icalcomp, prop);
+       prop = i_cal_property_new_version ("2.0");
+       i_cal_component_take_property (icalcomp, prop);
 
        return icalcomp;
 }
 
 /**
  * e_cal_util_new_component:
- * @kind: Kind of the component to create.
+ * @kind: Kind of the component to create, as #ICalComponentKind.
  *
- * Creates a new #icalcomponent of the specified kind.
+ * Creates a new #ICalComponent of the specified kind. Free it
+ * with g_object_unref(), when no longer needed.
  *
- * Returns: the newly created component.
+ * Returns: (transfer full): the newly created component.
  */
-icalcomponent *
-e_cal_util_new_component (icalcomponent_kind kind)
+ICalComponent *
+e_cal_util_new_component (ICalComponentKind kind)
 {
-       icalcomponent *comp;
-       struct icaltimetype dtstamp;
+       ICalComponent *icalcomp;
+       ICalTimetype *dtstamp;
        gchar *uid;
 
-       comp = icalcomponent_new (kind);
+       icalcomp = i_cal_component_new (kind);
        uid = e_util_generate_uid ();
-       icalcomponent_set_uid (comp, uid);
+       i_cal_component_set_uid (icalcomp, uid);
        g_free (uid);
-       dtstamp = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
-       icalcomponent_set_dtstamp (comp, dtstamp);
+       dtstamp = i_cal_time_current_time_with_zone (i_cal_timezone_get_utc_timezone ());
+       i_cal_component_set_dtstamp (icalcomp, dtstamp);
+       g_object_unref (dtstamp);
 
-       return comp;
+       return icalcomp;
+}
+
+/**
+ * e_cal_util_copy_timezone:
+ * @zone: an ICalTimezone
+ *
+ * Copies the @zone together with its inner component and
+ * returns it as a new #ICalTimezone object. Free it with
+ * g_object_unref(), when no longer needed.
+ *
+ * Returns: (transfer full): a copy of the @zone
+ *
+ * Since: 3.36
+ **/
+ICalTimezone *
+e_cal_util_copy_timezone (const ICalTimezone *zone)
+{
+       ICalComponent *comp;
+       ICalTimezone *zone_copy;
+
+       g_return_val_if_fail (zone != NULL, NULL);
+
+       zone_copy = i_cal_timezone_copy (zone);
+       if (!zone_copy)
+               return NULL;
+
+       comp = i_cal_timezone_get_component (zone);
+       if (comp) {
+               ICalComponent *comp_copy;
+
+               comp_copy = i_cal_component_new_clone (comp);
+               i_cal_timezone_set_component (zone_copy, comp_copy);
+               g_object_unref (comp_copy);
+               g_object_unref (comp);
+       }
+
+       return zone_copy;
 }
 
 static gchar *
@@ -149,20 +154,22 @@ read_line (const gchar *string)
  * e_cal_util_parse_ics_string:
  * @string: iCalendar string to be parsed.
  *
- * Parses an iCalendar string and returns a new #icalcomponent representing
+ * Parses an iCalendar string and returns a new #ICalComponent representing
  * that string. Note that this function deals with multiple VCALENDAR's in the
  * string, something that Mozilla used to do and which libical does not
  * support.
  *
- * Returns: a newly created #icalcomponent or NULL if the string isn't a
- * valid iCalendar string.
+ * Free the returned non-NULL component with g_object_unref(), when no longer needed.
+ *
+ * Returns: (transfer full) (nullable): a newly created #ICalComponent, or %NULL,
+ *    if the string isn't a valid iCalendar string.
  */
-icalcomponent *
+ICalComponent *
 e_cal_util_parse_ics_string (const gchar *string)
 {
        GString *comp_str = NULL;
        gchar *s;
-       icalcomponent *icalcomp = NULL;
+       ICalComponent *icalcomp = NULL;
 
        g_return_val_if_fail (string != NULL, NULL);
 
@@ -170,7 +177,7 @@ e_cal_util_parse_ics_string (const gchar *string)
        s = g_strstr_len (string, strlen (string), "BEGIN:VCALENDAR");
 
        if (s == NULL)
-               return icalparser_parse_string (string);
+               return i_cal_parser_parse_string (string);
 
        while (*s != '\0') {
                gchar *line = read_line (s);
@@ -181,13 +188,14 @@ e_cal_util_parse_ics_string (const gchar *string)
                        comp_str = g_string_append (comp_str, line);
 
                if (strncmp (line, "END:VCALENDAR", 13) == 0) {
-                       icalcomponent *tmp;
-
-                       tmp = icalparser_parse_string (comp_str->str);
-                       if (tmp && icalcomponent_isa (tmp) == ICAL_VCALENDAR_COMPONENT) {
-                               if (icalcomp)
-                                       icalcomponent_merge_component (icalcomp, tmp);
-                               else
+                       ICalComponent *tmp;
+
+                       tmp = i_cal_parser_parse_string (comp_str->str);
+                       if (tmp && i_cal_component_isa (tmp) == I_CAL_VCALENDAR_COMPONENT) {
+                               if (icalcomp) {
+                                       i_cal_component_merge_component (icalcomp, tmp);
+                                       g_object_unref (tmp);
+                               } else
                                        icalcomp = tmp;
                        } else {
                                g_warning (
@@ -257,16 +265,18 @@ get_line_fn (gchar *buf,
  * @filename: Name of the file to be parsed.
  *
  * Parses the given file, and, if it contains a valid iCalendar object,
- * parse it and return a new #icalcomponent.
+ * parse it and return a new #ICalComponent.
  *
- * Returns: a newly created #icalcomponent or NULL if the file doesn't
- * contain a valid iCalendar object.
+ * Free the returned non-NULL component with g_object_unref(), when no longer needed.
+ *
+ * Returns: (transfer full) (nullable): a newly created #ICalComponent, or %NULL,
+ *    if the file doesn't contain a valid iCalendar object.
  */
-icalcomponent *
+ICalComponent *
 e_cal_util_parse_ics_file (const gchar *filename)
 {
-       icalparser *parser;
-       icalcomponent *icalcomp;
+       ICalParser *parser;
+       ICalComponent *icalcomp;
        struct ics_file fl;
 
        fl.file = g_fopen (filename, "rb");
@@ -275,11 +285,11 @@ e_cal_util_parse_ics_file (const gchar *filename)
 
        fl.bof = TRUE;
 
-       parser = icalparser_new ();
-       icalparser_set_gen_data (parser, &fl);
+       parser = i_cal_parser_new ();
+       i_cal_parser_set_gen_data (parser, &fl);
 
-       icalcomp = icalparser_parse (parser, get_line_fn);
-       icalparser_free (parser);
+       icalcomp = i_cal_parser_parse (parser, get_line_fn);
+       g_object_unref (parser);
        fclose (fl.file);
 
        return icalcomp;
@@ -290,13 +300,13 @@ e_cal_util_parse_ics_file (const gchar *filename)
  */
 static void
 compute_alarm_range (ECalComponent *comp,
-                     GList *alarm_uids,
+                     GSList *alarm_uids,
                      time_t start,
                      time_t end,
                      time_t *alarm_start,
                      time_t *alarm_end)
 {
-       GList *l;
+       GSList *link;
        time_t repeat_time;
 
        *alarm_start = start;
@@ -304,41 +314,45 @@ compute_alarm_range (ECalComponent *comp,
 
        repeat_time = 0;
 
-       for (l = alarm_uids; l; l = l->next) {
+       for (link = alarm_uids; link; link = g_slist_next (link)) {
                const gchar *auid;
                ECalComponentAlarm *alarm;
-               ECalComponentAlarmTrigger trigger;
-               struct icaldurationtype *dur;
+               ECalComponentAlarmTrigger *trigger;
+               ICalDurationType *dur;
                time_t dur_time;
-               ECalComponentAlarmRepeat repeat;
+               ECalComponentAlarmRepeat *repeat;
 
-               auid = l->data;
+               auid = link->data;
                alarm = e_cal_component_get_alarm (comp, auid);
                g_return_if_fail (alarm != NULL);
 
-               e_cal_component_alarm_get_trigger (alarm, &trigger);
-               e_cal_component_alarm_get_repeat (alarm, &repeat);
-               e_cal_component_alarm_free (alarm);
+               trigger = e_cal_component_alarm_get_trigger (alarm);
+               repeat = e_cal_component_alarm_get_repeat (alarm);
 
-               switch (trigger.type) {
+               if (!trigger) {
+                       e_cal_component_alarm_free (alarm);
+                       continue;
+               }
+
+               switch (e_cal_component_alarm_trigger_get_kind (trigger)) {
                case E_CAL_COMPONENT_ALARM_TRIGGER_NONE:
                case E_CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE:
                        break;
 
                case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START:
                case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_END:
-                       dur = &trigger.u.rel_duration;
-                       dur_time = icaldurationtype_as_int (*dur);
+                       dur = e_cal_component_alarm_trigger_get_duration (trigger);
+                       dur_time = i_cal_duration_type_as_int (dur);
 
-                       if (repeat.repetitions != 0) {
+                       if (repeat && e_cal_component_alarm_repeat_get_repetitions (repeat) != 0) {
                                gint rdur;
 
-                               rdur = repeat.repetitions *
-                                       icaldurationtype_as_int (repeat.duration);
+                               rdur = e_cal_component_alarm_repeat_get_repetitions (repeat) *
+                                       e_cal_component_alarm_repeat_get_interval_seconds (repeat);
                                repeat_time = MAX (repeat_time, rdur);
                        }
 
-                       if (dur->is_neg)
+                       if (i_cal_duration_type_is_neg (dur))
                                /* If the duration is negative then dur_time
                                 * will be negative as well; that is why we
                                 * subtract to expand the range.
@@ -348,10 +362,9 @@ compute_alarm_range (ECalComponent *comp,
                                *alarm_start = MIN (*alarm_start, start - dur_time);
 
                        break;
-
-               default:
-                       g_return_if_reached ();
                }
+
+               e_cal_component_alarm_free (alarm);
        }
 
        *alarm_start -= repeat_time;
@@ -360,31 +373,29 @@ compute_alarm_range (ECalComponent *comp,
 
 /* Closure data to generate alarm occurrences */
 struct alarm_occurrence_data {
+       ECalComponent *comp;
+
        /* These are the info we have */
-       GList *alarm_uids;
+       GSList *alarm_uids; /* gchar * */
        time_t start;
        time_t end;
        ECalComponentAlarmAction *omit;
 
        /* This is what we compute */
-       GSList *triggers;
+       GSList *triggers; /* ECalComponentAlarmInstance * */
        gint n_triggers;
 };
 
 static void
 add_trigger (struct alarm_occurrence_data *aod,
              const gchar *auid,
-             time_t trigger,
+             time_t instance_time,
              time_t occur_start,
              time_t occur_end)
 {
        ECalComponentAlarmInstance *instance;
 
-       instance = g_new (ECalComponentAlarmInstance, 1);
-       instance->auid = g_strdup (auid);
-       instance->trigger = trigger;
-       instance->occur_start = occur_start;
-       instance->occur_end = occur_end;
+       instance = e_cal_component_alarm_instance_new (auid, instance_time, occur_start, occur_end);
 
        aod->triggers = g_slist_prepend (aod->triggers, instance);
        aod->n_triggers++;
@@ -394,51 +405,65 @@ add_trigger (struct alarm_occurrence_data *aod,
  * of a component's RELATIVE alarms.
  */
 static gboolean
-add_alarm_occurrences_cb (ECalComponent *comp,
-                          time_t start,
-                          time_t end,
-                          gpointer data)
+add_alarm_occurrences_cb (ICalComponent *icalcomp,
+                         ICalTimetype *instance_start,
+                         ICalTimetype *instance_end,
+                         gpointer user_data,
+                         GCancellable *cancellable,
+                         GError **error)
 {
        struct alarm_occurrence_data *aod;
-       GList *l;
+       time_t start, end;
+       GSList *link;
 
-       aod = data;
+       aod = user_data;
+       start = i_cal_time_as_timet (instance_start);
+       end = i_cal_time_as_timet (instance_end);
 
-       for (l = aod->alarm_uids; l; l = l->next) {
+       for (link = aod->alarm_uids; link; link = g_slist_next (link)) {
                const gchar *auid;
                ECalComponentAlarm *alarm;
                ECalComponentAlarmAction action;
-               ECalComponentAlarmTrigger trigger;
-               ECalComponentAlarmRepeat repeat;
-               struct icaldurationtype *dur;
+               ECalComponentAlarmTrigger *trigger;
+               ECalComponentAlarmRepeat *repeat;
+               ICalDurationType *dur;
                time_t dur_time;
                time_t occur_time, trigger_time;
                gint i;
 
-               auid = l->data;
-               alarm = e_cal_component_get_alarm (comp, auid);
+               auid = link->data;
+               alarm = e_cal_component_get_alarm (aod->comp, auid);
                g_return_val_if_fail (alarm != NULL, FALSE);
 
-               e_cal_component_alarm_get_action (alarm, &action);
-               e_cal_component_alarm_get_trigger (alarm, &trigger);
-               e_cal_component_alarm_get_repeat (alarm, &repeat);
-               e_cal_component_alarm_free (alarm);
+               action = e_cal_component_alarm_get_action (alarm);
+               trigger = e_cal_component_alarm_get_trigger (alarm);
+               repeat = e_cal_component_alarm_get_repeat (alarm);
+
+               if (!trigger) {
+                       e_cal_component_alarm_free (alarm);
+                       continue;
+               }
 
                for (i = 0; aod->omit[i] != -1; i++) {
                        if (aod->omit[i] == action)
                                break;
                }
-               if (aod->omit[i] != -1)
+
+               if (aod->omit[i] != -1) {
+                       e_cal_component_alarm_free (alarm);
                        continue;
+               }
 
-               if (trigger.type != E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START
-                   && trigger.type != E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_END)
+               if (e_cal_component_alarm_trigger_get_kind (trigger) != 
E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START &&
+                   e_cal_component_alarm_trigger_get_kind (trigger) != 
E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_END) {
+                       e_cal_component_alarm_free (alarm);
                        continue;
+               }
 
-               dur = &trigger.u.rel_duration;
-               dur_time = icaldurationtype_as_int (*dur);
+               dur = e_cal_component_alarm_trigger_get_duration (trigger);
+               dur_time = i_cal_duration_type_as_int (dur);
 
-               if (trigger.type == E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START)
+               if (e_cal_component_alarm_trigger_get_kind (trigger) == 
E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START)
                        occur_time = start;
                else
                        occur_time = end;
@@ -453,16 +478,17 @@ add_alarm_occurrences_cb (ECalComponent *comp,
 
                /* Add repeating alarms */
 
-               if (repeat.repetitions != 0) {
-                       gint i;
+               if (repeat && e_cal_component_alarm_repeat_get_repetitions (repeat) != 0) {
+                       gint ii, repetitions;
                        time_t repeat_time;
 
-                       repeat_time = icaldurationtype_as_int (repeat.duration);
+                       repeat_time = e_cal_component_alarm_repeat_get_interval_seconds (repeat);
+                       repetitions = e_cal_component_alarm_repeat_get_repetitions (repeat);
 
-                       for (i = 0; i < repeat.repetitions; i++) {
+                       for (ii = 0; ii < repetitions; ii++) {
                                time_t t;
 
-                               t = trigger_time + (i + 1) * repeat_time;
+                               t = trigger_time + (ii + 1) * repeat_time;
 
                                if (t >= aod->start && t < aod->end)
                                        add_trigger (aod, auid, t, start, end);
@@ -473,6 +499,8 @@ add_alarm_occurrences_cb (ECalComponent *comp,
 
                if (trigger_time >= aod->start && trigger_time < aod->end)
                        add_trigger (aod, auid, trigger_time, start, end);
+
+               e_cal_component_alarm_free (alarm);
        }
 
        return TRUE;
@@ -482,93 +510,105 @@ add_alarm_occurrences_cb (ECalComponent *comp,
 static void
 generate_absolute_triggers (ECalComponent *comp,
                             struct alarm_occurrence_data *aod,
-                            ECalRecurResolveTimezoneFn resolve_tzid,
+                            ECalRecurResolveTimezoneCb resolve_tzid,
                             gpointer user_data,
-                            icaltimezone *default_timezone)
+                            ICalTimezone *default_timezone)
 {
-       GList *l;
-       ECalComponentDateTime dt_start, dt_end;
+       GSList *link;
+       ECalComponentDateTime *dtstart, *dtend;
+       time_t occur_start, occur_end;
+
+       dtstart = e_cal_component_get_dtstart (comp);
+       dtend = e_cal_component_get_dtend (comp);
+
+       /* No particular occurrence, so just use the times from the
+        * component */
+
+       if (dtstart && e_cal_component_datetime_get_value (dtstart)) {
+               ICalTimezone *zone;
+               const gchar *tzid = e_cal_component_datetime_get_tzid (dtstart);
+
+               if (tzid && !i_cal_time_is_date (e_cal_component_datetime_get_value (dtstart)))
+                       zone = (* resolve_tzid) (tzid, user_data, NULL, NULL);
+               else
+                       zone = default_timezone ? g_object_ref (default_timezone) : NULL;
+
+               occur_start = i_cal_time_as_timet_with_zone (e_cal_component_datetime_get_value (dtstart), 
zone);
 
-       e_cal_component_get_dtstart (comp, &dt_start);
-       e_cal_component_get_dtend (comp, &dt_end);
+               g_clear_object (&zone);
+       } else
+               occur_start = -1;
 
-       for (l = aod->alarm_uids; l; l = l->next) {
+       if (dtend && e_cal_component_datetime_get_value (dtend)) {
+               ICalTimezone *zone;
+               const gchar *tzid = e_cal_component_datetime_get_tzid (dtend);
+
+               if (tzid && !i_cal_time_is_date (e_cal_component_datetime_get_value (dtend)))
+                       zone = (* resolve_tzid) (tzid, user_data, NULL, NULL);
+               else
+                       zone = default_timezone ? g_object_ref (default_timezone) : NULL;
+
+               occur_end = i_cal_time_as_timet_with_zone (e_cal_component_datetime_get_value (dtend), zone);
+
+               g_clear_object (&zone);
+       } else
+               occur_end = -1;
+
+       for (link = aod->alarm_uids; link; link = g_slist_next (link)) {
                const gchar *auid;
                ECalComponentAlarm *alarm;
                ECalComponentAlarmAction action;
-               ECalComponentAlarmRepeat repeat;
-               ECalComponentAlarmTrigger trigger;
+               ECalComponentAlarmRepeat *repeat;
+               ECalComponentAlarmTrigger *trigger;
                time_t abs_time;
-               time_t occur_start, occur_end;
-               icaltimezone *zone;
+               ICalTimezone *zone;
                gint i;
 
-               auid = l->data;
+               auid = link->data;
                alarm = e_cal_component_get_alarm (comp, auid);
                g_return_if_fail (alarm != NULL);
 
-               e_cal_component_alarm_get_action (alarm, &action);
-               e_cal_component_alarm_get_trigger (alarm, &trigger);
-               e_cal_component_alarm_get_repeat (alarm, &repeat);
-               e_cal_component_alarm_free (alarm);
+               action = e_cal_component_alarm_get_action (alarm);
+               trigger = e_cal_component_alarm_get_trigger (alarm);
+               repeat = e_cal_component_alarm_get_repeat (alarm);
 
                for (i = 0; aod->omit[i] != -1; i++) {
                        if (aod->omit[i] == action)
                                break;
                }
-               if (aod->omit[i] != -1)
+
+               if (aod->omit[i] != -1) {
+                       e_cal_component_alarm_free (alarm);
                        continue;
+               }
 
-               if (trigger.type != E_CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE)
+               if (e_cal_component_alarm_trigger_get_kind (trigger) != 
E_CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE) {
+                       e_cal_component_alarm_free (alarm);
                        continue;
+               }
 
                /* Absolute triggers are always in UTC;
                 * see RFC 2445 section 4.8.6.3 */
-               zone = icaltimezone_get_utc_timezone ();
+               zone = i_cal_timezone_get_utc_timezone ();
 
-               abs_time = icaltime_as_timet_with_zone (trigger.u.abs_time, zone);
-
-               /* No particular occurrence, so just use the times from the
-                * component */
-
-               if (dt_start.value) {
-                       if (dt_start.tzid && !dt_start.value->is_date)
-                               zone = (* resolve_tzid) (dt_start.tzid, user_data);
-                       else
-                               zone = default_timezone;
-
-                       occur_start = icaltime_as_timet_with_zone (
-                               *dt_start.value, zone);
-               } else
-                       occur_start = -1;
-
-               if (dt_end.value) {
-                       if (dt_end.tzid && !dt_end.value->is_date)
-                               zone = (* resolve_tzid) (dt_end.tzid, user_data);
-                       else
-                               zone = default_timezone;
-
-                       occur_end = icaltime_as_timet_with_zone (*dt_end.value, zone);
-               } else
-                       occur_end = -1;
+               abs_time = i_cal_time_as_timet_with_zone (e_cal_component_alarm_trigger_get_absolute_time 
(trigger), zone);
 
                /* Add repeating alarms */
 
-               if (repeat.repetitions != 0) {
-                       gint i;
+               if (repeat && e_cal_component_alarm_repeat_get_repetitions (repeat) > 0) {
+                       gint ii, repetitions;
                        time_t repeat_time;
 
-                       repeat_time = icaldurationtype_as_int (repeat.duration);
+                       repeat_time = e_cal_component_alarm_repeat_get_interval_seconds (repeat);
+                       repetitions = e_cal_component_alarm_repeat_get_repetitions (repeat);
 
-                       for (i = 0; i < repeat.repetitions; i++) {
-                               time_t t;
+                       for (ii = 0; ii < repetitions; ii++) {
+                               time_t tt;
 
-                               t = abs_time + (i + 1) * repeat_time;
+                               tt = abs_time + (ii + 1) * repeat_time;
 
-                               if (t >= aod->start && t < aod->end)
-                                       add_trigger (
-                                               aod, auid, t,
-                                               occur_start, occur_end);
+                               if (tt >= aod->start && tt < aod->end)
+                                       add_trigger (aod, auid, tt, occur_start, occur_end);
                        }
                }
 
@@ -576,10 +616,12 @@ generate_absolute_triggers (ECalComponent *comp,
 
                if (abs_time >= aod->start && abs_time < aod->end)
                        add_trigger (aod, auid, abs_time, occur_start, occur_end);
+
+               e_cal_component_alarm_free (alarm);
        }
 
-       e_cal_component_free_datetime (&dt_start);
-       e_cal_component_free_datetime (&dt_end);
+       e_cal_component_datetime_free (dtstart);
+       e_cal_component_datetime_free (dtend);
 }
 
 /* Compares two alarm instances; called from g_slist_sort() */
@@ -588,13 +630,17 @@ compare_alarm_instance (gconstpointer a,
                         gconstpointer b)
 {
        const ECalComponentAlarmInstance *aia, *aib;
+       time_t atime, btime;
 
        aia = a;
        aib = b;
 
-       if (aia->trigger < aib->trigger)
+       atime = e_cal_component_alarm_instance_get_time (aia);
+       btime = e_cal_component_alarm_instance_get_time (aib);
+
+       if (atime < btime)
                return -1;
-       else if (aia->trigger > aib->trigger)
+       else if (atime > btime)
                return 1;
        else
                return 0;
@@ -612,35 +658,36 @@ compare_alarm_instance (gconstpointer a,
  * @default_timezone: The timezone used to resolve DATE and floating DATE-TIME
  * values.
  *
- * Generates alarm instances for a calendar component.  Returns the instances
+ * Generates alarm instances for a calendar component. Returns the instances
  * structure, or %NULL if no alarm instances occurred in the specified time
- * range.
+ * range. Free the returned structure with e_cal_component_alarms_free(),
+ * when no longer needed.
  *
- * Returns: (allow-none) (transfer full): a list of all the alarms found for the
- * given component in the given time range. The list of alarms should be freed
- * by using e_cal_component_alarms_free().
+ * Returns: (transfer full) (nullable): a list of all the alarms found
+ *    for the given component in the given time range.
  */
 ECalComponentAlarms *
 e_cal_util_generate_alarms_for_comp (ECalComponent *comp,
                                      time_t start,
                                      time_t end,
                                      ECalComponentAlarmAction *omit,
-                                     ECalRecurResolveTimezoneFn resolve_tzid,
+                                     ECalRecurResolveTimezoneCb resolve_tzid,
                                      gpointer user_data,
-                                     icaltimezone *default_timezone)
+                                     ICalTimezone *default_timezone)
 {
-       GList *alarm_uids;
+       GSList *alarm_uids;
        time_t alarm_start, alarm_end;
        struct alarm_occurrence_data aod;
+       ICalTimetype *alarm_start_tt, *alarm_end_tt;
        ECalComponentAlarms *alarms;
 
        if (!e_cal_component_has_alarms (comp))
                return NULL;
 
        alarm_uids = e_cal_component_get_alarm_uids (comp);
-       compute_alarm_range (
-               comp, alarm_uids, start, end, &alarm_start, &alarm_end);
+       compute_alarm_range (comp, alarm_uids, start, end, &alarm_start, &alarm_end);
 
+       aod.comp = comp;
        aod.alarm_uids = alarm_uids;
        aod.start = start;
        aod.end = end;
@@ -648,27 +695,30 @@ e_cal_util_generate_alarms_for_comp (ECalComponent *comp,
        aod.triggers = NULL;
        aod.n_triggers = 0;
 
-       e_cal_recur_generate_instances (
-               comp, alarm_start, alarm_end,
+       alarm_start_tt = i_cal_time_from_timet_with_zone (alarm_start, FALSE, i_cal_timezone_get_utc_timezone 
());
+       alarm_end_tt = i_cal_time_from_timet_with_zone (alarm_end, FALSE, i_cal_timezone_get_utc_timezone ());
+
+       e_cal_recur_generate_instances_sync (e_cal_component_get_icalcomponent (comp),
+               alarm_start_tt, alarm_end_tt,
                add_alarm_occurrences_cb, &aod,
                resolve_tzid, user_data,
-               default_timezone);
+               default_timezone, NULL, NULL);
+
+       g_clear_object (&alarm_start_tt);
+       g_clear_object (&alarm_end_tt);
 
        /* We add the ABSOLUTE triggers separately */
-       generate_absolute_triggers (
-               comp, &aod, resolve_tzid, user_data, default_timezone);
+       generate_absolute_triggers (comp, &aod, resolve_tzid, user_data, default_timezone);
 
-       cal_obj_uid_list_free (alarm_uids);
+       g_slist_free_full (alarm_uids, g_free);
 
        if (aod.n_triggers == 0)
                return NULL;
 
        /* Create the component alarm instances structure */
 
-       alarms = g_new (ECalComponentAlarms, 1);
-       alarms->comp = comp;
-       g_object_ref (G_OBJECT (alarms->comp));
-       alarms->alarms = g_slist_sort (aod.triggers, compare_alarm_instance);
+       alarms = e_cal_component_alarms_new (comp);
+       e_cal_component_alarms_take_instances (alarms, g_slist_sort (aod.triggers, compare_alarm_instance));
 
        return alarms;
 }
@@ -688,7 +738,9 @@ e_cal_util_generate_alarms_for_comp (ECalComponent *comp,
  * values.
  *
  * Iterates through all the components in the @comps list and generates alarm
- * instances for them; putting them in the @comp_alarms list.
+ * instances for them; putting them in the @comp_alarms list. Free the @comp_alarms
+ * with g_slist_free_full (comp_alarms, e_cal_component_alarms_free);, when
+ * no longer neeed.
  *
  * Returns: the number of elements it added to the list
  */
@@ -698,9 +750,9 @@ e_cal_util_generate_alarms_for_list (GList *comps,
                                      time_t end,
                                      ECalComponentAlarmAction *omit,
                                      GSList **comp_alarms,
-                                     ECalRecurResolveTimezoneFn resolve_tzid,
+                                     ECalRecurResolveTimezoneCb resolve_tzid,
                                      gpointer user_data,
-                                     icaltimezone *default_timezone)
+                                     ICalTimezone *default_timezone)
 {
        GList *l;
        gint n;
@@ -856,41 +908,45 @@ e_cal_util_seconds_to_string (gint64 seconds)
 
 /* callback for icalcomponent_foreach_tzid */
 typedef struct {
-       icalcomponent *vcal_comp;
-       icalcomponent *icalcomp;
+       ICalComponent *vcal_comp;
+       ICalComponent *icalcomp;
 } ForeachTzidData;
 
 static void
-add_timezone_cb (icalparameter *param,
-                 gpointer data)
+add_timezone_cb (ICalParameter *param,
+                 gpointer user_data)
 {
-       icaltimezone *tz;
+       ICalTimezone *tz;
        const gchar *tzid;
-       icalcomponent *vtz_comp;
-       ForeachTzidData *f_data = (ForeachTzidData *) data;
+       ICalComponent *vtz_comp;
+       ForeachTzidData *f_data = user_data;
 
-       tzid = icalparameter_get_tzid (param);
+       tzid = i_cal_parameter_get_tzid (param);
        if (!tzid)
                return;
 
-       tz = icalcomponent_get_timezone (f_data->vcal_comp, tzid);
-       if (tz)
+       tz = i_cal_component_get_timezone (f_data->vcal_comp, tzid);
+       if (tz) {
+               g_object_unref (tz);
                return;
+       }
 
-       tz = icalcomponent_get_timezone (f_data->icalcomp, tzid);
+       tz = i_cal_component_get_timezone (f_data->icalcomp, tzid);
        if (!tz) {
-               tz = icaltimezone_get_builtin_timezone_from_tzid (tzid);
+               tz = i_cal_timezone_get_builtin_timezone_from_tzid (tzid);
                if (!tz)
                        return;
+
+               g_object_ref (tz);
        }
 
-       vtz_comp = icaltimezone_get_component (tz);
-       if (!vtz_comp)
-               return;
+       vtz_comp = i_cal_timezone_get_component (tz);
+       if (vtz_comp) {
+               i_cal_component_take_component (f_data->vcal_comp, i_cal_component_new_clone (vtz_comp));
+               g_object_unref (vtz_comp);
+       }
 
-       icalcomponent_add_component (
-               f_data->vcal_comp,
-               icalcomponent_new_clone (vtz_comp));
+       g_object_unref (tz);
 }
 
 /**
@@ -902,8 +958,8 @@ add_timezone_cb (icalparameter *param,
  * in the given @icalcomp.
  */
 void
-e_cal_util_add_timezones_from_component (icalcomponent *vcal_comp,
-                                         icalcomponent *icalcomp)
+e_cal_util_add_timezones_from_component (ICalComponent *vcal_comp,
+                                        ICalComponent *icalcomp)
 {
        ForeachTzidData f_data;
 
@@ -912,103 +968,122 @@ e_cal_util_add_timezones_from_component (icalcomponent *vcal_comp,
 
        f_data.vcal_comp = vcal_comp;
        f_data.icalcomp = icalcomp;
-       icalcomponent_foreach_tzid (icalcomp, add_timezone_cb, &f_data);
+       i_cal_component_foreach_tzid (icalcomp, add_timezone_cb, &f_data);
+}
+
+/**
+ * e_cal_util_component_has_property:
+ * @icalcomp: an #ICalComponent
+ * @prop_kind: a property kind to look for, as an %ICalPropertyKind
+ *
+ * Returns, whether the @icalcomp has a property of @prop_kind. To check
+ * for a specific X property use e_cal_util_component_has_x_property().
+ *
+ * Returns: whether the @icalcomp has a property of @prop_kind
+ *
+ * Since: 3.36
+ **/
+gboolean
+e_cal_util_component_has_property (ICalComponent *icalcomp,
+                                  ICalPropertyKind prop_kind)
+{
+       ICalProperty *prop;
+
+       g_return_val_if_fail (I_CAL_IS_COMPONENT (icalcomp), FALSE);
+
+       prop = i_cal_component_get_first_property (icalcomp, prop_kind);
+
+       if (!prop)
+               return FALSE;
+
+       g_object_unref (prop);
+
+       return TRUE;
 }
 
 /**
  * e_cal_util_component_is_instance:
- * @icalcomp: An #icalcomponent.
+ * @icalcomp: An #ICalComponent.
  *
- * Checks whether an #icalcomponent is an instance of a recurring appointment.
+ * Checks whether an #ICalComponent is an instance of a recurring appointment.
  *
  * Returns: TRUE if it is an instance, FALSE if not.
  */
 gboolean
-e_cal_util_component_is_instance (icalcomponent *icalcomp)
+e_cal_util_component_is_instance (ICalComponent *icalcomp)
 {
-       icalproperty *prop;
-
        g_return_val_if_fail (icalcomp != NULL, FALSE);
 
-       prop = icalcomponent_get_first_property (
-               icalcomp, ICAL_RECURRENCEID_PROPERTY);
-
-       return (prop != NULL);
+       return e_cal_util_component_has_property (icalcomp, I_CAL_RECURRENCEID_PROPERTY);
 }
 
 /**
  * e_cal_util_component_has_alarms:
- * @icalcomp: An #icalcomponent.
+ * @icalcomp: An #ICalComponent.
  *
- * Checks whether an #icalcomponent has any alarm.
+ * Checks whether an #ICalComponent has any alarm.
  *
  * Returns: TRUE if it has alarms, FALSE otherwise.
  */
 gboolean
-e_cal_util_component_has_alarms (icalcomponent *icalcomp)
+e_cal_util_component_has_alarms (ICalComponent *icalcomp)
 {
-       icalcomponent *alarm;
+       ICalComponent *alarm;
 
        g_return_val_if_fail (icalcomp != NULL, FALSE);
 
-       alarm = icalcomponent_get_first_component (
-               icalcomp, ICAL_VALARM_COMPONENT);
+       alarm = i_cal_component_get_first_component (icalcomp, I_CAL_VALARM_COMPONENT);
+
+       if (!alarm)
+               return FALSE;
+
+       g_object_unref (alarm);
 
-       return (alarm != NULL);
+       return TRUE;
 }
 
 /**
  * e_cal_util_component_has_organizer:
- * @icalcomp: An #icalcomponent.
+ * @icalcomp: An #ICalComponent.
  *
- * Checks whether an #icalcomponent has an organizer.
+ * Checks whether an #ICalComponent has an organizer.
  *
  * Returns: TRUE if there is an organizer, FALSE if not.
  */
 gboolean
-e_cal_util_component_has_organizer (icalcomponent *icalcomp)
+e_cal_util_component_has_organizer (ICalComponent *icalcomp)
 {
-       icalproperty *prop;
-
        g_return_val_if_fail (icalcomp != NULL, FALSE);
 
-       prop = icalcomponent_get_first_property (
-               icalcomp, ICAL_ORGANIZER_PROPERTY);
-
-       return (prop != NULL);
+       return e_cal_util_component_has_property (icalcomp, I_CAL_ORGANIZER_PROPERTY);
 }
 
 /**
  * e_cal_util_component_has_attendee:
- * @icalcomp: An #icalcomponent.
+ * @icalcomp: An #ICalComponent.
  *
- * Checks if an #icalcomponent has any attendees.
+ * Checks if an #ICalComponent has any attendees.
  *
  * Returns: TRUE if there are attendees, FALSE if not.
  */
 gboolean
-e_cal_util_component_has_attendee (icalcomponent *icalcomp)
+e_cal_util_component_has_attendee (ICalComponent *icalcomp)
 {
-       icalproperty *prop;
-
        g_return_val_if_fail (icalcomp != NULL, FALSE);
 
-       prop = icalcomponent_get_first_property (
-               icalcomp, ICAL_ATTENDEE_PROPERTY);
-
-       return (prop != NULL);
+       return e_cal_util_component_has_property (icalcomp, I_CAL_ATTENDEE_PROPERTY);
 }
 
 /**
  * e_cal_util_component_has_recurrences:
- * @icalcomp: An #icalcomponent.
+ * @icalcomp: An #ICalComponent.
  *
- * Checks if an #icalcomponent has recurrence dates or rules.
+ * Checks if an #ICalComponent has recurrence dates or rules.
  *
  * Returns: TRUE if there are recurrence dates/rules, FALSE if not.
  */
 gboolean
-e_cal_util_component_has_recurrences (icalcomponent *icalcomp)
+e_cal_util_component_has_recurrences (ICalComponent *icalcomp)
 {
        g_return_val_if_fail (icalcomp != NULL, FALSE);
 
@@ -1018,100 +1093,34 @@ e_cal_util_component_has_recurrences (icalcomponent *icalcomp)
 
 /**
  * e_cal_util_component_has_rdates:
- * @icalcomp: An #icalcomponent.
+ * @icalcomp: An #ICalComponent.
  *
- * Checks if an #icalcomponent has recurrence dates.
+ * Checks if an #ICalComponent has recurrence dates.
  *
  * Returns: TRUE if there are recurrence dates, FALSE if not.
  */
 gboolean
-e_cal_util_component_has_rdates (icalcomponent *icalcomp)
+e_cal_util_component_has_rdates (ICalComponent *icalcomp)
 {
-       icalproperty *prop;
-
        g_return_val_if_fail (icalcomp != NULL, FALSE);
 
-       prop = icalcomponent_get_first_property (
-               icalcomp, ICAL_RDATE_PROPERTY);
-
-       return (prop != NULL);
+       return e_cal_util_component_has_property (icalcomp, I_CAL_RDATE_PROPERTY);
 }
 
 /**
  * e_cal_util_component_has_rrules:
- * @icalcomp: An #icalcomponent.
+ * @icalcomp: An #ICalComponent.
  *
- * Checks if an #icalcomponent has recurrence rules.
+ * Checks if an #ICalComponent has recurrence rules.
  *
  * Returns: TRUE if there are recurrence rules, FALSE if not.
  */
 gboolean
-e_cal_util_component_has_rrules (icalcomponent *icalcomp)
+e_cal_util_component_has_rrules (ICalComponent *icalcomp)
 {
-       icalproperty *prop;
-
        g_return_val_if_fail (icalcomp != NULL, FALSE);
 
-       prop = icalcomponent_get_first_property (
-               icalcomp, ICAL_RRULE_PROPERTY);
-
-       return (prop != NULL);
-}
-
-/**
- * e_cal_util_event_dates_match:
- * @icalcomp1: An #icalcomponent.
- * @icalcomp2: An #icalcomponent.
- *
- * Compare the dates of two #icalcomponent's to check if they match.
- *
- * Returns: TRUE if the dates of both components match, FALSE otherwise.
- */
-gboolean
-e_cal_util_event_dates_match (icalcomponent *icalcomp1,
-                              icalcomponent *icalcomp2)
-{
-       struct icaltimetype c1_dtstart, c1_dtend, c2_dtstart, c2_dtend;
-
-       g_return_val_if_fail (icalcomp1 != NULL, FALSE);
-       g_return_val_if_fail (icalcomp2 != NULL, FALSE);
-
-       c1_dtstart = icalcomponent_get_dtstart (icalcomp1);
-       c1_dtend = icalcomponent_get_dtend (icalcomp1);
-       c2_dtstart = icalcomponent_get_dtstart (icalcomp2);
-       c2_dtend = icalcomponent_get_dtend (icalcomp2);
-
-       /* if either value is NULL, they must both be NULL to match */
-       if (icaltime_is_valid_time (c1_dtstart) || icaltime_is_valid_time (c2_dtstart)) {
-               if (!(icaltime_is_valid_time (c1_dtstart) && icaltime_is_valid_time (c2_dtstart)))
-                       return FALSE;
-       } else {
-               if (icaltime_compare (c1_dtstart, c2_dtstart))
-                       return FALSE;
-       }
-
-       if (icaltime_is_valid_time (c1_dtend) || icaltime_is_valid_time (c2_dtend)) {
-               if (!(icaltime_is_valid_time (c1_dtend) && icaltime_is_valid_time (c2_dtend)))
-                       return FALSE;
-       } else {
-               if (icaltime_compare (c1_dtend, c2_dtend))
-                       return FALSE;
-       }
-
-       /* now match the timezones */
-       if (!(!c1_dtstart.zone && !c2_dtstart.zone) ||
-           (c1_dtstart.zone && c2_dtstart.zone &&
-            !strcmp (icaltimezone_get_tzid ((icaltimezone *) c1_dtstart.zone),
-                     icaltimezone_get_tzid ((icaltimezone *) c2_dtstart.zone))))
-               return FALSE;
-
-       if (!(!c1_dtend.zone && !c2_dtend.zone) ||
-           (c1_dtend.zone && c2_dtend.zone &&
-            !strcmp (icaltimezone_get_tzid ((icaltimezone *) c1_dtend.zone),
-                     icaltimezone_get_tzid ((icaltimezone *) c2_dtend.zone))))
-               return FALSE;
-
-       return TRUE;
+       return e_cal_util_component_has_property (icalcomp, I_CAL_RRULE_PROPERTY);
 }
 
 /* Individual instances management */
@@ -1122,67 +1131,72 @@ struct instance_data {
 };
 
 static void
-check_instance (icalcomponent *comp,
-                struct icaltime_span *span,
-                gpointer data)
+check_instance (ICalComponent *comp,
+               ICalTimeSpan *span,
+               gpointer user_data)
 {
-       struct instance_data *instance = data;
+       struct instance_data *instance = user_data;
 
-       if (span->start == instance->start)
+       if (i_cal_time_span_get_start (span) == instance->start)
                instance->found = TRUE;
 }
 
 /**
  * e_cal_util_construct_instance:
- * @icalcomp: A recurring #icalcomponent
+ * @icalcomp: A recurring #ICalComponent
  * @rid: The RECURRENCE-ID to construct a component for
  *
  * This checks that @rid indicates a valid recurrence of @icalcomp, and
- * if so, generates a copy of @comp containing a RECURRENCE-ID of @rid.
+ * if so, generates a copy of @icalcomp containing a RECURRENCE-ID of @rid.
  *
- * Returns: the instance, or %NULL.
+ * Free the returned non-NULL component with g_object_unref(), when
+ * no longer needed.
+ *
+ * Returns: (transfer full) (nullable): the instance as a new #ICalComponent, or %NULL.
  **/
-icalcomponent *
-e_cal_util_construct_instance (icalcomponent *icalcomp,
-                               struct icaltimetype rid)
+ICalComponent *
+e_cal_util_construct_instance (ICalComponent *icalcomp,
+                              const ICalTimetype *rid)
 {
        struct instance_data instance;
-       struct icaltimetype start, end;
+       ICalTimetype *start, *end;
 
        g_return_val_if_fail (icalcomp != NULL, NULL);
 
        /* Make sure this is really recurring */
-       if (!icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY) &&
-           !icalcomponent_get_first_property (icalcomp, ICAL_RDATE_PROPERTY))
+       if (!e_cal_util_component_has_recurrences (icalcomp))
                return NULL;
 
        /* Make sure the specified instance really exists */
-       start = icaltime_convert_to_zone (rid, icaltimezone_get_utc_timezone ());
-       end = start;
-       icaltime_adjust (&end, 0, 0, 0, 1);
+       start = i_cal_time_convert_to_zone ((ICalTimetype *) rid, i_cal_timezone_get_utc_timezone ());
+       end = i_cal_timetype_new_clone (start);
+       i_cal_time_adjust (end, 0, 0, 0, 1);
 
-       instance.start = icaltime_as_timet (start);
+       instance.start = i_cal_time_as_timet (start);
        instance.found = FALSE;
-       icalcomponent_foreach_recurrence (icalcomp, start, end,
-                                         check_instance, &instance);
+       i_cal_component_foreach_recurrence (icalcomp, start, end, check_instance, &instance);
+
+       g_object_unref (start);
+       g_object_unref (end);
+
        if (!instance.found)
                return NULL;
 
        /* Make the instance */
-       icalcomp = icalcomponent_new_clone (icalcomp);
-       icalcomponent_set_recurrenceid (icalcomp, rid);
+       icalcomp = i_cal_component_new_clone (icalcomp);
+       i_cal_component_set_recurrenceid (icalcomp, (ICalTimetype *) rid);
 
        return icalcomp;
 }
 
 static inline gboolean
-time_matches_rid (struct icaltimetype itt,
-                  struct icaltimetype rid,
+time_matches_rid (const ICalTimetype *itt,
+                  const ICalTimetype *rid,
                   ECalObjModType mod)
 {
        gint compare;
 
-       compare = icaltime_compare (itt, rid);
+       compare = i_cal_time_compare ((ICalTimetype *) itt, (ICalTimetype *) rid);
        if (compare == 0)
                return TRUE;
        else if (compare < 0 && (mod & E_CAL_OBJ_MOD_THIS_AND_PRIOR))
@@ -1194,169 +1208,220 @@ time_matches_rid (struct icaltimetype itt,
 }
 
 static void
-e_cal_util_remove_instances_ex (icalcomponent *icalcomp,
-                               struct icaltimetype rid,
+e_cal_util_remove_instances_ex (ICalComponent *icalcomp,
+                               const ICalTimetype *rid,
                                ECalObjModType mod,
                                gboolean keep_rid,
                                gboolean can_add_exrule)
 {
-       icalproperty *prop;
-       struct icaltimetype itt, recur;
-       struct icalrecurrencetype rule;
-       icalrecur_iterator *iter;
+       ICalProperty *prop;
+       ICalTimetype *itt, *recur;
+       ICalRecurrenceType *rule;
+       ICalRecurIterator *iter;
        GSList *remove_props = NULL, *rrules = NULL, *link;
 
        g_return_if_fail (icalcomp != NULL);
        g_return_if_fail (mod != E_CAL_OBJ_MOD_ALL);
 
        /* First remove RDATEs and EXDATEs in the indicated range. */
-       for (prop = icalcomponent_get_first_property (icalcomp, ICAL_RDATE_PROPERTY);
+       for (prop = i_cal_component_get_first_property (icalcomp, I_CAL_RDATE_PROPERTY);
             prop;
-            prop = icalcomponent_get_next_property (icalcomp, ICAL_RDATE_PROPERTY)) {
-               struct icaldatetimeperiodtype period;
+            g_object_unref (prop), prop = i_cal_component_get_next_property (icalcomp, 
I_CAL_RDATE_PROPERTY)) {
+               ICalDatetimeperiodType *period;
+               ICalTimetype *period_time;
+
+               period = i_cal_property_get_rdate (prop);
+               if (!period)
+                       continue;
+
+               period_time = i_cal_datetimeperiod_type_get_time (period);
 
-               period = icalproperty_get_rdate (prop);
-               if (time_matches_rid (period.time, rid, mod) && (!keep_rid ||
-                   icaltime_compare (period.time, rid) != 0))
-                       remove_props = g_slist_prepend (remove_props, prop);
+               if (time_matches_rid (period_time, rid, mod) && (!keep_rid ||
+                   i_cal_time_compare (period_time, (ICalTimetype *) rid) != 0))
+                       remove_props = g_slist_prepend (remove_props, g_object_ref (prop));
+
+               g_clear_object (&period_time);
+               g_object_unref (period);
        }
-       for (prop = icalcomponent_get_first_property (icalcomp, ICAL_EXDATE_PROPERTY);
+
+       for (prop = i_cal_component_get_first_property (icalcomp, I_CAL_EXDATE_PROPERTY);
             prop;
-            prop = icalcomponent_get_next_property (icalcomp, ICAL_EXDATE_PROPERTY)) {
-               itt = icalproperty_get_exdate (prop);
-               if (time_matches_rid (itt, rid, mod) && (!keep_rid ||
-                   icaltime_compare (itt, rid) != 0))
-                       remove_props = g_slist_prepend (remove_props, prop);
+            g_object_unref (prop), prop = i_cal_component_get_next_property (icalcomp, 
I_CAL_EXDATE_PROPERTY)) {
+               itt = i_cal_property_get_exdate (prop);
+               if (!itt)
+                       continue;
+
+               if (time_matches_rid (itt, rid, mod) && (!keep_rid || i_cal_time_compare (itt, (ICalTimetype 
*) rid) != 0))
+                       remove_props = g_slist_prepend (remove_props, g_object_ref (prop));
+
+               g_object_unref (itt);
        }
 
        for (link = remove_props; link; link = g_slist_next (link)) {
                prop = link->data;
 
-               icalcomponent_remove_property (icalcomp, prop);
+               i_cal_component_remove_property (icalcomp, prop);
        }
 
-       g_slist_free (remove_props);
+       g_slist_free_full (remove_props, g_object_unref);
        remove_props = NULL;
 
        /* If we're only removing one instance, just add an EXDATE. */
        if (mod == E_CAL_OBJ_MOD_THIS) {
-               prop = icalproperty_new_exdate (rid);
-               icalcomponent_add_property (icalcomp, prop);
+               prop = i_cal_property_new_exdate ((ICalTimetype *) rid);
+               i_cal_component_take_property (icalcomp, prop);
                return;
        }
 
        /* Otherwise, iterate through RRULEs */
        /* FIXME: this may generate duplicate EXRULEs */
-       for (prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
+       for (prop = i_cal_component_get_first_property (icalcomp, I_CAL_RRULE_PROPERTY);
             prop;
-            prop = icalcomponent_get_next_property (icalcomp, ICAL_RRULE_PROPERTY)) {
-               rrules = g_slist_prepend (rrules, prop);
+            g_object_unref (prop), prop = i_cal_component_get_next_property (icalcomp, 
I_CAL_RRULE_PROPERTY)) {
+               rrules = g_slist_prepend (rrules, g_object_ref (prop));
        }
 
        for (link = rrules; link; link = g_slist_next (link)) {
                prop = link->data;
-               rule = icalproperty_get_rrule (prop);
 
-               iter = icalrecur_iterator_new (rule, rid);
-               recur = icalrecur_iterator_next (iter);
+               rule = i_cal_property_get_rrule (prop);
+               if (!rule)
+                       continue;
+
+               iter = i_cal_recur_iterator_new (rule, (ICalTimetype *) rid);
+               recur = i_cal_recur_iterator_next (iter);
+
+               if (!recur) {
+                       g_object_unref (rule);
+                       g_object_unref (iter);
+                       continue;
+               }
 
                if (mod & E_CAL_OBJ_MOD_THIS_AND_FUTURE) {
                        /* Truncate the rule at rid. */
-                       if (!icaltime_is_null_time (recur)) {
+                       if (!i_cal_time_is_null_time (recur)) {
+                               gint rule_count = i_cal_recurrence_type_get_count (rule);
+
                                /* Use count if it was used */
-                               if (rule.count > 0) {
+                               if (rule_count > 0) {
                                        gint occurrences_count = 0;
-                                       icalrecur_iterator *count_iter;
-                                       struct icaltimetype count_recur;
-
-                                       count_iter = icalrecur_iterator_new (rule, icalcomponent_get_dtstart 
(icalcomp));
-                                       while (count_recur = icalrecur_iterator_next (count_iter), 
!icaltime_is_null_time (count_recur) && occurrences_count < rule.count) {
-                                               if (icaltime_compare (count_recur, rid) >= 0)
+                                       ICalRecurIterator *count_iter;
+                                       ICalTimetype *count_recur, *dtstart;
+
+                                       dtstart = i_cal_component_get_dtstart (icalcomp);
+                                       count_iter = i_cal_recur_iterator_new (rule, dtstart);
+                                       while (count_recur = i_cal_recur_iterator_next (count_iter),
+                                              count_recur && !i_cal_time_is_null_time (count_recur) && 
occurrences_count < rule_count) {
+                                               if (i_cal_time_compare (count_recur, (ICalTimetype *) rid) >= 
0)
                                                        break;
 
                                                occurrences_count++;
+                                               g_object_unref (count_recur);
                                        }
 
-                                       icalrecur_iterator_free (count_iter);
-
-                                       if (keep_rid && icaltime_compare (count_recur, rid) == 0)
+                                       if (keep_rid && count_recur && i_cal_time_compare (count_recur, 
(ICalTimetype *) rid) == 0)
                                                occurrences_count++;
 
                                        /* The caller should make sure that the remove will keep at least one 
instance */
                                        g_warn_if_fail (occurrences_count > 0);
 
-                                       rule.count = occurrences_count;
+                                       i_cal_recurrence_type_set_count (rule, occurrences_count);
+
+                                       g_clear_object (&count_recur);
+                                       g_clear_object (&count_iter);
+                                       g_clear_object (&dtstart);
                                } else {
-                                       if (keep_rid && icaltime_compare (recur, rid) == 0)
-                                               rule.until = icaltime_add (rid, icalcomponent_get_duration 
(icalcomp));
-                                       else
-                                               rule.until = rid;
-                                       icaltime_adjust (&rule.until, 0, 0, 0, -1);
+                                       ICalTimetype *ttuntil;
+
+                                       if (keep_rid && i_cal_time_compare (recur, (ICalTimetype *) rid) == 
0) {
+                                               ICalDurationType *dur;
+
+                                               dur = i_cal_component_get_duration (icalcomp);
+                                               ttuntil = i_cal_time_add ((ICalTimetype *) rid, dur);
+                                               g_clear_object (&dur);
+                                       } else {
+                                               ttuntil = i_cal_timetype_new_clone (rid);
+                                       }
+                                       i_cal_time_adjust (ttuntil, 0, 0, 0, -1);
+                                       i_cal_recurrence_type_set_until (rule, ttuntil);
+                                       g_object_unref (ttuntil);
                                }
 
-                               icalproperty_set_rrule (prop, rule);
-                               icalproperty_remove_parameter_by_name (prop, "X-EVOLUTION-ENDDATE");
+                               i_cal_property_set_rrule (prop, rule);
+                               i_cal_property_remove_parameter_by_name (prop, 
E_CAL_EVOLUTION_ENDDATE_PARAMETER);
                        }
                } else {
                        /* (If recur == rid, skip to the next occurrence) */
-                       if (!keep_rid && icaltime_compare (recur, rid) == 0)
-                               recur = icalrecur_iterator_next (iter);
+                       if (!keep_rid && i_cal_time_compare (recur, (ICalTimetype *) rid) == 0) {
+                               g_object_unref (recur);
+                               recur = i_cal_recur_iterator_next (iter);
+                       }
 
                        /* If there is a recurrence after rid, add
                         * an EXRULE to block instances up to rid.
                         * Otherwise, just remove the RRULE.
                         */
-                       if (!icaltime_is_null_time (recur)) {
+                       if (!i_cal_time_is_null_time (recur)) {
                                if (can_add_exrule) {
-                                       rule.count = 0;
+                                       ICalTimetype *ttuntil;
+                                       ICalDurationType *dur = i_cal_component_get_duration (icalcomp);
+
+                                       i_cal_recurrence_type_set_count (rule, 0);
+
                                        /* iCalendar says we should just use rid
                                         * here, but Outlook/Exchange handle
                                         * UNTIL incorrectly.
                                         */
-                                       if (keep_rid && icaltime_compare (recur, rid) == 0) {
-                                               struct icaldurationtype duration = icalcomponent_get_duration 
(icalcomp);
-                                               duration.is_neg = !duration.is_neg;
-                                               rule.until = icaltime_add (rid, duration);
-                                       } else
-                                               rule.until = icaltime_add (rid, icalcomponent_get_duration 
(icalcomp));
-                                       prop = icalproperty_new_exrule (rule);
-                                       icalcomponent_add_property (icalcomp, prop);
+                                       if (keep_rid && i_cal_time_compare (recur, (ICalTimetype *) rid) == 
0) {
+                                               i_cal_duration_type_set_is_neg (dur, 
!i_cal_duration_type_is_neg (dur));
+                                               ttuntil = i_cal_time_add ((ICalTimetype *) rid, dur);
+                                       } else {
+                                               ttuntil = i_cal_time_add ((ICalTimetype *) rid, dur);
+                                       }
+
+                                       i_cal_recurrence_type_set_until (rule, ttuntil);
+
+                                       g_clear_object (&ttuntil);
+                                       g_clear_object (&dur);
+
+                                       prop = i_cal_property_new_exrule (rule);
+                                       i_cal_component_take_property (icalcomp, prop);
                                }
                        } else {
-                               remove_props = g_slist_prepend (remove_props, prop);
+                               remove_props = g_slist_prepend (remove_props, g_object_ref (prop));
                        }
                }
 
-               icalrecur_iterator_free (iter);
+               g_object_unref (recur);
+               g_object_unref (rule);
+               g_object_unref (iter);
        }
 
        for (link = remove_props; link; link = g_slist_next (link)) {
                prop = link->data;
 
-               icalcomponent_remove_property (icalcomp, prop);
+               i_cal_component_remove_property (icalcomp, prop);
        }
 
-       g_slist_free (remove_props);
-       g_slist_free (rrules);
+       g_slist_free_full (remove_props, g_object_unref);
+       g_slist_free_full (rrules, g_object_unref);
 }
 
 /**
  * e_cal_util_remove_instances:
- * @icalcomp: A (recurring) #icalcomponent
+ * @icalcomp: A (recurring) #ICalComponent
  * @rid: The base RECURRENCE-ID to remove
  * @mod: How to interpret @rid
  *
- * Removes one or more instances from @comp according to @rid and @mod.
- *
- * FIXME: should probably have a return value indicating whether @icalcomp
- *        still has any instances
+ * Removes one or more instances from @icalcomp according to @rid and @mod.
  **/
 void
-e_cal_util_remove_instances (icalcomponent *icalcomp,
-                             struct icaltimetype rid,
+e_cal_util_remove_instances (ICalComponent *icalcomp,
+                             const ICalTimetype *rid,
                              ECalObjModType mod)
 {
        g_return_if_fail (icalcomp != NULL);
+       g_return_if_fail (rid != NULL);
        g_return_if_fail (mod != E_CAL_OBJ_MOD_ALL);
 
        e_cal_util_remove_instances_ex (icalcomp, rid, mod, FALSE, TRUE);
@@ -1364,11 +1429,11 @@ e_cal_util_remove_instances (icalcomponent *icalcomp,
 
 /**
  * e_cal_util_split_at_instance:
- * @icalcomp: A (recurring) #icalcomponent
+ * @icalcomp: A (recurring) #ICalComponent
  * @rid: The base RECURRENCE-ID to remove
- * @master_dtstart: The DTSTART of the master object
+ * @master_dtstart: (nullable): The DTSTART of the master object
  *
- * Splits a recurring @icalcomp into two at time @rid. The returned icalcomponent
+ * Splits a recurring @icalcomp into two at time @rid. The returned #ICalComponent
  * is modified @icalcomp which contains recurrences beginning at @rid, inclusive.
  * The instance identified by @rid should exist. The @master_dtstart can be
  * a null time, then it is read from the @icalcomp.
@@ -1376,136 +1441,187 @@ e_cal_util_remove_instances (icalcomponent *icalcomp,
  * Use e_cal_util_remove_instances() with E_CAL_OBJ_MOD_THIS_AND_FUTURE mode
  * on the @icalcomp to remove the overlapping interval from it, if needed.
  *
- * Returns: the split icalcomponent, or %NULL.
+ * Free the returned non-NULL component with g_object_unref(), when
+ * done with it.
+ *
+ * Returns: (transfer full) (nullable): the split @icalcom, or %NULL.
  *
  * Since: 3.16
  **/
-icalcomponent *
-e_cal_util_split_at_instance (icalcomponent *icalcomp,
-                             struct icaltimetype rid,
-                             struct icaltimetype master_dtstart)
+ICalComponent *
+e_cal_util_split_at_instance (ICalComponent *icalcomp,
+                             const ICalTimetype *rid,
+                             const ICalTimetype *master_dtstart)
 {
-       icalproperty *prop;
+       ICalProperty *prop;
        struct instance_data instance;
-       struct icaltimetype start, end;
-       struct icaldurationtype duration;
+       ICalTimetype *start, *end, *dtstart = NULL;
+       ICalDurationType *duration;
        GSList *remove_props = NULL, *link;
 
        g_return_val_if_fail (icalcomp != NULL, NULL);
-       g_return_val_if_fail (!icaltime_is_null_time (rid), NULL);
+       g_return_val_if_fail (rid != NULL, NULL);
+       g_return_val_if_fail (!i_cal_time_is_null_time ((ICalTimetype *) rid), NULL);
 
        /* Make sure this is really recurring */
-       if (!icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY) &&
-           !icalcomponent_get_first_property (icalcomp, ICAL_RDATE_PROPERTY))
+       if (!e_cal_util_component_has_recurrences (icalcomp))
                return NULL;
 
        /* Make sure the specified instance really exists */
-       start = icaltime_convert_to_zone (rid, icaltimezone_get_utc_timezone ());
-       end = start;
-       icaltime_adjust (&end, 0, 0, 0, 1);
+       start = i_cal_time_convert_to_zone ((ICalTimetype *) rid, i_cal_timezone_get_utc_timezone ());
+       end = i_cal_timetype_new_clone (start);
+       i_cal_time_adjust (end, 0, 0, 0, 1);
 
-       instance.start = icaltime_as_timet (start);
+       instance.start = i_cal_time_as_timet (start);
        instance.found = FALSE;
-       icalcomponent_foreach_recurrence (icalcomp, start, end,
-                                         check_instance, &instance);
+       i_cal_component_foreach_recurrence (icalcomp, start, end, check_instance, &instance);
+       g_clear_object (&start);
+       g_clear_object (&end);
+
        /* Make the copy */
-       icalcomp = icalcomponent_new_clone (icalcomp);
+       icalcomp = i_cal_component_new_clone (icalcomp);
 
        e_cal_util_remove_instances_ex (icalcomp, rid, E_CAL_OBJ_MOD_THIS_AND_PRIOR, TRUE, FALSE);
 
-       start = rid;
-       if (icaltime_is_null_time (master_dtstart))
-               master_dtstart = icalcomponent_get_dtstart (icalcomp);
-       duration = icalcomponent_get_duration (icalcomp);
+       start = i_cal_timetype_new_clone ((ICalTimetype *) rid);
+
+       if (!master_dtstart || i_cal_time_is_null_time ((ICalTimetype *) master_dtstart)) {
+               dtstart = i_cal_component_get_dtstart (icalcomp);
+               master_dtstart = dtstart;
+       }
+
+       duration = i_cal_component_get_duration (icalcomp);
 
        /* Expect that DTSTART and DTEND are already set when the instance could not be found */
        if (instance.found) {
-               icalcomponent_set_dtstart (icalcomp, start);
+               ICalTimetype *dtend;
+
+               dtend = i_cal_component_get_dtend (icalcomp);
+
+               i_cal_component_set_dtstart (icalcomp, start);
+
                /* Update either DURATION or DTEND */
-               if (icaltime_is_null_time (icalcomponent_get_dtend (icalcomp))) {
-                       icalcomponent_set_duration (icalcomp, duration);
+               if (i_cal_time_is_null_time (dtend)) {
+                       i_cal_component_set_duration (icalcomp, duration);
                } else {
-                       end = start;
-                       if (duration.is_neg)
-                               icaltime_adjust (&end, -duration.days - 7 * duration.weeks, -duration.hours, 
-duration.minutes, -duration.seconds);
+                       end = i_cal_timetype_new_clone (start);
+                       if (i_cal_duration_type_is_neg (duration))
+                               i_cal_time_adjust (end, -i_cal_duration_type_get_days (duration)
+                                                       - 7 * i_cal_duration_type_get_weeks (duration),
+                                                       -i_cal_duration_type_get_hours (duration),
+                                                       -i_cal_duration_type_get_minutes (duration),
+                                                       -i_cal_duration_type_get_seconds (duration));
                        else
-                               icaltime_adjust (&end, duration.days + 7 * duration.weeks, duration.hours, 
duration.minutes, duration.seconds);
-                       icalcomponent_set_dtend (icalcomp, end);
+                               i_cal_time_adjust (end, i_cal_duration_type_get_days (duration)
+                                                       + 7 * i_cal_duration_type_get_weeks (duration),
+                                                       i_cal_duration_type_get_hours (duration),
+                                                       i_cal_duration_type_get_minutes (duration),
+                                                       i_cal_duration_type_get_seconds (duration));
+
+                       i_cal_component_set_dtend (icalcomp, end);
                }
+
+               g_clear_object (&dtend);
        }
 
+       g_clear_object (&start);
+       g_clear_object (&end);
+       g_clear_object (&duration);
+
        /* any RRULE with 'count' should be shortened */
-       for (prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
+       for (prop = i_cal_component_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
             prop;
-            prop = icalcomponent_get_next_property (icalcomp, ICAL_RRULE_PROPERTY)) {
-               struct icaltimetype recur;
-               struct icalrecurrencetype rule;
+            g_object_unref (prop), prop = i_cal_component_get_next_property (icalcomp, ICAL_RRULE_PROPERTY)) 
{
+               ICalTimetype *recur;
+               ICalRecurrenceType *rule;
+               gint rule_count;
 
-               rule = icalproperty_get_rrule (prop);
+               rule = i_cal_property_get_rrule (prop);
+               if (!rule)
+                       continue;
 
-               if (rule.count != 0) {
+               rule_count = i_cal_recurrence_type_get_count (rule);
+
+               if (rule_count != 0) {
                        gint occurrences_count = 0;
-                       icalrecur_iterator *iter;
+                       ICalRecurIterator *iter;
 
-                       iter = icalrecur_iterator_new (rule, master_dtstart);
-                       while (recur = icalrecur_iterator_next (iter), !icaltime_is_null_time (recur) && 
occurrences_count < rule.count) {
-                               if (icaltime_compare (recur, rid) >= 0)
+                       iter = i_cal_recur_iterator_new (rule, (ICalTimetype *) master_dtstart);
+                       while (recur = i_cal_recur_iterator_next (iter),
+                              recur && !i_cal_time_is_null_time (recur) && occurrences_count < rule_count) {
+                               if (i_cal_time_compare (recur, (ICalTimetype *) rid) >= 0)
                                        break;
 
                                occurrences_count++;
+                               g_object_unref (recur);
                        }
 
-                       icalrecur_iterator_free (iter);
-
-                       if (icaltime_is_null_time (recur)) {
-                               remove_props = g_slist_prepend (remove_props, prop);
+                       if (!recur || i_cal_time_is_null_time (recur)) {
+                               remove_props = g_slist_prepend (remove_props, g_object_ref (prop));
                        } else {
-                               rule.count -= occurrences_count;
-                               icalproperty_set_rrule (prop, rule);
-                               icalproperty_remove_parameter_by_name (prop, "X-EVOLUTION-ENDDATE");
+                               i_cal_recurrence_type_set_count (rule, rule_count - occurrences_count);
+                               i_cal_property_set_rrule (prop, rule);
+                               i_cal_property_remove_parameter_by_name (prop, 
E_CAL_EVOLUTION_ENDDATE_PARAMETER);
                        }
+
+                       g_clear_object (&iter);
+                       g_clear_object (&recur);
                }
+
+               g_object_unref (rule);
        }
 
        for (link = remove_props; link; link = g_slist_next (link)) {
                prop = link->data;
 
-               icalcomponent_remove_property (icalcomp, prop);
+               i_cal_component_remove_property (icalcomp, prop);
        }
 
-       g_slist_free (remove_props);
+       g_slist_free_full (remove_props, g_object_unref);
+       g_clear_object (&dtstart);
 
        return icalcomp;
 }
 
 typedef struct {
-       struct icaltimetype rid;
+       const ICalTimetype *rid;
        gboolean matches;
 } CheckFirstInstanceData;
 
 static gboolean
-check_first_instance_cb (ECalComponent *comp,
-                        time_t instance_start,
-                        time_t instance_end,
-                        gpointer user_data)
+check_first_instance_cb (ICalComponent *icalcomp,
+                        ICalTimetype *instance_start,
+                        ICalTimetype *instance_end,
+                        gpointer user_data,
+                        GCancellable *cancellable,
+                        GError **error)
 {
        CheckFirstInstanceData *ifs = user_data;
-       icalcomponent *icalcomp;
-       struct icaltimetype rid;
+       ICalProperty *prop;
+       ICalTimetype *rid;
 
        g_return_val_if_fail (ifs != NULL, FALSE);
 
-       icalcomp = e_cal_component_get_icalcomponent (comp);
-       if (icalcomponent_get_first_property (icalcomp, ICAL_RECURRENCEID_PROPERTY) != NULL) {
-               rid = icalcomponent_get_recurrenceid (icalcomp);
+       prop = i_cal_component_get_first_property (icalcomp, I_CAL_RECURRENCEID_PROPERTY);
+       if (prop) {
+               rid = i_cal_property_get_recurrenceid (prop);
+               g_object_unref (prop);
        } else {
-               struct icaltimetype dtstart;
+               ICalTimetype *dtstart;
+               ICalTimezone *zone;
 
-               dtstart = icalcomponent_get_dtstart (icalcomp);
-               rid = icaltime_from_timet_with_zone (instance_start, dtstart.is_date, dtstart.zone);
+               dtstart = i_cal_component_get_dtstart (icalcomp);
+               zone = i_cal_timetype_get_zone (dtstart);
+
+               rid = i_cal_time_from_timet_with_zone (i_cal_time_as_timet (instance_start), 
i_cal_time_is_date (dtstart), zone);
+
+               g_clear_object (&zone);
+               g_clear_object (&dtstart);
        }
 
-       ifs->matches = icaltime_compare (ifs->rid, rid) == 0;
+       ifs->matches = i_cal_time_compare ((ICalTimetype *) ifs->rid, rid) == 0;
+
+       g_clear_object (&rid);
 
        return FALSE;
 }
@@ -1514,7 +1630,7 @@ check_first_instance_cb (ECalComponent *comp,
  * e_cal_util_is_first_instance:
  * @comp: an #ECalComponent instance
  * @rid: a recurrence ID
- * @tz_cb: (closure tz_cb_data) (scope call): The #ECalRecurResolveTimezoneFn to call
+ * @tz_cb: (closure tz_cb_data) (scope call): The #ECalRecurResolveTimezoneCb to call
  * @tz_cb_data: (closure): User data to be passed to the @tz_cb callback
  *
  * Returns whether the given @rid is the first instance of
@@ -1526,26 +1642,36 @@ check_first_instance_cb (ECalComponent *comp,
  **/
 gboolean
 e_cal_util_is_first_instance (ECalComponent *comp,
-                             struct icaltimetype rid,
-                             ECalRecurResolveTimezoneFn tz_cb,
+                             const ICalTimetype *rid,
+                             ECalRecurResolveTimezoneCb tz_cb,
                              gpointer tz_cb_data)
 {
        CheckFirstInstanceData ifs;
-       icalcomponent *icalcomp;
-       time_t start, end;
+       ICalComponent *icalcomp;
+       ICalTimetype *start, *end;
 
        g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
-       g_return_val_if_fail (!icaltime_is_null_time (rid), FALSE);
+       g_return_val_if_fail (rid && !i_cal_time_is_null_time ((ICalTimetype *) rid), FALSE);
 
        ifs.rid = rid;
        ifs.matches = FALSE;
 
        icalcomp = e_cal_component_get_icalcomponent (comp);
-       start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp)) - 24 * 60 * 60;
-       end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp)) + 24 * 60 * 60;
 
-       e_cal_recur_generate_instances (comp, start, end, check_first_instance_cb, &ifs,
-               tz_cb, tz_cb_data, icaltimezone_get_utc_timezone ());
+       start = i_cal_component_get_dtstart (icalcomp);
+       i_cal_time_adjust (start, -1, 0, 0, 0);
+
+       end = i_cal_component_get_dtend (icalcomp);
+       i_cal_time_adjust (end, +1, 0, 0, 0);
+
+       e_cal_recur_generate_instances_sync (e_cal_component_get_icalcomponent (comp),
+               start, end,
+               check_first_instance_cb, &ifs,
+               tz_cb, tz_cb_data, i_cal_timezone_get_utc_timezone (),
+               NULL, NULL);
+
+       g_clear_object (&start);
+       g_clear_object (&end);
 
        return ifs.matches;
 }
@@ -1568,19 +1694,19 @@ e_cal_util_get_system_timezone_location (void)
 /**
  * e_cal_util_get_system_timezone:
  *
- * Fetches system timezone icaltimezone object.
+ * Fetches system timezone ICalTimezone object.
  *
  * The returned pointer is part of the built-in timezones and should not be freed.
  *
- * Returns: (transfer none): The icaltimezone object of the system timezone, or %NULL on an error.
+ * Returns: (transfer none) (nullable): The ICalTimezone object of the system timezone, or %NULL on an error.
  *
  * Since: 2.28
  **/
-icaltimezone *
+ICalTimezone *
 e_cal_util_get_system_timezone (void)
 {
        gchar *location;
-       icaltimezone *zone;
+       ICalTimezone *zone;
 
        location = e_cal_system_timezone_get_location ();
 
@@ -1588,7 +1714,7 @@ e_cal_util_get_system_timezone (void)
        if (!location)
                return NULL;
 
-       zone = icaltimezone_get_builtin_timezone (location);
+       zone = i_cal_timezone_get_builtin_timezone (location);
 
        g_free (location);
 
@@ -1597,21 +1723,28 @@ e_cal_util_get_system_timezone (void)
 
 static time_t
 componenttime_to_utc_timet (const ECalComponentDateTime *dt_time,
-                            ECalRecurResolveTimezoneFn tz_cb,
+                            ECalRecurResolveTimezoneCb tz_cb,
                             gpointer tz_cb_data,
-                            const icaltimezone *default_zone)
+                            const ICalTimezone *default_zone)
 {
+       ICalTimetype *value = NULL;
        time_t timet = -1;
-       icaltimezone *zone = NULL;
 
        g_return_val_if_fail (dt_time != NULL, -1);
 
-       if (dt_time->value) {
-               if (dt_time->tzid)
-                       zone = tz_cb (dt_time->tzid, tz_cb_data);
+       if (dt_time)
+               value = e_cal_component_datetime_get_value (dt_time);
+
+       if (value) {
+               ICalTimezone *zone = NULL;
+               const gchar *tzid = e_cal_component_datetime_get_tzid (dt_time);
 
-               timet = icaltime_as_timet_with_zone (
-                       *dt_time->value, zone ? zone : default_zone);
+               if (tzid)
+                       zone = tz_cb (tzid, tz_cb_data, NULL, NULL);
+
+               timet = i_cal_time_as_timet_with_zone (value, zone ? zone : (ICalTimezone *) default_zone);
+
+               g_clear_object (&zone);
        }
 
        return timet;
@@ -1620,12 +1753,12 @@ componenttime_to_utc_timet (const ECalComponentDateTime *dt_time,
 /**
  * e_cal_util_get_component_occur_times:
  * @comp: an #ECalComponent
- * @start: (out): Location to store the start time
- * @end: (out): Location to store the end time
- * @tz_cb: (closure tz_cb_data) (scope call): The #ECalRecurResolveTimezoneFn to call
+ * @out_start: (out): Location to store the start time
+ * @out_end: (out): Location to store the end time
+ * @tz_cb: (closure tz_cb_data) (scope call): The #ECalRecurResolveTimezoneCb to call
  * @tz_cb_data: (closure): User data to be passed to the @tz_cb callback
  * @default_timezone: The default timezone
- * @kind: the type of component, indicated with an icalcomponent_kind
+ * @kind: the type of component, indicated with an #ICalComponentKind
  *
  * Find out when the component starts and stops, being careful about
  * recurrences.
@@ -1634,68 +1767,66 @@ componenttime_to_utc_timet (const ECalComponentDateTime *dt_time,
  **/
 void
 e_cal_util_get_component_occur_times (ECalComponent *comp,
-                                      time_t *start,
-                                      time_t *end,
-                                      ECalRecurResolveTimezoneFn tz_cb,
+                                      time_t *out_start,
+                                      time_t *out_end,
+                                      ECalRecurResolveTimezoneCb tz_cb,
                                       gpointer tz_cb_data,
-                                      const icaltimezone *default_timezone,
-                                      icalcomponent_kind kind)
+                                      const ICalTimezone *default_timezone,
+                                      ICalComponentKind kind)
 {
-       struct icalrecurrencetype ir;
-       ECalComponentDateTime dt_start, dt_end;
+       ICalTimezone *utc_zone;
+       ECalComponentDateTime *dtstart, *dtend;
        time_t duration;
 
        g_return_if_fail (comp != NULL);
-       g_return_if_fail (start != NULL);
-       g_return_if_fail (end != NULL);
+       g_return_if_fail (out_start != NULL);
+       g_return_if_fail (out_end != NULL);
 
-       e_cal_recur_ensure_end_dates (comp, FALSE, tz_cb, tz_cb_data);
+       utc_zone = i_cal_timezone_get_utc_timezone ();
+       e_cal_recur_ensure_end_dates (comp, FALSE, tz_cb, tz_cb_data, NULL, NULL);
 
        /* Get dtstart of the component and convert it to UTC */
-       e_cal_component_get_dtstart (comp, &dt_start);
+       dtstart = e_cal_component_get_dtstart (comp);
 
-       if ((*start = componenttime_to_utc_timet (&dt_start, tz_cb, tz_cb_data, default_timezone)) == -1)
-               *start = _TIME_MIN;
+       if ((*out_start = componenttime_to_utc_timet (dtstart, tz_cb, tz_cb_data, default_timezone)) == -1)
+               *out_start = _TIME_MIN;
 
-       e_cal_component_free_datetime (&dt_start);
+       e_cal_component_datetime_free (dtstart);
 
-       e_cal_component_get_dtend (comp, &dt_end);
-       duration = componenttime_to_utc_timet (&dt_end, tz_cb, tz_cb_data, default_timezone);
-       if (duration <= 0 || *start == _TIME_MIN || *start > duration)
+       dtend = e_cal_component_get_dtend (comp);
+       duration = componenttime_to_utc_timet (dtend, tz_cb, tz_cb_data, default_timezone);
+       if (duration <= 0 || *out_start == _TIME_MIN || *out_start > duration)
                duration = 0;
        else
-               duration = duration - *start;
-       e_cal_component_free_datetime (&dt_end);
+               duration = duration - *out_start;
+       e_cal_component_datetime_free (dtend);
 
        /* find out end date of component */
-       *end = _TIME_MAX;
+       *out_end = _TIME_MAX;
 
-       if (kind == ICAL_VTODO_COMPONENT) {
+       if (kind == I_CAL_VTODO_COMPONENT) {
                /* max from COMPLETED and DUE properties */
-               struct icaltimetype *tt = NULL;
+               ICalTimetype *tt;
                time_t completed_time = -1, due_time = -1, max_time;
-               ECalComponentDateTime dt_due;
+               ECalComponentDateTime *dtdue;
 
-               e_cal_component_get_completed (comp, &tt);
+               tt = e_cal_component_get_completed (comp);
                if (tt) {
                        /* COMPLETED must be in UTC. */
-                       completed_time = icaltime_as_timet_with_zone (
-                               *tt, icaltimezone_get_utc_timezone ());
-                       e_cal_component_free_icaltimetype (tt);
+                       completed_time = i_cal_time_as_timet_with_zone (tt, utc_zone);
+                       g_object_unref (tt);
                }
 
-               e_cal_component_get_due (comp, &dt_due);
-               if (dt_due.value != NULL)
-                       due_time = componenttime_to_utc_timet (
-                               &dt_due, tz_cb, tz_cb_data,
-                               default_timezone);
+               dtdue = e_cal_component_get_due (comp);
+               if (dtdue)
+                       due_time = componenttime_to_utc_timet (dtdue, tz_cb, tz_cb_data, default_timezone);
 
-               e_cal_component_free_datetime (&dt_due);
+               e_cal_component_datetime_free (dtdue);
 
                max_time = MAX (completed_time, due_time);
 
                if (max_time != -1)
-                       *end = max_time;
+                       *out_end = max_time;
 
        } else {
                /* ALARMS, EVENTS: DTEND and reccurences */
@@ -1705,62 +1836,65 @@ e_cal_util_get_component_occur_times (ECalComponent *comp,
                if (e_cal_component_has_recurrences (comp)) {
                        GSList *rrules = NULL;
                        GSList *exrules = NULL;
-                       GSList *elem;
                        GSList *rdates = NULL;
+                       GSList *elem;
 
                        /* Do the RRULEs, EXRULEs and RDATEs*/
-                       e_cal_component_get_rrule_property_list (comp, &rrules);
-                       e_cal_component_get_exrule_property_list (comp, &exrules);
-                       e_cal_component_get_rdate_list (comp, &rdates);
+                       rrules = e_cal_component_get_rrule_properties (comp);
+                       exrules = e_cal_component_get_exrule_properties (comp);
+                       rdates = e_cal_component_get_rdates (comp);
 
-                       for (elem = rrules; elem; elem = elem->next) {
+                       for (elem = rrules; elem; elem = g_slist_next (elem)) {
+                               ICalProperty *prop = elem->data;
+                               ICalRecurrenceType *ir;
                                time_t rule_end;
-                               icaltimezone *utc_zone;
-                               icalproperty *prop = elem->data;
-                               ir = icalproperty_get_rrule (prop);
 
-                               utc_zone = icaltimezone_get_utc_timezone ();
-                               rule_end = e_cal_recur_obtain_enddate (
-                                       &ir, prop, utc_zone, TRUE);
+                               ir = i_cal_property_get_rrule (prop);
+                               rule_end = e_cal_recur_obtain_enddate (ir, prop, utc_zone, TRUE);
 
                                if (rule_end == -1) /* repeats forever */
                                        may_end = _TIME_MAX;
                                else if (rule_end + duration > may_end) /* new maximum */
                                        may_end = rule_end + duration;
+
+                               g_clear_object (&ir);
                        }
 
                        /* Do the EXRULEs. */
-                       for (elem = exrules; elem; elem = elem->next) {
-                               icalproperty *prop = elem->data;
+                       for (elem = exrules; elem; elem = g_slist_next (elem)) {
+                               ICalProperty *prop = elem->data;
+                               ICalRecurrenceType *ir;
                                time_t rule_end;
-                               icaltimezone *utc_zone;
-                               ir = icalproperty_get_exrule (prop);
 
-                               utc_zone = icaltimezone_get_utc_timezone ();
-                               rule_end = e_cal_recur_obtain_enddate (
-                                       &ir, prop, utc_zone, TRUE);
+                               ir = i_cal_property_get_exrule (prop);
+
+                               rule_end = e_cal_recur_obtain_enddate (ir, prop, utc_zone, TRUE);
 
                                if (rule_end == -1) /* repeats forever */
                                        may_end = _TIME_MAX;
                                else if (rule_end + duration > may_end)
                                        may_end = rule_end + duration;
+
+                               g_clear_object (&ir);
                        }
 
                        /* Do the RDATEs */
-                       for (elem = rdates; elem; elem = elem->next) {
-                               ECalComponentPeriod *p = elem->data;
+                       for (elem = rdates; elem; elem = g_slist_next (elem)) {
+                               const ECalComponentPeriod *period = elem->data;
                                time_t rdate_end = _TIME_MAX;
 
                                /* FIXME: We currently assume RDATEs are in the same timezone
                                 * as DTSTART. We should get the RDATE timezone and convert
                                 * to the DTSTART timezone first. */
 
-                               /* Check if the end date or duration is set, libical seems to set
-                                * second to -1 to denote an unset time */
-                               if (p->type != E_CAL_COMPONENT_PERIOD_DATETIME || p->u.end.second != -1)
-                                       rdate_end = icaltime_as_timet (icaltime_add (p->start, 
p->u.duration));
-                               else
-                                       rdate_end = icaltime_as_timet (p->u.end);
+                               if (e_cal_component_period_get_kind (period) != 
E_CAL_COMPONENT_PERIOD_DATETIME) {
+                                       ICalTimetype *tt;
+                                       tt = i_cal_time_add (e_cal_component_period_get_start (period), 
e_cal_component_period_get_duration (period));
+                                       rdate_end = i_cal_time_as_timet (tt);
+                                       g_object_unref (tt);
+                               } else {
+                                       rdate_end = i_cal_time_as_timet (e_cal_component_period_get_end 
(period));
+                               }
 
                                if (rdate_end == -1) /* repeats forever */
                                        may_end = _TIME_MAX;
@@ -1768,19 +1902,20 @@ e_cal_util_get_component_occur_times (ECalComponent *comp,
                                        may_end = rdate_end;
                        }
 
-                       e_cal_component_free_period_list (rdates);
-               } else if (*start != _TIME_MIN) {
-                       may_end = *start;
+                       g_slist_free_full (rrules, g_object_unref);
+                       g_slist_free_full (exrules, g_object_unref);
+                       g_slist_free_full (rdates, e_cal_component_period_free);
+               } else if (*out_start != _TIME_MIN) {
+                       may_end = *out_start;
                }
 
                /* Get dtend of the component and convert it to UTC */
-               e_cal_component_get_dtend (comp, &dt_end);
+               dtend = e_cal_component_get_dtend (comp);
 
-               if (dt_end.value) {
+               if (dtend) {
                        time_t dtend_time;
 
-                       dtend_time = componenttime_to_utc_timet (
-                               &dt_end, tz_cb, tz_cb_data, default_timezone);
+                       dtend_time = componenttime_to_utc_timet (dtend, tz_cb, tz_cb_data, default_timezone);
 
                        if (dtend_time == -1 || (dtend_time > may_end))
                                may_end = dtend_time;
@@ -1788,180 +1923,187 @@ e_cal_util_get_component_occur_times (ECalComponent *comp,
                        may_end = _TIME_MAX;
                }
 
-               e_cal_component_free_datetime (&dt_end);
+               e_cal_component_datetime_free (dtend);
 
-               *end = may_end == _TIME_MIN ? _TIME_MAX : may_end;
+               *out_end = may_end == _TIME_MIN ? _TIME_MAX : may_end;
        }
 }
 
 /**
- * e_cal_util_find_x_property:
- * @icalcomp: an icalcomponent
+ * e_cal_util_component_has_x_property:
+ * @icalcomp: an #ICalComponent
  * @x_name: name of the X property
  *
- * Searches for an X property named @x_name within X properties
- * of @icalcomp and returns it.
+ * Returns, whether the @icalcomp contains X property named @x_name. To check
+ * for standard property use e_cal_util_component_has_property().
  *
- * Returns: (nullable) (transfer none): the first X icalproperty named
- *    @x_name, or %NULL, when none found. The returned structure is owned
- *    by @icalcomp.
+ * Returns: whether the @icalcomp contains X property named @x_name
  *
- * Since: 3.26
+ * Since: 3.36
  **/
-icalproperty *
-e_cal_util_find_x_property (icalcomponent *icalcomp,
-                           const gchar *x_name)
+gboolean
+e_cal_util_component_has_x_property (ICalComponent *icalcomp,
+                                    const gchar *x_name)
 {
-       icalproperty *prop;
+       ICalProperty *prop;
 
-       g_return_val_if_fail (icalcomp != NULL, NULL);
-       g_return_val_if_fail (x_name != NULL, NULL);
+       g_return_val_if_fail (I_CAL_IS_COMPONENT (icalcomp), FALSE);
+       g_return_val_if_fail (x_name != NULL, FALSE);
 
-       for (prop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
-            prop;
-            prop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY)) {
-               const gchar *prop_name = icalproperty_get_x_name (prop);
+       prop = e_cal_util_component_find_x_property (icalcomp, x_name);
 
-               if (g_strcmp0 (prop_name, x_name) == 0)
-                       break;
-       }
+       if (!prop)
+               return FALSE;
 
-       return prop;
+       g_object_unref (prop);
+
+       return TRUE;
 }
 
+
 /**
- * e_cal_util_dup_x_property:
- * @icalcomp: an icalcomponent
+ * e_cal_util_component_find_x_property:
+ * @icalcomp: an #ICalComponent
  * @x_name: name of the X property
  *
  * Searches for an X property named @x_name within X properties
- * of @icalcomp and returns its value as a newly allocated string.
- * Free it with g_free(), when no longer needed.
+ * of @icalcomp and returns it. Free the non-NULL object
+ * with g_object_unref(), when no longer needed.
  *
- * Returns: (nullable) (transfer full): Newly allocated value of the first @x_name
- *    X property in @icalcomp, or %NULL, if not found.
+ * Returns: (transfer full) (nullable): the first X ICalProperty named
+ *    @x_name, or %NULL, when none found.
  *
- * Since: 3.26
+ * Since: 3.36
  **/
-gchar *
-e_cal_util_dup_x_property (icalcomponent *icalcomp,
-                          const gchar *x_name)
+ICalProperty *
+e_cal_util_component_find_x_property (ICalComponent *icalcomp,
+                                     const gchar *x_name)
 {
-       icalproperty *prop;
+       ICalProperty *prop;
 
        g_return_val_if_fail (icalcomp != NULL, NULL);
        g_return_val_if_fail (x_name != NULL, NULL);
 
-       prop = e_cal_util_find_x_property (icalcomp, x_name);
+       for (prop = i_cal_component_get_first_property (icalcomp, I_CAL_X_PROPERTY);
+            prop;
+            g_object_unref (prop), prop = i_cal_component_get_next_property (icalcomp, I_CAL_X_PROPERTY)) {
+               const gchar *prop_name = i_cal_property_get_x_name (prop);
 
-       if (!prop)
-               return NULL;
+               if (g_strcmp0 (prop_name, x_name) == 0)
+                       break;
+       }
 
-       return icalproperty_get_value_as_string_r (prop);
+       return prop;
 }
 
 /**
- * e_cal_util_get_x_property:
- * @icalcomp: an icalcomponent
+ * e_cal_util_component_dup_x_property:
+ * @icalcomp: an #ICalComponent
  * @x_name: name of the X property
  *
  * Searches for an X property named @x_name within X properties
- * of @icalcomp and returns its value. The returned string is
- * owned by libical. See e_cal_util_dup_x_property().
+ * of @icalcomp and returns its value as a newly allocated string.
+ * Free it with g_free(), when no longer needed.
  *
- * Returns: (nullable) (transfer none): Value of the first @x_name
+ * Returns: (nullable) (transfer full): Newly allocated value of the first @x_name
  *    X property in @icalcomp, or %NULL, if not found.
  *
- * Since: 3.26
+ * Since: 3.36
  **/
-const gchar *
-e_cal_util_get_x_property (icalcomponent *icalcomp,
-                          const gchar *x_name)
+gchar *
+e_cal_util_component_dup_x_property (ICalComponent *icalcomp,
+                                    const gchar *x_name)
 {
-       icalproperty *prop;
+       ICalProperty *prop;
+       gchar *x_value;
 
        g_return_val_if_fail (icalcomp != NULL, NULL);
        g_return_val_if_fail (x_name != NULL, NULL);
 
-       prop = e_cal_util_find_x_property (icalcomp, x_name);
+       prop = e_cal_util_component_find_x_property (icalcomp, x_name);
 
        if (!prop)
                return NULL;
 
-       return icalproperty_get_value_as_string (prop);
+       x_value = i_cal_property_get_value_as_string_r (prop);
+
+       g_object_unref (prop);
+
+       return x_value;
 }
 
 /**
- * e_cal_util_set_x_property:
- * @icalcomp: an icalcomponent
+ * e_cal_util_component_set_x_property:
+ * @icalcomp: an #ICalComponent
  * @x_name: name of the X property
  * @value: (nullable): a value to set, or %NULL
  *
  * Sets a value of the first X property named @x_name in @icalcomp,
  * if any such already exists, or adds a new property with this name
  * and value. As a special case, if @value is %NULL, then removes
- * the first X property names @x_name from @icalcomp instead.
+ * the first X property named @x_name from @icalcomp instead.
  *
- * Since: 3.26
+ * Since: 3.36
  **/
 void
-e_cal_util_set_x_property (icalcomponent *icalcomp,
-                          const gchar *x_name,
-                          const gchar *value)
+e_cal_util_component_set_x_property (ICalComponent *icalcomp,
+                                    const gchar *x_name,
+                                    const gchar *value)
 {
-       icalproperty *prop;
+       ICalProperty *prop;
 
        g_return_if_fail (icalcomp != NULL);
        g_return_if_fail (x_name != NULL);
 
        if (!value) {
-               e_cal_util_remove_x_property (icalcomp, x_name);
+               e_cal_util_component_remove_x_property (icalcomp, x_name);
                return;
        }
 
-       prop = e_cal_util_find_x_property (icalcomp, x_name);
+       prop = e_cal_util_component_find_x_property (icalcomp, x_name);
        if (prop) {
-               icalproperty_set_value_from_string (prop, value, "NO");
+               i_cal_property_set_value_from_string (prop, value, "NO");
+               g_object_unref (prop);
        } else {
-               prop = icalproperty_new_x (value);
-               icalproperty_set_x_name (prop, x_name);
-               icalcomponent_add_property (icalcomp, prop);
+               prop = i_cal_property_new_x (value);
+               i_cal_property_set_x_name (prop, x_name);
+               i_cal_component_take_property (icalcomp, prop);
        }
 }
 
 /**
- * e_cal_util_remove_x_property:
- * @icalcomp: an icalcomponent
+ * e_cal_util_component_remove_x_property:
+ * @icalcomp: an #ICalComponent
  * @x_name: name of the X property
  *
  * Removes the first X property named @x_name in @icalcomp.
  *
  * Returns: %TRUE, when any such had been found and removed, %FALSE otherwise.
  *
- * Since: 3.26
+ * Since: 3.36
  **/
 gboolean
-e_cal_util_remove_x_property (icalcomponent *icalcomp,
-                             const gchar *x_name)
+e_cal_util_component_remove_x_property (ICalComponent *icalcomp,
+                                       const gchar *x_name)
 {
-       icalproperty *prop;
+       ICalProperty *prop;
 
        g_return_val_if_fail (icalcomp != NULL, FALSE);
        g_return_val_if_fail (x_name != NULL, FALSE);
 
-       prop = e_cal_util_find_x_property (icalcomp, x_name);
+       prop = e_cal_util_component_find_x_property (icalcomp, x_name);
        if (!prop)
                return FALSE;
 
-       icalcomponent_remove_property (icalcomp, prop);
-       icalproperty_free (prop);
+       i_cal_component_remove_property (icalcomp, prop);
+       g_object_unref (prop);
 
        return TRUE;
 }
 
 /**
- * e_cal_util_remove_property_by_kind:
- * @icalcomp: an icalcomponent
+ * e_cal_util_component_remove_property_by_kind:
+ * @icalcomp: an #ICalComponent
  * @kind: the kind of the property to remove
  * @all: %TRUE to remove all, or %FALSE to remove only the first property of the @kind
  *
@@ -1972,18 +2114,18 @@ e_cal_util_remove_x_property (icalcomponent *icalcomp,
  * Since: 3.30
  **/
 guint
-e_cal_util_remove_property_by_kind (icalcomponent *icalcomp,
-                                   icalproperty_kind kind,
-                                   gboolean all)
+e_cal_util_component_remove_property_by_kind (ICalComponent *icalcomp,
+                                             ICalPropertyKind kind,
+                                             gboolean all)
 {
-       icalproperty *prop;
+       ICalProperty *prop;
        guint count = 0;
 
        g_return_val_if_fail (icalcomp != NULL, 0);
 
-       while (prop = icalcomponent_get_first_property (icalcomp, kind), prop) {
-               icalcomponent_remove_property (icalcomp, prop);
-               icalproperty_free (prop);
+       while (prop = i_cal_component_get_first_property (icalcomp, kind), prop) {
+               i_cal_component_remove_property (icalcomp, prop);
+               g_object_unref (prop);
 
                count++;
 
@@ -1995,16 +2137,16 @@ e_cal_util_remove_property_by_kind (icalcomponent *icalcomp,
 }
 
 typedef struct _NextOccurrenceData {
-       struct icaltimetype interval_start;
-       struct icaltimetype next;
+       ICalTimetype *interval_start;
+       ICalTimetype *next;
        gboolean found_next;
        gboolean any_hit;
 } NextOccurrenceData;
 
 static gboolean
-ecu_find_next_occurrence_cb (icalcomponent *comp,
-                            struct icaltimetype instance_start,
-                            struct icaltimetype instance_end,
+ecu_find_next_occurrence_cb (ICalComponent *comp,
+                            ICalTimetype *instance_start,
+                            ICalTimetype *instance_end,
                             gpointer user_data,
                             GCancellable *cancellable,
                             GError **error)
@@ -2015,8 +2157,9 @@ ecu_find_next_occurrence_cb (icalcomponent *comp,
 
        nod->any_hit = TRUE;
 
-       if (icaltime_compare (nod->interval_start, instance_start) < 0) {
-               nod->next = instance_start;
+       if (i_cal_time_compare (nod->interval_start, instance_start) < 0) {
+               g_clear_object (&nod->next);
+               nod->next = g_object_ref (instance_start);
                nod->found_next = TRUE;
                return FALSE;
        }
@@ -2026,17 +2169,17 @@ ecu_find_next_occurrence_cb (icalcomponent *comp,
 
 /* the returned FALSE means failure in timezone resolution, not in @out_time */
 static gboolean
-e_cal_util_find_next_occurrence (icalcomponent *vtodo,
-                                struct icaltimetype for_time,
-                                struct icaltimetype *out_time, /* set to icaltime_null_time() on failure */
+e_cal_util_find_next_occurrence (ICalComponent *vtodo,
+                                ICalTimetype *for_time,
+                                ICalTimetype **out_time, /* set to NULL on failure */
                                 ECalClient *cal_client,
                                 GCancellable *cancellable,
                                 GError **error)
 {
        NextOccurrenceData nod;
-       struct icaltimetype interval_start = for_time, interval_end, orig_dtstart, orig_due;
+       ICalTimetype *interval_start, *interval_end = NULL, *orig_dtstart, *orig_due;
        gint advance_days = 8;
-       icalproperty *prop;
+       ICalProperty *prop;
        gboolean success;
        GError *local_error = NULL;
 
@@ -2044,70 +2187,89 @@ e_cal_util_find_next_occurrence (icalcomponent *vtodo,
        g_return_val_if_fail (out_time != NULL, FALSE);
        g_return_val_if_fail (E_IS_CAL_CLIENT (cal_client), FALSE);
 
-       orig_dtstart = icalcomponent_get_dtstart (vtodo);
-       orig_due = icalcomponent_get_due (vtodo);
+       orig_dtstart = i_cal_component_get_dtstart (vtodo);
+       orig_due = i_cal_component_get_due (vtodo);
 
-       e_cal_util_remove_property_by_kind (vtodo, ICAL_DUE_PROPERTY, TRUE);
+       e_cal_util_component_remove_property_by_kind (vtodo, I_CAL_DUE_PROPERTY, TRUE);
 
-       if (!icaltime_is_null_time (for_time) && icaltime_is_valid_time (for_time)) {
-               icalcomponent_set_dtstart (vtodo, for_time);
+       if (for_time && !i_cal_time_is_null_time (for_time) && i_cal_time_is_valid_time (for_time)) {
+               i_cal_component_set_dtstart (vtodo, for_time);
        }
 
-       interval_start = icalcomponent_get_dtstart (vtodo);
-       if (icaltime_is_null_time (interval_start) || !icaltime_is_valid_time (interval_start))
-               interval_start = icaltime_current_time_with_zone (e_cal_client_get_default_timezone 
(cal_client));
+       interval_start = i_cal_component_get_dtstart (vtodo);
+       if (!interval_start || i_cal_time_is_null_time (interval_start) || !i_cal_time_is_valid_time 
(interval_start)) {
+               g_clear_object (&interval_start);
+               interval_start = i_cal_time_current_time_with_zone (e_cal_client_get_default_timezone 
(cal_client));
+       }
 
-       prop = icalcomponent_get_first_property (vtodo, ICAL_RRULE_PROPERTY);
+       prop = i_cal_component_get_first_property (vtodo, I_CAL_RRULE_PROPERTY);
        if (prop) {
-               struct icalrecurrencetype rrule;
+               ICalRecurrenceType *rrule;
+
+               rrule = i_cal_property_get_rrule (prop);
 
-               rrule = icalproperty_get_rrule (prop);
+               if (rrule) {
+                       if (i_cal_recurrence_type_get_freq (rrule) == I_CAL_WEEKLY_RECURRENCE && 
i_cal_recurrence_type_get_interval (rrule) > 1)
+                               advance_days = (i_cal_recurrence_type_get_interval (rrule) * 7) + 1;
+                       else if (i_cal_recurrence_type_get_freq (rrule) == I_CAL_MONTHLY_RECURRENCE)
+                               advance_days = (i_cal_recurrence_type_get_interval (rrule) >= 1 ? 
i_cal_recurrence_type_get_interval (rrule) * 31 : 31) + 1;
+                       else if (i_cal_recurrence_type_get_freq (rrule) == I_CAL_YEARLY_RECURRENCE)
+                               advance_days = (i_cal_recurrence_type_get_interval (rrule) >= 1 ? 
i_cal_recurrence_type_get_interval (rrule) * 365 : 365) + 2;
+               }
 
-               if (rrule.freq == ICAL_WEEKLY_RECURRENCE && rrule.interval > 1)
-                       advance_days = (rrule.interval * 7) + 1;
-               else if (rrule.freq == ICAL_MONTHLY_RECURRENCE)
-                       advance_days = (rrule.interval >= 1 ? rrule.interval * 31 : 31) + 1;
-               else if (rrule.freq == ICAL_YEARLY_RECURRENCE)
-                       advance_days = (rrule.interval >= 1 ? rrule.interval * 365 : 365) + 2;
+               g_clear_object (&rrule);
+               g_clear_object (&prop);
        }
 
+       nod.next = NULL;
+
        do {
-               interval_end = interval_start;
-               icaltime_adjust (&interval_end, advance_days, 0, 0, 0);
+               interval_end = i_cal_timetype_new_clone (interval_start);
+               i_cal_time_adjust (interval_end, advance_days, 0, 0, 0);
+
+               g_clear_object (&(nod.next));
 
                nod.interval_start = interval_start;
-               nod.next = icaltime_null_time ();
+               nod.next = i_cal_time_null_time ();
                nod.found_next = FALSE;
                nod.any_hit = FALSE;
 
                success = e_cal_recur_generate_instances_sync (vtodo, interval_start, interval_end,
                        ecu_find_next_occurrence_cb, &nod,
-                       e_cal_client_resolve_tzid_sync, cal_client,
+                       e_cal_client_tzlookup_cb, cal_client,
                        e_cal_client_get_default_timezone (cal_client),
                        cancellable, &local_error) || nod.found_next;
 
+               g_object_unref (interval_start);
                interval_start = interval_end;
-               icaltime_adjust (&interval_start, -1, 0, 0, 0);
+               interval_end = NULL;
+               i_cal_time_adjust (interval_start, -1, 0, 0, 0);
 
        } while (!local_error && !g_cancellable_is_cancelled (cancellable) && !nod.found_next && nod.any_hit);
 
        if (success)
-               *out_time = nod.next;
+               *out_time = (nod.next && !i_cal_time_is_null_time (nod.next)) ? g_object_ref (nod.next) : 
NULL;
 
        if (local_error)
                g_propagate_error (error, local_error);
 
-       if (!icaltime_is_null_time (for_time) && icaltime_is_valid_time (for_time)) {
-               if (icaltime_is_null_time (orig_dtstart) || !icaltime_is_valid_time (orig_dtstart))
-                       e_cal_util_remove_property_by_kind (vtodo, ICAL_DTSTART_PROPERTY, FALSE);
+       if (for_time && !i_cal_time_is_null_time (for_time) && i_cal_time_is_valid_time (for_time)) {
+               if (!orig_dtstart || i_cal_time_is_null_time (orig_dtstart) || !i_cal_time_is_valid_time 
(orig_dtstart))
+                       e_cal_util_component_remove_property_by_kind (vtodo, I_CAL_DTSTART_PROPERTY, FALSE);
                else
-                       icalcomponent_set_dtstart (vtodo, orig_dtstart);
+                       i_cal_component_set_dtstart (vtodo, orig_dtstart);
        }
 
-       if (icaltime_is_null_time (orig_due) || !icaltime_is_valid_time (orig_due))
-               e_cal_util_remove_property_by_kind (vtodo, ICAL_DUE_PROPERTY, FALSE);
+       if (!orig_due || i_cal_time_is_null_time (orig_due) || !i_cal_time_is_valid_time (orig_due))
+               e_cal_util_component_remove_property_by_kind (vtodo, I_CAL_DUE_PROPERTY, FALSE);
        else
-               icalcomponent_set_due (vtodo, orig_due);
+               i_cal_component_set_due (vtodo, orig_due);
+
+       g_clear_object (&interval_start);
+       g_clear_object (&interval_end);
+       g_clear_object (&orig_dtstart);
+       g_clear_object (&orig_due);
+       g_clear_object (&(nod.next));
 
        return success;
 }
@@ -2135,37 +2297,44 @@ e_cal_util_find_next_occurrence (icalcomponent *vtodo,
  * Since: 3.30
  **/
 gboolean
-e_cal_util_init_recur_task_sync (icalcomponent *vtodo,
+e_cal_util_init_recur_task_sync (ICalComponent *vtodo,
                                 ECalClient *cal_client,
                                 GCancellable *cancellable,
                                 GError **error)
 {
-       struct icaltimetype dtstart, due;
+       ICalTimetype *dtstart, *due;
        gboolean success = TRUE;
 
        g_return_val_if_fail (vtodo != NULL, FALSE);
-       g_return_val_if_fail (icalcomponent_isa (vtodo) == ICAL_VTODO_COMPONENT, FALSE);
+       g_return_val_if_fail (i_cal_component_isa (vtodo) == I_CAL_VTODO_COMPONENT, FALSE);
        g_return_val_if_fail (E_IS_CAL_CLIENT (cal_client), FALSE);
 
        if (!e_cal_util_component_has_recurrences (vtodo))
                return TRUE;
 
        /* DTSTART is required for recurring components */
-       dtstart = icalcomponent_get_dtstart (vtodo);
-       if (icaltime_is_null_time (dtstart) || !icaltime_is_valid_time (dtstart)) {
-               dtstart = icaltime_current_time_with_zone (e_cal_client_get_default_timezone (cal_client));
-               icalcomponent_set_dtstart (vtodo, dtstart);
+       dtstart = i_cal_component_get_dtstart (vtodo);
+       if (!dtstart || i_cal_time_is_null_time (dtstart) || !i_cal_time_is_valid_time (dtstart)) {
+               g_clear_object (&dtstart);
+
+               dtstart = i_cal_time_current_time_with_zone (e_cal_client_get_default_timezone (cal_client));
+               i_cal_component_set_dtstart (vtodo, dtstart);
        }
 
-       due = icalcomponent_get_due (vtodo);
-       if (icaltime_is_null_time (due) || !icaltime_is_valid_time (due) ||
-           icaltime_compare (dtstart, due) < 0) {
-               success = e_cal_util_find_next_occurrence (vtodo, icaltime_null_time (), &due, cal_client, 
cancellable, error);
+       due = i_cal_component_get_due (vtodo);
+       if (!due || i_cal_time_is_null_time (due) || !i_cal_time_is_valid_time (due) ||
+           i_cal_time_compare (dtstart, due) < 0) {
+               g_clear_object (&due);
+
+               success = e_cal_util_find_next_occurrence (vtodo, NULL, &due, cal_client, cancellable, error);
 
-               if (!icaltime_is_null_time (due) && icaltime_is_valid_time (due))
-                       icalcomponent_set_due (vtodo, due);
+               if (due && !i_cal_time_is_null_time (due) && i_cal_time_is_valid_time (due))
+                       i_cal_component_set_due (vtodo, due);
        }
 
+       g_clear_object (&dtstart);
+       g_clear_object (&due);
+
        return success;
 }
 
@@ -2198,126 +2367,167 @@ e_cal_util_init_recur_task_sync (icalcomponent *vtodo,
  * Since: 3.30
  **/
 gboolean
-e_cal_util_mark_task_complete_sync (icalcomponent *vtodo,
+e_cal_util_mark_task_complete_sync (ICalComponent *vtodo,
                                    time_t completed_time,
                                    ECalClient *cal_client,
                                    GCancellable *cancellable,
                                    GError **error)
 {
-       icalproperty *prop;
+       ICalProperty *prop;
 
        g_return_val_if_fail (vtodo != NULL, FALSE);
-       g_return_val_if_fail (icalcomponent_isa (vtodo) == ICAL_VTODO_COMPONENT, FALSE);
+       g_return_val_if_fail (i_cal_component_isa (vtodo) == I_CAL_VTODO_COMPONENT, FALSE);
        g_return_val_if_fail (E_IS_CAL_CLIENT (cal_client), FALSE);
 
        if (e_cal_util_component_has_recurrences (vtodo)) {
                gboolean is_last = FALSE, change_count = FALSE;
-               struct icaltimetype new_dtstart = icaltime_null_time (), new_due = icaltime_null_time ();
+               ICalTimetype *new_dtstart = NULL, *new_due = NULL;
 
-               for (prop = icalcomponent_get_first_property (vtodo, ICAL_RRULE_PROPERTY);
+               for (prop = i_cal_component_get_first_property (vtodo, I_CAL_RRULE_PROPERTY);
                     prop && !is_last;
-                    prop = icalcomponent_get_next_property (vtodo, ICAL_RRULE_PROPERTY)) {
-                       struct icalrecurrencetype rrule;
+                    g_object_unref (prop), prop = i_cal_component_get_next_property (vtodo, 
I_CAL_RRULE_PROPERTY)) {
+                       ICalRecurrenceType *rrule;
+
+                       rrule = i_cal_property_get_rrule (prop);
 
-                       rrule = icalproperty_get_rrule (prop);
+                       if (rrule && i_cal_recurrence_type_get_interval (rrule) > 0) {
+                               gint count = i_cal_recurrence_type_get_count (rrule);
 
-                       if (rrule.interval > 0) {
-                               if (rrule.count > 0) {
-                                       is_last = rrule.count == 1;
+                               if (count > 0) {
+                                       is_last = count == 1;
                                        change_count = TRUE;
                                }
                        }
+
+                       g_clear_object (&rrule);
                }
 
+               g_clear_object (&prop);
+
                if (!is_last) {
-                       if (!e_cal_util_find_next_occurrence (vtodo, icaltime_null_time (), &new_dtstart, 
cal_client, cancellable, error))
+                       if (!e_cal_util_find_next_occurrence (vtodo, NULL, &new_dtstart, cal_client, 
cancellable, error)) {
+                               g_clear_object (&new_dtstart);
                                return FALSE;
+                       }
 
-                       if (!icaltime_is_null_time (new_dtstart) && icaltime_is_valid_time (new_dtstart)) {
-                               struct icaltimetype old_due;
+                       if (new_dtstart && !i_cal_time_is_null_time (new_dtstart) && i_cal_time_is_valid_time 
(new_dtstart)) {
+                               ICalTimetype *old_due;
 
-                               old_due = icalcomponent_get_due (vtodo);
+                               old_due = i_cal_component_get_due (vtodo);
 
                                /* When the previous DUE is before new DTSTART, then move relatively also the 
DUE
                                   date, to keep the difference... */
-                               if (!icaltime_is_null_time (old_due) && icaltime_is_valid_time (old_due) &&
-                                   icaltime_compare (old_due, new_dtstart) < 0) {
-                                       if (!e_cal_util_find_next_occurrence (vtodo, old_due, &new_due, 
cal_client, cancellable, error))
+                               if (old_due && !i_cal_time_is_null_time (old_due) && i_cal_time_is_valid_time 
(old_due) &&
+                                   i_cal_time_compare (old_due, new_dtstart) < 0) {
+                                       if (!e_cal_util_find_next_occurrence (vtodo, old_due, &new_due, 
cal_client, cancellable, error)) {
+                                               g_clear_object (&new_dtstart);
+                                               g_clear_object (&new_due);
+                                               g_clear_object (&old_due);
                                                return FALSE;
+                                       }
                                }
 
                                /* ...  otherwise set the new DUE as the next-next-DTSTART ... */
-                               if (icaltime_is_null_time (new_due) || !icaltime_is_valid_time (new_due)) {
-                                       if (!e_cal_util_find_next_occurrence (vtodo, new_dtstart, &new_due, 
cal_client, cancellable, error))
+                               if (!new_due || i_cal_time_is_null_time (new_due) || 
!i_cal_time_is_valid_time (new_due)) {
+                                       g_clear_object (&new_due);
+
+                                       if (!e_cal_util_find_next_occurrence (vtodo, new_dtstart, &new_due, 
cal_client, cancellable, error)) {
+                                               g_clear_object (&new_dtstart);
+                                               g_clear_object (&new_due);
+                                               g_clear_object (&old_due);
                                                return FALSE;
+                                       }
                                }
 
                                /* ... eventually fallback to the new DTSTART for the new DUE */
-                               if (icaltime_is_null_time (new_due) || !icaltime_is_valid_time (new_due))
-                                       new_due = new_dtstart;
+                               if (!new_due || i_cal_time_is_null_time (new_due) || 
!i_cal_time_is_valid_time (new_due)) {
+                                       g_clear_object (&new_due);
+                                       new_due = i_cal_timetype_new_clone (new_dtstart);
+                               }
+
+                               g_clear_object (&old_due);
                        }
                }
 
-               if (!is_last &&
-                   !icaltime_is_null_time (new_dtstart) && icaltime_is_valid_time (new_dtstart) &&
-                   !icaltime_is_null_time (new_due) && icaltime_is_valid_time (new_due)) {
+               if (!is_last && new_dtstart && new_due &&
+                   !i_cal_time_is_null_time (new_dtstart) && i_cal_time_is_valid_time (new_dtstart) &&
+                   !i_cal_time_is_null_time (new_due) && i_cal_time_is_valid_time (new_due)) {
                        /* Move to the next occurrence */
                        if (change_count) {
-                               for (prop = icalcomponent_get_first_property (vtodo, ICAL_RRULE_PROPERTY);
+                               for (prop = i_cal_component_get_first_property (vtodo, I_CAL_RRULE_PROPERTY);
                                     prop;
-                                    prop = icalcomponent_get_next_property (vtodo, ICAL_RRULE_PROPERTY)) {
-                                       struct icalrecurrencetype rrule;
+                                    g_object_unref (prop), prop = i_cal_component_get_next_property (vtodo, 
I_CAL_RRULE_PROPERTY)) {
+                                       ICalRecurrenceType *rrule;
+
+                                       rrule = i_cal_property_get_rrule (prop);
 
-                                       rrule = icalproperty_get_rrule (prop);
+                                       if (rrule && i_cal_recurrence_type_get_interval (rrule) > 0) {
+                                               gint count = i_cal_recurrence_type_get_count (rrule);
 
-                                       if (rrule.interval > 0) {
-                                               if (rrule.count > 0) {
-                                                       rrule.count--;
-                                                       icalproperty_set_rrule (prop, rrule);
+                                               if (count > 0) {
+                                                       i_cal_recurrence_type_set_count (rrule, count - 1);
+                                                       i_cal_property_set_rrule (prop, rrule);
                                                }
                                        }
+
+                                       g_clear_object (&rrule);
                                }
                        }
 
-                       icalcomponent_set_dtstart (vtodo, new_dtstart);
-                       icalcomponent_set_due (vtodo, new_due);
+                       i_cal_component_set_dtstart (vtodo, new_dtstart);
+                       i_cal_component_set_due (vtodo, new_due);
+
+                       e_cal_util_component_remove_property_by_kind (vtodo, I_CAL_COMPLETED_PROPERTY, TRUE);
 
-                       e_cal_util_remove_property_by_kind (vtodo, ICAL_COMPLETED_PROPERTY, TRUE);
+                       prop = i_cal_component_get_first_property (vtodo, I_CAL_PERCENTCOMPLETE_PROPERTY);
+                       if (prop) {
+                               i_cal_property_set_percentcomplete (prop, 0);
+                               g_object_unref (prop);
+                       }
 
-                       prop = icalcomponent_get_first_property (vtodo, ICAL_PERCENTCOMPLETE_PROPERTY);
-                       if (prop)
-                               icalproperty_set_percentcomplete (prop, 0);
+                       prop = i_cal_component_get_first_property (vtodo, I_CAL_STATUS_PROPERTY);
+                       if (prop) {
+                               i_cal_property_set_status (prop, I_CAL_STATUS_NEEDSACTION);
+                               g_object_unref (prop);
+                       }
 
-                       prop = icalcomponent_get_first_property (vtodo, ICAL_STATUS_PROPERTY);
-                       if (prop)
-                               icalproperty_set_status (prop, ICAL_STATUS_NEEDSACTION);
+                       g_clear_object (&new_dtstart);
+                       g_clear_object (&new_due);
 
                        return TRUE;
                }
        }
 
-       prop = icalcomponent_get_first_property (vtodo, ICAL_COMPLETED_PROPERTY);
-       if (!prop) {
-               prop = icalproperty_new_completed (completed_time != (time_t) -1 ?
-                       icaltime_from_timet_with_zone (completed_time, FALSE, icaltimezone_get_utc_timezone 
()) :
-                       icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ()));
-               icalcomponent_add_property (vtodo, prop);
+       prop = i_cal_component_get_first_property (vtodo, I_CAL_COMPLETED_PROPERTY);
+       if (prop) {
+               g_object_unref (prop);
+       } else {
+               ICalTimetype *tt;
+
+               tt = completed_time != (time_t) -1 ?
+                       i_cal_time_from_timet_with_zone (completed_time, FALSE, 
i_cal_timezone_get_utc_timezone ()) :
+                       i_cal_time_current_time_with_zone (i_cal_timezone_get_utc_timezone ());
+               prop = i_cal_property_new_completed (tt);
+               i_cal_component_take_property (vtodo, prop);
+               g_object_unref (tt);
        }
 
-       prop = icalcomponent_get_first_property (vtodo, ICAL_PERCENTCOMPLETE_PROPERTY);
+       prop = i_cal_component_get_first_property (vtodo, I_CAL_PERCENTCOMPLETE_PROPERTY);
        if (prop) {
-               icalproperty_set_percentcomplete (prop, 100);
+               i_cal_property_set_percentcomplete (prop, 100);
+               g_object_unref (prop);
        } else {
-               prop = icalproperty_new_percentcomplete (100);
-               icalcomponent_add_property (vtodo, prop);
+               prop = i_cal_property_new_percentcomplete (100);
+               i_cal_component_take_property (vtodo, prop);
        }
 
-       prop = icalcomponent_get_first_property (vtodo, ICAL_STATUS_PROPERTY);
+       prop = i_cal_component_get_first_property (vtodo, I_CAL_STATUS_PROPERTY);
        if (prop) {
-               icalproperty_set_status (prop, ICAL_STATUS_COMPLETED);
+               i_cal_property_set_status (prop, I_CAL_STATUS_COMPLETED);
+               g_object_unref (prop);
        } else {
-               prop = icalproperty_new_status (ICAL_STATUS_COMPLETED);
-               icalcomponent_add_property (vtodo, prop);
+               prop = i_cal_property_new_status (I_CAL_STATUS_COMPLETED);
+               i_cal_component_take_property (vtodo, prop);
        }
 
        return TRUE;
diff --git a/src/calendar/libecal/e-cal-util.h b/src/calendar/libecal/e-cal-util.h
index 57d842029..6ca93cf3f 100644
--- a/src/calendar/libecal/e-cal-util.h
+++ b/src/calendar/libecal/e-cal-util.h
@@ -32,75 +32,6 @@
 
 G_BEGIN_DECLS
 
-struct _ECalClient;
-
-/**
- * CalObjInstance:
- * @uid: UID of the object
- * @start: Start time of instance
- * @end: End time of instance
- *
- * Instance of a calendar object.  This can be an actual occurrence, a
- * recurrence, or an alarm trigger of a `real' calendar object.
- **/
-typedef struct {
-       gchar *uid;                     /* UID of the object */
-       time_t start;                   /* Start time of instance */
-       time_t end;                     /* End time of instance */
-} CalObjInstance;
-
-void cal_obj_instance_list_free (GList *list);
-
-void cal_obj_uid_list_free (GList *list);
-
-icalcomponent *        e_cal_util_new_top_level        (void);
-icalcomponent *        e_cal_util_new_component        (icalcomponent_kind kind);
-
-icalcomponent *        e_cal_util_parse_ics_string     (const gchar *string);
-icalcomponent *        e_cal_util_parse_ics_file       (const gchar *filename);
-
-ECalComponentAlarms *
-               e_cal_util_generate_alarms_for_comp
-                                               (ECalComponent *comp,
-                                                time_t start,
-                                                time_t end,
-                                                ECalComponentAlarmAction *omit,
-                                                ECalRecurResolveTimezoneFn resolve_tzid,
-                                                gpointer user_data,
-                                                icaltimezone *default_timezone);
-gint           e_cal_util_generate_alarms_for_list
-                                               (GList *comps,
-                                                time_t start,
-                                                time_t end,
-                                                ECalComponentAlarmAction *omit,
-                                                GSList **comp_alarms,
-                                                ECalRecurResolveTimezoneFn resolve_tzid,
-                                                gpointer user_data,
-                                                icaltimezone *default_timezone);
-
-const gchar *  e_cal_util_priority_to_string   (gint priority);
-gint           e_cal_util_priority_from_string (const gchar *string);
-
-gchar *                e_cal_util_seconds_to_string    (gint64 seconds);
-
-void           e_cal_util_add_timezones_from_component
-                                               (icalcomponent *vcal_comp,
-                                                icalcomponent *icalcomp);
-
-gboolean       e_cal_util_component_is_instance
-                                               (icalcomponent *icalcomp);
-gboolean       e_cal_util_component_has_alarms (icalcomponent *icalcomp);
-gboolean       e_cal_util_component_has_organizer
-                                               (icalcomponent *icalcomp);
-gboolean       e_cal_util_component_has_recurrences
-                                               (icalcomponent *icalcomp);
-gboolean       e_cal_util_component_has_rdates (icalcomponent *icalcomp);
-gboolean       e_cal_util_component_has_rrules (icalcomponent *icalcomp);
-gboolean       e_cal_util_component_has_attendee
-                                               (icalcomponent *icalcomp);
-gboolean       e_cal_util_event_dates_match    (icalcomponent *icalcomp1,
-                                                icalcomponent *icalcomp2);
-
 /* The static capabilities to be supported by backends */
 #define E_CAL_STATIC_CAPABILITY_NO_ALARM_REPEAT                "no-alarm-repeat"
 #define E_CAL_STATIC_CAPABILITY_NO_AUDIO_ALARMS                "no-audio-alarms"
@@ -257,53 +188,108 @@ gboolean e_cal_util_event_dates_match    (icalcomponent *icalcomp1,
  **/
 #define E_CAL_STATIC_CAPABILITY_COMPONENT_COLOR                "component-color"
 
-/* Recurrent events. Management for instances */
-icalcomponent *        e_cal_util_construct_instance   (icalcomponent *icalcomp,
-                                                struct icaltimetype rid);
-void           e_cal_util_remove_instances     (icalcomponent *icalcomp,
-                                                struct icaltimetype rid,
+struct _ECalClient;
+
+ICalComponent *        e_cal_util_new_top_level        (void);
+ICalComponent *        e_cal_util_new_component        (ICalComponentKind kind);
+ICalTimezone * e_cal_util_copy_timezone        (const ICalTimezone *zone);
+
+ICalComponent *        e_cal_util_parse_ics_string     (const gchar *string);
+ICalComponent *        e_cal_util_parse_ics_file       (const gchar *filename);
+
+ECalComponentAlarms *
+               e_cal_util_generate_alarms_for_comp
+                                               (ECalComponent *comp,
+                                                time_t start,
+                                                time_t end,
+                                                ECalComponentAlarmAction *omit,
+                                                ECalRecurResolveTimezoneCb resolve_tzid,
+                                                gpointer user_data,
+                                                ICalTimezone *default_timezone);
+gint           e_cal_util_generate_alarms_for_list
+                                               (GList *comps, /* ECalComponent * */
+                                                time_t start,
+                                                time_t end,
+                                                ECalComponentAlarmAction *omit,
+                                                GSList **comp_alarms,
+                                                ECalRecurResolveTimezoneCb resolve_tzid,
+                                                gpointer user_data,
+                                                ICalTimezone *default_timezone);
+
+const gchar *  e_cal_util_priority_to_string   (gint priority);
+gint           e_cal_util_priority_from_string (const gchar *string);
+
+gchar *                e_cal_util_seconds_to_string    (gint64 seconds);
+
+void           e_cal_util_add_timezones_from_component
+                                               (ICalComponent *vcal_comp,
+                                                ICalComponent *icalcomp);
+
+gboolean       e_cal_util_component_has_property
+                                               (ICalComponent *icalcomp,
+                                                ICalPropertyKind prop_kind);
+gboolean       e_cal_util_component_is_instance
+                                               (ICalComponent *icalcomp);
+gboolean       e_cal_util_component_has_alarms (ICalComponent *icalcomp);
+gboolean       e_cal_util_component_has_organizer
+                                               (ICalComponent *icalcomp);
+gboolean       e_cal_util_component_has_recurrences
+                                               (ICalComponent *icalcomp);
+gboolean       e_cal_util_component_has_rdates (ICalComponent *icalcomp);
+gboolean       e_cal_util_component_has_rrules (ICalComponent *icalcomp);
+gboolean       e_cal_util_component_has_attendee
+                                               (ICalComponent *icalcomp);
+ICalComponent *        e_cal_util_construct_instance   (ICalComponent *icalcomp,
+                                                const ICalTimetype *rid);
+void           e_cal_util_remove_instances     (ICalComponent *icalcomp,
+                                                const ICalTimetype *rid,
                                                 ECalObjModType mod);
-icalcomponent *        e_cal_util_split_at_instance    (icalcomponent *icalcomp,
-                                                struct icaltimetype rid,
-                                                struct icaltimetype master_dtstart);
+ICalComponent *        e_cal_util_split_at_instance    (ICalComponent *icalcomp,
+                                                const ICalTimetype *rid,
+                                                const ICalTimetype *master_dtstart);
 gboolean       e_cal_util_is_first_instance    (ECalComponent *comp,
-                                                struct icaltimetype rid,
-                                                ECalRecurResolveTimezoneFn tz_cb,
+                                                const ICalTimetype *rid,
+                                                ECalRecurResolveTimezoneCb tz_cb,
                                                 gpointer tz_cb_data);
 
 gchar *                e_cal_util_get_system_timezone_location (void);
-icaltimezone * e_cal_util_get_system_timezone (void);
+ICalTimezone * e_cal_util_get_system_timezone (void);
 void           e_cal_util_get_component_occur_times
                                                (ECalComponent *comp,
-                                                time_t * start,
-                                                time_t * end,
-                                                ECalRecurResolveTimezoneFn tz_cb,
+                                                time_t *out_start,
+                                                time_t *out_end,
+                                                ECalRecurResolveTimezoneCb tz_cb,
                                                 gpointer tz_cb_data,
-                                                const icaltimezone *default_timezone,
-                                                icalcomponent_kind kind);
+                                                const ICalTimezone *default_timezone,
+                                                ICalComponentKind kind);
 
-icalproperty * e_cal_util_find_x_property      (icalcomponent *icalcomp,
+gboolean       e_cal_util_component_has_x_property
+                                               (ICalComponent *icalcomp,
                                                 const gchar *x_name);
-gchar *                e_cal_util_dup_x_property       (icalcomponent *icalcomp,
+ICalProperty * e_cal_util_component_find_x_property
+                                               (ICalComponent *icalcomp,
                                                 const gchar *x_name);
-const gchar *  e_cal_util_get_x_property       (icalcomponent *icalcomp,
+gchar *                e_cal_util_component_dup_x_property
+                                               (ICalComponent *icalcomp,
                                                 const gchar *x_name);
-void           e_cal_util_set_x_property       (icalcomponent *icalcomp,
+void           e_cal_util_component_set_x_property
+                                               (ICalComponent *icalcomp,
                                                 const gchar *x_name,
                                                 const gchar *value);
-gboolean       e_cal_util_remove_x_property    (icalcomponent *icalcomp,
+gboolean       e_cal_util_component_remove_x_property
+                                               (ICalComponent *icalcomp,
                                                 const gchar *x_name);
-guint          e_cal_util_remove_property_by_kind
-                                               (icalcomponent *icalcomp,
-                                                icalproperty_kind kind,
+guint          e_cal_util_component_remove_property_by_kind
+                                               (ICalComponent *icalcomp,
+                                                ICalPropertyKind kind,
                                                 gboolean all);
 
-gboolean       e_cal_util_init_recur_task_sync (icalcomponent *vtodo,
+gboolean       e_cal_util_init_recur_task_sync (ICalComponent *vtodo,
                                                 struct _ECalClient *cal_client,
                                                 GCancellable *cancellable,
                                                 GError **error);
 gboolean       e_cal_util_mark_task_complete_sync
-                                               (icalcomponent *vtodo,
+                                               (ICalComponent *vtodo,
                                                 time_t completed_time,
                                                 struct _ECalClient *cal_client,
                                                 GCancellable *cancellable,
diff --git a/src/calendar/libecal/e-reminder-watcher.c b/src/calendar/libecal/e-reminder-watcher.c
index a86eddd44..158a10a4d 100644
--- a/src/calendar/libecal/e-reminder-watcher.c
+++ b/src/calendar/libecal/e-reminder-watcher.c
@@ -36,6 +36,7 @@
 
 #include "libedataserver/libedataserver.h"
 
+#include "e-cal-check-timezones.h"
 #include "e-cal-client.h"
 #include "e-cal-system-timezone.h"
 #include "e-cal-time-util.h"
@@ -62,7 +63,7 @@ struct _EReminderWatcherPrivate {
        guint expected_past_changes;
        guint expected_snoozed_changes;
 
-       icaltimezone *default_zone;
+       ICalTimezone *default_zone;
 
        GSList *clients; /* ClientData * */
        GSList *snoozed; /* EReminderData * */
@@ -97,15 +98,20 @@ static guint signals[LAST_SIGNAL];
 G_DEFINE_TYPE (EReminderWatcher, e_reminder_watcher, G_TYPE_OBJECT)
 
 G_DEFINE_BOXED_TYPE (EReminderData, e_reminder_data, e_reminder_data_copy, e_reminder_data_free)
-G_DEFINE_BOXED_TYPE (EReminderWatcherZone, e_reminder_watcher_zone, e_reminder_watcher_zone_copy, 
e_reminder_watcher_zone_free)
+
+struct _EReminderData {
+       gchar *source_uid;
+       ECalComponent *component;
+       ECalComponentAlarmInstance *instance;
+};
 
 static void
 e_reminder_watcher_objects_added_cb (ECalClientView *view,
-                                    const GSList *objects, /* icalcomponent * */
+                                    const GSList *objects, /* ICalComponent * */
                                     gpointer user_data);
 static void
 e_reminder_watcher_objects_modified_cb (ECalClientView *view,
-                                       const GSList *objects, /* icalcomponent * */
+                                       const GSList *objects, /* ICalComponent * */
                                        gpointer user_data);
 static void
 e_reminder_watcher_objects_removed_cb (ECalClientView *view,
@@ -147,7 +153,7 @@ e_reminder_watcher_timet_as_string (gint64 tt)
        static gchar buffers[10][32 + 1];
        static volatile gint curr_index = 0;
        gint counter = 0, index;
-       struct icaltimetype itt;
+       ICalTimetype *itt;
 
        while (index = (curr_index + 1) % 10, !g_atomic_int_compare_and_exchange (&curr_index, curr_index, 
index)) {
                counter++;
@@ -155,11 +161,13 @@ e_reminder_watcher_timet_as_string (gint64 tt)
                        break;
        }
 
-       itt = icaltime_from_timet_with_zone ((time_t) tt, 0, icaltimezone_get_utc_timezone ());
+       itt = i_cal_time_from_timet_with_zone ((time_t) tt, 0, i_cal_timezone_get_utc_timezone ());
 
        g_snprintf (buffers[index], 32, "%04d%02d%02dT%02d%02d%02d",
-               itt.year, itt.month, itt.day,
-               itt.hour, itt.minute, itt.second);
+               i_cal_timetype_get_year (itt), i_cal_timetype_get_month (itt), i_cal_timetype_get_day (itt),
+               i_cal_timetype_get_hour (itt), i_cal_timetype_get_minute (itt), i_cal_timetype_get_second 
(itt));
+
+       g_clear_object (&itt);
 
        return buffers[index];
 }
@@ -414,10 +422,7 @@ e_reminder_data_new_take_component (const gchar *source_uid,
        rd = g_new0 (EReminderData, 1);
        rd->source_uid = g_strdup (source_uid);
        rd->component = component;
-       rd->instance.auid = g_strdup (instance->auid);
-       rd->instance.trigger = instance->trigger;
-       rd->instance.occur_start = instance->occur_start;
-       rd->instance.occur_end = instance->occur_end;
+       rd->instance = e_cal_component_alarm_instance_copy (instance);
 
        return rd;
 }
@@ -462,7 +467,7 @@ e_reminder_data_copy (const EReminderData *rd)
        if (!rd)
                return NULL;
 
-       return e_reminder_data_new_take_component (rd->source_uid, g_object_ref (rd->component), 
&(rd->instance));
+       return e_reminder_data_new_take_component (rd->source_uid, g_object_ref (rd->component), 
rd->instance);
 }
 
 /**
@@ -481,44 +486,127 @@ e_reminder_data_free (gpointer rd)
 
        if (ptr) {
                g_clear_object (&ptr->component);
+               e_cal_component_alarm_instance_free (ptr->instance);
                g_free (ptr->source_uid);
-               g_free (ptr->instance.auid);
                g_free (ptr);
        }
 }
 
 /**
- * e_reminder_watcher_zone_copy:
- * @watcher_zone: (nullable): an #EReminderWatcherZone to copy, or %NULL
+ * e_reminder_data_get_source_uid:
+ * @rd: an #EReminderData
  *
- * Returns: (transfer full): copy of @watcher_zone, or %NULL, when it's also %NULL.
- *    Free returned instance with e_reminder_watcher_zone_free(), when no longer needed.
+ * Returns: an #ESource UID for @rd
  *
- * Since: 3.30
+ * Since: 3.36
  **/
-EReminderWatcherZone *
-e_reminder_watcher_zone_copy (const EReminderWatcherZone *watcher_zone)
+const gchar *
+e_reminder_data_get_source_uid (const EReminderData *rd)
 {
-       if (!watcher_zone)
-               return NULL;
+       g_return_val_if_fail (rd != NULL, NULL);
 
-       return (EReminderWatcherZone *) icaltimezone_copy ((icaltimezone *) watcher_zone);
+       return rd->source_uid;
 }
 
 /**
- * e_reminder_watcher_zone_free:
- * @watcher_zone: (nullable): an #EReminderWatcherZone to free
+ * e_reminder_data_set_source_uid:
+ * @rd: an #EReminderData
+ * @source_uid: an #ESource UID
  *
- * Frees @watcher_zone, previously allocated with e_reminder_watcher_zone_copy().
- * The function does nothing when the @watcher_zone is %NULL.
+ * Set an #ESource UID for @rd.
  *
- * Since: 3.30
+ * Since: 3.36
+ **/
+void
+e_reminder_data_set_source_uid (EReminderData *rd,
+                               const gchar *source_uid)
+{
+       g_return_if_fail (rd != NULL);
+
+       if (g_strcmp0 (rd->source_uid, source_uid) != 0) {
+               g_free (rd->source_uid);
+               rd->source_uid = g_strdup (source_uid);
+       }
+}
+
+/**
+ * e_reminder_data_get_component:
+ * @rd: an #EReminderData
+ *
+ * Returns: (transfer none): an #ECalComponent for @rd. It is owned by @rd,
+ *    thus do not free it.
+ *
+ * Since: 3.36
+ **/
+ECalComponent *
+e_reminder_data_get_component (const EReminderData *rd)
+{
+       g_return_val_if_fail (rd != NULL, NULL);
+
+       return rd->component;
+}
+
+/**
+ * e_reminder_data_set_component:
+ * @rd: an #EReminderData
+ * @component: an #ECalComponent
+ *
+ * Set an #ECalComponent @component as associated with this @rd.
+ * The @rd creates a copy of the @component.
+ *
+ * Since: 3.36
  **/
 void
-e_reminder_watcher_zone_free (EReminderWatcherZone *watcher_zone)
+e_reminder_data_set_component (EReminderData *rd,
+                              const ECalComponent *component)
 {
-       if (watcher_zone)
-               icaltimezone_free ((icaltimezone *) watcher_zone, 1);
+       g_return_if_fail (rd != NULL);
+       g_return_if_fail (E_IS_CAL_COMPONENT (component));
+
+       if (rd->component != component) {
+               g_clear_object (&rd->component);
+               rd->component = e_cal_component_clone ((ECalComponent *) component);
+       }
+}
+
+/**
+ * e_reminder_data_get_instance:
+ * @rd: an #EReminderData
+ *
+ * Returns: (transfer none): an #ECalComponentAlarmInstance for @rd.
+ *    It is owned by @rd, thus do not free it.
+ *
+ * Since: 3.36
+ **/
+ECalComponentAlarmInstance *
+e_reminder_data_get_instance (const EReminderData *rd)
+{
+       g_return_val_if_fail (rd != NULL, NULL);
+
+       return rd->instance;
+}
+
+/**
+ * e_reminder_data_set_instance:
+ * @rd: an #EReminderData
+ * @instance: an #ECalComponentAlarmInstance
+ *
+ * Set an #ECalComponentAlarmInstance @instance as associated with this @rd.
+ * The @rd creates a copy of the @instance.
+ *
+ * Since: 3.36
+ **/
+void
+e_reminder_data_set_instance (EReminderData *rd,
+                             const ECalComponentAlarmInstance *instance)
+{
+       g_return_if_fail (rd != NULL);
+       g_return_if_fail (instance != NULL);
+
+       if (rd->instance != instance) {
+               e_cal_component_alarm_instance_free (rd->instance);
+               rd->instance = e_cal_component_alarm_instance_copy (instance);
+       }
 }
 
 static gchar *
@@ -538,17 +626,17 @@ e_reminder_data_to_string (const EReminderData *rd)
        g_string_append (str, rd->source_uid);
        g_string_append_c (str, '\n');
 
-       if (rd->instance.auid)
-               g_string_append (str, rd->instance.auid);
+       if (rd->instance && e_cal_component_alarm_instance_get_uid (rd->instance))
+               g_string_append (str, e_cal_component_alarm_instance_get_uid (rd->instance));
        g_string_append_c (str, '\n');
 
-       g_string_append_printf (str, "%" G_GINT64_FORMAT, (gint64) rd->instance.trigger);
+       g_string_append_printf (str, "%" G_GINT64_FORMAT, (gint64) (rd->instance ? 
e_cal_component_alarm_instance_get_time (rd->instance) : -1));
        g_string_append_c (str, '\n');
 
-       g_string_append_printf (str, "%" G_GINT64_FORMAT, (gint64) rd->instance.occur_start);
+       g_string_append_printf (str, "%" G_GINT64_FORMAT, (gint64) (rd->instance ? 
e_cal_component_alarm_instance_get_occur_start (rd->instance) : -1));
        g_string_append_c (str, '\n');
 
-       g_string_append_printf (str, "%" G_GINT64_FORMAT, (gint64) rd->instance.occur_end);
+       g_string_append_printf (str, "%" G_GINT64_FORMAT, (gint64) (rd->instance ? 
e_cal_component_alarm_instance_get_occur_end (rd->instance) : -1));
        g_string_append_c (str, '\n');
 
        g_string_append (str, icalstr);
@@ -564,7 +652,7 @@ e_reminder_data_from_string (const gchar *str)
        gchar **strv;
        EReminderData *rd;
        ECalComponent *component;
-       ECalComponentAlarmInstance instance;
+       ECalComponentAlarmInstance *instance;
 
        g_return_val_if_fail (str != NULL, NULL);
 
@@ -583,13 +671,15 @@ e_reminder_data_from_string (const gchar *str)
                return NULL;
        }
 
-       instance.auid = (*(strv[1])) ? strv[1] : NULL;
-       instance.trigger = g_ascii_strtoll (strv[2], NULL, 10);
-       instance.occur_start = g_ascii_strtoll (strv[3], NULL, 10);
-       instance.occur_end = g_ascii_strtoll (strv[4], NULL, 10);
+       instance = e_cal_component_alarm_instance_new (
+               (*(strv[1])) ? strv[1] : NULL,
+               g_ascii_strtoll (strv[2], NULL, 10),
+               g_ascii_strtoll (strv[3], NULL, 10),
+               g_ascii_strtoll (strv[4], NULL, 10));
 
-       rd = e_reminder_data_new_take_component (strv[0], component, &instance);
+       rd = e_reminder_data_new_take_component (strv[0], component, instance);
 
+       e_cal_component_alarm_instance_free (instance);
        g_strfreev (strv);
 
        return rd;
@@ -600,6 +690,7 @@ e_reminder_data_compare (gconstpointer ptr1,
                         gconstpointer ptr2)
 {
        const EReminderData *rd1 = ptr1, *rd2 = ptr2;
+       time_t trigger1, trigger2;
 
        if (!rd1 || !rd2) {
                if (rd1 == rd2)
@@ -607,10 +698,13 @@ e_reminder_data_compare (gconstpointer ptr1,
                return !rd1 ? -1 : 1;
        }
 
-       if (rd1->instance.trigger == rd2->instance.trigger)
+       trigger1 = rd1->instance ? e_cal_component_alarm_instance_get_time (rd1->instance) : -1;
+       trigger2 = rd2->instance ? e_cal_component_alarm_instance_get_time (rd2->instance) : -1;
+
+       if (trigger1 == trigger2)
                return 0;
 
-       return rd1->instance.trigger < rd2->instance.trigger ? -1 : 1;
+       return trigger1 < trigger2 ? -1 : 1;
 }
 
 static void
@@ -656,8 +750,8 @@ match_not_component_id_cb (gpointer data,
                return FALSE;
 
        rd_id = e_cal_component_get_id (rd->component);
-       match = rd_id && g_strcmp0 (rd_id->uid, id->uid) == 0;
-       e_cal_component_free_id (rd_id);
+       match = rd_id && g_strcmp0 (e_cal_component_id_get_uid (rd_id), e_cal_component_id_get_uid (id)) == 0;
+       e_cal_component_id_free (rd_id);
 
        return !match;
 }
@@ -667,7 +761,7 @@ typedef struct _ObjectsChangedData {
        GSList *ids; /* ECalComponentId * */
        time_t interval_start;
        time_t interval_end;
-       icaltimezone *zone;
+       ICalTimezone *zone;
 } ObjectsChangedData;
 
 static void
@@ -677,9 +771,8 @@ objects_changed_data_free (gpointer ptr)
 
        if (ocd) {
                g_clear_object (&ocd->client);
-               g_slist_free_full (ocd->ids, (GDestroyNotify) e_cal_component_free_id);
-               if (ocd->zone)
-                       e_reminder_watcher_zone_free (ocd->zone);
+               g_slist_free_full (ocd->ids, (GDestroyNotify) e_cal_component_id_free);
+               g_clear_object (&ocd->zone);
                g_free (ocd);
        }
 }
@@ -705,13 +798,14 @@ e_reminder_watcher_objects_changed_thread (GTask *task,
 
        for (link = ocd->ids; link && !g_cancellable_is_cancelled (cancellable); link = g_slist_next (link)) {
                const ECalComponentId *id = link->data;
-               icalcomponent *icalcomp = NULL;
+               ICalComponent *icalcomp = NULL;
                GError *local_error = NULL;
 
-               if (!id || !id->uid || !*id->uid)
+               if (!id || !e_cal_component_id_get_uid (id))
                        continue;
 
-               if (e_cal_client_get_object_sync (ocd->client, id->uid, id->rid, &icalcomp, cancellable, 
&local_error) && !local_error && icalcomp) {
+               if (e_cal_client_get_object_sync (ocd->client, e_cal_component_id_get_uid (id), 
e_cal_component_id_get_rid (id),
+                   &icalcomp, cancellable, &local_error) && !local_error && icalcomp) {
                        ECalComponent *ecomp;
 
                        ecomp = e_cal_component_new_from_icalcomponent (icalcomp);
@@ -720,40 +814,45 @@ e_reminder_watcher_objects_changed_thread (GTask *task,
                                ECalComponentAlarms *alarms;
 
                                alarms = e_cal_util_generate_alarms_for_comp (
-                                       ecomp, ocd->interval_start, ocd->interval_end, omit, 
e_cal_client_resolve_tzid_cb,
+                                       ecomp, ocd->interval_start, ocd->interval_end, omit, 
e_cal_client_tzlookup_cb,
                                        ocd->client, ocd->zone);
 
-                               if (alarms && alarms->alarms) {
-                                       GSList *alink;
+                               if (alarms && e_cal_component_alarms_get_instances (alarms)) {
+                                       ECalComponent *alarms_comp = e_cal_component_alarms_get_component 
(alarms);
+                                       GSList *alink, *instances;
 
-                                       e_reminder_watcher_debug_print ("Source %s: Got %d alarms for object 
'%s':'%s' at interval %s .. %s\n", source_uid,
-                                               g_slist_length (alarms->alarms), id->uid, id->rid ? id->rid : 
"",
+                                       instances = e_cal_component_alarms_get_instances (alarms);
+
+                                       e_reminder_watcher_debug_print ("Source %s: Got %d alarms for object 
'%s':'%s' at interval %s .. %s\n",
+                                               source_uid, g_slist_length (instances), 
e_cal_component_id_get_uid (id),
+                                               e_cal_component_id_get_rid (id) ? e_cal_component_id_get_rid 
(id) : "",
                                                e_reminder_watcher_timet_as_string (ocd->interval_start),
                                                e_reminder_watcher_timet_as_string (ocd->interval_end));
 
-                                       for (alink = alarms->alarms; alink; alink = g_slist_next (alink)) {
+                                       for (alink = instances; alink; alink = g_slist_next (alink)) {
                                                const ECalComponentAlarmInstance *instance = alink->data;
 
                                                if (instance) {
                                                        reminders = g_slist_prepend (reminders, 
e_reminder_data_new_take_component (
-                                                               source_uid, g_object_ref (alarms->comp), 
instance));
+                                                               source_uid, g_object_ref (alarms_comp), 
instance));
                                                }
                                        }
                                } else {
-                                       e_reminder_watcher_debug_print ("Source %s: Got no alarms for object 
'%s':'%s' at interval %s .. %s\n", source_uid,
-                                               id->uid, id->rid ? id->rid : "",
+                                       e_reminder_watcher_debug_print ("Source %s: Got no alarms for object 
'%s':'%s' at interval %s .. %s\n",
+                                               source_uid, e_cal_component_id_get_uid (id),
+                                               e_cal_component_id_get_rid (id) ? e_cal_component_id_get_rid 
(id) : "",
                                                e_reminder_watcher_timet_as_string (ocd->interval_start),
                                                e_reminder_watcher_timet_as_string (ocd->interval_end));
                                }
 
-                               if (alarms)
-                                       e_cal_component_alarms_free (alarms);
-
+                               e_cal_component_alarms_free (alarms);
                                g_object_unref (ecomp);
                        }
                } else {
-                       e_reminder_watcher_debug_print ("Source %s: Failed to get object '%s':'%s': %s\n", 
source_uid,
-                               id->uid, id->rid ? id->rid : "", local_error ? local_error->message : 
"Unknown error");
+                       e_reminder_watcher_debug_print ("Source %s: Failed to get object '%s':'%s': %s\n",
+                               source_uid, e_cal_component_id_get_uid (id),
+                               e_cal_component_id_get_rid (id) ? e_cal_component_id_get_rid (id) : "",
+                               local_error ? local_error->message : "Unknown error");
                        g_clear_error (&local_error);
                }
 
@@ -779,7 +878,7 @@ e_reminder_watcher_objects_changed_thread (GTask *task,
                                ECalComponentId *id = link->data;
                                GSList *new_scheduled;
 
-                               if (!id || !id->uid)
+                               if (!id || !e_cal_component_id_get_uid (id))
                                        continue;
 
                                new_scheduled = e_reminder_watcher_move_matched (scheduled, 
match_not_component_id_cb, id);
@@ -829,7 +928,7 @@ e_reminder_watcher_objects_changed_done_cb (GObject *source_object,
 static void
 e_reminder_watcher_objects_changed (EReminderWatcher *watcher,
                                    ECalClient *client,
-                                   const GSList *objects) /* icalcomponent * */
+                                   const GSList *objects) /* ICalComponent * */
 {
        GSList *link, *ids = NULL;
 
@@ -844,23 +943,25 @@ e_reminder_watcher_objects_changed (EReminderWatcher *watcher,
        }
 
        for (link = (GSList *) objects; link; link = g_slist_next (link)) {
-               icalcomponent *icalcomp = link->data;
+               ICalComponent *icalcomp = link->data;
                ECalComponentId *id;
                const gchar *uid;
                gchar *rid = NULL;
 
-               uid = icalcomponent_get_uid (icalcomp);
+               uid = i_cal_component_get_uid (icalcomp);
                if (!uid || !*uid)
                        continue;
 
                if (e_cal_util_component_is_instance (icalcomp)) {
-                       struct icaltimetype itt;
+                       ICalTimetype *itt;
 
-                       itt = icalcomponent_get_recurrenceid (icalcomp);
-                       if (icaltime_is_valid_time (itt) && !icaltime_is_null_time (itt))
-                               rid = icaltime_as_ical_string_r (itt);
+                       itt = i_cal_component_get_recurrenceid (icalcomp);
+                       if (i_cal_time_is_valid_time (itt) && !i_cal_time_is_null_time (itt))
+                               rid = i_cal_time_as_ical_string_r (itt);
                        else
                                rid = g_strdup ("0");
+
+                       g_clear_object (&itt);
                }
 
                id = e_cal_component_id_new (uid, rid && *rid ? rid : NULL);
@@ -927,7 +1028,7 @@ e_reminder_watcher_objects_removed (EReminderWatcher *watcher,
                ECalComponentId *id = link->data;
                GSList *new_scheduled;
 
-               if (!id || !id->uid)
+               if (!id || e_cal_component_id_get_uid (id))
                        continue;
 
                new_scheduled = e_reminder_watcher_move_matched (scheduled, match_not_component_id_cb, id);
@@ -947,7 +1048,7 @@ e_reminder_watcher_objects_removed (EReminderWatcher *watcher,
 
 static void
 e_reminder_watcher_objects_added_cb (ECalClientView *view,
-                                    const GSList *objects, /* icalcomponent * */
+                                    const GSList *objects, /* ICalComponent * */
                                     gpointer user_data)
 {
        EReminderWatcher *watcher = user_data;
@@ -971,7 +1072,7 @@ e_reminder_watcher_objects_added_cb (ECalClientView *view,
 
 static void
 e_reminder_watcher_objects_modified_cb (ECalClientView *view,
-                                       const GSList *objects, /* icalcomponent * */
+                                       const GSList *objects, /* ICalComponent * */
                                        gpointer user_data)
 {
        EReminderWatcher *watcher = user_data;
@@ -1092,7 +1193,7 @@ e_reminder_watcher_schedule_timer_impl (EReminderWatcher *watcher,
 static void
 e_reminder_watcher_format_time_impl (EReminderWatcher *watcher,
                                     const EReminderData *rd,
-                                    struct icaltimetype *itt,
+                                    ICalTimetype *itt,
                                     gchar **inout_buffer,
                                     gint buffer_size)
 {
@@ -1195,19 +1296,29 @@ e_reminder_watcher_find (GSList *reminders, /* EReminderData * */
                id2 = e_cal_component_get_id (rd2->component);
 
                if (id2) {
-                       if (g_strcmp0 (id1->uid, id2->uid) == 0 && (
-                           (g_strcmp0 (id1->rid, id2->rid) == 0 ||
-                           ((!id1->rid || !*(id1->rid)) && (!id2->rid || !*(id2->rid))))) &&
-                           g_strcmp0 (rd->instance.auid, rd2->instance.auid) == 0 &&
-                           rd->instance.trigger == rd2->instance.trigger)
+                       const gchar *uid1, *uid2, *rid1, *rid2, *auid1, *auid2;
+
+                       uid1 = e_cal_component_id_get_uid (id1);
+                       rid1 = e_cal_component_id_get_rid (id1);
+                       uid2 = e_cal_component_id_get_uid (id2);
+                       rid2 = e_cal_component_id_get_rid (id2);
+                       auid1 = e_cal_component_alarm_instance_get_uid (e_reminder_data_get_instance (rd));
+                       auid2 = e_cal_component_alarm_instance_get_uid (e_reminder_data_get_instance (rd2));
+
+                       if (g_strcmp0 (uid1, uid2) == 0 && (
+                           (g_strcmp0 (rid1, rid2) == 0 ||
+                           ((!rid1 || !*rid1) && (!rid2 || !*rid2)))) &&
+                           g_strcmp0 (auid1, auid2) == 0 &&
+                           e_cal_component_alarm_instance_get_time (e_reminder_data_get_instance (rd)) ==
+                           e_cal_component_alarm_instance_get_time (e_reminder_data_get_instance (rd2)))
                                found = rd2;
 
-                       e_cal_component_free_id (id2);
+                       e_cal_component_id_free (id2);
                }
        }
 
        if (id1)
-               e_cal_component_free_id (id1);
+               e_cal_component_id_free (id1);
 
        return found;
 }
@@ -1331,9 +1442,9 @@ e_reminder_watcher_remove_from_past (EReminderWatcher *watcher,
                e_reminder_watcher_save_past (watcher, reminders);
 
                e_reminder_watcher_debug_print ("Removed reminder from past for '%s' from %s at %s\n",
-                       icalcomponent_get_summary (e_cal_component_get_icalcomponent (found->component)),
+                       i_cal_component_get_summary (e_cal_component_get_icalcomponent (found->component)),
                        found->source_uid,
-                       e_reminder_watcher_timet_as_string (found->instance.trigger));
+                       e_reminder_watcher_timet_as_string (e_cal_component_alarm_instance_get_time 
(found->instance)));
 
                e_reminder_data_free (found);
        }
@@ -1366,9 +1477,9 @@ e_reminder_watcher_remove_from_snoozed (EReminderWatcher *watcher,
                        e_reminder_watcher_save_snoozed (watcher);
 
                e_reminder_watcher_debug_print ("Removed reminder from snoozed for '%s' from %s at %s\n",
-                       icalcomponent_get_summary (e_cal_component_get_icalcomponent (found->component)),
+                       i_cal_component_get_summary (e_cal_component_get_icalcomponent (found->component)),
                        found->source_uid,
-                       e_reminder_watcher_timet_as_string (found->instance.trigger));
+                       e_reminder_watcher_timet_as_string (e_cal_component_alarm_instance_get_time 
(found->instance)));
 
                e_reminder_data_free (found);
        }
@@ -1490,8 +1601,8 @@ e_reminder_watcher_gather_nearest_scheduled_cb (gpointer key,
        gint *out_nearest = user_data;
        EReminderData *rd = reminders ? reminders->data : NULL;
 
-       if (rd && out_nearest && (!*out_nearest || rd->instance.trigger < *out_nearest))
-               *out_nearest = rd->instance.trigger;
+       if (rd && out_nearest && (!*out_nearest || e_cal_component_alarm_instance_get_time (rd->instance) < 
*out_nearest))
+               *out_nearest = e_cal_component_alarm_instance_get_time (rd->instance);
 }
 
 static gint64
@@ -1525,8 +1636,8 @@ e_reminder_watcher_maybe_schedule_next_trigger (EReminderWatcher *watcher,
        if (watcher->priv->snoozed && watcher->priv->snoozed->data) {
                const EReminderData *rd = watcher->priv->snoozed->data;
 
-               if (next_trigger <= 0 || rd->instance.trigger < next_trigger)
-                       next_trigger = rd->instance.trigger;
+               if (next_trigger <= 0 || e_cal_component_alarm_instance_get_time (rd->instance) < 
next_trigger)
+                       next_trigger = e_cal_component_alarm_instance_get_time (rd->instance);
        }
 
        if (watcher->priv->scheduled) {
@@ -1620,9 +1731,9 @@ e_reminder_watcher_reminders_snoozed_changed_cb (GSettings *settings,
                                changed = TRUE;
 
                                e_reminder_watcher_debug_print ("Removed reminder from snoozed for '%s' from 
%s at %s\n",
-                                       icalcomponent_get_summary (e_cal_component_get_icalcomponent 
(rd->component)),
+                                       i_cal_component_get_summary (e_cal_component_get_icalcomponent 
(rd->component)),
                                        rd->source_uid,
-                                       e_reminder_watcher_timet_as_string (rd->instance.trigger));
+                                       e_reminder_watcher_timet_as_string 
(e_cal_component_alarm_instance_get_time (rd->instance)));
                        }
                }
 
@@ -1633,9 +1744,9 @@ e_reminder_watcher_reminders_snoozed_changed_cb (GSettings *settings,
                                changed = TRUE;
 
                                e_reminder_watcher_debug_print ("Added reminder to snoozed for '%s' from %s 
at %s\n",
-                                       icalcomponent_get_summary (e_cal_component_get_icalcomponent 
(rd->component)),
+                                       i_cal_component_get_summary (e_cal_component_get_icalcomponent 
(rd->component)),
                                        rd->source_uid,
-                                       e_reminder_watcher_timet_as_string (rd->instance.trigger));
+                                       e_reminder_watcher_timet_as_string 
(e_cal_component_alarm_instance_get_time (rd->instance)));
                        }
                }
 
@@ -1653,9 +1764,9 @@ e_reminder_watcher_reminders_snoozed_changed_cb (GSettings *settings,
                                continue;
 
                        e_reminder_watcher_debug_print ("Removed reminder from snoozed for '%s' from %s at 
%s\n",
-                               icalcomponent_get_summary (e_cal_component_get_icalcomponent (rd->component)),
+                               i_cal_component_get_summary (e_cal_component_get_icalcomponent 
(rd->component)),
                                rd->source_uid,
-                               e_reminder_watcher_timet_as_string (rd->instance.trigger));
+                               e_reminder_watcher_timet_as_string (e_cal_component_alarm_instance_get_time 
(rd->instance)));
                }
 
                g_slist_free_full (old_snoozed, e_reminder_data_free);
@@ -2022,7 +2133,7 @@ e_reminder_watcher_finalize (GObject *object)
 {
        EReminderWatcher *watcher = E_REMINDER_WATCHER (object);
 
-       e_reminder_watcher_zone_free ((EReminderWatcherZone *) watcher->priv->default_zone);
+       g_clear_object (&watcher->priv->default_zone);
        g_rec_mutex_clear (&watcher->priv->lock);
 
        /* Chain up to parent's method. */
@@ -2071,8 +2182,7 @@ e_reminder_watcher_class_init (EReminderWatcherClass *klass)
        /**
         * EReminderWatcher:default-zone:
         *
-        * An icaltimezone to be used as the default time zone.
-        * It's encapsulated in a boxed type #EReminderWatcherZone.
+        * An #ICalTimezone to be used as the default time zone.
         *
         * Since: 3.30
         **/
@@ -2083,7 +2193,7 @@ e_reminder_watcher_class_init (EReminderWatcherClass *klass)
                        "default-zone",
                        "Default Zone",
                        "The default time zone",
-                       E_TYPE_REMINDER_WATCHER_ZONE,
+                       I_CAL_TYPE_TIMEZONE,
                        G_PARAM_READWRITE |
                        G_PARAM_EXPLICIT_NOTIFY |
                        G_PARAM_STATIC_STRINGS));
@@ -2115,7 +2225,7 @@ e_reminder_watcher_class_init (EReminderWatcherClass *klass)
         * EReminderWatcher::format-time:
         * @watcher: an #EReminderWatcher
         * @rd: an #EReminderData
-        * @itt: a pointer to struct icaltimetype
+        * @itt: an #ICalTimetype
         * @inout_buffer: (inout): a pointer to a buffer to fill with formatted @itt
         * @buffer_size: size of inout_buffer
         *
@@ -2186,23 +2296,23 @@ e_reminder_watcher_class_init (EReminderWatcherClass *klass)
 static void
 e_reminder_watcher_init (EReminderWatcher *watcher)
 {
-       icaltimezone *zone = NULL;
+       ICalTimezone *zone = NULL;
        gchar *location;
 
        location = e_cal_system_timezone_get_location ();
        if (location) {
-               zone = icaltimezone_get_builtin_timezone (location);
+               zone = i_cal_timezone_get_builtin_timezone (location);
                g_free (location);
        }
 
        if (!zone)
-               zone = icaltimezone_get_utc_timezone ();
+               zone = i_cal_timezone_get_utc_timezone ();
 
        watcher->priv = G_TYPE_INSTANCE_GET_PRIVATE (watcher, E_TYPE_REMINDER_WATCHER, 
EReminderWatcherPrivate);
        watcher->priv->cancellable = g_cancellable_new ();
        watcher->priv->settings = g_settings_new ("org.gnome.evolution-data-server.calendar");
        watcher->priv->scheduled = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, 
e_reminder_watcher_free_rd_slist);
-       watcher->priv->default_zone = icaltimezone_copy (zone);
+       watcher->priv->default_zone = e_cal_util_copy_timezone (zone);
        watcher->priv->timers_enabled = TRUE;
 
        g_rec_mutex_init (&watcher->priv->lock);
@@ -2268,7 +2378,7 @@ e_reminder_watcher_ref_opened_client (EReminderWatcher *watcher,
 /**
  * e_reminder_watcher_set_default_zone:
  * @watcher: an #EReminderWatcher
- * @zone: (nullable): an icaltimezone or #EReminderWatcherZone structure
+ * @zone: (nullable): an #ICalTimezone
  *
  * Sets the default zone for the @watcher. This is used when calculating
  * trigger times for floating component times. When the @zone is %NULL,
@@ -2278,27 +2388,27 @@ e_reminder_watcher_ref_opened_client (EReminderWatcher *watcher,
  **/
 void
 e_reminder_watcher_set_default_zone (EReminderWatcher *watcher,
-                                    const icaltimezone *zone)
+                                    const ICalTimezone *zone)
 {
        const gchar *new_location;
 
        g_return_if_fail (E_IS_REMINDER_WATCHER (watcher));
 
        if (!zone)
-               zone = icaltimezone_get_utc_timezone ();
+               zone = i_cal_timezone_get_utc_timezone ();
 
        g_rec_mutex_lock (&watcher->priv->lock);
 
-       new_location = icaltimezone_get_location ((icaltimezone *) zone);
+       new_location = i_cal_timezone_get_location ((ICalTimezone *) zone);
 
        if (new_location && g_strcmp0 (new_location,
-           icaltimezone_get_location (watcher->priv->default_zone)) == 0) {
+           i_cal_timezone_get_location (watcher->priv->default_zone)) == 0) {
                g_rec_mutex_unlock (&watcher->priv->lock);
                return;
        }
 
-       e_reminder_watcher_zone_free ((EReminderWatcherZone *) watcher->priv->default_zone);
-       watcher->priv->default_zone = (icaltimezone *) e_reminder_watcher_zone_copy ((const 
EReminderWatcherZone *) zone);
+       g_clear_object (&watcher->priv->default_zone);
+       watcher->priv->default_zone = e_cal_util_copy_timezone (zone);
 
        g_rec_mutex_unlock (&watcher->priv->lock);
 
@@ -2310,20 +2420,20 @@ e_reminder_watcher_set_default_zone (EReminderWatcher *watcher,
  * @watcher: an #EReminderWatcher
  *
  * Returns: (transfer full): A copy of the currently set default time zone.
- *    Use e_reminder_watcher_zone_free() to free it, when no longer needed.
+ *    Free it with g_object_unref(), when no longer needed.
  *
  * Since: 3.30
  **/
-icaltimezone *
+ICalTimezone *
 e_reminder_watcher_dup_default_zone (EReminderWatcher *watcher)
 {
-       icaltimezone *zone;
+       ICalTimezone *zone;
 
        g_return_val_if_fail (E_IS_REMINDER_WATCHER (watcher), NULL);
 
        g_rec_mutex_lock (&watcher->priv->lock);
 
-       zone = (icaltimezone *) e_reminder_watcher_zone_copy ((EReminderWatcherZone *) 
watcher->priv->default_zone);
+       zone = e_cal_util_copy_timezone (watcher->priv->default_zone);
 
        g_rec_mutex_unlock (&watcher->priv->lock);
 
@@ -2399,50 +2509,72 @@ static gchar *
 e_reminder_watcher_get_alarm_summary (EReminderWatcher *watcher,
                                      const EReminderData *rd)
 {
-       ECalComponentText summary_text, alarm_text;
+       ECalComponentText *summary_text, *alarm_text;
        ECalComponentAlarm *alarm;
        gchar *alarm_summary;
+       const gchar *summary_text_value, *alarm_text_value;
 
        g_return_val_if_fail (watcher != NULL, NULL);
        g_return_val_if_fail (rd != NULL, NULL);
 
-       summary_text.value = NULL;
-       alarm_text.value = NULL;
+       alarm_text = NULL;
 
-       e_cal_component_get_summary (rd->component, &summary_text);
+       summary_text = e_cal_component_get_summary (rd->component);
+       if (summary_text) {
+               const gchar *value;
 
-       alarm = e_cal_component_get_alarm (rd->component, rd->instance.auid);
+               value = e_cal_component_text_get_value (summary_text);
+               if (!value || !*value) {
+                       e_cal_component_text_free (summary_text);
+                       summary_text = NULL;
+               }
+       }
+
+       alarm = e_cal_component_get_alarm (rd->component, e_cal_component_alarm_instance_get_uid 
(rd->instance));
        if (alarm) {
                ECalClient *client;
 
                client = e_reminder_watcher_ref_opened_client (watcher, rd->source_uid);
 
                if (client && e_client_check_capability (E_CLIENT (client), 
E_CAL_STATIC_CAPABILITY_ALARM_DESCRIPTION)) {
-                       e_cal_component_alarm_get_description (alarm, &alarm_text);
-                       if (!alarm_text.value || !*alarm_text.value)
-                               alarm_text.value = NULL;
+                       alarm_text = e_cal_component_alarm_get_description (alarm);
+                       if (alarm_text) {
+                               const gchar *value;
+
+                               value = e_cal_component_text_get_value (alarm_text);
+                               if (!value || !*value) {
+                                       e_cal_component_text_free (alarm_text);
+                                       alarm_text = NULL;
+                               }
+                       }
                }
 
                g_clear_object (&client);
        }
 
-       if (alarm_text.value && summary_text.value &&
-           e_util_utf8_strcasecmp (alarm_text.value, summary_text.value) == 0)
-               alarm_text.value = NULL;
+       summary_text_value = summary_text ? e_cal_component_text_get_value (summary_text) : NULL;
+       alarm_text_value = alarm_text ? e_cal_component_text_get_value (alarm_text) : NULL;
+
+       if (alarm_text_value && summary_text_value &&
+           e_util_utf8_strcasecmp (alarm_text_value, summary_text_value) == 0) {
+               alarm_text_value = NULL;
+       }
 
-       if (summary_text.value && *summary_text.value &&
-           alarm_text.value && *alarm_text.value)
-               alarm_summary = g_strconcat (summary_text.value, "\n", alarm_text.value, NULL);
-       else if (summary_text.value && *summary_text.value)
-               alarm_summary = g_strdup (summary_text.value);
-       else if (alarm_text.value && *alarm_text.value)
-               alarm_summary = g_strdup (alarm_text.value);
+       if (summary_text_value && *summary_text_value &&
+           alarm_text_value && *alarm_text_value)
+               alarm_summary = g_strconcat (summary_text_value, "\n", alarm_text_value, NULL);
+       else if (summary_text_value && *summary_text_value)
+               alarm_summary = g_strdup (summary_text_value);
+       else if (alarm_text_value && *alarm_text_value)
+               alarm_summary = g_strdup (alarm_text_value);
        else
                alarm_summary = NULL;
 
        if (alarm)
                e_cal_component_alarm_free (alarm);
 
+       e_cal_component_text_free (summary_text);
+
        return alarm_summary;
 }
 
@@ -2466,7 +2598,7 @@ e_reminder_watcher_describe_data (EReminderWatcher *watcher,
                                  const EReminderData *rd,
                                  guint32 flags)
 {
-       icalcomponent *icalcomp;
+       ICalComponent *icalcomp;
        gchar *description = NULL;
        gboolean use_markup;
 
@@ -2486,37 +2618,39 @@ e_reminder_watcher_describe_data (EReminderWatcher *watcher,
                timestr[0] = 0;
                markup = g_string_sized_new (256);
                summary = e_reminder_watcher_get_alarm_summary (watcher, rd);
-               location = icalcomponent_get_location (icalcomp);
+               location = i_cal_component_get_location (icalcomp);
 
-               if (rd->instance.occur_start > 0) {
+               if (e_cal_component_alarm_instance_get_occur_start (rd->instance) > 0) {
                        gchar *timestrptr = timestr;
-                       icaltimezone *zone;
-                       struct icaltimetype itt;
+                       ICalTimezone *zone;
+                       ICalTimetype *itt;
                        gboolean is_date = FALSE;
 
-                       if (rd->instance.occur_end > rd->instance.occur_start) {
-                               timediff = e_cal_util_seconds_to_string (rd->instance.occur_end - 
rd->instance.occur_start);
+                       if (e_cal_component_alarm_instance_get_occur_end (rd->instance) > 
e_cal_component_alarm_instance_get_occur_start (rd->instance)) {
+                               timediff = e_cal_util_seconds_to_string (
+                                       e_cal_component_alarm_instance_get_occur_end (rd->instance) -
+                                       e_cal_component_alarm_instance_get_occur_start (rd->instance));
                        }
 
                        zone = e_reminder_watcher_dup_default_zone (watcher);
-                       if (zone && (!icaltimezone_get_location (zone) || g_strcmp0 
(icaltimezone_get_location (zone), "UTC") == 0)) {
-                               icaltimezone_free (zone, 1);
-                               zone = NULL;
+                       if (zone && (!i_cal_timezone_get_location (zone) || g_strcmp0 
(i_cal_timezone_get_location (zone), "UTC") == 0)) {
+                               g_clear_object (&zone);
                        }
 
-                       itt = icalcomponent_get_dtstart (icalcomp);
-                       if (icaltime_is_valid_time (itt) && !icaltime_is_null_time (itt))
-                               is_date = itt.is_date;
+                       itt = i_cal_component_get_dtstart (icalcomp);
+                       if (itt && i_cal_time_is_valid_time (itt) && !i_cal_time_is_null_time (itt))
+                               is_date = i_cal_time_is_date (itt);
+                       g_clear_object (&itt);
 
-                       itt = icaltime_from_timet_with_zone (rd->instance.occur_start, is_date, zone);
+                       itt = i_cal_time_from_timet_with_zone (e_cal_component_alarm_instance_get_occur_start 
(rd->instance), is_date, zone);
 
-                       g_signal_emit (watcher, signals[FORMAT_TIME], 0, rd, &itt, &timestrptr, 254, NULL);
+                       g_signal_emit (watcher, signals[FORMAT_TIME], 0, rd, itt, &timestrptr, 254, NULL);
 
                        if (!*timestr)
-                               e_reminder_watcher_format_time_impl (watcher, rd, &itt, &timestrptr, 254);
+                               e_reminder_watcher_format_time_impl (watcher, rd, itt, &timestrptr, 254);
 
-                       if (zone)
-                               icaltimezone_free (zone, 1);
+                       g_clear_object (&zone);
+                       g_clear_object (&itt);
                }
 
                if (!summary || !*summary) {
@@ -2625,7 +2759,7 @@ foreach_trigger_cb (gpointer key,
        for (link = reminders; link; link = g_slist_next (link)) {
                rd = link->data;
 
-               if (!rd || rd->instance.trigger > ftd->current_time)
+               if (!rd || e_cal_component_alarm_instance_get_time (rd->instance) > ftd->current_time)
                        break;
        }
 
@@ -2716,7 +2850,7 @@ e_reminder_watcher_timer_elapsed (EReminderWatcher *watcher)
        for (link = snoozed; link; link = g_slist_next (link)) {
                EReminderData *rd = link->data;
 
-               if (rd && rd->instance.trigger <= ftd.current_time) {
+               if (rd && e_cal_component_alarm_instance_get_time (rd->instance) <= ftd.current_time) {
                        link->data = NULL;
 
                        changed = e_reminder_watcher_remove_from_snoozed (watcher, rd, FALSE) || changed;
@@ -2746,11 +2880,11 @@ e_reminder_watcher_timer_elapsed (EReminderWatcher *watcher)
 
                                        ptrigger = g_hash_table_lookup (last_notifies, rd->source_uid);
                                        if (ptrigger) {
-                                               if (*ptrigger < rd->instance.trigger)
-                                                       *ptrigger = rd->instance.trigger;
+                                               if (*ptrigger < e_cal_component_alarm_instance_get_time 
(rd->instance))
+                                                       *ptrigger = e_cal_component_alarm_instance_get_time 
(rd->instance);
                                        } else {
                                                ptrigger = g_new0 (time_t, 1);
-                                               *ptrigger = rd->instance.trigger;
+                                               *ptrigger = e_cal_component_alarm_instance_get_time 
(rd->instance);
                                                g_hash_table_insert (last_notifies, rd->source_uid, ptrigger);
                                        }
                                }
@@ -2766,11 +2900,11 @@ e_reminder_watcher_timer_elapsed (EReminderWatcher *watcher)
 
                                        ptrigger = g_hash_table_lookup (last_notifies, rd->source_uid);
                                        if (ptrigger) {
-                                               if (*ptrigger < rd->instance.trigger)
-                                                       *ptrigger = rd->instance.trigger;
+                                               if (*ptrigger < e_cal_component_alarm_instance_get_time 
(rd->instance))
+                                                       *ptrigger = e_cal_component_alarm_instance_get_time 
(rd->instance);
                                        } else {
                                                ptrigger = g_new0 (time_t, 1);
-                                               *ptrigger = rd->instance.trigger;
+                                               *ptrigger = e_cal_component_alarm_instance_get_time 
(rd->instance);
                                                g_hash_table_insert (last_notifies, rd->source_uid, ptrigger);
                                        }
                                }
@@ -2920,14 +3054,14 @@ e_reminder_watcher_snooze (EReminderWatcher *watcher,
        changed = e_reminder_watcher_remove_from_past (watcher, rd_copy);
        changed = e_reminder_watcher_remove_from_snoozed (watcher, rd_copy, FALSE) || changed;
 
-       rd_copy->instance.trigger = (time_t) until;
+       e_cal_component_alarm_instance_set_time (rd_copy->instance, (time_t) until);
 
        changed = e_reminder_watcher_add (&watcher->priv->snoozed, rd_copy, FALSE, TRUE) || changed;
 
        e_reminder_watcher_debug_print ("Added reminder to snoozed for '%s' from %s at %s\n",
-               icalcomponent_get_summary (e_cal_component_get_icalcomponent (rd_copy->component)),
+               i_cal_component_get_summary (e_cal_component_get_icalcomponent (rd_copy->component)),
                rd_copy->source_uid,
-               e_reminder_watcher_timet_as_string (rd_copy->instance.trigger));
+               e_reminder_watcher_timet_as_string (e_cal_component_alarm_instance_get_time 
(rd_copy->instance)));
 
        e_reminder_watcher_save_snoozed (watcher);
        e_reminder_watcher_maybe_schedule_next_trigger (watcher, until);
@@ -3036,11 +3170,17 @@ e_reminder_watcher_dismiss_one_sync (ECalClient *client,
        if (id) {
                GError *local_error = NULL;
 
-               success = e_cal_client_discard_alarm_sync (client, id->uid, id->rid, rd->instance.auid, 
cancellable, &local_error);
+               success = e_cal_client_discard_alarm_sync (client,
+                       e_cal_component_id_get_uid (id),
+                       e_cal_component_id_get_rid (id),
+                       e_cal_component_alarm_instance_get_uid (rd->instance),
+                       cancellable, &local_error);
 
                e_reminder_watcher_debug_print ("Discard alarm for '%s' from %s (uid:%s rid:%s auid:%s) 
%s%s%s%s\n",
-                       icalcomponent_get_summary (e_cal_component_get_icalcomponent (rd->component)),
-                       rd->source_uid, id->uid, id->rid ? id->rid : "null", rd->instance.auid,
+                       i_cal_component_get_summary (e_cal_component_get_icalcomponent (rd->component)),
+                       rd->source_uid, e_cal_component_id_get_uid (id),
+                       e_cal_component_id_get_rid (id) ? e_cal_component_id_get_rid (id) : "null",
+                       e_cal_component_alarm_instance_get_uid (rd->instance),
                        success ? "succeeded" : "failed",
                        (!success || local_error) ? " (" : "",
                        local_error ? local_error->message : success ? "" : "Unknown error",
@@ -3050,7 +3190,7 @@ e_reminder_watcher_dismiss_one_sync (ECalClient *client,
                success = TRUE;
                g_clear_error (&local_error);
 
-               e_cal_component_free_id (id);
+               e_cal_component_id_free (id);
        }
 
        return success;
diff --git a/src/calendar/libecal/e-reminder-watcher.h b/src/calendar/libecal/e-reminder-watcher.h
index 285d6cc67..7da0c9df5 100644
--- a/src/calendar/libecal/e-reminder-watcher.h
+++ b/src/calendar/libecal/e-reminder-watcher.h
@@ -59,11 +59,7 @@ G_BEGIN_DECLS
  *
  * Since: 3.30
  **/
-typedef struct _EReminderData {
-       gchar *source_uid;
-       ECalComponent *component;
-       ECalComponentAlarmInstance instance;
-} EReminderData;
+typedef struct _EReminderData EReminderData;
 
 GType          e_reminder_data_get_type        (void) G_GNUC_CONST;
 EReminderData *        e_reminder_data_new             (const gchar *source_uid,
@@ -71,21 +67,16 @@ EReminderData *     e_reminder_data_new             (const gchar *source_uid,
                                                 const ECalComponentAlarmInstance *instance);
 EReminderData *        e_reminder_data_copy            (const EReminderData *rd);
 void           e_reminder_data_free            (gpointer rd); /* EReminderData * */
-
-/**
- * EReminderWatcherZone:
- *
- * A libical's icaltimezone encapsulated as a GBoxed type.
- * It can be retyped into icaltimezone directly.
- *
- * Since: 3.30
- **/
-typedef icaltimezone EReminderWatcherZone;
-
-GType          e_reminder_watcher_zone_get_type(void) G_GNUC_CONST;
-EReminderWatcherZone *
-               e_reminder_watcher_zone_copy    (const EReminderWatcherZone *watcher_zone);
-void           e_reminder_watcher_zone_free    (EReminderWatcherZone *watcher_zone);
+const gchar *  e_reminder_data_get_source_uid  (const EReminderData *rd);
+void           e_reminder_data_set_source_uid  (EReminderData *rd,
+                                                const gchar *source_uid);
+ECalComponent *        e_reminder_data_get_component   (const EReminderData *rd);
+void           e_reminder_data_set_component   (EReminderData *rd,
+                                                const ECalComponent *component);
+ECalComponentAlarmInstance *
+               e_reminder_data_get_instance    (const EReminderData *rd);
+void           e_reminder_data_set_instance    (EReminderData *rd,
+                                                const ECalComponentAlarmInstance *instance);
 
 typedef struct _EReminderWatcher EReminderWatcher;
 typedef struct _EReminderWatcherClass EReminderWatcherClass;
@@ -128,7 +119,7 @@ struct _EReminderWatcherClass {
                                                 gint64 at_time);
        void            (* format_time)         (EReminderWatcher *watcher,
                                                 const EReminderData *rd,
-                                                struct icaltimetype *itt,
+                                                ICalTimetype *itt,
                                                 gchar **inout_buffer,
                                                 gint buffer_size);
        void            (* triggered)           (EReminderWatcher *watcher,
@@ -166,8 +157,8 @@ ESourceRegistry *
 ECalClient *   e_reminder_watcher_ref_opened_client    (EReminderWatcher *watcher,
                                                         const gchar *source_uid);
 void           e_reminder_watcher_set_default_zone     (EReminderWatcher *watcher,
-                                                        const icaltimezone *zone);
-icaltimezone * e_reminder_watcher_dup_default_zone     (EReminderWatcher *watcher);
+                                                        const ICalTimezone *zone);
+ICalTimezone * e_reminder_watcher_dup_default_zone     (EReminderWatcher *watcher);
 gboolean       e_reminder_watcher_get_timers_enabled   (EReminderWatcher *watcher);
 void           e_reminder_watcher_set_timers_enabled   (EReminderWatcher *watcher,
                                                         gboolean enabled);
diff --git a/src/calendar/libecal/e-timezone-cache.c b/src/calendar/libecal/e-timezone-cache.c
index 0f0f86a75..dee781ac5 100644
--- a/src/calendar/libecal/e-timezone-cache.c
+++ b/src/calendar/libecal/e-timezone-cache.c
@@ -20,7 +20,7 @@
  * @include: libecal/libecal.h
  * @short_description: An interface for caching time zone data
  *
- * Several classes (both client-side and server-side) cache #icaltimezone
+ * Several classes (both client-side and server-side) cache #ICalTimezone
  * instances internally, indexed by their TZID strings.  Classes which do
  * this should implement #ETimezoneCacheInterface to provide a consistent
  * API for accessing time zone data.
@@ -39,7 +39,7 @@ e_timezone_cache_default_init (ETimezoneCacheInterface *iface)
        /**
         * ETimezoneCache::timezone-added:
         * @cache: the #ETimezoneCache which emitted the signal
-        * @zone: the newly-added #icaltimezone
+        * @zone: the newly-added #ICalTimezone
         *
         * Emitted when a new #icaltimezone is added to @cache.
         **/
@@ -50,29 +50,29 @@ e_timezone_cache_default_init (ETimezoneCacheInterface *iface)
                G_STRUCT_OFFSET (ETimezoneCacheInterface, timezone_added),
                NULL, NULL, NULL,
                G_TYPE_NONE, 1,
-               G_TYPE_POINTER);
+               I_CAL_TYPE_TIMEZONE);
 }
 
 /**
  * e_timezone_cache_add_timezone:
  * @cache: an #ETimezoneCache
- * @zone: an #icaltimezone
+ * @zone: an #ICalTimezone
  *
  * Adds a copy of @zone to @cache and emits a
  * #ETimezoneCache::timezone-added signal.  The @cache will use the TZID
- * string returned by icaltimezone_get_tzid() as the lookup key, which can
+ * string returned by i_cal_timezone_get_tzid() as the lookup key, which can
  * be passed to e_timezone_cache_get_timezone() to obtain @zone again.
  *
- * If the @cache already has an #icaltimezone with the same TZID string
+ * If the @cache already has an #ICalTimezone with the same TZID string
  * as @zone, the @cache will remain unchanged to avoid invalidating any
- * #icaltimezone pointers which may have already been returned through
+ * #ICalTimezone pointers which may have already been returned through
  * e_timezone_cache_get_timezone().
  *
  * Since: 3.8
  **/
 void
 e_timezone_cache_add_timezone (ETimezoneCache *cache,
-                               icaltimezone *zone)
+                              ICalTimezone *zone)
 {
        ETimezoneCacheInterface *iface;
 
@@ -90,15 +90,15 @@ e_timezone_cache_add_timezone (ETimezoneCache *cache,
  * @cache: an #ETimezoneCache
  * @tzid: the TZID of a timezone
  *
- * Obtains an #icaltimezone by its TZID string.  If no match is found,
- * the function returns %NULL.  The returned #icaltimezone is owned by
+ * Obtains an #ICalTimezone by its TZID string.  If no match is found,
+ * the function returns %NULL.  The returned #ICalTimezone is owned by
  * the @cache and should not be modified or freed.
  *
- * Returns: an #icaltimezone, or %NULL
+ * Returns: (transfer none) (nullable): an #ICalTimezone, or %NULL
  *
  * Since: 3.8
  **/
-icaltimezone *
+ICalTimezone *
 e_timezone_cache_get_timezone (ETimezoneCache *cache,
                                const gchar *tzid)
 {
@@ -117,7 +117,7 @@ e_timezone_cache_get_timezone (ETimezoneCache *cache,
  * e_timezone_cache_list_timezones:
  * @cache: an #ETimezoneCache
  *
- * Returns a list of #icaltimezone instances that were explicitly added to
+ * Returns a list of #ICalTimezone instances that were explicitly added to
  * the @cache through e_timezone_cache_add_timezone().  In particular, any
  * built-in time zone data that e_timezone_cache_get_timezone() may use to
  * match a TZID string is excluded from the returned list.
@@ -125,8 +125,8 @@ e_timezone_cache_get_timezone (ETimezoneCache *cache,
  * Free the returned list with g_list_free().  The list elements are owned
  * by the @cache and should not be modified or freed.
  *
- * Returns: (transfer container) (element-type icaltimezone): a #GList of
- *          #icaltimezone instances
+ * Returns: (transfer container) (element-type ICalTimezone): a #GList of
+ *    #ICalTimezone instances
  *
  * Since: 3.8
  **/
@@ -142,4 +142,3 @@ e_timezone_cache_list_timezones (ETimezoneCache *cache)
 
        return iface->list_timezones (cache);
 }
-
diff --git a/src/calendar/libecal/e-timezone-cache.h b/src/calendar/libecal/e-timezone-cache.h
index af1b46de7..91240bd80 100644
--- a/src/calendar/libecal/e-timezone-cache.h
+++ b/src/calendar/libecal/e-timezone-cache.h
@@ -64,22 +64,25 @@ struct _ETimezoneCacheInterface {
        /*< public >*/
        /* Methods */
        void            (*add_timezone)         (ETimezoneCache *cache,
-                                                icaltimezone *zone);
-       icaltimezone *  (*get_timezone)         (ETimezoneCache *cache,
+                                                ICalTimezone *zone);
+       ICalTimezone *  (*get_timezone)         (ETimezoneCache *cache,
                                                 const gchar *tzid);
-       GList *         (*list_timezones)       (ETimezoneCache *cache);
+       GList *         (*list_timezones)       (ETimezoneCache *cache); /* ICalTimezone * */
 
        /* Signals */
        void            (*timezone_added)       (ETimezoneCache *cache,
-                                                icaltimezone *zone);
+                                                ICalTimezone *zone);
+
+       /* Padding for future expansion */
+       gpointer reserved_signals[4];
 };
 
 GType          e_timezone_cache_get_type       (void) G_GNUC_CONST;
 void           e_timezone_cache_add_timezone   (ETimezoneCache *cache,
-                                                icaltimezone *zone);
-icaltimezone * e_timezone_cache_get_timezone   (ETimezoneCache *cache,
+                                                ICalTimezone *zone);
+ICalTimezone * e_timezone_cache_get_timezone   (ETimezoneCache *cache,
                                                 const gchar *tzid);
-GList *                e_timezone_cache_list_timezones (ETimezoneCache *cache);
+GList *                e_timezone_cache_list_timezones (ETimezoneCache *cache); /* ICalTimezone * */
 
 G_END_DECLS
 
diff --git a/src/libedataserverui/e-reminders-widget.c b/src/libedataserverui/e-reminders-widget.c
index 7b42c2d95..3703e1c39 100644
--- a/src/libedataserverui/e-reminders-widget.c
+++ b/src/libedataserverui/e-reminders-widget.c
@@ -262,7 +262,7 @@ reminders_get_reminder_markups (ERemindersWidget *reminders,
                gboolean in_future;
                gchar *time_str;
 
-               diff = (g_get_real_time () / G_USEC_PER_SEC) - ((gint64) rd->instance.occur_start);
+               diff = (g_get_real_time () / G_USEC_PER_SEC) - ((gint64) 
e_cal_component_alarm_instance_get_occur_start (e_reminder_data_get_instance (rd)));
                in_future = diff < 0;
                if (in_future)
                        diff = (-1) * diff;
@@ -870,9 +870,9 @@ reminders_widget_row_activated_cb (GtkTreeView *tree_view,
                                const gchar *scheme = NULL;
                                const gchar *comp_uid = NULL;
 
-                               e_cal_component_get_uid (rd->component, &comp_uid);
+                               comp_uid = e_cal_component_get_uid (e_reminder_data_get_component (rd));
 
-                               switch (e_cal_component_get_vtype (rd->component)) {
+                               switch (e_cal_component_get_vtype (e_reminder_data_get_component (rd))) {
                                        case E_CAL_COMPONENT_EVENT:
                                                scheme = "calendar:";
                                                break;
@@ -886,7 +886,7 @@ reminders_widget_row_activated_cb (GtkTreeView *tree_view,
                                                break;
                                }
 
-                               if (scheme && comp_uid && rd->source_uid) {
+                               if (scheme && comp_uid && e_reminder_data_get_source_uid (rd)) {
                                        GString *uri;
                                        gchar *tmp;
                                        GError *error = NULL;
@@ -895,7 +895,7 @@ reminders_widget_row_activated_cb (GtkTreeView *tree_view,
                                        g_string_append (uri, scheme);
                                        g_string_append (uri, "///?");
 
-                                       tmp = g_uri_escape_string (rd->source_uid, NULL, TRUE);
+                                       tmp = g_uri_escape_string (e_reminder_data_get_source_uid (rd), NULL, 
TRUE);
                                        g_string_append (uri, "source-uid=");
                                        g_string_append (uri, tmp);
                                        g_free (tmp);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]