[evolution-ews] Bug 782826 - Allow adding Free/Busy as a foreign Calendar



commit 338d7dd0871086d6d294b3191c76608fa3be8047
Author: Milan Crha <mcrha redhat com>
Date:   Wed May 24 09:38:55 2017 +0200

    Bug 782826 - Allow adding Free/Busy as a foreign Calendar

 src/calendar/e-cal-backend-ews-utils.c             |  233 +-----------
 src/calendar/e-cal-backend-ews-utils.h             |    3 -
 src/calendar/e-cal-backend-ews.c                   |  392 +++++++++++++++-----
 src/configuration/e-ews-subscribe-foreign-folder.c |   66 +++-
 src/server/CMakeLists.txt                          |    2 +
 src/server/e-ews-calendar-utils.c                  |  258 +++++++++++++
 src/server/e-ews-calendar-utils.h                  |   46 +++
 src/server/e-ews-connection.c                      |   19 +-
 src/server/e-ews-folder.c                          |   41 ++-
 src/server/e-ews-folder.h                          |    3 +
 src/server/e-source-ews-folder.c                   |  176 +++++++++
 src/server/e-source-ews-folder.h                   |   17 +
 12 files changed, 915 insertions(+), 341 deletions(-)
---
diff --git a/src/calendar/e-cal-backend-ews-utils.c b/src/calendar/e-cal-backend-ews-utils.c
index 41d77b4..7c37be2 100644
--- a/src/calendar/e-cal-backend-ews-utils.c
+++ b/src/calendar/e-cal-backend-ews-utils.c
@@ -40,6 +40,7 @@
 #include <libecal/libecal.h>
 #include <libsoup/soup-misc.h>
 
+#include "server/e-ews-calendar-utils.h"
 #include "server/e-ews-connection.h"
 #include "server/e-ews-message.h"
 #include "server/e-ews-item-change.h"
@@ -336,49 +337,6 @@ ews_set_alarm (ESoapMessage *msg,
 
 }
 
-void
-ewscal_set_time (ESoapMessage *msg,
-                 const gchar *name,
-                 icaltimetype *t,
-                 gboolean with_timezone)
-{
-       gchar *str;
-       gchar *tz_ident = NULL;
-
-       if (with_timezone) {
-               if (t->is_utc || !t->zone || t->zone == icaltimezone_get_utc_timezone ()) {
-                       tz_ident = g_strdup ("Z");
-               } else {
-                       gint offset, is_daylight, hrs, mins;
-
-                       offset = icaltimezone_get_utc_offset (
-                               icaltimezone_get_utc_timezone (), t, &is_daylight);
-
-                       offset = offset * (-1);
-                       hrs = offset / 60;
-                       mins = offset % 60;
-
-                       if (hrs < 0)
-                               hrs *= -1;
-                       if (mins < 0)
-                               mins *= -1;
-
-                       tz_ident = g_strdup_printf ("%s%02d:%02d", offset > 0 ? "+" : "-", hrs, mins);
-               }
-       }
-
-       str = g_strdup_printf (
-               "%04d-%02d-%02dT%02d:%02d:%02d%s",
-               t->year, t->month, t->day,
-               t->hour, t->minute, t->second,
-               tz_ident ? tz_ident : "");
-
-       e_ews_message_write_string_parameter (msg, name, NULL, str);
-
-       g_free (tz_ident);
-       g_free (str);
-}
-
 static void
 ewscal_set_date (ESoapMessage *msg,
                  const gchar *name,
@@ -711,136 +669,6 @@ ewscal_set_meeting_timezone (ESoapMessage *msg,
        e_soap_message_end_element (msg); /* "MeetingTimeZone" */
 }
 
-static void
-ewscal_add_availability_rrule (ESoapMessage *msg,
-                               icalproperty *prop)
-{
-       struct icalrecurrencetype recur = icalproperty_get_rrule (prop);
-       gchar buffer[16];
-       gint dayorder;
-
-       dayorder = icalrecurrencetype_day_position (recur.by_day[0]);
-       dayorder = dayorder % 5;
-       if (dayorder < 0)
-               dayorder += 5;
-       dayorder += 1;
-
-       /* expected value is 1..5, inclusive */
-       snprintf (buffer, 16, "%d", dayorder);
-       e_ews_message_write_string_parameter (msg, "DayOrder", NULL, buffer);
-
-       snprintf (buffer, 16, "%d", recur.by_month[0]);
-       e_ews_message_write_string_parameter (msg, "Month", NULL, buffer);
-
-       e_ews_message_write_string_parameter (msg, "DayOfWeek", NULL, number_to_weekday 
(icalrecurrencetype_day_day_of_week (recur.by_day[0])));
-}
-
-static void
-ewscal_add_availability_default_timechange (ESoapMessage *msg)
-{
-
-       e_soap_message_start_element (msg, "StandardTime", NULL, NULL);
-       e_ews_message_write_string_parameter (msg, "Bias", NULL, "0");
-       e_ews_message_write_string_parameter (msg, "Time", NULL, "00:00:00");
-       e_ews_message_write_string_parameter (msg, "DayOrder", NULL, "0");
-       e_ews_message_write_string_parameter (msg, "Month", NULL, "0");
-       e_ews_message_write_string_parameter (msg, "DayOfWeek", NULL, "Sunday");
-       e_soap_message_end_element (msg);
-
-       e_soap_message_start_element (msg, "DaylightTime", NULL, NULL);
-       e_ews_message_write_string_parameter (msg, "Bias", NULL, "0");
-       e_ews_message_write_string_parameter (msg, "Time", NULL, "00:00:00");
-       e_ews_message_write_string_parameter (msg, "DayOrder", NULL, "0");
-       e_ews_message_write_string_parameter (msg, "Month", NULL, "0");
-       e_ews_message_write_string_parameter (msg, "DayOfWeek", NULL, "Sunday");
-       e_soap_message_end_element (msg);
-}
-
-static void
-ewscal_add_availability_timechange (ESoapMessage *msg,
-                                    icalcomponent *comp,
-                                    gint baseoffs)
-{
-       gchar buffer[16];
-       icalproperty *prop;
-       struct icaltimetype dtstart;
-       gint utcoffs;
-
-       /* Calculate zone Offset from BaseOffset */
-       prop = icalcomponent_get_first_property (comp, ICAL_TZOFFSETTO_PROPERTY);
-       if (prop) {
-               utcoffs = -icalproperty_get_tzoffsetto (prop) / 60;
-               utcoffs -= baseoffs;
-               snprintf (buffer, 16, "%d", utcoffs);
-               e_ews_message_write_string_parameter (msg, "Bias", NULL, buffer);
-       }
-
-       prop = icalcomponent_get_first_property (comp, ICAL_DTSTART_PROPERTY);
-       if (prop) {
-               dtstart = icalproperty_get_dtstart (prop);
-               snprintf (buffer, 16, "%02d:%02d:%02d", dtstart.hour, dtstart.minute, dtstart.second);
-               e_ews_message_write_string_parameter (msg, "Time", NULL, buffer);
-       }
-
-       prop = icalcomponent_get_first_property (comp, ICAL_RRULE_PROPERTY);
-       if (prop)
-               ewscal_add_availability_rrule (msg, prop);
-}
-
-void
-ewscal_set_availability_timezone (ESoapMessage *msg,
-                                  icaltimezone *icaltz)
-{
-       icalcomponent *comp;
-       icalproperty *prop;
-       icalcomponent *xstd, *xdaylight;
-       gint std_utcoffs;
-       gchar *offset;
-
-       if (!icaltz)
-               return;
-
-       comp = icaltimezone_get_component (icaltz);
-
-       xstd = icalcomponent_get_first_component (comp, ICAL_XSTANDARD_COMPONENT);
-       xdaylight = icalcomponent_get_first_component (comp, ICAL_XDAYLIGHT_COMPONENT);
-
-       /*TimeZone is the root element of GetUserAvailabilityRequest*/
-       e_soap_message_start_element (msg, "TimeZone", NULL, NULL);
-
-       /* Fetch the timezone offsets for the standard (or only) zone.
-        * Negate it, because Exchange does it backwards */
-       if (xstd) {
-               prop = icalcomponent_get_first_property (xstd, ICAL_TZOFFSETTO_PROPERTY);
-               std_utcoffs = -icalproperty_get_tzoffsetto (prop) / 60;
-       } else
-               std_utcoffs = 0;
-
-       /* This is the overall BaseOffset tag, which the Standard and Daylight
-        * zones are offset from. It's redundant, but Exchange always sets it
-        * to the offset of the Standard zone, and the Offset in the Standard
-        * zone to zero. So try to avoid problems by doing the same. */
-       offset = g_strdup_printf ("%d", std_utcoffs);
-       e_ews_message_write_string_parameter (msg, "Bias", NULL, offset);
-       g_free (offset);
-
-       if (xdaylight) {
-               /* Standard */
-               e_soap_message_start_element (msg, "StandardTime", NULL, NULL);
-               ewscal_add_availability_timechange (msg, xstd, std_utcoffs);
-               e_soap_message_end_element (msg); /* "StandardTime" */
-
-               /* DayLight */
-               e_soap_message_start_element (msg, "DaylightTime", NULL, NULL);
-               ewscal_add_availability_timechange (msg, xdaylight, std_utcoffs);
-               e_soap_message_end_element (msg); /* "DaylightTime" */
-       } else
-               /* Set default values*/
-               ewscal_add_availability_default_timechange (msg);
-
-       e_soap_message_end_element (msg); /* "TimeZone" */
-}
-
 void
 ewscal_set_reccurence (ESoapMessage *msg,
                        icalproperty *rrule,
@@ -1319,8 +1147,8 @@ convert_vevent_calcomp_to_xml (ESoapMessage *msg,
                        ical_location_end);
        }
 
-       ewscal_set_time (msg, "Start", &dtstart, FALSE);
-       ewscal_set_time (msg, "End", &dtend, FALSE);
+       e_ews_cal_utils_set_time (msg, "Start", &dtstart, FALSE);
+       e_ews_cal_utils_set_time (msg, "End", &dtend, FALSE);
        /* We have to do the time zone(s) later, or the server rejects the request */
 
        /* All day event ? */
@@ -1422,7 +1250,7 @@ convert_vtodo_calcomp_to_xml (ESoapMessage *msg,
        prop = icalcomponent_get_first_property (icalcomp, ICAL_DUE_PROPERTY);
        if (prop) {
                dt = icalproperty_get_due (prop);
-               ewscal_set_time (msg, "DueDate", &dt, TRUE);
+               e_ews_cal_utils_set_time (msg, "DueDate", &dt, TRUE);
        }
 
        prop = icalcomponent_get_first_property (icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY);
@@ -1435,7 +1263,7 @@ convert_vtodo_calcomp_to_xml (ESoapMessage *msg,
        prop = icalcomponent_get_first_property (icalcomp, ICAL_DTSTART_PROPERTY);
        if (prop) {
                dt = icalproperty_get_dtstart (prop);
-               ewscal_set_time (msg, "StartDate", &dt, TRUE);
+               e_ews_cal_utils_set_time (msg, "StartDate", &dt, TRUE);
        }
 
        prop = icalcomponent_get_first_property (icalcomp, ICAL_STATUS_PROPERTY);
@@ -1749,13 +1577,13 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
 
        if (dt_start_changed) {
                e_ews_message_start_set_item_field (msg, "Start", "calendar","CalendarItem");
-               ewscal_set_time (msg, "Start", &dtstart, FALSE);
+               e_ews_cal_utils_set_time (msg, "Start", &dtstart, FALSE);
                e_ews_message_end_set_item_field (msg);
        }
 
        if (dt_end_changed) {
                e_ews_message_start_set_item_field (msg, "End", "calendar", "CalendarItem");
-               ewscal_set_time (msg, "End", &dtend, FALSE);
+               e_ews_cal_utils_set_time (msg, "End", &dtend, FALSE);
                e_ews_message_end_set_item_field (msg);
        }
 
@@ -1913,7 +1741,7 @@ convert_vtodo_component_to_updatexml (ESoapMessage *msg,
        if (prop) {
                dt = icalproperty_get_due (prop);
                e_ews_message_start_set_item_field (msg, "DueDate", "task", "Task");
-               ewscal_set_time (msg, "DueDate", &dt, TRUE);
+               e_ews_cal_utils_set_time (msg, "DueDate", &dt, TRUE);
                e_ews_message_end_set_item_field (msg);
        } else {
                e_ews_message_add_delete_item_field (msg, "DueDate", "task");
@@ -1932,7 +1760,7 @@ convert_vtodo_component_to_updatexml (ESoapMessage *msg,
        if (prop) {
                dt = icalproperty_get_dtstart (prop);
                e_ews_message_start_set_item_field (msg, "StartDate", "task", "Task");
-               ewscal_set_time (msg, "StartDate", &dt, TRUE);
+               e_ews_cal_utils_set_time (msg, "StartDate", &dt, TRUE);
                e_ews_message_end_set_item_field (msg);
        } else {
                e_ews_message_add_delete_item_field (msg, "StartDate", "task");
@@ -2098,49 +1926,6 @@ e_cal_backend_ews_clear_reminder_is_set (ESoapMessage *msg,
 }
 
 void
-e_cal_backend_ews_prepare_free_busy_request (ESoapMessage *msg,
-                                            gpointer user_data)
-{
-       EwsCalendarConvertData *convert_data = user_data;
-       GSList *addr;
-       icaltimetype t_start, t_end;
-       icaltimezone *utc_zone = icaltimezone_get_utc_timezone ();
-
-       ewscal_set_availability_timezone (msg, utc_zone);
-
-       e_soap_message_start_element (msg, "MailboxDataArray", "messages", NULL);
-
-       for (addr = convert_data->users; addr; addr = addr->next) {
-               e_soap_message_start_element (msg, "MailboxData", NULL, NULL);
-
-               e_soap_message_start_element (msg, "Email", NULL, NULL);
-               e_ews_message_write_string_parameter (msg, "Address", NULL, addr->data);
-               e_soap_message_end_element (msg); /* "Email" */
-
-               e_ews_message_write_string_parameter (msg, "AttendeeType", NULL, "Required");
-               e_ews_message_write_string_parameter (msg, "ExcludeConflicts", NULL, "false");
-
-               e_soap_message_end_element (msg); /* "MailboxData" */
-       }
-
-       e_soap_message_end_element (msg); /* "MailboxDataArray" */
-
-       e_soap_message_start_element (msg, "FreeBusyViewOptions", NULL, NULL);
-
-       e_soap_message_start_element (msg, "TimeWindow", NULL, NULL);
-       t_start = icaltime_from_timet_with_zone (convert_data->start, 0, utc_zone);
-       t_end = icaltime_from_timet_with_zone (convert_data->end, 0, utc_zone);
-       ewscal_set_time (msg, "StartTime", &t_start, FALSE);
-       ewscal_set_time (msg, "EndTime", &t_end, FALSE);
-       e_soap_message_end_element (msg); /* "TimeWindow" */
-
-       e_ews_message_write_string_parameter (msg, "MergedFreeBusyIntervalInMinutes", NULL, "60");
-       e_ews_message_write_string_parameter (msg, "RequestedView", NULL, "DetailedMerged");
-
-       e_soap_message_end_element (msg); /* "FreeBusyViewOptions" */
-}
-
-void
 e_cal_backend_ews_prepare_set_free_busy_status (ESoapMessage *msg,
                                                gpointer user_data)
 {
diff --git a/src/calendar/e-cal-backend-ews-utils.h b/src/calendar/e-cal-backend-ews-utils.h
index c17c803..0427a2f 100644
--- a/src/calendar/e-cal-backend-ews-utils.h
+++ b/src/calendar/e-cal-backend-ews-utils.h
@@ -57,10 +57,8 @@ typedef struct {
 const gchar *e_ews_collect_organizer (icalcomponent *comp);
 void e_ews_collect_attendees (icalcomponent *comp, GSList **required, GSList **optional, GSList **resource);
 
-void ewscal_set_time (ESoapMessage *msg, const gchar *name, icaltimetype *t, gboolean with_timezone);
 void ewscal_set_timezone (ESoapMessage *msg, const gchar *name, EEwsCalendarTimeZoneDefinition *tzd);
 void ewscal_set_meeting_timezone (ESoapMessage *msg, icaltimezone *icaltz);
-void ewscal_set_availability_timezone (ESoapMessage *msg, icaltimezone *icaltz);
 void ewscal_set_reccurence (ESoapMessage *msg, icalproperty *rrule, icaltimetype *dtstart);
 void ewscal_set_reccurence_exceptions (ESoapMessage *msg, icalcomponent *comp);
 void ewscal_get_attach_differences (const GSList *original, const GSList *modified, GSList **removed, GSList 
**added);
@@ -77,7 +75,6 @@ void e_cal_backend_ews_unref_windows_zones (void);
 void e_cal_backend_ews_convert_calcomp_to_xml (ESoapMessage *msg, gpointer user_data);
 void e_cal_backend_ews_convert_component_to_updatexml (ESoapMessage *msg, gpointer user_data);
 void e_cal_backend_ews_clear_reminder_is_set (ESoapMessage *msg, gpointer user_data);
-void e_cal_backend_ews_prepare_free_busy_request (ESoapMessage *msg, gpointer user_data);
 void e_cal_backend_ews_prepare_set_free_busy_status (ESoapMessage *msg,gpointer user_data);
 void e_cal_backend_ews_prepare_accept_item_request (ESoapMessage *msg, gpointer user_data);
 
diff --git a/src/calendar/e-cal-backend-ews.c b/src/calendar/e-cal-backend-ews.c
index 6e6d2ca..b32837a 100644
--- a/src/calendar/e-cal-backend-ews.c
+++ b/src/calendar/e-cal-backend-ews.c
@@ -41,6 +41,7 @@
 #include <calendar/gui/itip-utils.h>
 
 #include "server/e-source-ews-folder.h"
+#include "server/e-ews-calendar-utils.h"
 #include "server/e-ews-connection-utils.h"
 #include "server/e-ews-camel-common.h"
 
@@ -84,6 +85,7 @@ struct _ECalBackendEwsPrivate {
 
        guint subscription_key;
        gboolean listen_notifications;
+       gboolean is_freebusy_calendar;
 };
 
 #define PRIV_LOCK(p)   (g_rec_mutex_lock (&(p)->rec_mutex))
@@ -732,7 +734,7 @@ cbews_listen_notifications_cb (ECalBackendEws *cbews,
                return;
        }
 
-       cbews->priv->listen_notifications = camel_ews_settings_get_listen_notifications (ews_settings);
+       cbews->priv->listen_notifications = !cbews->priv->is_freebusy_calendar && 
camel_ews_settings_get_listen_notifications (ews_settings);
        PRIV_UNLOCK (cbews->priv);
 
        thread = g_thread_new (NULL, handle_notifications_thread, g_object_ref (cbews));
@@ -816,6 +818,7 @@ e_cal_backend_ews_open (ECalBackend *backend,
                extension_name = E_SOURCE_EXTENSION_EWS_FOLDER;
                extension = e_source_get_extension (source, extension_name);
                priv->folder_id = e_source_ews_folder_dup_id (extension);
+               priv->is_freebusy_calendar = g_strcmp0 (priv->folder_id, "freebusy-calendar") == 0;
 
                priv->storage_path = g_build_filename (cache_dir, priv->folder_id, NULL);
 
@@ -845,11 +848,11 @@ e_cal_backend_ews_open (ECalBackend *backend,
                ret = cal_backend_ews_ensure_connected (cbews, cancellable, &error);
 
        if (ret) {
-               e_cal_backend_set_writable (backend, TRUE);
+               e_cal_backend_set_writable (backend, !priv->is_freebusy_calendar);
 
                PRIV_LOCK (priv);
                if (priv->cnc != NULL) {
-                       priv->listen_notifications = camel_ews_settings_get_listen_notifications 
(ews_settings);
+                       priv->listen_notifications = !priv->is_freebusy_calendar && 
camel_ews_settings_get_listen_notifications (ews_settings);
 
                        if (priv->listen_notifications)
                                cbews_listen_notifications_cb (cbews, NULL, ews_settings);
@@ -3856,6 +3859,34 @@ cbews_forget_all_components (ECalBackendEws *cbews)
        g_slist_free_full (ids, (GDestroyNotify) e_cal_component_free_id);
 }
 
+static gboolean
+ews_freebusy_ecomp_changed (ECalComponent *ecomp,
+                           icalcomponent *vevent)
+{
+       icalcomponent *icomp;
+       gboolean changed = FALSE;
+
+       g_return_val_if_fail (vevent != NULL, FALSE);
+
+       if (!ecomp)
+               return TRUE;
+
+       icomp = e_cal_component_get_icalcomponent (ecomp);
+       if (!icomp)
+               return TRUE;
+
+       if (!changed)
+               changed = g_strcmp0 (icalcomponent_get_summary (icomp), icalcomponent_get_summary (vevent)) 
!= 0;
+       if (!changed)
+               changed = g_strcmp0 (icalcomponent_get_location (icomp), icalcomponent_get_location (vevent)) 
!= 0;
+       if (!changed)
+               changed = icaltime_compare (icalcomponent_get_dtstart (icomp), icalcomponent_get_dtstart 
(vevent)) != 0;
+       if (!changed)
+               changed = icaltime_compare (icalcomponent_get_dtend (icomp), icalcomponent_get_dtend 
(vevent)) != 0;
+
+       return changed;
+}
+
 static gpointer
 ews_start_sync_thread (gpointer data)
 {
@@ -3876,95 +3907,288 @@ ews_start_sync_thread (gpointer data)
 
        cancellable = cal_backend_ews_ref_cancellable (cbews);
 
-       old_sync_state = g_strdup (e_cal_backend_store_get_key_value (priv->store, SYNC_KEY));
-       do {
-               EEwsAdditionalProps *add_props;
-               GCancellable *cancellable;
+       if (priv->is_freebusy_calendar) {
+               ESourceEwsFolder *ews_folder;
+               EEWSFreeBusyData fbdata;
+               GSList *free_busy = NULL, *link;
+               gboolean success;
+               time_t today;
 
-               includes_last_item = TRUE;
+               ews_folder = e_source_get_extension (e_backend_get_source (E_BACKEND (cbews)), 
E_SOURCE_EXTENSION_EWS_FOLDER);
 
-               add_props = e_ews_additional_props_new ();
-               add_props->field_uri = g_strdup ("item:ItemClass");
+               today = time_day_begin (time (NULL));
 
-               cancellable = cal_backend_ews_ref_cancellable (cbews);
+               fbdata.period_start = time_add_week (today, -e_source_ews_folder_get_freebusy_weeks_before 
(ews_folder));
+               fbdata.period_end = time_day_end (time_add_week (today, 
e_source_ews_folder_get_freebusy_weeks_after (ews_folder)));
+               fbdata.user_mails = g_slist_prepend (NULL, e_source_ews_folder_dup_foreign_mail (ews_folder));
 
-               ret = e_ews_connection_sync_folder_items_sync (
-                       priv->cnc,
-                       EWS_PRIORITY_MEDIUM,
-                       old_sync_state,
-                       priv->folder_id,
-                       "IdOnly",
-                       add_props,
-                       EWS_MAX_FETCH_COUNT,
-                       &new_sync_state,
-                       &includes_last_item,
-                       &items_created,
-                       &items_updated,
-                       &items_deleted,
-                       cancellable,
-                       &error);
+               success = e_ews_connection_get_free_busy_sync (priv->cnc, G_PRIORITY_DEFAULT,
+                       e_ews_cal_utils_prepare_free_busy_request, &fbdata,
+                       &free_busy, cancellable, &error);
 
-               e_ews_additional_props_free (add_props);
-               g_clear_object (&cancellable);
-               g_free (old_sync_state);
-               old_sync_state = NULL;
-
-               if (!ret) {
-                       if (g_error_matches (error, EWS_CONNECTION_ERROR, 
EWS_CONNECTION_ERROR_INVALIDSYNCSTATEDATA)) {
-                               g_clear_error (&error);
-                               e_cal_backend_store_put_key_value (priv->store, SYNC_KEY, NULL);
-                               cbews_forget_all_components (cbews);
-
-                               if (!e_ews_connection_sync_folder_items_sync (
-                                                       priv->cnc,
-                                                       EWS_PRIORITY_MEDIUM,
-                                                       NULL,
-                                                       priv->folder_id,
-                                                       "IdOnly",
-                                                       NULL,
-                                                       EWS_MAX_FETCH_COUNT,
-                                                       &new_sync_state,
-                                                       &includes_last_item,
-                                                       &items_created,
-                                                       &items_updated,
-                                                       &items_deleted,
-                                                       cancellable,
-                                                       &error)) {
-                                       if (!g_error_matches (
-                                                       error,
-                                                       EWS_CONNECTION_ERROR,
-                                                       EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED)) {
-                                               e_cal_backend_set_writable (E_CAL_BACKEND (cbews), TRUE);
-                                               break;
+               if (success) {
+                       icaltimezone *utc_zone = icaltimezone_get_utc_timezone ();
+                       GSList *ids;
+                       GHashTable *known;
+                       GHashTableIter iter;
+                       gpointer key;
+
+                       known = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+                       ids = e_cal_backend_store_get_component_ids (priv->store);
+                       for (link = ids; link; link = g_slist_next (link)) {
+                               ECalComponentId *id = link->data;
+
+                               if (id && id->uid && *id->uid)
+                                       g_hash_table_insert (known, g_strdup (id->uid), NULL);
+                       }
+                       g_slist_free_full (ids, (GDestroyNotify) e_cal_component_free_id);
+
+                       for (link = free_busy; link; link = g_slist_next (link)) {
+                               icalcomponent *fbcomp = link->data;
+                               icalproperty *fbprop;
+                               icalparameter *param;
+                               struct icalperiodtype fb;
+                               icalparameter_fbtype fbtype;
+
+                               if (!fbcomp || icalcomponent_isa (fbcomp) != ICAL_VFREEBUSY_COMPONENT)
+                                       continue;
+
+                               for (fbprop = icalcomponent_get_first_property (fbcomp, 
ICAL_FREEBUSY_PROPERTY);
+                                    fbprop;
+                                    fbprop = icalcomponent_get_next_property (fbcomp, 
ICAL_FREEBUSY_PROPERTY)) {
+                                       icalcomponent *vevent;
+                                       const gchar *id, *summary, *location;
+
+                                       param = icalproperty_get_first_parameter (fbprop, 
ICAL_FBTYPE_PARAMETER);
+                                       if (!param)
+                                               continue;
+
+                                       fbtype = icalparameter_get_fbtype (param);
+
+                                       if (fbtype != ICAL_FBTYPE_FREE &&
+                                           fbtype != ICAL_FBTYPE_BUSY &&
+                                           fbtype != ICAL_FBTYPE_BUSYUNAVAILABLE &&
+                                           fbtype != ICAL_FBTYPE_BUSYTENTATIVE)
+                                               continue;
+
+                                       fb = icalproperty_get_freebusy (fbprop);
+                                       id = icalproperty_get_parameter_as_string (fbprop, "X-EWS-ID");
+                                       summary = icalproperty_get_parameter_as_string (fbprop, "X-SUMMARY");
+                                       location = icalproperty_get_parameter_as_string (fbprop, 
"X-LOCATION");
+
+                                       vevent = icalcomponent_new_vevent ();
+
+                                       if (id && *id) {
+                                               icalcomponent_set_uid (vevent, id);
+                                       } else {
+                                               gchar *uid;
+
+                                               uid = g_strdup_printf ("%s-%s-%d",
+                                                       icaltime_as_ical_string (fb.start),
+                                                       icaltime_as_ical_string (fb.end),
+                                                       (gint) fbtype);
+
+                                               icalcomponent_set_uid (vevent, uid);
+
+                                               g_free (uid);
+                                       }
+
+                                       fb.start.zone = utc_zone;
+                                       fb.start.is_utc = 1;
+                                       fb.end.zone = utc_zone;
+                                       fb.end.is_utc = 1;
+
+                                       icalcomponent_set_dtstart (vevent, fb.start);
+                                       icalcomponent_set_dtend (vevent, fb.end);
+
+                                       icalcomponent_add_property (vevent, icalproperty_new_created 
(icaltime_current_time_with_zone (utc_zone)));
+
+                                       if (fbtype == ICAL_FBTYPE_FREE) {
+                                               icalcomponent_set_summary (vevent, C_("FreeBusyType", 
"Free"));
+                                               icalcomponent_add_property (vevent, icalproperty_new_transp 
(ICAL_TRANSP_TRANSPARENT));
+                                       } else if (fbtype == ICAL_FBTYPE_BUSY) {
+                                               icalcomponent_set_summary (vevent, C_("FreeBusyType", 
"Busy"));
+                                       } else if (fbtype == ICAL_FBTYPE_BUSYUNAVAILABLE) {
+                                               icalcomponent_set_summary (vevent, C_("FreeBusyType", "Out of 
Office"));
+                                       } else if (fbtype == ICAL_FBTYPE_BUSYTENTATIVE) {
+                                               icalcomponent_set_summary (vevent, C_("FreeBusyType", 
"Tentative"));
+                                       }
+
+                                       if (summary && *summary)
+                                               icalcomponent_set_summary (vevent, summary);
+
+                                       if (location && *location)
+                                               icalcomponent_set_location (vevent, location);
+
+                                       PRIV_LOCK (priv);
+                                       if (g_hash_table_remove (known, icalcomponent_get_uid (vevent))) {
+                                               ECalComponent *ecomp = g_hash_table_lookup 
(priv->item_id_hash, icalcomponent_get_uid (vevent));
+
+                                               g_object_ref (ecomp);
+
+                                               PRIV_UNLOCK (priv);
+
+                                               if (ews_freebusy_ecomp_changed (ecomp, vevent)) {
+                                                       ECalComponent *new_ecomp;
+                                                       gchar *uid = g_strdup (icalcomponent_get_uid 
(vevent));
+
+                                                       new_ecomp = e_cal_component_new_from_icalcomponent 
(vevent);
+                                                       if (new_ecomp) {
+                                                               PRIV_LOCK (priv);
+                                                               g_hash_table_insert (priv->item_id_hash, uid, 
g_object_ref (new_ecomp));
+                                                               PRIV_UNLOCK (priv);
+
+                                                               put_component_to_store (cbews, new_ecomp);
+                                                               e_cal_backend_notify_component_modified 
(E_CAL_BACKEND (cbews), ecomp, new_ecomp);
+
+                                                               g_object_unref (new_ecomp);
+                                                       } else {
+                                                               g_free (uid);
+                                                       }
+                                               } else {
+                                                       icalcomponent_free (vevent);
+                                               }
+
+                                               g_clear_object (&ecomp);
+                                       } else {
+                                               ECalComponent *ecomp;
+                                               gchar *uid = g_strdup (icalcomponent_get_uid (vevent));
+
+                                               ecomp = e_cal_component_new_from_icalcomponent (vevent);
+                                               if (ecomp)
+                                                       g_hash_table_insert (priv->item_id_hash, uid, 
g_object_ref (ecomp));
+                                               else
+                                                       g_free (uid);
+
+                                               PRIV_UNLOCK (priv);
+
+                                               if (ecomp) {
+                                                       put_component_to_store (cbews, ecomp);
+                                                       e_cal_backend_notify_component_created (E_CAL_BACKEND 
(cbews), ecomp);
+                                               }
+
+                                               g_clear_object (&ecomp);
                                        }
                                }
-                       } else {
-                               break;
                        }
+
+                       g_hash_table_iter_init (&iter, known);
+                       while (g_hash_table_iter_next (&iter, &key, NULL)) {
+                               ECalComponentId id = { 0 };
+
+                               id.uid = key;
+                               id.rid = NULL;
+
+                               if (e_cal_backend_store_remove_component (priv->store, id.uid, id.rid)) {
+                                       e_cal_backend_notify_component_removed (E_CAL_BACKEND (cbews), &id, 
NULL, NULL);
+
+                                       PRIV_LOCK (priv);
+                                       g_hash_table_remove (priv->item_id_hash, id.uid);
+                                       PRIV_UNLOCK (priv);
+                               }
+                       }
+
+                       g_hash_table_destroy (known);
+               } else if (g_error_matches (error, EWS_CONNECTION_ERROR, 
EWS_CONNECTION_ERROR_NOFREEBUSYACCESS)) {
+                       cbews_forget_all_components (cbews);
+                       e_cal_backend_notify_error (E_CAL_BACKEND (cbews), error->message);
+                       g_clear_error (&error);
                }
 
-               ret = cal_backend_ews_process_folder_items (
-                               cbews,
-                               new_sync_state,
-                               items_created,
-                               items_updated,
-                               items_deleted);
+               g_slist_free_full (free_busy, (GDestroyNotify) icalcomponent_free);
+               g_slist_free_full (fbdata.user_mails, g_free);
+       } else {
+               old_sync_state = g_strdup (e_cal_backend_store_get_key_value (priv->store, SYNC_KEY));
+               do {
+                       EEwsAdditionalProps *add_props;
+                       GCancellable *cancellable;
 
-               if (!ret)
-                       break;
+                       includes_last_item = TRUE;
 
-               g_slist_free_full (items_created, g_object_unref);
-               g_slist_free_full (items_updated, g_object_unref);
-               g_slist_free_full (items_deleted, g_free);
-               items_created = NULL;
-               items_updated = NULL;
-               items_deleted = NULL;
+                       add_props = e_ews_additional_props_new ();
+                       add_props->field_uri = g_strdup ("item:ItemClass");
 
-               e_cal_backend_store_put_key_value (priv->store, SYNC_KEY, new_sync_state);
+                       cancellable = cal_backend_ews_ref_cancellable (cbews);
+
+                       ret = e_ews_connection_sync_folder_items_sync (
+                               priv->cnc,
+                               EWS_PRIORITY_MEDIUM,
+                               old_sync_state,
+                               priv->folder_id,
+                               "IdOnly",
+                               add_props,
+                               EWS_MAX_FETCH_COUNT,
+                               &new_sync_state,
+                               &includes_last_item,
+                               &items_created,
+                               &items_updated,
+                               &items_deleted,
+                               cancellable,
+                               &error);
 
-               old_sync_state = new_sync_state;
-               new_sync_state = NULL;
-       } while (!includes_last_item);
+                       e_ews_additional_props_free (add_props);
+                       g_clear_object (&cancellable);
+                       g_free (old_sync_state);
+                       old_sync_state = NULL;
+
+                       if (!ret) {
+                               if (g_error_matches (error, EWS_CONNECTION_ERROR, 
EWS_CONNECTION_ERROR_INVALIDSYNCSTATEDATA)) {
+                                       g_clear_error (&error);
+                                       e_cal_backend_store_put_key_value (priv->store, SYNC_KEY, NULL);
+                                       cbews_forget_all_components (cbews);
+
+                                       if (!e_ews_connection_sync_folder_items_sync (
+                                                               priv->cnc,
+                                                               EWS_PRIORITY_MEDIUM,
+                                                               NULL,
+                                                               priv->folder_id,
+                                                               "IdOnly",
+                                                               NULL,
+                                                               EWS_MAX_FETCH_COUNT,
+                                                               &new_sync_state,
+                                                               &includes_last_item,
+                                                               &items_created,
+                                                               &items_updated,
+                                                               &items_deleted,
+                                                               cancellable,
+                                                               &error)) {
+                                               if (!g_error_matches (
+                                                               error,
+                                                               EWS_CONNECTION_ERROR,
+                                                               EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED)) {
+                                                       e_cal_backend_set_writable (E_CAL_BACKEND (cbews), 
TRUE);
+                                                       break;
+                                               }
+                                       }
+                               } else {
+                                       break;
+                               }
+                       }
+
+                       ret = cal_backend_ews_process_folder_items (
+                                       cbews,
+                                       new_sync_state,
+                                       items_created,
+                                       items_updated,
+                                       items_deleted);
+
+                       if (!ret)
+                               break;
+
+                       g_slist_free_full (items_created, g_object_unref);
+                       g_slist_free_full (items_updated, g_object_unref);
+                       g_slist_free_full (items_deleted, g_free);
+                       items_created = NULL;
+                       items_updated = NULL;
+                       items_deleted = NULL;
+
+                       e_cal_backend_store_put_key_value (priv->store, SYNC_KEY, new_sync_state);
+
+                       old_sync_state = new_sync_state;
+                       new_sync_state = NULL;
+               } while (!includes_last_item);
+       }
 
        ews_refreshing_dec (cbews);
 
@@ -4162,7 +4386,7 @@ e_cal_backend_ews_get_free_busy (ECalBackend *backend,
        ECalBackendEwsPrivate *priv = cbews->priv;
        GError *error = NULL;
        EwsCalendarAsyncData *free_busy_data;
-       EwsCalendarConvertData convert_data = { 0 };
+       EEWSFreeBusyData fbdata = { 0 };
        GSList *users_copy = NULL;
 
        /* make sure we're not offline */
@@ -4192,15 +4416,15 @@ e_cal_backend_ews_get_free_busy (ECalBackend *backend,
        free_busy_data->context = context;
        free_busy_data->users = users_copy;
 
-       convert_data.users = users_copy;
-       convert_data.start = start;
-       convert_data.end = end;
+       fbdata.period_start = start;
+       fbdata.period_end = end;
+       fbdata.user_mails = users_copy;
 
        e_ews_connection_get_free_busy (
                priv->cnc,
                EWS_PRIORITY_MEDIUM,
-               e_cal_backend_ews_prepare_free_busy_request,
-               &convert_data,
+               e_ews_cal_utils_prepare_free_busy_request,
+               &fbdata,
                cancellable,
                ews_cal_get_free_busy_cb,
                free_busy_data);
diff --git a/src/configuration/e-ews-subscribe-foreign-folder.c 
b/src/configuration/e-ews-subscribe-foreign-folder.c
index 20136a4..f619355 100644
--- a/src/configuration/e-ews-subscribe-foreign-folder.c
+++ b/src/configuration/e-ews-subscribe-foreign-folder.c
@@ -32,6 +32,8 @@
 #include "camel/camel-ews-store-summary.h"
 #include "camel/camel-ews-utils.h"
 
+#include "server/e-ews-calendar-utils.h"
+
 #include "e-ews-config-utils.h"
 #include "e-ews-search-user.h"
 #include "e-ews-subscribe-foreign-folder.h"
@@ -342,24 +344,53 @@ check_foreign_folder_thread (GObject *with_object,
                return;
        }
 
-       fid.id = (gchar *) (cffd->use_foldername ? cffd->use_foldername : cffd->orig_foldername);
-       fid.change_key = NULL;
-       fid.is_distinguished_id = cffd->use_foldername != NULL;
-
-       if (!e_ews_connection_get_folder_info_sync (conn, G_PRIORITY_DEFAULT,
-               cffd->email, &fid, &folder, cancellable, &local_error)) {
-               if (g_error_matches (local_error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_ITEMNOTFOUND) ||
-                   g_error_matches (local_error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_FOLDERNOTFOUND)) 
{
-                       g_clear_error (&local_error);
-                       local_error = g_error_new (
-                               EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_FOLDERNOTFOUND,
-                               _("Folder ā€œ%sā€ not found. Either it does not exist or you do not have 
permission to access it."),
-                               cffd->orig_foldername);
+       if (g_strcmp0 (cffd->use_foldername, "freebusy-calendar") == 0) {
+               EEWSFreeBusyData fbdata;
+               GSList *free_busy = NULL;
+               gboolean success;
+
+               fbdata.period_start = time (NULL);
+               fbdata.period_end = fbdata.period_start + (60 * 60);
+               fbdata.user_mails = g_slist_prepend (NULL, cffd->email);
+
+               success = e_ews_connection_get_free_busy_sync (conn, G_PRIORITY_DEFAULT,
+                       e_ews_cal_utils_prepare_free_busy_request, &fbdata,
+                       &free_busy, cancellable, perror);
+
+               g_slist_free_full (free_busy, (GDestroyNotify) icalcomponent_free);
+               g_slist_free (fbdata.user_mails);
+
+               if (!success) {
+                       g_object_unref (conn);
+                       return;
                }
 
-               g_propagate_error (perror, local_error);
-               g_object_unref (conn);
-               return;
+               folder = g_object_new (E_TYPE_EWS_FOLDER, NULL);
+               e_ews_folder_set_id (folder, e_ews_folder_id_new (cffd->use_foldername, NULL, FALSE));
+               /* Translators: This is used as a calendar name; it constructs "User Name - Availability" 
string shown in UI */
+               e_ews_folder_set_name (folder, _("Availability"));
+               e_ews_folder_set_folder_type (folder, E_EWS_FOLDER_TYPE_CALENDAR);
+               e_ews_folder_set_foreign_mail (folder, cffd->email);
+       } else {
+               fid.id = (gchar *) (cffd->use_foldername ? cffd->use_foldername : cffd->orig_foldername);
+               fid.change_key = NULL;
+               fid.is_distinguished_id = cffd->use_foldername != NULL;
+
+               if (!e_ews_connection_get_folder_info_sync (conn, G_PRIORITY_DEFAULT,
+                       cffd->email, &fid, &folder, cancellable, &local_error)) {
+                       if (g_error_matches (local_error, EWS_CONNECTION_ERROR, 
EWS_CONNECTION_ERROR_ITEMNOTFOUND) ||
+                           g_error_matches (local_error, EWS_CONNECTION_ERROR, 
EWS_CONNECTION_ERROR_FOLDERNOTFOUND)) {
+                               g_clear_error (&local_error);
+                               local_error = g_error_new (
+                                       EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_FOLDERNOTFOUND,
+                                       _("Folder ā€œ%sā€ not found. Either it does not exist or you do not have 
permission to access it."),
+                                       cffd->orig_foldername);
+                       }
+
+                       g_propagate_error (perror, local_error);
+                       g_object_unref (conn);
+                       return;
+               }
        }
 
        if (g_cancellable_set_error_if_cancelled (cancellable, perror)) {
@@ -516,6 +547,8 @@ subscribe_foreign_response_cb (GObject *dialog,
                use_foldername = g_strdup ("contacts");
        } else if (g_strcmp0 (orig_foldername, _("Calendar")) == 0) {
                use_foldername = g_strdup ("calendar");
+       } else if (g_strcmp0 (orig_foldername, _("Free/Busy as Calendar")) == 0) {
+               use_foldername = g_strdup ("freebusy-calendar");
        } else if (g_strcmp0 (orig_foldername, _("Memos")) == 0) {
                use_foldername = g_strdup ("notes");
        } else if (g_strcmp0 (orig_foldername, _("Tasks")) == 0) {
@@ -721,6 +754,7 @@ e_ews_subscribe_foreign_folder (GtkWindow *parent,
        gtk_combo_box_text_append_text (combo_text, _("Inbox"));
        gtk_combo_box_text_append_text (combo_text, _("Contacts"));
        gtk_combo_box_text_append_text (combo_text, _("Calendar"));
+       gtk_combo_box_text_append_text (combo_text, _("Free/Busy as Calendar"));
        gtk_combo_box_text_append_text (combo_text, _("Memos"));
        gtk_combo_box_text_append_text (combo_text, _("Tasks"));
        gtk_combo_box_set_active (GTK_COMBO_BOX (combo_text), 0);
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
index 6875659..8ce6c4e 100644
--- a/src/server/CMakeLists.txt
+++ b/src/server/CMakeLists.txt
@@ -3,6 +3,8 @@ glib_mkenums(e-ews-enumtypes e-ews-enums.h E_EWS_ENUMTYPES_H)
 set(SOURCES
        camel-ews-settings.c
        camel-ews-settings.h
+       e-ews-calendar-utils.c
+       e-ews-calendar-utils.h
        e-ews-camel-common.c
        e-ews-camel-common.h
        e-ews-connection.c
diff --git a/src/server/e-ews-calendar-utils.c b/src/server/e-ews-calendar-utils.c
new file mode 100644
index 0000000..2e1549a
--- /dev/null
+++ b/src/server/e-ews-calendar-utils.c
@@ -0,0 +1,258 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include "evolution-ews-config.h"
+
+#include "e-ews-message.h"
+
+#include "e-ews-calendar-utils.h"
+
+static const gchar *
+number_to_weekday (gint num)
+{
+       static const gchar *days[] = {
+               "Sunday", "Monday", "Tuesday", "Wednesday",
+               "Thursday", "Friday", "Saturday",
+               "Day", "Weekday", "WeekendDay"
+       };
+
+       return days[num - 1];
+}
+
+static void
+ewscal_add_availability_rrule (ESoapMessage *msg,
+                               icalproperty *prop)
+{
+       struct icalrecurrencetype recur = icalproperty_get_rrule (prop);
+       gchar buffer[16];
+       gint dayorder;
+
+       dayorder = icalrecurrencetype_day_position (recur.by_day[0]);
+       dayorder = dayorder % 5;
+       if (dayorder < 0)
+               dayorder += 5;
+       dayorder += 1;
+
+       /* expected value is 1..5, inclusive */
+       snprintf (buffer, 16, "%d", dayorder);
+       e_ews_message_write_string_parameter (msg, "DayOrder", NULL, buffer);
+
+       snprintf (buffer, 16, "%d", recur.by_month[0]);
+       e_ews_message_write_string_parameter (msg, "Month", NULL, buffer);
+
+       e_ews_message_write_string_parameter (msg, "DayOfWeek", NULL, number_to_weekday 
(icalrecurrencetype_day_day_of_week (recur.by_day[0])));
+}
+
+static void
+ewscal_add_availability_default_timechange (ESoapMessage *msg)
+{
+
+       e_soap_message_start_element (msg, "StandardTime", NULL, NULL);
+       e_ews_message_write_string_parameter (msg, "Bias", NULL, "0");
+       e_ews_message_write_string_parameter (msg, "Time", NULL, "00:00:00");
+       e_ews_message_write_string_parameter (msg, "DayOrder", NULL, "0");
+       e_ews_message_write_string_parameter (msg, "Month", NULL, "0");
+       e_ews_message_write_string_parameter (msg, "DayOfWeek", NULL, "Sunday");
+       e_soap_message_end_element (msg);
+
+       e_soap_message_start_element (msg, "DaylightTime", NULL, NULL);
+       e_ews_message_write_string_parameter (msg, "Bias", NULL, "0");
+       e_ews_message_write_string_parameter (msg, "Time", NULL, "00:00:00");
+       e_ews_message_write_string_parameter (msg, "DayOrder", NULL, "0");
+       e_ews_message_write_string_parameter (msg, "Month", NULL, "0");
+       e_ews_message_write_string_parameter (msg, "DayOfWeek", NULL, "Sunday");
+       e_soap_message_end_element (msg);
+}
+
+static void
+ewscal_add_availability_timechange (ESoapMessage *msg,
+                                    icalcomponent *comp,
+                                    gint baseoffs)
+{
+       gchar buffer[16];
+       icalproperty *prop;
+       struct icaltimetype dtstart;
+       gint utcoffs;
+
+       /* Calculate zone Offset from BaseOffset */
+       prop = icalcomponent_get_first_property (comp, ICAL_TZOFFSETTO_PROPERTY);
+       if (prop) {
+               utcoffs = -icalproperty_get_tzoffsetto (prop) / 60;
+               utcoffs -= baseoffs;
+               snprintf (buffer, 16, "%d", utcoffs);
+               e_ews_message_write_string_parameter (msg, "Bias", NULL, buffer);
+       }
+
+       prop = icalcomponent_get_first_property (comp, ICAL_DTSTART_PROPERTY);
+       if (prop) {
+               dtstart = icalproperty_get_dtstart (prop);
+               snprintf (buffer, 16, "%02d:%02d:%02d", dtstart.hour, dtstart.minute, dtstart.second);
+               e_ews_message_write_string_parameter (msg, "Time", NULL, buffer);
+       }
+
+       prop = icalcomponent_get_first_property (comp, ICAL_RRULE_PROPERTY);
+       if (prop)
+               ewscal_add_availability_rrule (msg, prop);
+}
+
+static void
+ewscal_set_availability_timezone (ESoapMessage *msg,
+                                  icaltimezone *icaltz)
+{
+       icalcomponent *comp;
+       icalproperty *prop;
+       icalcomponent *xstd, *xdaylight;
+       gint std_utcoffs;
+       gchar *offset;
+
+       if (!icaltz)
+               return;
+
+       comp = icaltimezone_get_component (icaltz);
+
+       xstd = icalcomponent_get_first_component (comp, ICAL_XSTANDARD_COMPONENT);
+       xdaylight = icalcomponent_get_first_component (comp, ICAL_XDAYLIGHT_COMPONENT);
+
+       /*TimeZone is the root element of GetUserAvailabilityRequest*/
+       e_soap_message_start_element (msg, "TimeZone", NULL, NULL);
+
+       /* Fetch the timezone offsets for the standard (or only) zone.
+        * Negate it, because Exchange does it backwards */
+       if (xstd) {
+               prop = icalcomponent_get_first_property (xstd, ICAL_TZOFFSETTO_PROPERTY);
+               std_utcoffs = -icalproperty_get_tzoffsetto (prop) / 60;
+       } else
+               std_utcoffs = 0;
+
+       /* This is the overall BaseOffset tag, which the Standard and Daylight
+        * zones are offset from. It's redundant, but Exchange always sets it
+        * to the offset of the Standard zone, and the Offset in the Standard
+        * zone to zero. So try to avoid problems by doing the same. */
+       offset = g_strdup_printf ("%d", std_utcoffs);
+       e_ews_message_write_string_parameter (msg, "Bias", NULL, offset);
+       g_free (offset);
+
+       if (xdaylight) {
+               /* Standard */
+               e_soap_message_start_element (msg, "StandardTime", NULL, NULL);
+               ewscal_add_availability_timechange (msg, xstd, std_utcoffs);
+               e_soap_message_end_element (msg); /* "StandardTime" */
+
+               /* DayLight */
+               e_soap_message_start_element (msg, "DaylightTime", NULL, NULL);
+               ewscal_add_availability_timechange (msg, xdaylight, std_utcoffs);
+               e_soap_message_end_element (msg); /* "DaylightTime" */
+       } else
+               /* Set default values*/
+               ewscal_add_availability_default_timechange (msg);
+
+       e_soap_message_end_element (msg); /* "TimeZone" */
+}
+
+void
+e_ews_cal_utils_prepare_free_busy_request (ESoapMessage *msg,
+                                          gpointer user_data)
+{
+       const EEWSFreeBusyData *fbdata = user_data;
+       icaltimetype t_start, t_end;
+       icaltimezone *utc_zone = icaltimezone_get_utc_timezone ();
+       GSList *link;
+
+       g_return_if_fail (fbdata != NULL);
+
+       ewscal_set_availability_timezone (msg, utc_zone);
+
+       e_soap_message_start_element (msg, "MailboxDataArray", "messages", NULL);
+
+       for (link = (GSList *) fbdata->user_mails; link; link = g_slist_next (link)) {
+               const gchar *mail = link->data;
+
+               e_soap_message_start_element (msg, "MailboxData", NULL, NULL);
+
+               e_soap_message_start_element (msg, "Email", NULL, NULL);
+               e_ews_message_write_string_parameter (msg, "Address", NULL, mail);
+               e_soap_message_end_element (msg); /* "Email" */
+
+               e_ews_message_write_string_parameter (msg, "AttendeeType", NULL, "Required");
+               e_ews_message_write_string_parameter (msg, "ExcludeConflicts", NULL, "false");
+
+               e_soap_message_end_element (msg); /* "MailboxData" */
+       }
+
+       e_soap_message_end_element (msg); /* "MailboxDataArray" */
+
+       e_soap_message_start_element (msg, "FreeBusyViewOptions", NULL, NULL);
+
+       e_soap_message_start_element (msg, "TimeWindow", NULL, NULL);
+       t_start = icaltime_from_timet_with_zone (fbdata->period_start, 0, utc_zone);
+       t_end = icaltime_from_timet_with_zone (fbdata->period_end, 0, utc_zone);
+       e_ews_cal_utils_set_time (msg, "StartTime", &t_start, FALSE);
+       e_ews_cal_utils_set_time (msg, "EndTime", &t_end, FALSE);
+       e_soap_message_end_element (msg); /* "TimeWindow" */
+
+       e_ews_message_write_string_parameter (msg, "MergedFreeBusyIntervalInMinutes", NULL, "60");
+       e_ews_message_write_string_parameter (msg, "RequestedView", NULL, "DetailedMerged");
+
+       e_soap_message_end_element (msg); /* "FreeBusyViewOptions" */
+}
+
+void
+e_ews_cal_utils_set_time (ESoapMessage *msg,
+                         const gchar *name,
+                         icaltimetype *tt,
+                         gboolean with_timezone)
+{
+       gchar *str;
+       gchar *tz_ident = NULL;
+
+       g_return_if_fail (tt != NULL);
+
+       if (with_timezone) {
+               if (tt->is_utc || !tt->zone || tt->zone == icaltimezone_get_utc_timezone ()) {
+                       tz_ident = g_strdup ("Z");
+               } else {
+                       gint offset, is_daylight, hrs, mins;
+
+                       offset = icaltimezone_get_utc_offset (
+                               icaltimezone_get_utc_timezone (), tt, &is_daylight);
+
+                       offset = offset * (-1);
+                       hrs = offset / 60;
+                       mins = offset % 60;
+
+                       if (hrs < 0)
+                               hrs *= -1;
+                       if (mins < 0)
+                               mins *= -1;
+
+                       tz_ident = g_strdup_printf ("%s%02d:%02d", offset > 0 ? "+" : "-", hrs, mins);
+               }
+       }
+
+       str = g_strdup_printf (
+               "%04d-%02d-%02dT%02d:%02d:%02d%s",
+               tt->year, tt->month, tt->day,
+               tt->hour, tt->minute, tt->second,
+               tz_ident ? tz_ident : "");
+
+       e_ews_message_write_string_parameter (msg, name, NULL, str);
+
+       g_free (tz_ident);
+       g_free (str);
+}
diff --git a/src/server/e-ews-calendar-utils.h b/src/server/e-ews-calendar-utils.h
new file mode 100644
index 0000000..6419a7b
--- /dev/null
+++ b/src/server/e-ews-calendar-utils.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef E_EWS_CALENDAR_UTILS_H
+#define E_EWS_CALENDAR_UTILS_H
+
+#include <time.h>
+#include <libical/ical.h>
+
+#include "server/e-soap-message.h"
+
+G_BEGIN_DECLS
+
+typedef struct _EEWSFreeBusyData {
+       time_t period_start;
+       time_t period_end;
+       GSList *user_mails; /* gchar * */
+} EEWSFreeBusyData;
+
+void           e_ews_cal_utils_prepare_free_busy_request
+                                               (ESoapMessage *msg,
+                                                gpointer user_data); /* EEWSFreeBusyData * */
+void           e_ews_cal_utils_set_time        (ESoapMessage *msg,
+                                                const gchar *name,
+                                                icaltimetype *tt,
+                                                gboolean with_timezone);
+
+G_END_DECLS
+
+#endif /* E_EWS_CALENDAR_UTILS_H */
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index 0c7d84a..02f2aca 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -7357,13 +7357,15 @@ ews_handle_free_busy_view (ESoapParameter *param,
        ESoapParameter *viewparam, *eventarray, *event_param, *subparam;
        GTimeVal t_val;
        const gchar *name;
-       gchar *value, *new_val = NULL, *summary = NULL, *location = NULL;
+       gchar *value, *new_val = NULL, *summary = NULL, *location = NULL, *id = NULL;
 
        viewparam = e_soap_parameter_get_first_child_by_name (param, "FreeBusyView");
        if (!viewparam) return;
        vfb = icalcomponent_new_vfreebusy ();
        eventarray = e_soap_parameter_get_first_child_by_name (viewparam, "CalendarEventArray");
-       for (event_param = e_soap_parameter_get_first_child (eventarray); event_param != NULL; event_param = 
e_soap_parameter_get_next_child (event_param), icalprop = NULL) {
+       for (event_param = eventarray ? e_soap_parameter_get_first_child (eventarray) : NULL;
+            event_param != NULL;
+            event_param = e_soap_parameter_get_next_child (event_param), icalprop = NULL) {
                for (subparam = e_soap_parameter_get_first_child (event_param); subparam != NULL; subparam = 
e_soap_parameter_get_next_child (subparam)) {
                        name = e_soap_parameter_get_name (subparam);
 
@@ -7420,6 +7422,10 @@ ews_handle_free_busy_view (ESoapParameter *param,
                        } else if (!g_ascii_strcasecmp (name, "CalendarEventDetails")) {
                                ESoapParameter *dparam;
 
+                               dparam = e_soap_parameter_get_first_child_by_name (subparam, "ID");
+                               if (dparam)
+                                       id = e_soap_parameter_get_string_value (dparam);
+
                                dparam = e_soap_parameter_get_first_child_by_name (subparam, "Subject");
                                if (dparam)
                                        summary = e_soap_parameter_get_string_value (dparam);
@@ -7430,6 +7436,8 @@ ews_handle_free_busy_view (ESoapParameter *param,
                        }
                }
                if (icalprop != NULL) {
+                       if (id)
+                               icalproperty_set_parameter_from_string (icalprop, "X-EWS-ID", id);
                        if (summary)
                                icalproperty_set_parameter_from_string (icalprop, "X-SUMMARY", summary);
                        if (location)
@@ -7437,10 +7445,9 @@ ews_handle_free_busy_view (ESoapParameter *param,
                        icalcomponent_add_property (vfb, icalprop);
                }
 
-               g_free (summary);
-               g_free (location);
-               summary = NULL;
-               location = NULL;
+               g_clear_pointer (&summary, g_free);
+               g_clear_pointer (&location, g_free);
+               g_clear_pointer (&id, g_free);
        }
 
        async_data->items = g_slist_append (async_data->items, vfb);
diff --git a/src/server/e-ews-folder.c b/src/server/e-ews-folder.c
index 69f99bf..0c5a99b 100644
--- a/src/server/e-ews-folder.c
+++ b/src/server/e-ews-folder.c
@@ -45,6 +45,7 @@ struct _EEwsFolderPrivate {
        guint32 child_count;
        guint64 size;
        gboolean foreign;
+       gchar *foreign_mail;
 };
 
 static void
@@ -68,14 +69,9 @@ e_ews_folder_finalize (GObject *object)
        priv = folder->priv;
 
        g_clear_error (&priv->error);
-
-       if (priv->name) {
-               g_free (priv->name);
-               priv->name = NULL;
-       }
-
-       g_free (priv->escaped_name);
-       priv->escaped_name = NULL;
+       g_clear_pointer (&priv->name, g_free);
+       g_clear_pointer (&priv->escaped_name, g_free);
+       g_clear_pointer (&priv->foreign_mail, g_free);
 
        if (priv->fid) {
                g_free (priv->fid->id);
@@ -407,6 +403,16 @@ e_ews_folder_get_id (const EEwsFolder *folder)
        return (const EwsFolderId *) folder->priv->fid;
 }
 
+void
+e_ews_folder_set_id (EEwsFolder *folder,
+                    EwsFolderId *fid)
+{
+       g_return_if_fail (E_IS_EWS_FOLDER (folder));
+
+       e_ews_folder_id_free (folder->priv->fid);
+       folder->priv->fid = fid;
+}
+
 const EwsFolderId *
 e_ews_folder_get_parent_id (const EEwsFolder *folder)
 {
@@ -501,6 +507,24 @@ e_ews_folder_set_foreign (EEwsFolder *folder,
        folder->priv->foreign = is_foreign;
 }
 
+const gchar *
+e_ews_folder_get_foreign_mail (const EEwsFolder *folder)
+{
+       g_return_val_if_fail (E_IS_EWS_FOLDER (folder), NULL);
+
+       return folder->priv->foreign_mail;
+}
+
+void
+e_ews_folder_set_foreign_mail (EEwsFolder *folder,
+                              const gchar *foreign_mail)
+{
+       g_return_if_fail (E_IS_EWS_FOLDER (folder));
+
+       g_free (folder->priv->foreign_mail);
+       folder->priv->foreign_mail = g_strdup (foreign_mail);
+}
+
 /* escapes backslashes with \5C and forward slashes with \2F */
 gchar *
 e_ews_folder_utils_escape_name (const gchar *folder_name)
@@ -676,6 +700,7 @@ e_ews_folder_utils_populate_esource (ESource *source,
                        e_source_ews_folder_set_change_key (folder_ext, NULL);
                        e_source_ews_folder_set_foreign (folder_ext, e_ews_folder_get_foreign (folder));
                        e_source_ews_folder_set_foreign_subfolders (folder_ext, (flags & 
E_EWS_ESOURCE_FLAG_INCLUDE_SUBFOLDERS) != 0);
+                       e_source_ews_folder_set_foreign_mail (folder_ext, e_ews_folder_get_foreign_mail 
(folder));
                        e_source_ews_folder_set_public (folder_ext, (flags & 
E_EWS_ESOURCE_FLAG_PUBLIC_FOLDER) != 0);
 
                        offline_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_OFFLINE);
diff --git a/src/server/e-ews-folder.h b/src/server/e-ews-folder.h
index 21e9a58..546f39f 100644
--- a/src/server/e-ews-folder.h
+++ b/src/server/e-ews-folder.h
@@ -69,6 +69,7 @@ const EwsFolderId *
                e_ews_folder_get_parent_id (const EEwsFolder *folder);
 const EwsFolderId *
                e_ews_folder_get_id (const EEwsFolder *folder);
+void           e_ews_folder_set_id (EEwsFolder *folder, EwsFolderId *fid);
 guint32                e_ews_folder_get_total_count (const EEwsFolder *folder);
 guint32                e_ews_folder_get_unread_count (const EEwsFolder *folder);
 guint32                e_ews_folder_get_child_count (const EEwsFolder *folder);
@@ -79,6 +80,8 @@ EEwsFolderType        e_ews_folder_get_folder_type (const EEwsFolder *folder);
 void           e_ews_folder_set_folder_type (EEwsFolder *folder, EEwsFolderType folder_type);
 gboolean       e_ews_folder_get_foreign (const EEwsFolder *folder);
 void           e_ews_folder_set_foreign (EEwsFolder *folder, gboolean is_foreign);
+const gchar *  e_ews_folder_get_foreign_mail (const EEwsFolder *folder);
+void           e_ews_folder_set_foreign_mail (EEwsFolder *folder, const gchar *foreign_mail);
 
 EwsFolderId *  e_ews_folder_id_new (const gchar *id,
                                     const gchar *change_key,
diff --git a/src/server/e-source-ews-folder.c b/src/server/e-source-ews-folder.c
index ccd79ef..6392c23 100644
--- a/src/server/e-source-ews-folder.c
+++ b/src/server/e-source-ews-folder.c
@@ -29,7 +29,10 @@ struct _ESourceEwsFolderPrivate {
        gchar *id;
        gboolean foreign;
        gboolean foreign_subfolders;
+       gchar *foreign_mail;
        gboolean is_public;
+       guint freebusy_weeks_before;
+       guint freebusy_weeks_after;
 };
 
 enum {
@@ -38,6 +41,9 @@ enum {
        PROP_ID,
        PROP_FOREIGN,
        PROP_FOREIGN_SUBFOLDERS,
+       PROP_FOREIGN_MAIL,
+       PROP_FREEBUSY_WEEKS_BEFORE,
+       PROP_FREEBUSY_WEEKS_AFTER,
        PROP_PUBLIC
 };
 
@@ -77,6 +83,24 @@ source_ews_folder_set_property (GObject *object,
                                g_value_get_boolean (value));
                        return;
 
+               case PROP_FOREIGN_MAIL:
+                       e_source_ews_folder_set_foreign_mail (
+                               E_SOURCE_EWS_FOLDER (object),
+                               g_value_get_string (value));
+                       return;
+
+               case PROP_FREEBUSY_WEEKS_BEFORE:
+                       e_source_ews_folder_set_freebusy_weeks_before (
+                               E_SOURCE_EWS_FOLDER (object),
+                               g_value_get_uint (value));
+                       return;
+
+               case PROP_FREEBUSY_WEEKS_AFTER:
+                       e_source_ews_folder_set_freebusy_weeks_after (
+                               E_SOURCE_EWS_FOLDER (object),
+                               g_value_get_uint (value));
+                       return;
+
                case PROP_PUBLIC:
                        e_source_ews_folder_set_public (
                                E_SOURCE_EWS_FOLDER (object),
@@ -122,6 +146,27 @@ source_ews_folder_get_property (GObject *object,
                                E_SOURCE_EWS_FOLDER (object)));
                        return;
 
+               case PROP_FOREIGN_MAIL:
+                       g_value_take_string (
+                               value,
+                               e_source_ews_folder_dup_foreign_mail (
+                               E_SOURCE_EWS_FOLDER (object)));
+                       return;
+
+               case PROP_FREEBUSY_WEEKS_BEFORE:
+                       g_value_set_uint (
+                               value,
+                               e_source_ews_folder_get_freebusy_weeks_before (
+                               E_SOURCE_EWS_FOLDER (object)));
+                       return;
+
+               case PROP_FREEBUSY_WEEKS_AFTER:
+                       g_value_set_uint (
+                               value,
+                               e_source_ews_folder_get_freebusy_weeks_after (
+                               E_SOURCE_EWS_FOLDER (object)));
+                       return;
+
                case PROP_PUBLIC:
                        g_value_set_boolean (
                                value,
@@ -142,6 +187,7 @@ source_ews_folder_finalize (GObject *object)
 
        g_free (priv->change_key);
        g_free (priv->id);
+       g_free (priv->foreign_mail);
 
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (e_source_ews_folder_parent_class)->finalize (object);
@@ -218,6 +264,45 @@ e_source_ews_folder_class_init (ESourceEwsFolderClass *class)
 
        g_object_class_install_property (
                object_class,
+               PROP_FOREIGN_MAIL,
+               g_param_spec_string (
+                       "foreign-mail",
+                       "ForeignMail",
+                       "Other user's mail address",
+                       NULL,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT |
+                       G_PARAM_STATIC_STRINGS |
+                       E_SOURCE_PARAM_SETTING));
+
+       g_object_class_install_property (
+               object_class,
+               PROP_FREEBUSY_WEEKS_BEFORE,
+               g_param_spec_uint (
+                       "freebusy-weeks-before",
+                       "FreeBusyWeeksBefore",
+                       "How many weeks to read Free/Busy before today",
+                       0, 5, 1,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT |
+                       G_PARAM_STATIC_STRINGS |
+                       E_SOURCE_PARAM_SETTING));
+
+       g_object_class_install_property (
+               object_class,
+               PROP_FREEBUSY_WEEKS_AFTER,
+               g_param_spec_uint (
+                       "freebusy-weeks-after",
+                       "FreeBusyWeeksAfter",
+                       "How many weeks to read Free/Busy after today",
+                       1, 54, 5,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT |
+                       G_PARAM_STATIC_STRINGS |
+                       E_SOURCE_PARAM_SETTING));
+
+       g_object_class_install_property (
+               object_class,
                PROP_PUBLIC,
                g_param_spec_boolean (
                        "public",
@@ -400,6 +485,97 @@ e_source_ews_folder_set_foreign_subfolders (ESourceEwsFolder *extension,
        g_object_notify (G_OBJECT (extension), "foreign-subfolders");
 }
 
+const gchar *
+e_source_ews_folder_get_foreign_mail (ESourceEwsFolder *extension)
+{
+       g_return_val_if_fail (E_IS_SOURCE_EWS_FOLDER (extension), NULL);
+
+       return extension->priv->foreign_mail;
+}
+
+gchar *
+e_source_ews_folder_dup_foreign_mail (ESourceEwsFolder *extension)
+{
+       const gchar *protected;
+       gchar *duplicate;
+
+       g_return_val_if_fail (E_IS_SOURCE_EWS_FOLDER (extension), NULL);
+
+       e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+       protected = e_source_ews_folder_get_foreign_mail (extension);
+       duplicate = g_strdup (protected);
+
+       e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+       return duplicate;
+}
+
+void
+e_source_ews_folder_set_foreign_mail (ESourceEwsFolder *extension,
+                                     const gchar *foreign_mail)
+{
+       g_return_if_fail (E_IS_SOURCE_EWS_FOLDER (extension));
+
+       e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+       if (g_strcmp0 (extension->priv->foreign_mail, foreign_mail) == 0) {
+               e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+               return;
+       }
+
+       g_free (extension->priv->foreign_mail);
+       extension->priv->foreign_mail = g_strdup (foreign_mail);
+
+       e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+       g_object_notify (G_OBJECT (extension), "foreign-mail");
+}
+
+guint
+e_source_ews_folder_get_freebusy_weeks_before (ESourceEwsFolder *extension)
+{
+       g_return_val_if_fail (E_IS_SOURCE_EWS_FOLDER (extension), 0);
+
+       return extension->priv->freebusy_weeks_before;
+}
+
+void
+e_source_ews_folder_set_freebusy_weeks_before (ESourceEwsFolder *extension,
+                                              guint freebusy_weeks_before)
+{
+       g_return_if_fail (E_IS_SOURCE_EWS_FOLDER (extension));
+
+       if (extension->priv->freebusy_weeks_before == freebusy_weeks_before)
+               return;
+
+       extension->priv->freebusy_weeks_before = freebusy_weeks_before;
+
+       g_object_notify (G_OBJECT (extension), "freebusy-weeks-before");
+}
+
+guint
+e_source_ews_folder_get_freebusy_weeks_after (ESourceEwsFolder *extension)
+{
+       g_return_val_if_fail (E_IS_SOURCE_EWS_FOLDER (extension), 0);
+
+       return extension->priv->freebusy_weeks_after;
+}
+
+void
+e_source_ews_folder_set_freebusy_weeks_after (ESourceEwsFolder *extension,
+                                             guint freebusy_weeks_after)
+{
+       g_return_if_fail (E_IS_SOURCE_EWS_FOLDER (extension));
+
+       if (extension->priv->freebusy_weeks_after == freebusy_weeks_after)
+               return;
+
+       extension->priv->freebusy_weeks_after = freebusy_weeks_after;
+
+       g_object_notify (G_OBJECT (extension), "freebusy-weeks-after");
+}
+
 gboolean
 e_source_ews_folder_get_public (ESourceEwsFolder *extension)
 {
diff --git a/src/server/e-source-ews-folder.h b/src/server/e-source-ews-folder.h
index c0637d8..e9c07a1 100644
--- a/src/server/e-source-ews-folder.h
+++ b/src/server/e-source-ews-folder.h
@@ -84,6 +84,23 @@ gboolean     e_source_ews_folder_get_foreign_subfolders
 void           e_source_ews_folder_set_foreign_subfolders
                                                (ESourceEwsFolder *extension,
                                                 gboolean foreign_subfolders);
+const gchar *  e_source_ews_folder_get_foreign_mail
+                                               (ESourceEwsFolder *extension);
+gchar *                e_source_ews_folder_dup_foreign_mail
+                                               (ESourceEwsFolder *extension);
+void           e_source_ews_folder_set_foreign_mail
+                                               (ESourceEwsFolder *extension,
+                                                const gchar *foreign_mail);
+guint          e_source_ews_folder_get_freebusy_weeks_before
+                                               (ESourceEwsFolder *extension);
+void           e_source_ews_folder_set_freebusy_weeks_before
+                                               (ESourceEwsFolder *extension,
+                                                guint freebusy_weeks_before);
+guint          e_source_ews_folder_get_freebusy_weeks_after
+                                               (ESourceEwsFolder *extension);
+void           e_source_ews_folder_set_freebusy_weeks_after
+                                               (ESourceEwsFolder *extension,
+                                                guint freebusy_weeks_after);
 gboolean       e_source_ews_folder_get_public  (ESourceEwsFolder *extension);
 void           e_source_ews_folder_set_public  (ESourceEwsFolder *extension,
                                                 gboolean is_public);


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