[evolution-ews/wip/mcrha/soup3: 2/2] M!6 - Port to libsoup3




commit 67ccc31524dd89b02fe78ab4363eb8c81c7034ca
Author: Milan Crha <mcrha redhat com>
Date:   Thu Dec 9 12:21:06 2021 +0100

    M!6 - Port to libsoup3
    
    Closes https://gitlab.gnome.org/GNOME/evolution-ews/-/merge_requests/6

 CMakeLists.txt                                     |    13 +-
 src/EWS/addressbook/e-book-backend-ews.c           |   376 +-
 src/EWS/calendar/e-cal-backend-ews-utils.c         |   677 +-
 src/EWS/calendar/e-cal-backend-ews-utils.h         |    20 +-
 src/EWS/calendar/e-cal-backend-ews.c               |    16 +-
 src/EWS/camel/camel-ews-folder.c                   |    96 +-
 src/EWS/camel/camel-ews-store.c                    |    26 +-
 src/EWS/camel/camel-ews-utils.c                    |    70 +-
 src/EWS/camel/camel-ews-utils.h                    |     4 +-
 src/EWS/common/CMakeLists.txt                      |    10 +-
 src/EWS/common/camel-ews-settings.c                |     8 +-
 src/EWS/common/e-ews-calendar-utils.c              |   308 +-
 src/EWS/common/e-ews-calendar-utils.h              |     8 +-
 src/EWS/common/e-ews-camel-common.c                |   109 +-
 src/EWS/common/e-ews-connection-utils.c            |   339 +-
 src/EWS/common/e-ews-connection-utils.h            |    12 +-
 src/EWS/common/e-ews-connection.c                  | 12990 ++++++++-----------
 src/EWS/common/e-ews-connection.h                  |   730 +-
 src/EWS/common/e-ews-debug.c                       |    70 +-
 src/EWS/common/e-ews-debug.h                       |     4 -
 src/EWS/common/e-ews-folder.c                      |    26 +-
 src/EWS/common/e-ews-folder.h                      |     8 +-
 src/EWS/common/e-ews-item-change.c                 |   460 +-
 src/EWS/common/e-ews-item-change.h                 |   183 +-
 src/EWS/common/e-ews-item.c                        |     2 +-
 src/EWS/common/e-ews-item.h                        |     4 +-
 src/EWS/common/e-ews-message.c                     |   383 -
 src/EWS/common/e-ews-notification.c                |   482 +-
 src/EWS/common/e-ews-notification.h                |     3 +
 src/EWS/common/e-ews-oof-settings.c                |   612 +-
 src/EWS/common/e-ews-oof-settings.h                |    15 +-
 src/EWS/common/e-ews-query-to-restriction.c        |   172 +-
 src/EWS/common/e-ews-query-to-restriction.h        |     4 +-
 src/EWS/common/e-ews-request.c                     |   327 +
 .../common/{e-ews-message.h => e-ews-request.h}    |    64 +-
 src/EWS/common/e-oauth2-service-office365.c        |    12 +-
 src/EWS/common/e-soap-message.c                    |  1163 --
 src/EWS/common/e-soap-message.h                    |   146 -
 src/EWS/common/e-soap-request.c                    |  1145 ++
 src/EWS/common/e-soap-request.h                    |   187 +
 src/EWS/common/e-soap-response.c                   |   313 +-
 src/EWS/common/e-soap-response.h                   |    26 +
 src/EWS/common/e-soup-auth-negotiate.c             |   342 -
 src/EWS/common/e-soup-auth-negotiate.h             |    30 -
 src/EWS/evolution/e-ews-config-lookup.c            |    42 +-
 src/EWS/evolution/e-ews-photo-source.c             |   157 +-
 src/EWS/evolution/e-ews-search-user.c              |     4 +-
 src/EWS/evolution/e-ews-subscribe-foreign-folder.c |     2 +-
 src/EWS/evolution/e-mail-config-ews-autodiscover.c |     6 +-
 src/EWS/evolution/e-mail-config-ews-backend.c      |    16 +-
 .../evolution/e-mail-config-ews-delegates-page.c   |   213 +-
 .../evolution/e-mail-config-ews-oal-combo-box.c    |     2 +-
 src/EWS/evolution/e-mail-config-ews-ooo-page.c     |     2 +-
 src/EWS/registry/e-ews-backend.c                   |    12 +-
 src/Microsoft365/camel/camel-m365-folder.c         |     4 +-
 src/Microsoft365/camel/camel-m365-store.c          |     7 +-
 src/Microsoft365/common/e-m365-connection.c        |   762 +-
 src/Microsoft365/common/e-m365-connection.h        |    15 +-
 .../common/e-oauth2-service-microsoft365.c         |    12 +-
 src/Microsoft365/registry/e-m365-backend.c         |     4 +-
 60 files changed, 9364 insertions(+), 13891 deletions(-)
---
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 36ca1b18..a83f16a4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,16 +18,16 @@ set(PROJECT_DISTCONFIGURE_PARAMS
 )
 
 # Keep these two definitions in agreement.
-set(glib_minimum_version 2.62)
-set(glib_encoded_version GLIB_VERSION_2_62)
+set(glib_minimum_version 2.68)
+set(glib_encoded_version GLIB_VERSION_2_68)
 
 # Keep these two definitions in agreement.
 set(gdk_minimum_version 3.10)
 set(gdk_encoded_version GDK_VERSION_3_10)
 
 # Keep these two definitions in agreement.
-set(soup_minimum_version 2.58)
-set(soup_encoded_version SOUP_VERSION_2_58)
+set(soup_minimum_version 3.0)
+set(soup_encoded_version SOUP_VERSION_3_0)
 
 # Warn about API usage that violates our minimum requirements.
 add_definitions(-DGLIB_VERSION_MAX_ALLOWED=${glib_encoded_version})
@@ -139,7 +139,7 @@ pkg_check_modules(GNOME_PLATFORM REQUIRED
        gtk+-3.0>=${gdk_minimum_version}
 )
 
-pkg_check_modules(SOUP REQUIRED libsoup-2.4>=${soup_minimum_version})
+pkg_check_modules(SOUP REQUIRED libsoup-3.0>=${soup_minimum_version})
 
 pkg_check_modules(LIBICAL_GLIB REQUIRED libical-glib>=${libical_glib_minimum_version})
 
@@ -287,5 +287,6 @@ add_subdirectory(po)
 add_subdirectory(src)
 
 if(ENABLE_TESTS)
-       add_subdirectory(tests)
+       message(WARNING "tests are disabled until uhttpmock is ported to libsoup3")
+       #add_subdirectory(tests)
 endif(ENABLE_TESTS)
diff --git a/src/EWS/addressbook/e-book-backend-ews.c b/src/EWS/addressbook/e-book-backend-ews.c
index e7c3c799..9bd46e94 100644
--- a/src/EWS/addressbook/e-book-backend-ews.c
+++ b/src/EWS/addressbook/e-book-backend-ews.c
@@ -28,7 +28,7 @@
 #include <libedata-book/libedata-book.h>
 
 #include "common/e-ews-item-change.h"
-#include "common/e-ews-message.h"
+#include "common/e-ews-request.h"
 #include "common/e-ews-connection.h"
 #include "common/e-ews-connection-utils.h"
 #include "common/e-ews-item.h"
@@ -757,7 +757,7 @@ ebews_find_cert_base64_data (EContact *contact,
 
 static void
 ebews_set_cert (EBookBackendEws *bbews,
-               ESoapMessage *message,
+               ESoapRequest *request,
                EContact *contact,
                const gchar *kind,
                gint fallback_index)
@@ -772,31 +772,31 @@ ebews_set_cert (EBookBackendEws *bbews,
        if (!base64_data)
                return;
 
-       e_soap_message_start_element (message, kind, NULL, NULL);
-       e_ews_message_write_string_parameter (message, "Base64Binary", NULL, base64_data);
-       e_soap_message_end_element (message);
+       e_soap_request_start_element (request, kind, NULL, NULL);
+       e_ews_request_write_string_parameter (request, "Base64Binary", NULL, base64_data);
+       e_soap_request_end_element (request);
 }
 
 static void
 ebews_set_user_cert (EBookBackendEws *bbews,
-                    ESoapMessage *message,
+                    ESoapRequest *request,
                     EContact *contact)
 {
-       ebews_set_cert (bbews, message, contact, E_EWS_CERT_KIND_USER, 0);
+       ebews_set_cert (bbews, request, contact, E_EWS_CERT_KIND_USER, 0);
 }
 
 
 static void
 ebews_set_msex_cert (EBookBackendEws *bbews,
-                    ESoapMessage *message,
+                    ESoapRequest *request,
                     EContact *contact)
 {
-       ebews_set_cert (bbews, message, contact, E_EWS_CERT_KIND_MSEX, 1);
+       ebews_set_cert (bbews, request, contact, E_EWS_CERT_KIND_MSEX, 1);
 }
 
 static void
 ebews_set_cert_changes (EBookBackendEws *bbews,
-                       ESoapMessage *message,
+                       ESoapRequest *request,
                        EContact *new,
                        EContact *old,
                        const gchar *kind,
@@ -805,7 +805,7 @@ ebews_set_cert_changes (EBookBackendEws *bbews,
        const gchar *new_base64_data, *old_base64_data;
 
        /* The first pass */
-       if (!message)
+       if (!request)
                return;
 
        /* Support for certificates was added in Exchange 2010 SP2. */
@@ -820,38 +820,38 @@ ebews_set_cert_changes (EBookBackendEws *bbews,
                return;
 
        if (new_base64_data) {
-               e_ews_message_start_set_item_field (message, kind, "contacts", "Contact");
-               e_soap_message_start_element (message, kind, NULL, NULL);
-               e_ews_message_write_string_parameter (message, "Base64Binary", NULL, new_base64_data);
-               e_soap_message_end_element (message);
-               e_ews_message_end_set_item_field (message);
+               e_ews_request_start_set_item_field (request, kind, "contacts", "Contact");
+               e_soap_request_start_element (request, kind, NULL, NULL);
+               e_ews_request_write_string_parameter (request, "Base64Binary", NULL, new_base64_data);
+               e_soap_request_end_element (request);
+               e_ews_request_end_set_item_field (request);
        } else {
-               e_ews_message_add_delete_item_field (message, kind, "contacts");
+               e_ews_request_add_delete_item_field (request, kind, "contacts");
        }
 }
 
 static void
 ebews_set_user_cert_changes (EBookBackendEws *bbews,
-                            ESoapMessage *message,
+                            ESoapRequest *request,
                             EContact *new,
                             EContact *old,
                             gchar **out_new_change_key,
                             GCancellable *cancellable,
                             GError **error)
 {
-       ebews_set_cert_changes (bbews, message, new, old, E_EWS_CERT_KIND_USER, 0);
+       ebews_set_cert_changes (bbews, request, new, old, E_EWS_CERT_KIND_USER, 0);
 }
 
 static void
 ebews_set_msex_cert_changes (EBookBackendEws *bbews,
-                            ESoapMessage *message,
+                            ESoapRequest *request,
                             EContact *new,
                             EContact *old,
                             gchar **out_new_change_key,
                             GCancellable *cancellable,
                             GError **error)
 {
-       ebews_set_cert_changes (bbews, message, new, old, E_EWS_CERT_KIND_MSEX, 1);
+       ebews_set_cert_changes (bbews, request, new, old, E_EWS_CERT_KIND_MSEX, 1);
 }
 
 static void
@@ -1020,7 +1020,7 @@ ebews_populate_emails (EBookBackendEws *bbews,
 
 static void
 ebews_set_item_id (EBookBackendEws *bbews,
-                  ESoapMessage *message,
+                  ESoapRequest *request,
                   EContact *contact)
 {
 
@@ -1028,7 +1028,7 @@ ebews_set_item_id (EBookBackendEws *bbews,
 
 static void
 ebews_set_full_name (EBookBackendEws *bbews,
-                    ESoapMessage *msg,
+                    ESoapRequest *request,
                     EContact *contact)
 {
        EContactName *name;
@@ -1038,16 +1038,16 @@ ebews_set_full_name (EBookBackendEws *bbews,
                return;
 
        if (name->given)
-               e_ews_message_write_string_parameter (msg, "GivenName", NULL, name->given);
+               e_ews_request_write_string_parameter (request, "GivenName", NULL, name->given);
 
        if (name->additional && *name->additional)
-               e_ews_message_write_string_parameter (msg, "MiddleName", NULL, name->additional);
+               e_ews_request_write_string_parameter (request, "MiddleName", NULL, name->additional);
 
        e_contact_name_free (name);
 }
 
 static void
-ebews_set_date_value (ESoapMessage *message,
+ebews_set_date_value (ESoapRequest *request,
                      EContact *contact,
                      EContactField field,
                      const gchar *element_name)
@@ -1063,7 +1063,7 @@ ebews_set_date_value (ESoapMessage *message,
        value = g_strdup_printf ("%04d-%02d-%02dT00:00:00Z",
                date->year, date->month, date->day);
 
-       e_ews_message_write_string_parameter (message, element_name, NULL, value);
+       e_ews_request_write_string_parameter (request, element_name, NULL, value);
 
        e_contact_date_free (date);
        g_free (value);
@@ -1071,30 +1071,30 @@ ebews_set_date_value (ESoapMessage *message,
 
 static void
 ebews_set_birth_date (EBookBackendEws *bbews,
-                     ESoapMessage *message,
+                     ESoapRequest *request,
                      EContact *contact)
 {
-       ebews_set_date_value (message, contact, E_CONTACT_BIRTH_DATE, "Birthday");
+       ebews_set_date_value (request, contact, E_CONTACT_BIRTH_DATE, "Birthday");
 }
 
 static void
 ebews_set_anniversary (EBookBackendEws *bbews,
-                      ESoapMessage *message,
+                      ESoapRequest *request,
                       EContact *contact)
 {
-       ebews_set_date_value (message, contact, E_CONTACT_ANNIVERSARY, "WeddingAnniversary");
+       ebews_set_date_value (request, contact, E_CONTACT_ANNIVERSARY, "WeddingAnniversary");
 }
 
 static void
 ebews_set_photo (EBookBackendEws *bbews,
-                ESoapMessage *message,
+                ESoapRequest *request,
                 EContact *contact)
 {
 
 }
 
 static gboolean
-add_entry (ESoapMessage *msg,
+add_entry (ESoapRequest *request,
            EContact *contact,
            EContactField field,
            const gchar *entry_name,
@@ -1106,9 +1106,9 @@ add_entry (ESoapMessage *msg,
 
        if (entry_val && *entry_val) {
                if (include_hdr)
-                       e_soap_message_start_element (msg, include_hdr, NULL, NULL);
+                       e_soap_request_start_element (request, include_hdr, NULL, NULL);
 
-               e_ews_message_write_string_parameter_with_attribute (msg, "Entry", NULL, entry_val, "Key", 
entry_name);
+               e_ews_request_write_string_parameter_with_attribute (request, "Entry", NULL, entry_val, 
"Key", entry_name);
 
                g_free (entry_val);
                return TRUE;
@@ -1120,23 +1120,23 @@ add_entry (ESoapMessage *msg,
 
 static void
 ebews_set_phone_numbers (EBookBackendEws *bbews,
-                        ESoapMessage *msg,
+                        ESoapRequest *request,
                         EContact *contact)
 {
        gint i;
        const gchar *include_hdr = "PhoneNumbers";
 
        for (i = 0; i < G_N_ELEMENTS (phone_field_map); i++) {
-               if (add_entry (msg, contact, phone_field_map[i].field, phone_field_map[i].element, 
include_hdr))
+               if (add_entry (request, contact, phone_field_map[i].field, phone_field_map[i].element, 
include_hdr))
                        include_hdr = NULL;
        }
 
        if (!include_hdr)
-               e_soap_message_end_element (msg);
+               e_soap_request_end_element (request);
 }
 
 static gboolean
-add_physical_address (ESoapMessage *msg,
+add_physical_address (ESoapRequest *request,
                       EContact *contact,
                       EContactField field,
                       const gchar *entry_name,
@@ -1149,18 +1149,18 @@ add_physical_address (ESoapMessage *msg,
                return FALSE;
 
        if (include_start_hdr)
-               e_soap_message_start_element (msg, "PhysicalAddresses", NULL, NULL);
+               e_soap_request_start_element (request, "PhysicalAddresses", NULL, NULL);
 
-       e_soap_message_start_element (msg, "Entry", NULL, NULL);
+       e_soap_request_start_element (request, "Entry", NULL, NULL);
 
-       e_soap_message_add_attribute (msg, "Key", entry_name, NULL, NULL);
-       e_ews_message_write_string_parameter (msg, "Street", NULL, contact_addr->street);
-       e_ews_message_write_string_parameter (msg, "City", NULL, contact_addr->locality);
-       e_ews_message_write_string_parameter (msg, "State", NULL, contact_addr->region);
-       e_ews_message_write_string_parameter (msg, "CountryOrRegion", NULL, contact_addr->country);
-       e_ews_message_write_string_parameter (msg, "PostalCode", NULL, contact_addr->code);
+       e_soap_request_add_attribute (request, "Key", entry_name, NULL, NULL);
+       e_ews_request_write_string_parameter (request, "Street", NULL, contact_addr->street);
+       e_ews_request_write_string_parameter (request, "City", NULL, contact_addr->locality);
+       e_ews_request_write_string_parameter (request, "State", NULL, contact_addr->region);
+       e_ews_request_write_string_parameter (request, "CountryOrRegion", NULL, contact_addr->country);
+       e_ews_request_write_string_parameter (request, "PostalCode", NULL, contact_addr->code);
 
-       e_soap_message_end_element (msg);
+       e_soap_request_end_element (request);
        e_contact_address_free (contact_addr);
 
        return TRUE;
@@ -1168,25 +1168,25 @@ add_physical_address (ESoapMessage *msg,
 
 static void
 ebews_set_address (EBookBackendEws *bbews,
-                  ESoapMessage *msg,
+                  ESoapRequest *request,
                   EContact *contact)
 {
        gboolean include_hdr = TRUE;
 
-       if (add_physical_address (msg, contact, E_CONTACT_ADDRESS_WORK, "Business", include_hdr))
+       if (add_physical_address (request, contact, E_CONTACT_ADDRESS_WORK, "Business", include_hdr))
                include_hdr = FALSE;
-       if (add_physical_address (msg, contact, E_CONTACT_ADDRESS_HOME, "Home", include_hdr))
+       if (add_physical_address (request, contact, E_CONTACT_ADDRESS_HOME, "Home", include_hdr))
                include_hdr = FALSE;
-       if (add_physical_address (msg, contact, E_CONTACT_ADDRESS_OTHER, "Other", include_hdr))
+       if (add_physical_address (request, contact, E_CONTACT_ADDRESS_OTHER, "Other", include_hdr))
                include_hdr = FALSE;
 
        if (!include_hdr)
-               e_soap_message_end_element (msg);
+               e_soap_request_end_element (request);
 }
 
 static void
 ebews_set_ims (EBookBackendEws *bbews,
-              ESoapMessage *message,
+              ESoapRequest *request,
               EContact *contact)
 {
 
@@ -1194,51 +1194,51 @@ ebews_set_ims (EBookBackendEws *bbews,
 
 static void
 ebews_set_notes (EBookBackendEws *bbews,
-                ESoapMessage *msg,
+                ESoapRequest *request,
                 EContact *contact)
 {
        gchar *notes = e_contact_get (contact, E_CONTACT_NOTE);
        if (!notes)
                return;
 
-       e_ews_message_write_string_parameter_with_attribute (msg, "Body", NULL, notes, "BodyType", "Text");
+       e_ews_request_write_string_parameter_with_attribute (request, "Body", NULL, notes, "BodyType", 
"Text");
 
        g_free (notes);
 }
 
 static void
 ebews_set_emails (EBookBackendEws *bbews,
-                 ESoapMessage *msg,
+                 ESoapRequest *request,
                  EContact *contact)
 {
        const gchar *include_hdr = "EmailAddresses";
 
-       if (add_entry (msg, contact, E_CONTACT_EMAIL_1, "EmailAddress1", include_hdr))
+       if (add_entry (request, contact, E_CONTACT_EMAIL_1, "EmailAddress1", include_hdr))
                include_hdr = NULL;
-       if (add_entry (msg, contact, E_CONTACT_EMAIL_2, "EmailAddress2", include_hdr))
+       if (add_entry (request, contact, E_CONTACT_EMAIL_2, "EmailAddress2", include_hdr))
                include_hdr = NULL;
-       if (add_entry (msg, contact, E_CONTACT_EMAIL_3, "EmailAddress3", include_hdr))
+       if (add_entry (request, contact, E_CONTACT_EMAIL_3, "EmailAddress3", include_hdr))
                include_hdr = NULL;
 
        if (!include_hdr)
-               e_soap_message_end_element (msg);
+               e_soap_request_end_element (request);
 }
 
 static void
-convert_contact_property_to_updatexml (ESoapMessage *msg,
+convert_contact_property_to_updatexml (ESoapRequest *request,
                                        const gchar *name,
                                        const gchar *value,
                                        const gchar *prefix,
                                        const gchar *attr_name,
                                        const gchar *attr_value)
 {
-       e_ews_message_start_set_item_field (msg, name, prefix, "Contact");
-       e_ews_message_write_string_parameter_with_attribute (msg, name, NULL, value, attr_name, attr_value);
-       e_ews_message_end_set_item_field (msg);
+       e_ews_request_start_set_item_field (request, name, prefix, "Contact");
+       e_ews_request_write_string_parameter_with_attribute (request, name, NULL, value, attr_name, 
attr_value);
+       e_ews_request_end_set_item_field (request);
 }
 
 static void
-convert_indexed_contact_property_to_updatexml (ESoapMessage *message,
+convert_indexed_contact_property_to_updatexml (ESoapRequest *request,
                                                const gchar *name,
                                                const gchar *value,
                                                const gchar *prefix,
@@ -1249,20 +1249,19 @@ convert_indexed_contact_property_to_updatexml (ESoapMessage *message,
 
        if (!value || !*value)
                delete_field = TRUE;
-       e_ews_message_start_set_indexed_item_field (message, name , prefix, "Contact", key, delete_field);
+       e_ews_request_start_set_indexed_item_field (request, name , prefix, "Contact", key, delete_field);
 
-       if (!delete_field)
-       {
-               e_soap_message_start_element (message, element_name, NULL, NULL);
-               e_ews_message_write_string_parameter_with_attribute (message, "Entry", NULL, value, "Key", 
key);
-               e_soap_message_end_element (message);
+       if (!delete_field) {
+               e_soap_request_start_element (request, element_name, NULL, NULL);
+               e_ews_request_write_string_parameter_with_attribute (request, "Entry", NULL, value, "Key", 
key);
+               e_soap_request_end_element (request);
        }
-       e_ews_message_end_set_indexed_item_field (message, delete_field);
+       e_ews_request_end_set_indexed_item_field (request, delete_field);
 }
 
 static void
 ebews_set_full_name_changes (EBookBackendEws *bbews,
-                            ESoapMessage *message,
+                            ESoapRequest *request,
                             EContact *new,
                             EContact *old,
                             gchar **out_new_change_key,
@@ -1271,7 +1270,7 @@ ebews_set_full_name_changes (EBookBackendEws *bbews,
 {
        EContactName *name, *old_name;
 
-       if (!message)
+       if (!request)
                return;
 
        name = e_contact_get (new, E_CONTACT_NAME);
@@ -1280,17 +1279,17 @@ ebews_set_full_name_changes (EBookBackendEws *bbews,
                return;
 
        if (!old_name) {
-               convert_contact_property_to_updatexml (message, "GivenName", name->given, "contacts", NULL, 
NULL);
-               convert_contact_property_to_updatexml (message, "MiddleName", name->additional, "contacts", 
NULL, NULL);
+               convert_contact_property_to_updatexml (request, "GivenName", name->given, "contacts", NULL, 
NULL);
+               convert_contact_property_to_updatexml (request, "MiddleName", name->additional, "contacts", 
NULL, NULL);
        } else if (!name) {
-               convert_contact_property_to_updatexml (message, "GivenName", "", "contacts", NULL, NULL);
+               convert_contact_property_to_updatexml (request, "GivenName", "", "contacts", NULL, NULL);
 
-               convert_contact_property_to_updatexml (message, "MiddleName", "", "contacts", NULL, NULL);
+               convert_contact_property_to_updatexml (request, "MiddleName", "", "contacts", NULL, NULL);
        } else {
                if (g_strcmp0 (name->given, old_name->given) != 0)
-                       convert_contact_property_to_updatexml (message, "GivenName", name->given, "contacts", 
NULL, NULL);
+                       convert_contact_property_to_updatexml (request, "GivenName", name->given, "contacts", 
NULL, NULL);
                if (g_strcmp0 (name->additional, old_name->additional) != 0)
-                       convert_contact_property_to_updatexml (message, "MiddleName", name->additional, 
"contacts", NULL, NULL);
+                       convert_contact_property_to_updatexml (request, "MiddleName", name->additional, 
"contacts", NULL, NULL);
        }
 
        e_contact_name_free (name);
@@ -1299,7 +1298,7 @@ ebews_set_full_name_changes (EBookBackendEws *bbews,
 }
 
 static void
-ebews_set_date_value_changes (ESoapMessage *message,
+ebews_set_date_value_changes (ESoapRequest *request,
                              EContact *new,
                              EContact *old,
                              EContactField field,
@@ -1307,7 +1306,7 @@ ebews_set_date_value_changes (ESoapMessage *message,
 {
        EContactDate *new_date, *old_date;
 
-       if (!message)
+       if (!request)
                return;
 
        new_date = e_contact_get (new, field);
@@ -1320,11 +1319,11 @@ ebews_set_date_value_changes (ESoapMessage *message,
                        value = g_strdup_printf ("%04d-%02d-%02dT00:00:00Z",
                                new_date->year, new_date->month, new_date->day);
 
-                       convert_contact_property_to_updatexml (message, element_name, value, "contacts", 
NULL, NULL);
+                       convert_contact_property_to_updatexml (request, element_name, value, "contacts", 
NULL, NULL);
 
                        g_free (value);
                } else {
-                       e_ews_message_add_delete_item_field (message, element_name, "contacts");
+                       e_ews_request_add_delete_item_field (request, element_name, "contacts");
                }
        }
 
@@ -1334,26 +1333,26 @@ ebews_set_date_value_changes (ESoapMessage *message,
 
 static void
 ebews_set_birth_date_changes (EBookBackendEws *bbews,
-                             ESoapMessage *message,
+                             ESoapRequest *request,
                              EContact *new,
                              EContact *old,
                              gchar **out_new_change_key,
                              GCancellable *cancellable,
                              GError **error)
 {
-       ebews_set_date_value_changes (message, new, old, E_CONTACT_BIRTH_DATE, "Birthday");
+       ebews_set_date_value_changes (request, new, old, E_CONTACT_BIRTH_DATE, "Birthday");
 }
 
 static void
 ebews_set_anniversary_changes (EBookBackendEws *bbews,
-                              ESoapMessage *message,
+                              ESoapRequest *request,
                               EContact *new,
                               EContact *old,
                               gchar **out_new_change_key,
                               GCancellable *cancellable,
                               GError **error)
 {
-       ebews_set_date_value_changes (message, new, old, E_CONTACT_ANNIVERSARY, "WeddingAnniversary");
+       ebews_set_date_value_changes (request, new, old, E_CONTACT_ANNIVERSARY, "WeddingAnniversary");
 }
 
 static void
@@ -1472,7 +1471,7 @@ ebb_ews_photo_changed (EBookMetaBackend *meta_backend,
 
 static void
 ebews_set_photo_changes (EBookBackendEws *bbews,
-                        ESoapMessage *message,
+                        ESoapRequest *request,
                         EContact *new,
                         EContact *old,
                         gchar **out_new_change_key,
@@ -1494,7 +1493,7 @@ ebews_set_photo_changes (EBookBackendEws *bbews,
                return;
        }
 
-       if (message) {
+       if (request) {
                /* Photo changes can be done only in pre-flight stage,
                   because it modifies ChangeKey */
                return;
@@ -1579,7 +1578,7 @@ ebews_set_photo_changes (EBookBackendEws *bbews,
 
 static void
 ebews_set_phone_number_changes (EBookBackendEws *bbews,
-                               ESoapMessage *message,
+                               ESoapRequest *request,
                                EContact *new,
                                EContact *old,
                                gchar **out_new_change_key,
@@ -1589,7 +1588,7 @@ ebews_set_phone_number_changes (EBookBackendEws *bbews,
        gint i;
        gchar *new_value, *old_value;
 
-       if (!message)
+       if (!request)
                return;
 
        for (i = 0; i < G_N_ELEMENTS (phone_field_map); i++) {
@@ -1597,7 +1596,7 @@ ebews_set_phone_number_changes (EBookBackendEws *bbews,
                old_value = e_contact_get (old, phone_field_map[i].field);
 
                if (g_strcmp0 (new_value, old_value) != 0)
-                       convert_indexed_contact_property_to_updatexml (message, "PhoneNumber", new_value, 
"contacts", "PhoneNumbers", phone_field_map[i].element);
+                       convert_indexed_contact_property_to_updatexml (request, "PhoneNumber", new_value, 
"contacts", "PhoneNumbers", phone_field_map[i].element);
 
                g_free (new_value);
                g_free (old_value);
@@ -1605,7 +1604,7 @@ ebews_set_phone_number_changes (EBookBackendEws *bbews,
 }
 
 static void
-convert_indexed_contact_property_to_updatexml_physical_address (ESoapMessage *message,
+convert_indexed_contact_property_to_updatexml_physical_address (ESoapRequest *request,
                                                                 const gchar *name,
                                                                 const gchar *uri_element,
                                                                 const gchar *value,
@@ -1621,26 +1620,25 @@ convert_indexed_contact_property_to_updatexml_physical_address (ESoapMessage *me
 
        fielduri = g_strconcat (name, ":", uri_element, NULL);
 
-       e_ews_message_start_set_indexed_item_field (message, fielduri , prefix, "Contact", key, delete_field);
+       e_ews_request_start_set_indexed_item_field (request, fielduri , prefix, "Contact", key, delete_field);
 
-       if (!delete_field)
-       {
-               e_soap_message_start_element (message, element_name, NULL, NULL);
+       if (!delete_field) {
+               e_soap_request_start_element (request, element_name, NULL, NULL);
 
-               e_soap_message_start_element (message, "Entry", NULL, NULL);
-               e_soap_message_add_attribute (message, "Key", key, NULL, NULL);
-               e_ews_message_write_string_parameter (message, uri_element, NULL, value);
-               e_soap_message_end_element (message);
+               e_soap_request_start_element (request, "Entry", NULL, NULL);
+               e_soap_request_add_attribute (request, "Key", key, NULL, NULL);
+               e_ews_request_write_string_parameter (request, uri_element, NULL, value);
+               e_soap_request_end_element (request);
 
-               e_soap_message_end_element (message);
+               e_soap_request_end_element (request);
        }
-       e_ews_message_end_set_indexed_item_field (message, delete_field);
+       e_ews_request_end_set_indexed_item_field (request, delete_field);
 
        g_free (fielduri);
 }
 
 static void
-compare_address (ESoapMessage *message,
+compare_address (ESoapRequest *request,
                  EContact *new,
                  EContact *old,
                  EContactField field,
@@ -1665,15 +1663,15 @@ compare_address (ESoapMessage *message,
        }
 
        if (set || g_strcmp0 (new_address->street, old_address->street) != 0)
-               convert_indexed_contact_property_to_updatexml_physical_address (message, "PhysicalAddress", 
"Street", new_address->street, "contacts", "PhysicalAddresses", key);
+               convert_indexed_contact_property_to_updatexml_physical_address (request, "PhysicalAddress", 
"Street", new_address->street, "contacts", "PhysicalAddresses", key);
        if (set || g_strcmp0 (new_address->locality, old_address->locality) != 0)
-               convert_indexed_contact_property_to_updatexml_physical_address (message, "PhysicalAddress", 
"City", new_address->locality, "contacts", "PhysicalAddresses", key);
+               convert_indexed_contact_property_to_updatexml_physical_address (request, "PhysicalAddress", 
"City", new_address->locality, "contacts", "PhysicalAddresses", key);
        if (set || g_strcmp0 (new_address->region, old_address->region) != 0)
-               convert_indexed_contact_property_to_updatexml_physical_address (message, "PhysicalAddress", 
"State", new_address->region, "contacts", "PhysicalAddresses", key);
+               convert_indexed_contact_property_to_updatexml_physical_address (request, "PhysicalAddress", 
"State", new_address->region, "contacts", "PhysicalAddresses", key);
        if (set || g_strcmp0 (new_address->country, old_address->country) != 0)
-               convert_indexed_contact_property_to_updatexml_physical_address (message, "PhysicalAddress", 
"CountryOrRegion", new_address->country, "contacts", "PhysicalAddresses", key);
+               convert_indexed_contact_property_to_updatexml_physical_address (request, "PhysicalAddress", 
"CountryOrRegion", new_address->country, "contacts", "PhysicalAddresses", key);
        if (set || g_strcmp0 (new_address->code, old_address->code) != 0)
-               convert_indexed_contact_property_to_updatexml_physical_address (message, "PhysicalAddress", 
"PostalCode", new_address->code, "contacts", "PhysicalAddresses", key);
+               convert_indexed_contact_property_to_updatexml_physical_address (request, "PhysicalAddress", 
"PostalCode", new_address->code, "contacts", "PhysicalAddresses", key);
 
        e_contact_address_free (old_address);
        e_contact_address_free (new_address);
@@ -1681,24 +1679,24 @@ compare_address (ESoapMessage *message,
 
 static void
 ebews_set_address_changes (EBookBackendEws *bbews,
-                          ESoapMessage *message,
+                          ESoapRequest *request,
                           EContact *new,
                           EContact *old,
                           gchar **out_new_change_key,
                           GCancellable *cancellable,
                           GError **error)
 {
-       if (!message)
+       if (!request)
                return;
 
-       compare_address (message, new, old, E_CONTACT_ADDRESS_WORK, "Business");
-       compare_address (message, new, old, E_CONTACT_ADDRESS_HOME, "Home");
-       compare_address (message, new, old, E_CONTACT_ADDRESS_OTHER, "Other");
+       compare_address (request, new, old, E_CONTACT_ADDRESS_WORK, "Business");
+       compare_address (request, new, old, E_CONTACT_ADDRESS_HOME, "Home");
+       compare_address (request, new, old, E_CONTACT_ADDRESS_OTHER, "Other");
 }
 
 static void
 ebews_set_im_changes (EBookBackendEws *bbews,
-                     ESoapMessage *message,
+                     ESoapRequest *request,
                      EContact *new,
                      EContact *old,
                      gchar **out_new_change_key,
@@ -1710,7 +1708,7 @@ ebews_set_im_changes (EBookBackendEws *bbews,
 
 static void
 ebews_set_notes_changes (EBookBackendEws *bbews,
-                        ESoapMessage *message,
+                        ESoapRequest *request,
                         EContact *new,
                         EContact *old,
                         gchar **out_new_change_key,
@@ -1719,7 +1717,7 @@ ebews_set_notes_changes (EBookBackendEws *bbews,
 {
        gchar *old_notes, *new_notes;
 
-       if (!message)
+       if (!request)
                return;
 
        old_notes = e_contact_get (old, E_CONTACT_NOTE);
@@ -1727,7 +1725,7 @@ ebews_set_notes_changes (EBookBackendEws *bbews,
 
        if (g_strcmp0 (old_notes, new_notes) != 0) {
                convert_contact_property_to_updatexml (
-                               message, "Body", new_notes ? new_notes : "", "item", "BodyType", "Text");
+                               request, "Body", new_notes ? new_notes : "", "item", "BodyType", "Text");
        }
 
        g_free (old_notes);
@@ -1736,7 +1734,7 @@ ebews_set_notes_changes (EBookBackendEws *bbews,
 
 static void
 ebews_set_email_changes (EBookBackendEws *bbews,
-                        ESoapMessage *message,
+                        ESoapRequest *request,
                         EContact *new,
                         EContact *old,
                         gchar **out_new_change_key,
@@ -1745,27 +1743,27 @@ ebews_set_email_changes (EBookBackendEws *bbews,
 {
        gchar *new_value, *old_value;
 
-       if (!message)
+       if (!request)
                return;
 
        new_value = e_contact_get (new, E_CONTACT_EMAIL_1);
        old_value = e_contact_get (old, E_CONTACT_EMAIL_1);
        if (g_strcmp0 (new_value, old_value) != 0)
-               convert_indexed_contact_property_to_updatexml (message, "EmailAddress", new_value, 
"contacts", "EmailAddresses", "EmailAddress1");
+               convert_indexed_contact_property_to_updatexml (request, "EmailAddress", new_value, 
"contacts", "EmailAddresses", "EmailAddress1");
        g_free (new_value);
        g_free (old_value);
 
        new_value = e_contact_get (new, E_CONTACT_EMAIL_2);
        old_value = e_contact_get (old, E_CONTACT_EMAIL_2);
        if (g_strcmp0 (new_value, old_value) != 0)
-               convert_indexed_contact_property_to_updatexml (message, "EmailAddress", new_value, 
"contacts", "EmailAddresses", "EmailAddress2");
+               convert_indexed_contact_property_to_updatexml (request, "EmailAddress", new_value, 
"contacts", "EmailAddresses", "EmailAddress2");
        g_free (new_value);
        g_free (old_value);
 
        new_value = e_contact_get (new, E_CONTACT_EMAIL_3);
        old_value = e_contact_get (old, E_CONTACT_EMAIL_3);
        if (g_strcmp0 (new_value, old_value) != 0)
-               convert_indexed_contact_property_to_updatexml (message, "EmailAddress", new_value, 
"contacts", "EmailAddresses", "EmailAddress3");
+               convert_indexed_contact_property_to_updatexml (request, "EmailAddress", new_value, 
"contacts", "EmailAddresses", "EmailAddress3");
        g_free (new_value);
        g_free (old_value);
 }
@@ -1786,7 +1784,7 @@ ebews_populate_givenname (EBookBackendEws *bbews,
 
 static void
 ebews_set_givenname (EBookBackendEws *bbews,
-                    ESoapMessage *message,
+                    ESoapRequest *request,
                     EContact *contact)
 {
        /* Does nothing, the "GivenName" is filled by the "FullName" code */
@@ -1794,7 +1792,7 @@ ebews_set_givenname (EBookBackendEws *bbews,
 
 static void
 ebews_set_givenname_changes (EBookBackendEws *bbews,
-                            ESoapMessage *message,
+                            ESoapRequest *request,
                             EContact *new,
                             EContact *old,
                             gchar **out_new_change_key,
@@ -1839,7 +1837,7 @@ ebews_populate_categories (EBookBackendEws *bbews,
 
 static void
 ebews_set_categories (EBookBackendEws *bbews,
-                     ESoapMessage *message,
+                     ESoapRequest *request,
                      EContact *contact)
 {
        GList *values;
@@ -1848,13 +1846,13 @@ ebews_set_categories (EBookBackendEws *bbews,
        if (values) {
                GList *link;
 
-               e_soap_message_start_element (message, "Categories", NULL, NULL);
+               e_soap_request_start_element (request, "Categories", NULL, NULL);
                for (link = values; link; link = g_list_next (link)) {
                        const gchar *category = link->data;
                        if (category && *category)
-                               e_ews_message_write_string_parameter (message, "String", NULL, category);
+                               e_ews_request_write_string_parameter (request, "String", NULL, category);
                }
-               e_soap_message_end_element (message);
+               e_soap_request_end_element (request);
        }
 
        g_list_free_full (values, g_free);
@@ -1862,7 +1860,7 @@ ebews_set_categories (EBookBackendEws *bbews,
 
 static void
 ebews_set_categories_changes (EBookBackendEws *bbews,
-                             ESoapMessage *message,
+                             ESoapRequest *request,
                              EContact *new,
                              EContact *old,
                              gchar **out_new_change_key,
@@ -1871,7 +1869,7 @@ ebews_set_categories_changes (EBookBackendEws *bbews,
 {
        gchar *old_categories, *new_categories;
 
-       if (!message)
+       if (!request)
                return;
 
        old_categories = e_contact_get (old, E_CONTACT_CATEGORIES);
@@ -1882,27 +1880,27 @@ ebews_set_categories_changes (EBookBackendEws *bbews,
 
                values = e_contact_get (new, E_CONTACT_CATEGORY_LIST);
                if (values) {
-                       e_soap_message_start_element (message, "SetItemField", NULL, NULL);
+                       e_soap_request_start_element (request, "SetItemField", NULL, NULL);
 
-                       e_soap_message_start_element (message, "FieldURI", NULL, NULL);
-                       e_soap_message_add_attribute (message, "FieldURI", "item:Categories", NULL, NULL);
-                       e_soap_message_end_element (message);
+                       e_soap_request_start_element (request, "FieldURI", NULL, NULL);
+                       e_soap_request_add_attribute (request, "FieldURI", "item:Categories", NULL, NULL);
+                       e_soap_request_end_element (request);
 
-                       e_soap_message_start_element (message, "Contact", NULL, NULL);
-                       e_soap_message_start_element (message, "Categories", NULL, NULL);
+                       e_soap_request_start_element (request, "Contact", NULL, NULL);
+                       e_soap_request_start_element (request, "Categories", NULL, NULL);
 
                        for (link = values; link; link = g_list_next (link)) {
                                const gchar *category = link->data;
 
                                if (category && *category)
-                                       e_ews_message_write_string_parameter (message, "String", NULL, 
category);
+                                       e_ews_request_write_string_parameter (request, "String", NULL, 
category);
                        }
 
-                       e_soap_message_end_element (message); /* Categories */
-                       e_soap_message_end_element (message); /* Contact */
-                       e_soap_message_end_element (message); /* SetItemField */
+                       e_soap_request_end_element (request); /* Categories */
+                       e_soap_request_end_element (request); /* Contact */
+                       e_soap_request_end_element (request); /* SetItemField */
                } else {
-                       e_ews_message_add_delete_item_field (message, "Categories", "item");
+                       e_ews_request_add_delete_item_field (request, "Categories", "item");
                }
 
                g_list_free_full (values, g_free);
@@ -1919,8 +1917,8 @@ static const struct field_element_mapping {
        /* set function for simple string type values */
        const gchar * (*get_simple_prop_func) (EEwsItem *item);
        void (*populate_contact_func)(EBookBackendEws *bbews, EContact *contact, EEwsItem *item, GCancellable 
*cancellable, GError **error);
-       void (*set_value_in_soap_message) (EBookBackendEws *bbews, ESoapMessage *message, EContact *contact);
-       void (*set_changes) (EBookBackendEws *bbews, ESoapMessage *message, EContact *new, EContact *old, 
gchar **out_new_change_key, GCancellable *cancellable, GError **error);
+       void (*set_value_in_soap_request) (EBookBackendEws *bbews, ESoapRequest *request, EContact *contact);
+       void (*set_changes) (EBookBackendEws *bbews, ESoapRequest *request, EContact *new, EContact *old, 
gchar **out_new_change_key, GCancellable *cancellable, GError **error);
 
 } mappings[] = {
        /* The order should be maintained for create contacts to work */
@@ -1959,12 +1957,12 @@ static const struct field_element_mapping {
 };
 
 static void
-ebb_ews_write_dl_members (ESoapMessage *msg,
+ebb_ews_write_dl_members (ESoapRequest *request,
                          EContact *contact)
 {
        GSList *emails, *l;
 
-       e_soap_message_start_element (msg, "Members", NULL, NULL);
+       e_soap_request_start_element (request, "Members", NULL, NULL);
 
        emails = e_contact_get (contact, E_CONTACT_EMAIL);
        for (l = emails; l; l = l->next) {
@@ -1978,19 +1976,19 @@ ebb_ews_write_dl_members (ESoapMessage *msg,
                        const gchar *name = NULL, *email = NULL;
 
                        if (camel_internet_address_get (addr, 0, &name, &email) && email) {
-                               e_soap_message_start_element (msg, "Member", NULL, NULL);
-                               e_soap_message_start_element (msg, "Mailbox", NULL, NULL);
-                               e_ews_message_write_string_parameter (msg, "Name", NULL, name ? name : email);
-                               e_ews_message_write_string_parameter (msg, "EmailAddress", NULL, email);
-                               e_soap_message_end_element (msg); /* Mailbox */
-                               e_soap_message_end_element (msg); /* Member */
+                               e_soap_request_start_element (request, "Member", NULL, NULL);
+                               e_soap_request_start_element (request, "Mailbox", NULL, NULL);
+                               e_ews_request_write_string_parameter (request, "Name", NULL, name ? name : 
email);
+                               e_ews_request_write_string_parameter (request, "EmailAddress", NULL, email);
+                               e_soap_request_end_element (request); /* Mailbox */
+                               e_soap_request_end_element (request); /* Member */
                        }
                }
                g_object_unref (addr);
        }
 
        g_slist_free_full (emails, g_free);
-       e_soap_message_end_element (msg); /* Members */
+       e_soap_request_end_element (request); /* Members */
 }
 
 typedef struct _CreateItemsData
@@ -2000,7 +1998,7 @@ typedef struct _CreateItemsData
 } CreateItemsData;
 
 static gboolean
-ebb_ews_convert_dl_to_xml_cb (ESoapMessage *msg,
+ebb_ews_convert_dl_to_xml_cb (ESoapRequest *request,
                              gpointer user_data,
                              GError **error)
 {
@@ -2009,22 +2007,22 @@ ebb_ews_convert_dl_to_xml_cb (ESoapMessage *msg,
        EVCardAttribute *attribute;
        GList *values;
 
-       /* Prepare DistributionList node in the SOAP message */
-       e_soap_message_start_element (msg, "DistributionList", NULL, NULL);
+       /* Prepare DistributionList node in the SOAP request */
+       e_soap_request_start_element (request, "DistributionList", NULL, NULL);
 
        attribute = e_vcard_get_attribute (E_VCARD (contact), EVC_FN);
        values = e_vcard_attribute_get_values (attribute);
-       e_ews_message_write_string_parameter (msg, "DisplayName", NULL, values->data);
+       e_ews_request_write_string_parameter (request, "DisplayName", NULL, values->data);
 
-       ebb_ews_write_dl_members (msg, contact);
+       ebb_ews_write_dl_members (request, contact);
 
-       e_soap_message_end_element (msg); /* DistributionList */
+       e_soap_request_end_element (request); /* DistributionList */
 
        return TRUE;
 }
 
 static gboolean
-ebb_ews_convert_contact_to_xml_cb (ESoapMessage *msg,
+ebb_ews_convert_contact_to_xml_cb (ESoapRequest *request,
                                   gpointer user_data,
                                   GError **error)
 {
@@ -2032,8 +2030,8 @@ ebb_ews_convert_contact_to_xml_cb (ESoapMessage *msg,
        EContact *contact = cid->contact;
        gint i, element_type;
 
-       /* Prepare Contact node in the SOAP message */
-       e_soap_message_start_element (msg, "Contact", NULL, NULL);
+       /* Prepare Contact node in the SOAP request */
+       e_soap_request_start_element (request, "Contact", NULL, NULL);
 
        for (i = 0; i < G_N_ELEMENTS (mappings); i++) {
                element_type = mappings[i].element_type;
@@ -2047,14 +2045,14 @@ ebb_ews_convert_contact_to_xml_cb (ESoapMessage *msg,
 
                        val = e_contact_get (contact, mappings[i].field_id);
                        if (val && *val)
-                               e_ews_message_write_string_parameter (msg, mappings[i].element_name, NULL, 
val);
+                               e_ews_request_write_string_parameter (request, mappings[i].element_name, 
NULL, val);
                        g_free (val);
                } else
-                       mappings[i].set_value_in_soap_message (cid->bbews, msg, contact);
+                       mappings[i].set_value_in_soap_request (cid->bbews, request, contact);
        }
 
        /* end of "Contact" */
-       e_soap_message_end_element (msg);
+       e_soap_request_end_element (request);
 
        return TRUE;
 }
@@ -2070,7 +2068,7 @@ typedef struct _ConvertData {
 } ConvertData;
 
 static gboolean
-ebb_ews_convert_dl_to_updatexml_cb (ESoapMessage *msg,
+ebb_ews_convert_dl_to_updatexml_cb (ESoapRequest *request,
                                    gpointer user_data,
                                    GError **error)
 {
@@ -2085,14 +2083,14 @@ ebb_ews_convert_dl_to_updatexml_cb (ESoapMessage *msg,
                        change_key = e_contact_get (old_contact, E_CONTACT_REV);
        }
 
-       e_ews_message_start_item_change (msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
+       e_ews_request_start_item_change (request, E_EWS_ITEMCHANGE_TYPE_ITEM,
                e_contact_get_const (old_contact, E_CONTACT_UID),
                cd->change_key ? cd->change_key : change_key,
                0);
-       e_ews_message_start_set_item_field (msg, "Members", "distributionlist", "DistributionList");
-       ebb_ews_write_dl_members (msg, new_contact);
-       e_ews_message_end_set_item_field (msg);
-       e_ews_message_end_item_change (msg);
+       e_ews_request_start_set_item_field (request, "Members", "distributionlist", "DistributionList");
+       ebb_ews_write_dl_members (request, new_contact);
+       e_ews_request_end_set_item_field (request);
+       e_ews_request_end_item_change (request);
 
        g_free (change_key);
 
@@ -2100,7 +2098,7 @@ ebb_ews_convert_dl_to_updatexml_cb (ESoapMessage *msg,
 }
 
 static gboolean
-ebb_ews_convert_contact_to_updatexml_cb (ESoapMessage *msg,
+ebb_ews_convert_contact_to_updatexml_cb (ESoapRequest *request,
                                         gpointer user_data,
                                         GError **error)
 {
@@ -2136,7 +2134,7 @@ ebb_ews_convert_contact_to_updatexml_cb (ESoapMessage *msg,
                        change_key = e_contact_get (old_contact, E_CONTACT_REV);
        }
 
-       e_ews_message_start_item_change (msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
+       e_ews_request_start_item_change (request, E_EWS_ITEMCHANGE_TYPE_ITEM,
                e_contact_get_const (old_contact, E_CONTACT_UID),
                cd->change_key ? cd->change_key : change_key,
                0);
@@ -2149,7 +2147,7 @@ ebb_ews_convert_contact_to_updatexml_cb (ESoapMessage *msg,
                        value =  e_contact_get (new_contact, mappings[i].field_id);
                        old_value =  e_contact_get (old_contact, mappings[i].field_id);
                        if (g_strcmp0 (value, old_value) != 0)
-                               convert_contact_property_to_updatexml (msg, mappings[i].element_name, value, 
"contacts", NULL, NULL);
+                               convert_contact_property_to_updatexml (request, mappings[i].element_name, 
value, "contacts", NULL, NULL);
                        if (value)
                                g_free (value);
                        if (old_value)
@@ -2160,7 +2158,7 @@ ebb_ews_convert_contact_to_updatexml_cb (ESoapMessage *msg,
                        if (mappings[i].field_id == E_CONTACT_UID)
                                continue;
 
-                       mappings[i].set_changes (cd->bbews, msg, new_contact, old_contact, &new_change_key, 
cd->cancellable, cd->error);
+                       mappings[i].set_changes (cd->bbews, request, new_contact, old_contact, 
&new_change_key, cd->cancellable, cd->error);
 
                        if (new_change_key) {
                                g_free (cd->change_key);
@@ -2169,7 +2167,7 @@ ebb_ews_convert_contact_to_updatexml_cb (ESoapMessage *msg,
                }
        }
 
-       e_ews_message_end_item_change (msg);
+       e_ews_request_end_item_change (request);
 
        g_free (change_key);
 
@@ -2300,8 +2298,8 @@ ebb_ews_traverse_dl (EBookBackendEws *bbews,
                        bbews->priv->cnc,
                        EWS_PRIORITY_MEDIUM,
                        mb,
-                       &members,
                        &includes_last,
+                       &members,
                        cancellable,
                        &local_error);
 
@@ -2505,8 +2503,8 @@ ebb_ews_fetch_items_sync (EBookBackendEws *bbews,
 
                d_name = e_ews_item_get_subject (item);
                if (e_ews_connection_expand_dl_sync (
-                       bbews->priv->cnc, EWS_PRIORITY_MEDIUM, mb, &members,
-                       &includes_last, cancellable, &local_error)) {
+                       bbews->priv->cnc, EWS_PRIORITY_MEDIUM, mb, &includes_last, &members,
+                       cancellable, &local_error)) {
                        ret = ebb_ews_contacts_append_dl (bbews, item, id, d_name, members, contacts, 
cancellable, error);
                        g_slist_free_full (members, (GDestroyNotify) e_ews_mailbox_free);
                } else {
@@ -3462,7 +3460,7 @@ ebb_ews_update_cache_for_expression (EBookBackendEws *bbews,
                success = ebb_ews_build_restriction (expr, &restriction_expr) &&
                        e_book_meta_backend_ensure_connected_sync (meta_backend, cancellable, error) &&
                        e_ews_connection_resolve_names_sync (bbews->priv->cnc, EWS_PRIORITY_MEDIUM, 
restriction_expr,
-                               EWS_SEARCH_AD, NULL, TRUE, &mailboxes, &contacts, &includes_last_item, 
cancellable, error);
+                               EWS_SEARCH_AD, NULL, TRUE, &includes_last_item, &mailboxes, &contacts, 
cancellable, error);
 
                if (success) {
                        EBookCache *book_cache;
@@ -4001,7 +3999,7 @@ ebb_ews_get_changes_sync (EBookMetaBackend *meta_backend,
 
                        d (printf ("Ewsgal: Fetching oal full details file\n"));
                        if (!e_ews_connection_get_oal_detail_sync (oab_cnc, bbews->priv->folder_id, NULL, 
last_sync_tag, &full_l, &etag, cancellable, &local_error)) {
-                               if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_NOT_MODIFIED)) 
{
+                               if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, 
SOUP_STATUS_NOT_MODIFIED)) {
                                        g_clear_error (&local_error);
                                } else {
                                        success = FALSE;
@@ -4554,7 +4552,7 @@ ebb_ews_get_destination_address (EBackend *backend,
                                 guint16 *port)
 {
        CamelEwsSettings *ews_settings;
-       SoupURI *soup_uri;
+       GUri *uri;
        gchar *host_url;
        gboolean result = FALSE;
 
@@ -4572,10 +4570,10 @@ ebb_ews_get_destination_address (EBackend *backend,
        host_url = camel_ews_settings_dup_hosturl (ews_settings);
        g_return_val_if_fail (host_url != NULL, FALSE);
 
-       soup_uri = soup_uri_new (host_url);
-       if (soup_uri) {
-               *host = g_strdup (soup_uri_get_host (soup_uri));
-               *port = soup_uri_get_port (soup_uri);
+       uri = g_uri_parse (host_url, SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
+       if (uri) {
+               *host = g_strdup (g_uri_get_host (uri));
+               *port = g_uri_get_port (uri);
 
                result = *host && **host;
                if (!result) {
@@ -4583,7 +4581,7 @@ ebb_ews_get_destination_address (EBackend *backend,
                        *host = NULL;
                }
 
-               soup_uri_free (soup_uri);
+               g_uri_unref (uri);
        }
 
        g_free (host_url);
diff --git a/src/EWS/calendar/e-cal-backend-ews-utils.c b/src/EWS/calendar/e-cal-backend-ews-utils.c
index 2e904223..bd2281ff 100644
--- a/src/EWS/calendar/e-cal-backend-ews-utils.c
+++ b/src/EWS/calendar/e-cal-backend-ews-utils.c
@@ -27,11 +27,10 @@
 #include <libxml/xpathInternals.h>
 
 #include <libecal/libecal.h>
-#include <libsoup/soup-misc.h>
 
 #include "common/e-ews-calendar-utils.h"
 #include "common/e-ews-connection.h"
-#include "common/e-ews-message.h"
+#include "common/e-ews-request.h"
 #include "common/e-ews-item-change.h"
 
 #include "e-cal-backend-ews-utils.h"
@@ -329,7 +328,7 @@ ews_get_alarm (ECalComponent *comp)
 }
 
 void
-ews_set_alarm (ESoapMessage *msg,
+ews_set_alarm (ESoapRequest *request,
                ECalComponent *comp,
               ETimezoneCache *timezone_cache,
               ICalComponent *vcalendar,
@@ -346,7 +345,7 @@ ews_set_alarm (ESoapMessage *msg,
 
        alarm = e_cal_component_get_alarm (comp, (const gchar *) (alarm_uids->data));
 
-       e_ews_message_write_string_parameter (msg, "ReminderIsSet", NULL, "true");
+       e_ews_request_write_string_parameter (request, "ReminderIsSet", NULL, "true");
        action = e_cal_component_alarm_get_action (alarm);
        if (action == E_CAL_COMPONENT_ALARM_DISPLAY) {
                ECalComponentAlarmTrigger *trigger;
@@ -355,7 +354,7 @@ ews_set_alarm (ESoapMessage *msg,
                trigger = e_cal_component_alarm_get_trigger (alarm);
                if (trigger && e_cal_component_alarm_trigger_get_kind (trigger) == 
E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START) {
                        dur_int = (i_cal_duration_as_int (e_cal_component_alarm_trigger_get_duration 
(trigger)) / SECS_IN_MINUTE) * -1;
-                       e_ews_message_write_int_parameter (msg, "ReminderMinutesBeforeStart", NULL, dur_int);
+                       e_ews_request_write_int_parameter (request, "ReminderMinutesBeforeStart", NULL, 
dur_int);
                        if (with_due_by) {
                                ICalTime *dtstart;
 
@@ -363,7 +362,7 @@ ews_set_alarm (ESoapMessage *msg,
                                        I_CAL_DTSTART_PROPERTY, i_cal_property_get_dtstart);
 
                                if (dtstart && !i_cal_time_is_null_time (dtstart)) {
-                                       e_ews_message_write_time_parameter (msg, "ReminderDueBy", NULL,
+                                       e_ews_request_write_time_parameter (request, "ReminderDueBy", NULL,
                                                i_cal_time_as_timet_with_zone (dtstart, 
i_cal_timezone_get_utc_timezone ()));
                                }
 
@@ -376,7 +375,7 @@ ews_set_alarm (ESoapMessage *msg,
 }
 
 static void
-ewscal_set_date (ESoapMessage *msg,
+ewscal_set_date (ESoapRequest *request,
                  const gchar *name,
                  ICalTime *itt)
 {
@@ -386,7 +385,7 @@ ewscal_set_date (ESoapMessage *msg,
                "%04d-%02d-%02d",
                i_cal_time_get_year (itt), i_cal_time_get_month (itt), i_cal_time_get_day (itt));
 
-       e_ews_message_write_string_parameter (msg, name, NULL, str);
+       e_ews_request_write_string_parameter (request, name, NULL, str);
        g_free (str);
 }
 
@@ -432,23 +431,23 @@ static const gchar *weekindex_to_ical (gint index) {
 }
 
 static void
-ewscal_add_rrule (ESoapMessage *msg,
+ewscal_add_rrule (ESoapRequest *request,
                  ICalProperty *prop)
 {
        ICalRecurrence *recur = i_cal_property_get_rrule (prop);
 
-       e_soap_message_start_element (msg, "RelativeYearlyRecurrence", NULL, NULL);
+       e_soap_request_start_element (request, "RelativeYearlyRecurrence", NULL, NULL);
 
-       e_ews_message_write_string_parameter (msg, "DaysOfWeek", NULL, number_to_weekday 
(i_cal_recurrence_day_day_of_week (i_cal_recurrence_get_by_day (recur, 0))));
-       e_ews_message_write_string_parameter (msg, "DayOfWeekIndex", NULL, weekindex_to_ical 
(i_cal_recurrence_day_position (i_cal_recurrence_get_by_day (recur, 0))));
-       e_ews_message_write_string_parameter (msg, "Month", NULL, number_to_month 
(i_cal_recurrence_get_by_month (recur, 0)));
+       e_ews_request_write_string_parameter (request, "DaysOfWeek", NULL, number_to_weekday 
(i_cal_recurrence_day_day_of_week (i_cal_recurrence_get_by_day (recur, 0))));
+       e_ews_request_write_string_parameter (request, "DayOfWeekIndex", NULL, weekindex_to_ical 
(i_cal_recurrence_day_position (i_cal_recurrence_get_by_day (recur, 0))));
+       e_ews_request_write_string_parameter (request, "Month", NULL, number_to_month 
(i_cal_recurrence_get_by_month (recur, 0)));
 
-       e_soap_message_end_element (msg); /* "RelativeYearlyRecurrence" */
+       e_soap_request_end_element (request); /* "RelativeYearlyRecurrence" */
        g_clear_object (&recur);
 }
 
 static void
-ewscal_add_timechange (ESoapMessage *msg,
+ewscal_add_timechange (ESoapRequest *request,
                       ICalComponent *comp,
                       gint baseoffs)
 {
@@ -461,7 +460,7 @@ ewscal_add_timechange (ESoapMessage *msg,
        prop = i_cal_component_get_first_property (comp, I_CAL_TZNAME_PROPERTY);
        if (prop) {
                tzname = i_cal_property_get_tzname (prop);
-               e_soap_message_add_attribute (msg, "TimeZoneName", tzname, NULL, NULL);
+               e_soap_request_add_attribute (request, "TimeZoneName", tzname, NULL, NULL);
                g_object_unref (prop);
        }
 
@@ -474,7 +473,7 @@ ewscal_add_timechange (ESoapMessage *msg,
                utcoffs -= baseoffs;
                duration = i_cal_duration_new_from_int (utcoffs);
                offset = i_cal_duration_as_ical_string (duration);
-               e_ews_message_write_string_parameter (msg, "Offset", NULL, offset);
+               e_ews_request_write_string_parameter (request, "Offset", NULL, offset);
 
                g_clear_object (&duration);
                g_object_unref (prop);
@@ -483,7 +482,7 @@ ewscal_add_timechange (ESoapMessage *msg,
 
        prop = i_cal_component_get_first_property (comp, I_CAL_RRULE_PROPERTY);
        if (prop) {
-               ewscal_add_rrule (msg, prop);
+               ewscal_add_rrule (request, prop);
                g_object_unref (prop);
        }
 
@@ -491,14 +490,14 @@ ewscal_add_timechange (ESoapMessage *msg,
        if (prop) {
                dtstart = i_cal_property_get_dtstart (prop);
                snprintf (buffer, 16, "%02d:%02d:%02d", i_cal_time_get_hour (dtstart), i_cal_time_get_minute 
(dtstart), i_cal_time_get_second (dtstart));
-               e_ews_message_write_string_parameter (msg, "Time", NULL, buffer);
+               e_ews_request_write_string_parameter (request, "Time", NULL, buffer);
                g_clear_object (&dtstart);
                g_object_unref (prop);
        }
 }
 
 static void
-ewscal_set_absolute_date_transitions (ESoapMessage *msg,
+ewscal_set_absolute_date_transitions (ESoapRequest *request,
                                      GSList *absolute_date_transitions)
 {
        GSList *l;
@@ -509,20 +508,19 @@ ewscal_set_absolute_date_transitions (ESoapMessage *msg,
        for (l = absolute_date_transitions; l != NULL; l = l->next) {
                EEwsCalendarAbsoluteDateTransition *adt = l->data;
 
-               e_soap_message_start_element (msg, "AbsoluteDateTransition", NULL, NULL);
+               e_soap_request_start_element (request, "AbsoluteDateTransition", NULL, NULL);
 
-               e_ews_message_write_string_parameter_with_attribute (
-                       msg,
+               e_ews_request_write_string_parameter_with_attribute (request,
                        "To", NULL, adt->to->value,
                        "Kind", adt->to->kind);
-               e_ews_message_write_string_parameter (msg, "DateTime", NULL, adt->date_time);
+               e_ews_request_write_string_parameter (request, "DateTime", NULL, adt->date_time);
 
-               e_soap_message_end_element (msg); /* "AbsoluteDateTransition" */
+               e_soap_request_end_element (request); /* "AbsoluteDateTransition" */
        }
 }
 
 static void
-ewscal_set_recurring_day_transitions (ESoapMessage *msg,
+ewscal_set_recurring_day_transitions (ESoapRequest *request,
                                      GSList *recurring_day_transitions)
 {
        GSList *l;
@@ -533,23 +531,22 @@ ewscal_set_recurring_day_transitions (ESoapMessage *msg,
        for (l = recurring_day_transitions; l != NULL; l = l->next) {
                EEwsCalendarRecurringDayTransition *rdt = l->data;
 
-               e_soap_message_start_element (msg, "RecurringDayTransition", NULL, NULL);
+               e_soap_request_start_element (request, "RecurringDayTransition", NULL, NULL);
 
-               e_ews_message_write_string_parameter_with_attribute (
-                       msg,
+               e_ews_request_write_string_parameter_with_attribute (request,
                        "To", NULL, rdt->to->value,
                        "Kind", rdt->to->kind);
-               e_ews_message_write_string_parameter (msg, "TimeOffset", NULL, rdt->time_offset);
-               e_ews_message_write_string_parameter (msg, "Month", NULL, rdt->month);
-               e_ews_message_write_string_parameter (msg, "DayOfWeek", NULL, rdt->day_of_week);
-               e_ews_message_write_string_parameter (msg, "Occurrence", NULL, rdt->occurrence);
+               e_ews_request_write_string_parameter (request, "TimeOffset", NULL, rdt->time_offset);
+               e_ews_request_write_string_parameter (request, "Month", NULL, rdt->month);
+               e_ews_request_write_string_parameter (request, "DayOfWeek", NULL, rdt->day_of_week);
+               e_ews_request_write_string_parameter (request, "Occurrence", NULL, rdt->occurrence);
 
-               e_soap_message_end_element (msg); /* "RecurringDayTransition" */
+               e_soap_request_end_element (request); /* "RecurringDayTransition" */
        }
 }
 
 static void
-ewscal_set_recurring_date_transitions (ESoapMessage *msg,
+ewscal_set_recurring_date_transitions (ESoapRequest *request,
                                       GSList *recurring_date_transitions)
 {
        GSList *l;
@@ -560,22 +557,21 @@ ewscal_set_recurring_date_transitions (ESoapMessage *msg,
        for (l = recurring_date_transitions; l != NULL; l = l->next) {
                EEwsCalendarRecurringDateTransition *rdt = l->data;
 
-               e_soap_message_start_element (msg, "RecurringDateTransition", NULL, NULL);
+               e_soap_request_start_element (request, "RecurringDateTransition", NULL, NULL);
 
-               e_ews_message_write_string_parameter_with_attribute (
-                       msg,
+               e_ews_request_write_string_parameter_with_attribute (request,
                        "To", NULL, rdt->to->value,
                        "Kind", rdt->to->kind);
-               e_ews_message_write_string_parameter (msg, "TimeOffset", NULL, rdt->time_offset);
-               e_ews_message_write_string_parameter (msg, "Month", NULL, rdt->month);
-               e_ews_message_write_string_parameter (msg, "Day", NULL, rdt->day);
+               e_ews_request_write_string_parameter (request, "TimeOffset", NULL, rdt->time_offset);
+               e_ews_request_write_string_parameter (request, "Month", NULL, rdt->month);
+               e_ews_request_write_string_parameter (request, "Day", NULL, rdt->day);
 
-               e_soap_message_end_element (msg); /* "RecurringDateTransition" */
+               e_soap_request_end_element (request); /* "RecurringDateTransition" */
        }
 }
 
 void
-ewscal_set_timezone (ESoapMessage *msg,
+ewscal_set_timezone (ESoapRequest *request,
                     const gchar *name,
                     EEwsCalendarTimeZoneDefinition *tzd)
 {
@@ -584,63 +580,61 @@ ewscal_set_timezone (ESoapMessage *msg,
        if (name == NULL || tzd == NULL)
                return;
 
-       e_soap_message_start_element (msg, name, NULL, NULL);
-       e_soap_message_add_attribute (msg, "Id", tzd->id, NULL, NULL);
-       e_soap_message_add_attribute (msg, "Name", tzd->name, NULL, NULL);
+       e_soap_request_start_element (request, name, NULL, NULL);
+       e_soap_request_add_attribute (request, "Id", tzd->id, NULL, NULL);
+       e_soap_request_add_attribute (request, "Name", tzd->name, NULL, NULL);
 
-       e_soap_message_start_element (msg, "Periods", NULL, NULL);
+       e_soap_request_start_element (request, "Periods", NULL, NULL);
        for (l = tzd->periods; l != NULL; l = l->next) {
                EEwsCalendarPeriod *period = l->data;
 
-               e_soap_message_start_element (msg, "Period", NULL, NULL);
-               e_soap_message_add_attribute (msg, "Bias", period->bias, NULL, NULL);
-               e_soap_message_add_attribute (msg, "Name", period->name, NULL, NULL);
-               e_soap_message_add_attribute (msg, "Id", period->id, NULL, NULL);
-               e_soap_message_end_element (msg); /* "Period" */
+               e_soap_request_start_element (request, "Period", NULL, NULL);
+               e_soap_request_add_attribute (request, "Bias", period->bias, NULL, NULL);
+               e_soap_request_add_attribute (request, "Name", period->name, NULL, NULL);
+               e_soap_request_add_attribute (request, "Id", period->id, NULL, NULL);
+               e_soap_request_end_element (request); /* "Period" */
        }
-       e_soap_message_end_element (msg); /* "Periods" */
+       e_soap_request_end_element (request); /* "Periods" */
 
-       e_soap_message_start_element (msg, "TransitionsGroups", NULL, NULL);
+       e_soap_request_start_element (request, "TransitionsGroups", NULL, NULL);
        for (l = tzd->transitions_groups; l != NULL; l = l->next) {
                EEwsCalendarTransitionsGroup *tg = l->data;
 
-               e_soap_message_start_element (msg, "TransitionsGroup", NULL, NULL);
-               e_soap_message_add_attribute (msg, "Id", tg->id, NULL, NULL);
+               e_soap_request_start_element (request, "TransitionsGroup", NULL, NULL);
+               e_soap_request_add_attribute (request, "Id", tg->id, NULL, NULL);
 
                if (tg->transition != NULL) {
-                       e_soap_message_start_element (msg, "Transition", NULL, NULL);
-                       e_ews_message_write_string_parameter_with_attribute (
-                               msg,
+                       e_soap_request_start_element (request, "Transition", NULL, NULL);
+                       e_ews_request_write_string_parameter_with_attribute (request,
                                "To", NULL, tg->transition->value,
                                "Kind", tg->transition->kind);
-                       e_soap_message_end_element (msg); /* "Transition" */
+                       e_soap_request_end_element (request); /* "Transition" */
                }
 
-               ewscal_set_absolute_date_transitions (msg, tg->absolute_date_transitions);
-               ewscal_set_recurring_day_transitions (msg, tg->recurring_day_transitions);
-               ewscal_set_recurring_date_transitions (msg, tg->recurring_date_transitions);
+               ewscal_set_absolute_date_transitions (request, tg->absolute_date_transitions);
+               ewscal_set_recurring_day_transitions (request, tg->recurring_day_transitions);
+               ewscal_set_recurring_date_transitions (request, tg->recurring_date_transitions);
 
-               e_soap_message_end_element (msg); /* "TransitionsGroup" */
+               e_soap_request_end_element (request); /* "TransitionsGroup" */
        }
-       e_soap_message_end_element (msg); /* "TransitionsGroups" */
+       e_soap_request_end_element (request); /* "TransitionsGroups" */
 
-       e_soap_message_start_element (msg, "Transitions", NULL, NULL);
-       e_soap_message_start_element (msg, "Transition", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (
-               msg,
+       e_soap_request_start_element (request, "Transitions", NULL, NULL);
+       e_soap_request_start_element (request, "Transition", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (request,
                "To", NULL, tzd->transitions->transition->value,
                "Kind", tzd->transitions->transition->kind);
-       e_soap_message_end_element (msg); /* "Transition" */
-       ewscal_set_absolute_date_transitions (msg, tzd->transitions->absolute_date_transitions);
-       ewscal_set_recurring_day_transitions (msg, tzd->transitions->recurring_day_transitions);
-       ewscal_set_recurring_date_transitions (msg, tzd->transitions->recurring_date_transitions);
-       e_soap_message_end_element (msg); /* "Transitions" */
+       e_soap_request_end_element (request); /* "Transition" */
+       ewscal_set_absolute_date_transitions (request, tzd->transitions->absolute_date_transitions);
+       ewscal_set_recurring_day_transitions (request, tzd->transitions->recurring_day_transitions);
+       ewscal_set_recurring_date_transitions (request, tzd->transitions->recurring_date_transitions);
+       e_soap_request_end_element (request); /* "Transitions" */
 
-       e_soap_message_end_element (msg); /* "StartTimeZone" */
+       e_soap_request_end_element (request); /* "StartTimeZone" */
 }
 
 void
-ewscal_set_meeting_timezone (ESoapMessage *msg,
+ewscal_set_meeting_timezone (ESoapRequest *request,
                             ICalTimezone *icaltz,
                             ICalComponent *icomp)
 {
@@ -688,8 +682,8 @@ ewscal_set_meeting_timezone (ESoapMessage *msg,
        if (!location)
                location = i_cal_timezone_get_tznames (icaltz);
 
-       e_soap_message_start_element (msg, "MeetingTimeZone", NULL, NULL);
-       e_soap_message_add_attribute (msg, "TimeZoneName", location, NULL, NULL);
+       e_soap_request_start_element (request, "MeetingTimeZone", NULL, NULL);
+       e_soap_request_add_attribute (request, "TimeZoneName", location, NULL, NULL);
 
        /* Fetch the timezone offsets for the standard (or only) zone.
         * Negate it, because Exchange does it backwards */
@@ -710,7 +704,7 @@ ewscal_set_meeting_timezone (ESoapMessage *msg,
         * zone to zero. So try to avoid problems by doing the same. */
        duration = i_cal_duration_new_from_int (std_utcoffs);
        offset = i_cal_duration_as_ical_string (duration);
-       e_ews_message_write_string_parameter (msg, "BaseOffset", NULL, offset);
+       e_ews_request_write_string_parameter (request, "BaseOffset", NULL, offset);
        g_clear_object (&duration);
        free (offset);
 
@@ -719,16 +713,16 @@ ewscal_set_meeting_timezone (ESoapMessage *msg,
         * one. */
        if (xdaylight) {
                /* Standard */
-               e_soap_message_start_element (msg, "Standard", NULL, NULL);
-               ewscal_add_timechange (msg, xstd, std_utcoffs);
-               e_soap_message_end_element (msg); /* "Standard" */
+               e_soap_request_start_element (request, "Standard", NULL, NULL);
+               ewscal_add_timechange (request, xstd, std_utcoffs);
+               e_soap_request_end_element (request); /* "Standard" */
 
                /* DayLight */
-               e_soap_message_start_element (msg, "Daylight", NULL, NULL);
-               ewscal_add_timechange (msg, xdaylight, std_utcoffs);
-               e_soap_message_end_element (msg); /* "Daylight" */
+               e_soap_request_start_element (request, "Daylight", NULL, NULL);
+               ewscal_add_timechange (request, xdaylight, std_utcoffs);
+               e_soap_request_end_element (request); /* "Daylight" */
        }
-       e_soap_message_end_element (msg); /* "MeetingTimeZone" */
+       e_soap_request_end_element (request); /* "MeetingTimeZone" */
 
        g_clear_object (&comp);
        g_clear_object (&xstd);
@@ -736,7 +730,7 @@ ewscal_set_meeting_timezone (ESoapMessage *msg,
 }
 
 void
-ewscal_set_reccurence (ESoapMessage *msg,
+ewscal_set_reccurence (ESoapRequest *request,
                       ICalProperty *rrule,
                       ICalTime *dtstart)
 {
@@ -750,21 +744,21 @@ ewscal_set_reccurence (ESoapMessage *msg,
        if (!recur)
                return;
 
-       e_soap_message_start_element (msg, "Recurrence", NULL, NULL);
+       e_soap_request_start_element (request, "Recurrence", NULL, NULL);
 
        switch (i_cal_recurrence_get_freq (recur)) {
                case I_CAL_DAILY_RECURRENCE:
-                       e_soap_message_start_element (msg, "DailyRecurrence", NULL, NULL);
+                       e_soap_request_start_element (request, "DailyRecurrence", NULL, NULL);
                        snprintf (buffer, 32, "%d", i_cal_recurrence_get_interval (recur));
-                       e_ews_message_write_string_parameter (msg, "Interval", NULL, buffer);
-                       e_soap_message_end_element (msg); /* "DailyRecurrence" */
+                       e_ews_request_write_string_parameter (request, "Interval", NULL, buffer);
+                       e_soap_request_end_element (request); /* "DailyRecurrence" */
                        break;
 
                case I_CAL_WEEKLY_RECURRENCE:
-                       e_soap_message_start_element (msg, "WeeklyRecurrence", NULL, NULL);
+                       e_soap_request_start_element (request, "WeeklyRecurrence", NULL, NULL);
 
                        snprintf (buffer, 32, "%d", i_cal_recurrence_get_interval (recur));
-                       e_ews_message_write_string_parameter (msg, "Interval", NULL, buffer);
+                       e_ews_request_write_string_parameter (request, "Interval", NULL, buffer);
 
                        len = snprintf (
                                buffer, 256, "%s",
@@ -774,51 +768,50 @@ ewscal_set_reccurence (ESoapMessage *msg,
                                        buffer + len, 256 - len, " %s",
                                        number_to_weekday (i_cal_recurrence_day_day_of_week 
(i_cal_recurrence_get_by_day (recur, i))));
                        }
-                       e_ews_message_write_string_parameter (msg, "DaysOfWeek", NULL, buffer);
+                       e_ews_request_write_string_parameter (request, "DaysOfWeek", NULL, buffer);
 
-                       e_soap_message_end_element (msg); /* "WeeklyRecurrence" */
+                       e_soap_request_end_element (request); /* "WeeklyRecurrence" */
                        break;
 
                case I_CAL_MONTHLY_RECURRENCE:
                        if (i_cal_recurrence_get_by_month_day (recur, 0) == I_CAL_RECURRENCE_ARRAY_MAX) {
-                               e_soap_message_start_element (msg, "RelativeMonthlyRecurrence", NULL, NULL);
+                               e_soap_request_start_element (request, "RelativeMonthlyRecurrence", NULL, 
NULL);
 
                                /* For now this is what got implemented since this is the only
                                 relative monthly recurrence evolution can set.
                                 TODO: extend the code with all possible monthly recurrence settings */
                                snprintf (buffer, 32, "%d", i_cal_recurrence_get_interval (recur));
-                               e_ews_message_write_string_parameter (msg, "Interval", NULL, buffer);
+                               e_ews_request_write_string_parameter (request, "Interval", NULL, buffer);
 
-                               e_ews_message_write_string_parameter (
-                                       msg, "DaysOfWeek", NULL,
+                               e_ews_request_write_string_parameter (request, "DaysOfWeek", NULL,
                                        number_to_weekday (i_cal_recurrence_day_day_of_week 
(i_cal_recurrence_get_by_day (recur, 0))));
 
-                               e_ews_message_write_string_parameter (msg, "DayOfWeekIndex", NULL, 
weekindex_to_ical (
+                               e_ews_request_write_string_parameter (request, "DayOfWeekIndex", NULL, 
weekindex_to_ical (
                                        i_cal_recurrence_get_by_set_pos (recur, 0) == 5 ? -1 : 
i_cal_recurrence_get_by_set_pos (recur, 0)));
 
-                               e_soap_message_end_element (msg); /* "RelativeMonthlyRecurrence" */
+                               e_soap_request_end_element (request); /* "RelativeMonthlyRecurrence" */
                        } else {
-                               e_soap_message_start_element (msg, "AbsoluteMonthlyRecurrence", NULL, NULL);
+                               e_soap_request_start_element (request, "AbsoluteMonthlyRecurrence", NULL, 
NULL);
 
                                snprintf (buffer, 256, "%d", i_cal_recurrence_get_interval (recur));
-                               e_ews_message_write_string_parameter (msg, "Interval", NULL, buffer);
+                               e_ews_request_write_string_parameter (request, "Interval", NULL, buffer);
 
                                snprintf (buffer, 256, "%d", i_cal_recurrence_get_by_month_day (recur, 0) == 
-1 ? 31 : i_cal_recurrence_get_by_month_day (recur, 0));
-                               e_ews_message_write_string_parameter (msg, "DayOfMonth", NULL, buffer);
+                               e_ews_request_write_string_parameter (request, "DayOfMonth", NULL, buffer);
 
-                               e_soap_message_end_element (msg); /* "AbsoluteMonthlyRecurrence" */
+                               e_soap_request_end_element (request); /* "AbsoluteMonthlyRecurrence" */
                        }
                        break;
 
                case I_CAL_YEARLY_RECURRENCE:
                        #if 0 /* FIXME */
                        if (is_relative) {
-                               ewscal_add_rrule (msg, rrule);
+                               ewscal_add_rrule (request, rrule);
 
                        } else
                        #endif
                        {
-                               e_soap_message_start_element (msg, "AbsoluteYearlyRecurrence", NULL, NULL);
+                               e_soap_request_start_element (request, "AbsoluteYearlyRecurrence", NULL, 
NULL);
 
                                /* work according to RFC5545 Ā§3.3.10
                                 * dtstart is the default, give preference to by_month & by_month_day if they 
are set
@@ -828,20 +821,18 @@ ewscal_set_reccurence (ESoapMessage *msg,
                                } else {
                                        snprintf (buffer, 256, "%d", i_cal_time_get_day (dtstart));
                                }
-                               e_ews_message_write_string_parameter (msg, "DayOfMonth", NULL, buffer);
+                               e_ews_request_write_string_parameter (request, "DayOfMonth", NULL, buffer);
 
                                if (i_cal_recurrence_get_by_month (recur, 0) != I_CAL_RECURRENCE_ARRAY_MAX) {
                                        snprintf (buffer, 256, "%d", i_cal_recurrence_get_by_month_day 
(recur, 0));
-                                       e_ews_message_write_string_parameter (
-                                               msg, "Month", NULL,
+                                       e_ews_request_write_string_parameter (request, "Month", NULL,
                                                number_to_month (i_cal_recurrence_get_by_month (recur, 0)));
                                } else {
-                                       e_ews_message_write_string_parameter (
-                                               msg, "Month", NULL,
+                                       e_ews_request_write_string_parameter (request, "Month", NULL,
                                                number_to_month (i_cal_time_get_month (dtstart)));
                                }
 
-                               e_soap_message_end_element (msg); /* "AbsoluteYearlyRecurrence" */
+                               e_soap_request_end_element (request); /* "AbsoluteYearlyRecurrence" */
 
                        }
                        break;
@@ -856,32 +847,32 @@ ewscal_set_reccurence (ESoapMessage *msg,
        }
 
        if (i_cal_recurrence_get_count (recur) > 0) {
-               e_soap_message_start_element (msg, "NumberedRecurrence", NULL, NULL);
-               ewscal_set_date (msg, "StartDate", dtstart);
+               e_soap_request_start_element (request, "NumberedRecurrence", NULL, NULL);
+               ewscal_set_date (request, "StartDate", dtstart);
                snprintf (buffer, 32, "%d", i_cal_recurrence_get_count (recur));
-               e_ews_message_write_string_parameter (msg, "NumberOfOccurrences", NULL, buffer);
-               e_soap_message_end_element (msg); /* "NumberedRecurrence" */
+               e_ews_request_write_string_parameter (request, "NumberOfOccurrences", NULL, buffer);
+               e_soap_request_end_element (request); /* "NumberedRecurrence" */
        } else {
                ICalTime *until;
 
                until = i_cal_recurrence_get_until (recur);
 
                if (until && !i_cal_time_is_null_time (until)) {
-                       e_soap_message_start_element (msg, "EndDateRecurrence", NULL, NULL);
-                       ewscal_set_date (msg, "StartDate", dtstart);
-                       ewscal_set_date (msg, "EndDate", until);
-                       e_soap_message_end_element (msg); /* "EndDateRecurrence" */
+                       e_soap_request_start_element (request, "EndDateRecurrence", NULL, NULL);
+                       ewscal_set_date (request, "StartDate", dtstart);
+                       ewscal_set_date (request, "EndDate", until);
+                       e_soap_request_end_element (request); /* "EndDateRecurrence" */
                } else {
-                       e_soap_message_start_element (msg, "NoEndRecurrence", NULL, NULL);
-                       ewscal_set_date (msg, "StartDate", dtstart);
-                       e_soap_message_end_element (msg); /* "NoEndRecurrence" */
+                       e_soap_request_start_element (request, "NoEndRecurrence", NULL, NULL);
+                       ewscal_set_date (request, "StartDate", dtstart);
+                       e_soap_request_end_element (request); /* "NoEndRecurrence" */
                }
 
                g_clear_object (&until);
        }
 
 exit:
-       e_soap_message_end_element (msg); /* "Recurrence" */
+       e_soap_request_end_element (request); /* "Recurrence" */
        g_object_unref (recur);
 }
 
@@ -932,7 +923,7 @@ icomponent_get_datetime (ICalComponent *comp,
 }
 
 void
-ewscal_set_reccurence_exceptions (ESoapMessage *msg,
+ewscal_set_reccurence_exceptions (ESoapRequest *request,
                                  ICalComponent *comp)
 {
        ICalProperty *exdate;
@@ -942,21 +933,21 @@ ewscal_set_reccurence_exceptions (ESoapMessage *msg,
        if (!exdate)
                return;
 
-       e_soap_message_start_element (msg, "DeletedOccurrences", NULL, NULL);
+       e_soap_request_start_element (request, "DeletedOccurrences", NULL, NULL);
 
        for (; exdate; g_object_unref (exdate), exdate = i_cal_component_get_next_property (comp, 
I_CAL_EXDATE_PROPERTY)) {
                ICalTime *exdatetime = icomponent_get_datetime (comp, exdate);
 
-               e_soap_message_start_element (msg, "DeletedOccurrence", NULL, NULL);
+               e_soap_request_start_element (request, "DeletedOccurrence", NULL, NULL);
 
-               ewscal_set_date (msg, "Start", exdatetime);
+               ewscal_set_date (request, "Start", exdatetime);
 
-               e_soap_message_end_element (msg); /* "DeletedOccurrence" */
+               e_soap_request_end_element (request); /* "DeletedOccurrence" */
 
                g_clear_object (&exdatetime);
        }
 
-       e_soap_message_end_element (msg); /* "DeletedOccurrences" */
+       e_soap_request_end_element (request); /* "DeletedOccurrences" */
 }
 
 /*
@@ -1017,58 +1008,58 @@ e_ews_clean_icomponent (ICalComponent *icomp)
 }
 
 static void
-add_attendees_list_to_message (ESoapMessage *msg,
+add_attendees_list_to_message (ESoapRequest *request,
                                const gchar *listname,
                                GSList *list)
 {
        GSList *item;
 
-       e_soap_message_start_element (msg, listname, NULL, NULL);
+       e_soap_request_start_element (request, listname, NULL, NULL);
 
        for (item = list; item != NULL; item = item->next) {
-               e_soap_message_start_element (msg, "Attendee", NULL, NULL);
-               e_soap_message_start_element (msg, "Mailbox", NULL, NULL);
+               e_soap_request_start_element (request, "Attendee", NULL, NULL);
+               e_soap_request_start_element (request, "Mailbox", NULL, NULL);
 
-               e_ews_message_write_string_parameter (msg, "EmailAddress", NULL, item->data);
+               e_ews_request_write_string_parameter (request, "EmailAddress", NULL, item->data);
 
-               e_soap_message_end_element (msg); /* "Mailbox" */
-               e_soap_message_end_element (msg); /* "Attendee" */
+               e_soap_request_end_element (request); /* "Mailbox" */
+               e_soap_request_end_element (request); /* "Attendee" */
        }
 
-       e_soap_message_end_element (msg);
+       e_soap_request_end_element (request);
 }
 
 static void
-convert_sensitivity_calcomp_to_xml (ESoapMessage *msg,
+convert_sensitivity_calcomp_to_xml (ESoapRequest *request,
                                    ICalComponent *icomp)
 {
        ICalProperty *prop;
 
-       g_return_if_fail (msg != NULL);
+       g_return_if_fail (request != NULL);
        g_return_if_fail (icomp != NULL);
 
        prop = i_cal_component_get_first_property (icomp, I_CAL_CLASS_PROPERTY);
        if (prop) {
                ICalProperty_Class classify = i_cal_property_get_class (prop);
                if (classify == I_CAL_CLASS_PUBLIC) {
-                       e_ews_message_write_string_parameter (msg, "Sensitivity", NULL, "Normal");
+                       e_ews_request_write_string_parameter (request, "Sensitivity", NULL, "Normal");
                } else if (classify == I_CAL_CLASS_PRIVATE) {
-                       e_ews_message_write_string_parameter (msg, "Sensitivity", NULL, "Private");
+                       e_ews_request_write_string_parameter (request, "Sensitivity", NULL, "Private");
                } else if (classify == I_CAL_CLASS_CONFIDENTIAL) {
-                       e_ews_message_write_string_parameter (msg, "Sensitivity", NULL, "Personal");
+                       e_ews_request_write_string_parameter (request, "Sensitivity", NULL, "Personal");
                }
                g_object_unref (prop);
        }
 }
 
 static void
-convert_categories_calcomp_to_xml (ESoapMessage *msg,
+convert_categories_calcomp_to_xml (ESoapRequest *request,
                                   ECalComponent *comp,
                                   ICalComponent *icomp)
 {
        GSList *categ_list, *citer;
 
-       g_return_if_fail (msg != NULL);
+       g_return_if_fail (request != NULL);
        g_return_if_fail (icomp != NULL);
 
        if (comp) {
@@ -1097,7 +1088,7 @@ convert_categories_calcomp_to_xml (ESoapMessage *msg,
        }
 
        if (citer) {
-               e_soap_message_start_element (msg, "Categories", NULL, NULL);
+               e_soap_request_start_element (request, "Categories", NULL, NULL);
 
                for (citer = categ_list; citer; citer = g_slist_next (citer)) {
                        const gchar *category = citer->data;
@@ -1105,10 +1096,10 @@ convert_categories_calcomp_to_xml (ESoapMessage *msg,
                        if (!category || !*category)
                                continue;
 
-                       e_ews_message_write_string_parameter (msg, "String", NULL, category);
+                       e_ews_request_write_string_parameter (request, "String", NULL, category);
                }
 
-               e_soap_message_end_element (msg); /* Categories */
+               e_soap_request_end_element (request); /* Categories */
        }
 
        g_slist_free_full (categ_list, g_free);
@@ -1133,7 +1124,7 @@ check_is_all_day_event (const ICalTime *dtstart,
 }
 
 static gboolean
-convert_vevent_calcomp_to_xml (ESoapMessage *msg,
+convert_vevent_calcomp_to_xml (ESoapRequest *request,
                                gpointer user_data,
                               GError **error)
 {
@@ -1155,28 +1146,28 @@ convert_vevent_calcomp_to_xml (ESoapMessage *msg,
        /* FORMAT OF A SAMPLE SOAP MESSAGE: http://msdn.microsoft.com/en-us/library/aa564690.aspx */
 
        /* Prepare CalendarItem node in the SOAP message */
-       e_soap_message_start_element (msg, "CalendarItem", NULL, NULL);
+       e_soap_request_start_element (request, "CalendarItem", NULL, NULL);
 
        /* subject */
        value = i_cal_component_get_summary (icomp);
        if (value)
-               e_ews_message_write_string_parameter (msg, "Subject", NULL, value);
+               e_ews_request_write_string_parameter (request, "Subject", NULL, value);
 
-       convert_sensitivity_calcomp_to_xml (msg, icomp);
+       convert_sensitivity_calcomp_to_xml (request, icomp);
 
        /* description */
        value = i_cal_component_get_description (icomp);
        if (value)
-               e_ews_message_write_string_parameter_with_attribute (msg, "Body", NULL, value, "BodyType", 
"Text");
+               e_ews_request_write_string_parameter_with_attribute (request, "Body", NULL, value, 
"BodyType", "Text");
 
-       convert_categories_calcomp_to_xml (msg, comp, icomp);
+       convert_categories_calcomp_to_xml (request, comp, icomp);
 
        /* set alarms */
        has_alarms = e_cal_component_has_alarms (comp);
        if (has_alarms)
-               ews_set_alarm (msg, comp, convert_data->timezone_cache, convert_data->vcalendar, FALSE);
+               ews_set_alarm (request, comp, convert_data->timezone_cache, convert_data->vcalendar, FALSE);
        else
-               e_ews_message_write_string_parameter (msg, "ReminderIsSet", NULL, "false");
+               e_ews_request_write_string_parameter (request, "ReminderIsSet", NULL, "false");
 
        /* start time, end time and meeting time zone */
        dtstart = e_cal_backend_ews_get_datetime_with_zone (convert_data->timezone_cache, 
convert_data->vcalendar, icomp, I_CAL_DTSTART_PROPERTY, i_cal_property_get_dtstart);
@@ -1194,14 +1185,12 @@ convert_vevent_calcomp_to_xml (ESoapMessage *msg,
        satisfies = e_ews_connection_satisfies_server_version (convert_data->connection, E_EWS_EXCHANGE_2010);
        if (satisfies && ical_location_start != NULL && ical_location_end != NULL) {
                /* set iana timezone info as an extended property */
-               e_ews_message_add_extended_property_distinguished_name_string (
-                       msg,
+               e_ews_request_add_extended_property_distinguished_name_string (request,
                        "PublicStrings",
                        "EvolutionEWSStartTimeZone",
                        ical_location_start);
 
-               e_ews_message_add_extended_property_distinguished_name_string (
-                       msg,
+               e_ews_request_add_extended_property_distinguished_name_string (request,
                        "PublicStrings",
                        "EvolutionEWSEndTimeZone",
                        ical_location_end);
@@ -1209,49 +1198,49 @@ convert_vevent_calcomp_to_xml (ESoapMessage *msg,
 
        is_all_day_event = check_is_all_day_event (dtstart, tzid_start, dtend, tzid_end);
 
-       e_ews_cal_utils_set_time (msg, "Start", dtstart, is_all_day_event && i_cal_time_is_date (dtstart));
+       e_ews_cal_utils_set_time (request, "Start", dtstart, is_all_day_event && i_cal_time_is_date 
(dtstart));
 
        /* Cover components without DTEND */
        if (dtend && i_cal_time_is_valid_time (dtend) &&
            !i_cal_time_is_null_time (dtend))
-               e_ews_cal_utils_set_time (msg, "End", dtend, is_all_day_event && i_cal_time_is_date (dtend));
+               e_ews_cal_utils_set_time (request, "End", dtend, is_all_day_event && i_cal_time_is_date 
(dtend));
        else
-               e_ews_cal_utils_set_time (msg, "End", dtstart, is_all_day_event && i_cal_time_is_date 
(dtstart));
+               e_ews_cal_utils_set_time (request, "End", dtstart, is_all_day_event && i_cal_time_is_date 
(dtstart));
 
        /* We have to do the time zone(s) later, or the server rejects the request */
 
        /* All day event ? */
        if (is_all_day_event)
-               e_ews_message_write_string_parameter (msg, "IsAllDayEvent", NULL, "true");
+               e_ews_request_write_string_parameter (request, "IsAllDayEvent", NULL, "true");
 
        /*freebusy*/
        prop = i_cal_component_get_first_property (icomp, I_CAL_TRANSP_PROPERTY);
        if (!prop || i_cal_property_get_transp (prop) == I_CAL_TRANSP_TRANSPARENT)
-               e_ews_message_write_string_parameter (msg, "LegacyFreeBusyStatus", NULL, "Free");
+               e_ews_request_write_string_parameter (request, "LegacyFreeBusyStatus", NULL, "Free");
        else
-               e_ews_message_write_string_parameter (msg, "LegacyFreeBusyStatus", NULL, "Busy");
+               e_ews_request_write_string_parameter (request, "LegacyFreeBusyStatus", NULL, "Busy");
        g_clear_object (&prop);
 
        /* location */
        value = i_cal_component_get_location (icomp);
        if (value)
-               e_ews_message_write_string_parameter (msg, "Location", NULL, value);
+               e_ews_request_write_string_parameter (request, "Location", NULL, value);
 
        /* collect attendees */
        e_ews_collect_attendees (icomp, &required, &optional, &resource, &rsvp_requested);
 
-       e_ews_message_write_string_parameter (msg, "IsResponseRequested", NULL, rsvp_requested ? "true" : 
"false");
+       e_ews_request_write_string_parameter (request, "IsResponseRequested", NULL, rsvp_requested ? "true" : 
"false");
 
        if (required != NULL) {
-               add_attendees_list_to_message (msg, "RequiredAttendees", required);
+               add_attendees_list_to_message (request, "RequiredAttendees", required);
                g_slist_free (required);
        }
        if (optional != NULL) {
-               add_attendees_list_to_message (msg, "OptionalAttendees", optional);
+               add_attendees_list_to_message (request, "OptionalAttendees", optional);
                g_slist_free (optional);
        }
        if (resource != NULL) {
-               add_attendees_list_to_message (msg, "Resources", resource);
+               add_attendees_list_to_message (request, "Resources", resource);
                g_slist_free (resource);
        }
        /* end of attendees */
@@ -1259,7 +1248,7 @@ convert_vevent_calcomp_to_xml (ESoapMessage *msg,
        /* Recurrence */
        prop = i_cal_component_get_first_property (icomp, I_CAL_RRULE_PROPERTY);
        if (prop) {
-               ewscal_set_reccurence (msg, prop, dtstart);
+               ewscal_set_reccurence (request, prop, dtstart);
                g_object_unref (prop);
        }
 
@@ -1281,19 +1270,19 @@ convert_vevent_calcomp_to_xml (ESoapMessage *msg,
                                &tzds,
                                NULL,
                                NULL)) {
-                       ewscal_set_timezone (msg, "StartTimeZone", tzds->data);
-                       ewscal_set_timezone (msg, "EndTimeZone", tzds->data);
+                       ewscal_set_timezone (request, "StartTimeZone", tzds->data);
+                       ewscal_set_timezone (request, "EndTimeZone", tzds->data);
                }
 
                g_slist_free (msdn_locations);
                g_slist_free_full (tzds, (GDestroyNotify) e_ews_calendar_time_zone_definition_free);
        } else {
-               e_ews_message_replace_server_version (msg, E_EWS_EXCHANGE_2007_SP1);
+               e_ews_request_replace_server_version (request, E_EWS_EXCHANGE_2007_SP1);
 
-               ewscal_set_meeting_timezone (msg, tzid_start, icomp);
+               ewscal_set_meeting_timezone (request, tzid_start, icomp);
        }
 
-       e_soap_message_end_element (msg); /* "CalendarItem" */
+       e_soap_request_end_element (request); /* "CalendarItem" */
 
        g_clear_object (&dtstart);
        g_clear_object (&dtend);
@@ -1315,7 +1304,7 @@ ews_priority_to_string (gint priority)
 }
 
 static gboolean
-convert_vtodo_calcomp_to_xml (ESoapMessage *msg,
+convert_vtodo_calcomp_to_xml (ESoapRequest *request,
                               gpointer user_data,
                              GError **error)
 {
@@ -1328,29 +1317,29 @@ convert_vtodo_calcomp_to_xml (ESoapMessage *msg,
        gboolean success;
        /* gboolean has_alarms; */
 
-       e_soap_message_start_element (msg, "Task", NULL, NULL);
+       e_soap_request_start_element (request, "Task", NULL, NULL);
 
-       e_ews_message_write_string_parameter (msg, "Subject", NULL, i_cal_component_get_summary (icomp));
+       e_ews_request_write_string_parameter (request, "Subject", NULL, i_cal_component_get_summary (icomp));
 
-       convert_sensitivity_calcomp_to_xml (msg, icomp);
+       convert_sensitivity_calcomp_to_xml (request, icomp);
 
-       e_ews_message_write_string_parameter_with_attribute (msg, "Body", NULL, 
i_cal_component_get_description (icomp), "BodyType", "Text");
+       e_ews_request_write_string_parameter_with_attribute (request, "Body", NULL, 
i_cal_component_get_description (icomp), "BodyType", "Text");
 
-       convert_categories_calcomp_to_xml (msg, NULL, icomp);
+       convert_categories_calcomp_to_xml (request, NULL, icomp);
 
        prop = i_cal_component_get_first_property (icomp, I_CAL_PRIORITY_PROPERTY);
        if (prop) {
                gint priority;
 
                priority = i_cal_property_get_priority (prop);
-               e_ews_message_write_string_parameter (msg, "Importance", NULL, ews_priority_to_string 
(priority));
+               e_ews_request_write_string_parameter (request, "Importance", NULL, ews_priority_to_string 
(priority));
                g_object_unref (prop);
        }
 
        prop = i_cal_component_get_first_property (icomp, I_CAL_DUE_PROPERTY);
        if (prop) {
                dt = e_cal_backend_ews_get_datetime_with_zone (convert_data->timezone_cache, 
convert_data->vcalendar, icomp, I_CAL_DUE_PROPERTY, i_cal_property_get_due);
-               e_ews_cal_utils_set_time (msg, "DueDate", dt, TRUE);
+               e_ews_cal_utils_set_time (request, "DueDate", dt, TRUE);
                g_clear_object (&dt);
                g_object_unref (prop);
        }
@@ -1359,16 +1348,16 @@ convert_vtodo_calcomp_to_xml (ESoapMessage *msg,
        if (prop) {
                value = i_cal_property_get_percentcomplete (prop);
                snprintf (buffer, 16, "%d", value);
-               e_ews_message_write_string_parameter (msg, "PercentComplete", NULL, buffer);
+               e_ews_request_write_string_parameter (request, "PercentComplete", NULL, buffer);
                g_object_unref (prop);
        }
 
-       success = e_ews_cal_utils_set_recurrence (msg, icomp, FALSE, error);
+       success = e_ews_cal_utils_set_recurrence (request, icomp, FALSE, error);
 
        prop = i_cal_component_get_first_property (icomp, I_CAL_DTSTART_PROPERTY);
        if (prop) {
                dt = e_cal_backend_ews_get_datetime_with_zone (convert_data->timezone_cache, 
convert_data->vcalendar, icomp, I_CAL_DTSTART_PROPERTY, i_cal_property_get_dtstart);
-               e_ews_cal_utils_set_time (msg, "StartDate", dt, TRUE);
+               e_ews_cal_utils_set_time (request, "StartDate", dt, TRUE);
                g_clear_object (&dt);
                g_object_unref (prop);
        }
@@ -1377,10 +1366,10 @@ convert_vtodo_calcomp_to_xml (ESoapMessage *msg,
        if (prop) {
                switch (i_cal_property_get_status (prop)) {
                case I_CAL_STATUS_INPROCESS:
-                       e_ews_message_write_string_parameter (msg, "Status", NULL, "InProgress");
+                       e_ews_request_write_string_parameter (request, "Status", NULL, "InProgress");
                        break;
                case I_CAL_STATUS_COMPLETED:
-                       e_ews_message_write_string_parameter (msg, "Status", NULL, "Completed");
+                       e_ews_request_write_string_parameter (request, "Status", NULL, "Completed");
                        break;
                default:
                        break;
@@ -1393,7 +1382,7 @@ convert_vtodo_calcomp_to_xml (ESoapMessage *msg,
                ECalComponent *comp = e_cal_component_new_from_icalcomponent (i_cal_component_clone (icomp));
 
                if (comp && e_cal_component_has_alarms (comp)) {
-                       ews_set_alarm (msg, comp, convert_data->timezone_cache, convert_data->vcalendar, 
TRUE);
+                       ews_set_alarm (request, comp, convert_data->timezone_cache, convert_data->vcalendar, 
TRUE);
                } else {
                        has_alarms = FALSE;
                }
@@ -1402,15 +1391,15 @@ convert_vtodo_calcomp_to_xml (ESoapMessage *msg,
        }
 
        if (!has_alarms)
-               e_ews_message_write_string_parameter (msg, "ReminderIsSet", NULL, "false"); */
+               e_ews_request_write_string_parameter (request, "ReminderIsSet", NULL, "false"); */
 
-       e_soap_message_end_element (msg); /* "Task" */
+       e_soap_request_end_element (request); /* "Task" */
 
        return success;
 }
 
 static gboolean
-convert_vjournal_calcomp_to_xml (ESoapMessage *msg,
+convert_vjournal_calcomp_to_xml (ESoapRequest *request,
                                 gpointer user_data,
                                 GError **error)
 {
@@ -1418,27 +1407,27 @@ convert_vjournal_calcomp_to_xml (ESoapMessage *msg,
        ICalComponent *icomp = convert_data->icomp;
        const gchar *text;
 
-       e_soap_message_start_element (msg, "Message", NULL, NULL);
-       e_ews_message_write_string_parameter (msg, "ItemClass", NULL, "IPM.StickyNote");
+       e_soap_request_start_element (request, "Message", NULL, NULL);
+       e_ews_request_write_string_parameter (request, "ItemClass", NULL, "IPM.StickyNote");
 
-       e_ews_message_write_string_parameter (msg, "Subject", NULL, i_cal_component_get_summary (icomp));
+       e_ews_request_write_string_parameter (request, "Subject", NULL, i_cal_component_get_summary (icomp));
 
-       convert_sensitivity_calcomp_to_xml (msg, icomp);
+       convert_sensitivity_calcomp_to_xml (request, icomp);
 
        text = i_cal_component_get_description (icomp);
        if (!text || !*text)
                text = i_cal_component_get_summary (icomp);
-       e_ews_message_write_string_parameter_with_attribute (msg, "Body", NULL, text, "BodyType", "Text");
+       e_ews_request_write_string_parameter_with_attribute (request, "Body", NULL, text, "BodyType", "Text");
 
-       convert_categories_calcomp_to_xml (msg, NULL, icomp);
+       convert_categories_calcomp_to_xml (request, NULL, icomp);
 
-       e_soap_message_end_element (msg); /* Message */
+       e_soap_request_end_element (request); /* Message */
 
        return TRUE;
 }
 
 gboolean
-e_cal_backend_ews_convert_calcomp_to_xml (ESoapMessage *msg,
+e_cal_backend_ews_convert_calcomp_to_xml (ESoapRequest *request,
                                          gpointer user_data,
                                          GError **error)
 {
@@ -1447,13 +1436,13 @@ e_cal_backend_ews_convert_calcomp_to_xml (ESoapMessage *msg,
 
        switch (i_cal_component_isa (convert_data->icomp)) {
        case I_CAL_VEVENT_COMPONENT:
-               success = convert_vevent_calcomp_to_xml (msg, convert_data, error);
+               success = convert_vevent_calcomp_to_xml (request, convert_data, error);
                break;
        case I_CAL_VTODO_COMPONENT:
-               success = convert_vtodo_calcomp_to_xml (msg, convert_data, error);
+               success = convert_vtodo_calcomp_to_xml (request, convert_data, error);
                break;
        case I_CAL_VJOURNAL_COMPONENT:
-               success = convert_vjournal_calcomp_to_xml (msg, convert_data, error);
+               success = convert_vjournal_calcomp_to_xml (request, convert_data, error);
                break;
        default:
                g_warn_if_reached ();
@@ -1465,19 +1454,19 @@ e_cal_backend_ews_convert_calcomp_to_xml (ESoapMessage *msg,
 
 static void
 convert_component_categories_to_updatexml (ECalComponent *comp,
-                                          ESoapMessage *msg,
+                                          ESoapRequest *request,
                                           const gchar *base_elem_name)
 {
        GSList *categ_list, *citer;
 
        g_return_if_fail (comp != NULL);
-       g_return_if_fail (msg != NULL);
+       g_return_if_fail (request != NULL);
        g_return_if_fail (base_elem_name != NULL);
 
        categ_list = e_cal_component_get_categories_list (comp);
 
-       e_ews_message_start_set_item_field (msg, "Categories", "item", base_elem_name);
-       e_soap_message_start_element (msg, "Categories", NULL, NULL);
+       e_ews_request_start_set_item_field (request, "Categories", "item", base_elem_name);
+       e_soap_request_start_element (request, "Categories", NULL, NULL);
 
        for (citer = categ_list; citer; citer = g_slist_next (citer)) {
                const gchar *category = citer->data;
@@ -1485,30 +1474,30 @@ convert_component_categories_to_updatexml (ECalComponent *comp,
                if (!category || !*category)
                        continue;
 
-               e_ews_message_write_string_parameter (msg, "String", NULL, category);
+               e_ews_request_write_string_parameter (request, "String", NULL, category);
        }
 
-       e_soap_message_end_element (msg); /* Categories */
-       e_ews_message_end_set_item_field (msg);
+       e_soap_request_end_element (request); /* Categories */
+       e_ews_request_end_set_item_field (request);
 
        g_slist_free_full (categ_list, g_free);
 }
 
 static void
-convert_vevent_property_to_updatexml (ESoapMessage *msg,
+convert_vevent_property_to_updatexml (ESoapRequest *request,
                                       const gchar *name,
                                       const gchar *value,
                                       const gchar *prefix,
                                       const gchar *attr_name,
                                       const gchar *attr_value)
 {
-       e_ews_message_start_set_item_field (msg, name, prefix, "CalendarItem");
-       e_ews_message_write_string_parameter_with_attribute (msg, name, NULL, value, attr_name, attr_value);
-       e_ews_message_end_set_item_field (msg);
+       e_ews_request_start_set_item_field (request, name, prefix, "CalendarItem");
+       e_ews_request_write_string_parameter_with_attribute (request, name, NULL, value, attr_name, 
attr_value);
+       e_ews_request_end_set_item_field (request);
 }
 
 static gboolean
-convert_vevent_component_to_updatexml (ESoapMessage *msg,
+convert_vevent_component_to_updatexml (ESoapRequest *request,
                                        gpointer user_data,
                                       GError **error)
 {
@@ -1531,14 +1520,13 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
        gboolean satisfies, rsvp_requested = TRUE, is_all_day_event = FALSE;
 
        if (convert_data->change_type == E_EWS_ITEMCHANGE_TYPE_OCCURRENCEITEM && convert_data->index > 0) {
-               e_ews_message_start_item_change (
-                       msg,
+               e_ews_request_start_item_change (request,
                        convert_data->change_type,
                        convert_data->item_id,
                        convert_data->change_key,
                        convert_data->index);
        } else {
-               e_ews_message_start_item_change (msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
+               e_ews_request_start_item_change (request, E_EWS_ITEMCHANGE_TYPE_ITEM,
                        convert_data->item_id, convert_data->change_key, 0);
        }
 
@@ -1546,20 +1534,20 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
        value = i_cal_component_get_summary (icomp);
        old_value = i_cal_component_get_summary (icomp_old);
        if (g_strcmp0 (value, old_value) != 0 || (value && !old_value)) {
-               convert_vevent_property_to_updatexml (msg, "Subject", value, "item", NULL, NULL);
+               convert_vevent_property_to_updatexml (request, "Subject", value, "item", NULL, NULL);
        } else if (!value && old_value) {
-               convert_vevent_property_to_updatexml (msg, "Subject", "", "item", NULL, NULL);
+               convert_vevent_property_to_updatexml (request, "Subject", "", "item", NULL, NULL);
        }
 
        prop = i_cal_component_get_first_property (icomp, I_CAL_CLASS_PROPERTY);
        if (prop) {
                ICalProperty_Class classify = i_cal_property_get_class (prop);
                if (classify == I_CAL_CLASS_PUBLIC) {
-                       convert_vevent_property_to_updatexml (msg, "Sensitivity", "Normal", "item", NULL, 
NULL);
+                       convert_vevent_property_to_updatexml (request, "Sensitivity", "Normal", "item", NULL, 
NULL);
                } else if (classify == I_CAL_CLASS_PRIVATE) {
-                       convert_vevent_property_to_updatexml (msg, "Sensitivity", "Private", "item", NULL, 
NULL);
+                       convert_vevent_property_to_updatexml (request, "Sensitivity", "Private", "item", 
NULL, NULL);
                } else if (classify == I_CAL_CLASS_CONFIDENTIAL) {
-                       convert_vevent_property_to_updatexml (msg, "Sensitivity", "Personal", "item", NULL, 
NULL);
+                       convert_vevent_property_to_updatexml (request, "Sensitivity", "Personal", "item", 
NULL, NULL);
                }
 
                g_object_unref (prop);
@@ -1569,9 +1557,9 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
        value = i_cal_component_get_description (icomp);
        old_value = i_cal_component_get_description (icomp_old);
        if (g_strcmp0 (value, old_value) != 0 || (value && !old_value)) {
-               convert_vevent_property_to_updatexml (msg, "Body", value, "item", "BodyType", "Text");
+               convert_vevent_property_to_updatexml (request, "Body", value, "item", "BodyType", "Text");
        } else if (!value && old_value) {
-               convert_vevent_property_to_updatexml (msg, "Body", "", "item", "BodyType", "Text");
+               convert_vevent_property_to_updatexml (request, "Body", "", "item", "BodyType", "Text");
        }
 
        /*update alarm items*/
@@ -1586,23 +1574,23 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
                if (alarm != alarm_old || !has_alarms_old) {
                        gchar buf[20];
                        snprintf (buf, 20, "%d", alarm);
-                       convert_vevent_property_to_updatexml (msg, "ReminderIsSet", "true", "item", NULL, 
NULL);
-                       convert_vevent_property_to_updatexml (msg, "ReminderMinutesBeforeStart", buf, "item", 
NULL, NULL);
+                       convert_vevent_property_to_updatexml (request, "ReminderIsSet", "true", "item", NULL, 
NULL);
+                       convert_vevent_property_to_updatexml (request, "ReminderMinutesBeforeStart", buf, 
"item", NULL, NULL);
                }
        } else {
-               convert_vevent_property_to_updatexml (msg, "ReminderIsSet", "false", "item", NULL, NULL);
+               convert_vevent_property_to_updatexml (request, "ReminderIsSet", "false", "item", NULL, NULL);
        }
 
        /* Categories */
-       convert_component_categories_to_updatexml (convert_data->comp, msg, "CalendarItem");
+       convert_component_categories_to_updatexml (convert_data->comp, request, "CalendarItem");
 
        /*location*/
        value = i_cal_component_get_location (icomp);
        old_value = i_cal_component_get_location (icomp_old);
        if (g_strcmp0 (value, old_value) != 0 || (value && !old_value)) {
-               convert_vevent_property_to_updatexml (msg, "Location", value, "calendar", NULL, NULL);
+               convert_vevent_property_to_updatexml (request, "Location", value, "calendar", NULL, NULL);
        } else if (!value && old_value) {
-               convert_vevent_property_to_updatexml (msg, "Location", "", "calendar", NULL, NULL);
+               convert_vevent_property_to_updatexml (request, "Location", "", "calendar", NULL, NULL);
        }
 
        /*freebusy*/
@@ -1614,14 +1602,14 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
        g_clear_object (&prop);
        if (new_transp != old_transp) {
                if (new_transp == I_CAL_TRANSP_TRANSPARENT)
-                       convert_vevent_property_to_updatexml (msg, "LegacyFreeBusyStatus","Free" , 
"calendar", NULL, NULL);
+                       convert_vevent_property_to_updatexml (request, "LegacyFreeBusyStatus","Free" , 
"calendar", NULL, NULL);
                else
-                       convert_vevent_property_to_updatexml (msg, "LegacyFreeBusyStatus","Busy" , 
"calendar", NULL, NULL);
+                       convert_vevent_property_to_updatexml (request, "LegacyFreeBusyStatus","Busy" , 
"calendar", NULL, NULL);
        }
 
        org_email_address = e_ews_collect_organizer (icomp);
        if (org_email_address && convert_data->user_email && g_ascii_strcasecmp (org_email_address, 
convert_data->user_email)) {
-               e_ews_message_end_item_change (msg);
+               e_ews_request_end_item_change (request);
                return TRUE;
        }
 
@@ -1683,8 +1671,7 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
                        dt_end_changed = TRUE;
 
                if ((dt_start_changed || dt_start_changed_timezone_name) && ical_location_start != NULL)
-                       e_ews_message_add_set_item_field_extended_distinguished_name_string (
-                               msg,
+                       e_ews_request_add_set_item_field_extended_distinguished_name_string (request,
                                NULL,
                                "CalendarItem",
                                "PublicStrings",
@@ -1692,8 +1679,7 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
                                ical_location_start);
 
                if ((dt_end_changed || dt_end_changed_timezone_name) && ical_location_end != NULL)
-                       e_ews_message_add_set_item_field_extended_distinguished_name_string (
-                               msg,
+                       e_ews_request_add_set_item_field_extended_distinguished_name_string (request,
                                NULL,
                                "CalendarItem",
                                "PublicStrings",
@@ -1707,52 +1693,52 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
                is_all_day_event = check_is_all_day_event (dtstart, tzid_start, dtend, tzid_end);
 
        if (dt_start_changed) {
-               e_ews_message_start_set_item_field (msg, "Start", "calendar","CalendarItem");
-               e_ews_cal_utils_set_time (msg, "Start", dtstart, is_all_day_event && i_cal_time_is_date 
(dtstart));
-               e_ews_message_end_set_item_field (msg);
+               e_ews_request_start_set_item_field (request, "Start", "calendar","CalendarItem");
+               e_ews_cal_utils_set_time (request, "Start", dtstart, is_all_day_event && i_cal_time_is_date 
(dtstart));
+               e_ews_request_end_set_item_field (request);
        }
 
        if (dt_end_changed) {
-               e_ews_message_start_set_item_field (msg, "End", "calendar", "CalendarItem");
-               e_ews_cal_utils_set_time (msg, "End", dtend, is_all_day_event && i_cal_time_is_date (dtend));
-               e_ews_message_end_set_item_field (msg);
+               e_ews_request_start_set_item_field (request, "End", "calendar", "CalendarItem");
+               e_ews_cal_utils_set_time (request, "End", dtend, is_all_day_event && i_cal_time_is_date 
(dtend));
+               e_ews_request_end_set_item_field (request);
        }
 
        /*Check for All Day Event*/
        if (dt_changed) {
                if (is_all_day_event)
-                       convert_vevent_property_to_updatexml (msg, "IsAllDayEvent", "true", "calendar", NULL, 
NULL);
+                       convert_vevent_property_to_updatexml (request, "IsAllDayEvent", "true", "calendar", 
NULL, NULL);
                else
-                       convert_vevent_property_to_updatexml (msg, "IsAllDayEvent", "false", "calendar", 
NULL, NULL);
+                       convert_vevent_property_to_updatexml (request, "IsAllDayEvent", "false", "calendar", 
NULL, NULL);
        }
 
        e_ews_collect_attendees (icomp, &required, &optional, &resource, &rsvp_requested);
 
-       convert_vevent_property_to_updatexml (msg, "IsResponseRequested", rsvp_requested ? "true" : "false", 
"calendar", NULL, NULL);
+       convert_vevent_property_to_updatexml (request, "IsResponseRequested", rsvp_requested ? "true" : 
"false", "calendar", NULL, NULL);
 
        if (required != NULL) {
-               e_ews_message_start_set_item_field (msg, "RequiredAttendees", "calendar", "CalendarItem");
+               e_ews_request_start_set_item_field (request, "RequiredAttendees", "calendar", "CalendarItem");
 
-               add_attendees_list_to_message (msg, "RequiredAttendees", required);
+               add_attendees_list_to_message (request, "RequiredAttendees", required);
                g_slist_free (required);
 
-               e_ews_message_end_set_item_field (msg);
+               e_ews_request_end_set_item_field (request);
        }
        if (optional != NULL) {
-               e_ews_message_start_set_item_field (msg, "OptionalAttendees", "calendar", "CalendarItem");
+               e_ews_request_start_set_item_field (request, "OptionalAttendees", "calendar", "CalendarItem");
 
-               add_attendees_list_to_message (msg, "OptionalAttendees", optional);
+               add_attendees_list_to_message (request, "OptionalAttendees", optional);
                g_slist_free (optional);
 
-               e_ews_message_end_set_item_field (msg);
+               e_ews_request_end_set_item_field (request);
        }
        if (resource != NULL) {
-               e_ews_message_start_set_item_field (msg, "Resources", "calendar", "CalendarItem");
+               e_ews_request_start_set_item_field (request, "Resources", "calendar", "CalendarItem");
 
-               add_attendees_list_to_message (msg, "Resources", resource);
+               add_attendees_list_to_message (request, "Resources", resource);
                g_slist_free (resource);
 
-               e_ews_message_end_set_item_field (msg);
+               e_ews_request_end_set_item_field (request);
        }
 
        /* Recurrence */
@@ -1769,9 +1755,9 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
                rrule_value = i_cal_property_get_value_as_string (prop);
 
        if (prop && g_strcmp0 (rrule_value, rrule_old_value)) {
-               e_ews_message_start_set_item_field (msg, "Recurrence", "calendar", "CalendarItem");
-               ewscal_set_reccurence (msg, prop, dtstart);
-               e_ews_message_end_set_item_field (msg);
+               e_ews_request_start_set_item_field (request, "Recurrence", "calendar", "CalendarItem");
+               ewscal_set_reccurence (request, prop, dtstart);
+               e_ews_request_end_set_item_field (request);
        }
        g_clear_object (&prop);
        g_free (rrule_value);
@@ -1799,9 +1785,9 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
 
                                tmp = tzds;
                                if (tzid_start != NULL) {
-                                       e_ews_message_start_set_item_field (msg, "StartTimeZone", "calendar", 
"CalendarItem");
-                                       ewscal_set_timezone (msg, "StartTimeZone", tmp->data);
-                                       e_ews_message_end_set_item_field (msg);
+                                       e_ews_request_start_set_item_field (request, "StartTimeZone", 
"calendar", "CalendarItem");
+                                       ewscal_set_timezone (request, "StartTimeZone", tmp->data);
+                                       e_ews_request_end_set_item_field (request);
 
                                        /*
                                         * Exchange server is smart enough to return the list of
@@ -1812,9 +1798,9 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
                                }
 
                                if (tzid_end != NULL) {
-                                       e_ews_message_start_set_item_field (msg, "EndTimeZone", "calendar", 
"CalendarItem");
-                                       ewscal_set_timezone (msg, "EndTimeZone", tmp->data);
-                                       e_ews_message_end_set_item_field (msg);
+                                       e_ews_request_start_set_item_field (request, "EndTimeZone", 
"calendar", "CalendarItem");
+                                       ewscal_set_timezone (request, "EndTimeZone", tmp->data);
+                                       e_ews_request_end_set_item_field (request);
                                }
                        }
 
@@ -1822,14 +1808,14 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
                        g_slist_free_full (tzds, (GDestroyNotify) e_ews_calendar_time_zone_definition_free);
                }
        } else if (dt_changed) {
-               e_ews_message_replace_server_version (msg, E_EWS_EXCHANGE_2007_SP1);
+               e_ews_request_replace_server_version (request, E_EWS_EXCHANGE_2007_SP1);
 
-               e_ews_message_start_set_item_field (msg, "MeetingTimeZone", "calendar", "CalendarItem");
-               ewscal_set_meeting_timezone (msg, tzid_start ? tzid_start : convert_data->default_zone, 
icomp);
-               e_ews_message_end_set_item_field (msg);
+               e_ews_request_start_set_item_field (request, "MeetingTimeZone", "calendar", "CalendarItem");
+               ewscal_set_meeting_timezone (request, tzid_start ? tzid_start : convert_data->default_zone, 
icomp);
+               e_ews_request_end_set_item_field (request);
        }
 
-       e_ews_message_end_item_change (msg);
+       e_ews_request_end_item_change (request);
 
        g_clear_object (&dtstart);
        g_clear_object (&dtend);
@@ -1840,20 +1826,20 @@ convert_vevent_component_to_updatexml (ESoapMessage *msg,
 }
 
 static void
-convert_vtodo_property_to_updatexml (ESoapMessage *msg,
+convert_vtodo_property_to_updatexml (ESoapRequest *request,
                                      const gchar *name,
                                      const gchar *value,
                                      const gchar *prefix,
                                      const gchar *attr_name,
                                      const gchar *attr_value)
 {
-       e_ews_message_start_set_item_field (msg, name, prefix, "Task");
-       e_ews_message_write_string_parameter_with_attribute (msg, name, NULL, value, attr_name, attr_value);
-       e_ews_message_end_set_item_field (msg);
+       e_ews_request_start_set_item_field (request, name, prefix, "Task");
+       e_ews_request_write_string_parameter_with_attribute (request, name, NULL, value, attr_name, 
attr_value);
+       e_ews_request_end_set_item_field (request);
 }
 
 static gboolean
-convert_vtodo_component_to_updatexml (ESoapMessage *msg,
+convert_vtodo_component_to_updatexml (ESoapRequest *request,
                                       gpointer user_data,
                                      GError **error)
 {
@@ -1865,46 +1851,45 @@ convert_vtodo_component_to_updatexml (ESoapMessage *msg,
        gchar buffer[16];
        gboolean success = TRUE;
 
-       e_ews_message_start_item_change (
-               msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
+       e_ews_request_start_item_change (request, E_EWS_ITEMCHANGE_TYPE_ITEM,
                convert_data->item_id, convert_data->change_key, 0);
 
-       convert_vtodo_property_to_updatexml (msg, "Subject", i_cal_component_get_summary (icomp), "item", 
NULL, NULL);
+       convert_vtodo_property_to_updatexml (request, "Subject", i_cal_component_get_summary (icomp), "item", 
NULL, NULL);
 
        prop = i_cal_component_get_first_property (icomp, I_CAL_CLASS_PROPERTY);
        if (prop) {
                ICalProperty_Class classify = i_cal_property_get_class (prop);
                if (classify == I_CAL_CLASS_PUBLIC) {
-                       convert_vtodo_property_to_updatexml (msg, "Sensitivity", "Normal", "item", NULL, 
NULL);
+                       convert_vtodo_property_to_updatexml (request, "Sensitivity", "Normal", "item", NULL, 
NULL);
                } else if (classify == I_CAL_CLASS_PRIVATE) {
-                       convert_vtodo_property_to_updatexml (msg, "Sensitivity", "Private", "item", NULL, 
NULL);
+                       convert_vtodo_property_to_updatexml (request, "Sensitivity", "Private", "item", NULL, 
NULL);
                } else if (classify == I_CAL_CLASS_CONFIDENTIAL) {
-                       convert_vtodo_property_to_updatexml (msg, "Sensitivity", "Personal", "item", NULL, 
NULL);
+                       convert_vtodo_property_to_updatexml (request, "Sensitivity", "Personal", "item", 
NULL, NULL);
                }
                g_object_unref (prop);
        }
 
-       convert_vtodo_property_to_updatexml (msg, "Body", i_cal_component_get_description (icomp), "item", 
"BodyType", "Text");
+       convert_vtodo_property_to_updatexml (request, "Body", i_cal_component_get_description (icomp), 
"item", "BodyType", "Text");
 
        prop = i_cal_component_get_first_property (icomp, I_CAL_DUE_PROPERTY);
        if (prop) {
                dt = e_cal_backend_ews_get_datetime_with_zone (convert_data->timezone_cache, 
convert_data->vcalendar, icomp, I_CAL_DUE_PROPERTY, i_cal_property_get_due);
-               e_ews_message_start_set_item_field (msg, "DueDate", "task", "Task");
-               e_ews_cal_utils_set_time (msg, "DueDate", dt, TRUE);
-               e_ews_message_end_set_item_field (msg);
+               e_ews_request_start_set_item_field (request, "DueDate", "task", "Task");
+               e_ews_cal_utils_set_time (request, "DueDate", dt, TRUE);
+               e_ews_request_end_set_item_field (request);
                g_object_unref (prop);
                g_clear_object (&dt);
        } else {
-               e_ews_message_add_delete_item_field (msg, "DueDate", "task");
+               e_ews_request_add_delete_item_field (request, "DueDate", "task");
        }
 
        prop = i_cal_component_get_first_property (icomp, I_CAL_PERCENTCOMPLETE_PROPERTY);
        if (prop) {
                value = i_cal_property_get_percentcomplete (prop);
                snprintf (buffer, 16, "%d", value);
-               e_ews_message_start_set_item_field (msg, "PercentComplete", "task", "Task");
-               e_ews_message_write_string_parameter (msg, "PercentComplete", NULL, buffer);
-               e_ews_message_end_set_item_field (msg);
+               e_ews_request_start_set_item_field (request, "PercentComplete", "task", "Task");
+               e_ews_request_write_string_parameter (request, "PercentComplete", NULL, buffer);
+               e_ews_request_end_set_item_field (request);
                g_object_unref (prop);
        }
 
@@ -1912,37 +1897,37 @@ convert_vtodo_component_to_updatexml (ESoapMessage *msg,
        value = i_cal_component_count_properties (e_cal_component_get_icalcomponent (convert_data->old_comp), 
I_CAL_RRULE_PROPERTY);
        if (i_cal_component_count_properties (icomp, I_CAL_RRULE_PROPERTY) > 0 ||
            (e_cal_util_component_has_x_property (icomp, X_EWS_TASK_REGENERATION) && value <= 0)) {
-               e_ews_message_start_set_item_field (msg, "Recurrence", "task", "Task");
-               success = success && e_ews_cal_utils_set_recurrence (msg, icomp, FALSE, error);
-               e_ews_message_end_set_item_field (msg); /* Recurrence */
+               e_ews_request_start_set_item_field (request, "Recurrence", "task", "Task");
+               success = success && e_ews_cal_utils_set_recurrence (request, icomp, FALSE, error);
+               e_ews_request_end_set_item_field (request); /* Recurrence */
        } else if (value > 0) {
-               e_ews_message_add_delete_item_field (msg, "Recurrence", "task");
+               e_ews_request_add_delete_item_field (request, "Recurrence", "task");
        }
 
        prop = i_cal_component_get_first_property (icomp, I_CAL_DTSTART_PROPERTY);
        if (prop) {
                dt = e_cal_backend_ews_get_datetime_with_zone (convert_data->timezone_cache, 
convert_data->vcalendar, icomp, I_CAL_DTSTART_PROPERTY, i_cal_property_get_dtstart);
-               e_ews_message_start_set_item_field (msg, "StartDate", "task", "Task");
-               e_ews_cal_utils_set_time (msg, "StartDate", dt, TRUE);
-               e_ews_message_end_set_item_field (msg);
+               e_ews_request_start_set_item_field (request, "StartDate", "task", "Task");
+               e_ews_cal_utils_set_time (request, "StartDate", dt, TRUE);
+               e_ews_request_end_set_item_field (request);
                g_object_unref (prop);
                g_clear_object (&dt);
        } else {
-               e_ews_message_add_delete_item_field (msg, "StartDate", "task");
+               e_ews_request_add_delete_item_field (request, "StartDate", "task");
        }
 
        prop = i_cal_component_get_first_property (icomp, I_CAL_STATUS_PROPERTY);
        if (prop) {
                switch (i_cal_property_get_status (prop)) {
                case I_CAL_STATUS_INPROCESS:
-                       convert_vtodo_property_to_updatexml (msg, "Status", "InProgress", "task", NULL, NULL);
+                       convert_vtodo_property_to_updatexml (request, "Status", "InProgress", "task", NULL, 
NULL);
                        break;
                case I_CAL_STATUS_COMPLETED:
-                       convert_vtodo_property_to_updatexml (msg, "Status", "Completed", "task", NULL, NULL);
+                       convert_vtodo_property_to_updatexml (request, "Status", "Completed", "task", NULL, 
NULL);
                        break;
                case I_CAL_STATUS_NONE:
                case I_CAL_STATUS_NEEDSACTION:
-                       convert_vtodo_property_to_updatexml (msg, "Status", "NotStarted", "task", NULL, NULL);
+                       convert_vtodo_property_to_updatexml (request, "Status", "NotStarted", "task", NULL, 
NULL);
                        break;
                default:
                        break;
@@ -1951,37 +1936,37 @@ convert_vtodo_component_to_updatexml (ESoapMessage *msg,
        }
 
        /* Categories */
-       convert_component_categories_to_updatexml (convert_data->comp, msg, "Task");
+       convert_component_categories_to_updatexml (convert_data->comp, request, "Task");
 
        prop = i_cal_component_get_first_property (icomp, I_CAL_PRIORITY_PROPERTY);
        if (prop) {
                gint priority;
 
                priority = i_cal_property_get_priority (prop);
-               convert_vtodo_property_to_updatexml (msg, "Importance", ews_priority_to_string (priority), 
"item", NULL, NULL);
+               convert_vtodo_property_to_updatexml (request, "Importance", ews_priority_to_string 
(priority), "item", NULL, NULL);
                g_object_unref (prop);
        }
 
-       e_ews_message_end_item_change (msg);
+       e_ews_request_end_item_change (request);
 
        return success;
 }
 
 static void
-convert_vjournal_property_to_updatexml (ESoapMessage *msg,
+convert_vjournal_property_to_updatexml (ESoapRequest *request,
                                        const gchar *name,
                                        const gchar *value,
                                        const gchar *prefix,
                                        const gchar *attr_name,
                                        const gchar *attr_value)
 {
-       e_ews_message_start_set_item_field (msg, name, prefix, "Message");
-       e_ews_message_write_string_parameter_with_attribute (msg, name, NULL, value, attr_name, attr_value);
-       e_ews_message_end_set_item_field (msg);
+       e_ews_request_start_set_item_field (request, name, prefix, "Message");
+       e_ews_request_write_string_parameter_with_attribute (request, name, NULL, value, attr_name, 
attr_value);
+       e_ews_request_end_set_item_field (request);
 }
 
 static gboolean
-convert_vjournal_component_to_updatexml (ESoapMessage *msg,
+convert_vjournal_component_to_updatexml (ESoapRequest *request,
                                         gpointer user_data,
                                         GError **error)
 {
@@ -1990,22 +1975,21 @@ convert_vjournal_component_to_updatexml (ESoapMessage *msg,
        ICalProperty *prop;
        const gchar *text;
 
-       e_ews_message_start_item_change (
-               msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
+       e_ews_request_start_item_change (request, E_EWS_ITEMCHANGE_TYPE_ITEM,
                convert_data->item_id, convert_data->change_key, 0);
 
-       convert_vjournal_property_to_updatexml (msg, "ItemClass", "IPM.StickyNote", "item", NULL, NULL);
-       convert_vjournal_property_to_updatexml (msg, "Subject", i_cal_component_get_summary (icomp), "item", 
NULL, NULL);
+       convert_vjournal_property_to_updatexml (request, "ItemClass", "IPM.StickyNote", "item", NULL, NULL);
+       convert_vjournal_property_to_updatexml (request, "Subject", i_cal_component_get_summary (icomp), 
"item", NULL, NULL);
 
        prop = i_cal_component_get_first_property (icomp, I_CAL_CLASS_PROPERTY);
        if (prop) {
                ICalProperty_Class classify = i_cal_property_get_class (prop);
                if (classify == I_CAL_CLASS_PUBLIC) {
-                       convert_vjournal_property_to_updatexml (msg, "Sensitivity", "Normal", "item", NULL, 
NULL);
+                       convert_vjournal_property_to_updatexml (request, "Sensitivity", "Normal", "item", 
NULL, NULL);
                } else if (classify == I_CAL_CLASS_PRIVATE) {
-                       convert_vjournal_property_to_updatexml (msg, "Sensitivity", "Private", "item", NULL, 
NULL);
+                       convert_vjournal_property_to_updatexml (request, "Sensitivity", "Private", "item", 
NULL, NULL);
                } else if (classify == I_CAL_CLASS_CONFIDENTIAL) {
-                       convert_vjournal_property_to_updatexml (msg, "Sensitivity", "Personal", "item", NULL, 
NULL);
+                       convert_vjournal_property_to_updatexml (request, "Sensitivity", "Personal", "item", 
NULL, NULL);
                }
                g_object_unref (prop);
        }
@@ -2014,18 +1998,18 @@ convert_vjournal_component_to_updatexml (ESoapMessage *msg,
        if (!text || !*text)
                text = i_cal_component_get_summary (icomp);
 
-       convert_vjournal_property_to_updatexml (msg, "Body", text, "item", "BodyType", "Text");
+       convert_vjournal_property_to_updatexml (request, "Body", text, "item", "BodyType", "Text");
 
        /* Categories */
-       convert_component_categories_to_updatexml (convert_data->comp, msg, "Message");
+       convert_component_categories_to_updatexml (convert_data->comp, request, "Message");
 
-       e_ews_message_end_item_change (msg);
+       e_ews_request_end_item_change (request);
 
        return TRUE;
 }
 
 gboolean
-e_cal_backend_ews_convert_component_to_updatexml (ESoapMessage *msg,
+e_cal_backend_ews_convert_component_to_updatexml (ESoapRequest *request,
                                                  gpointer user_data,
                                                  GError **error)
 {
@@ -2035,13 +2019,13 @@ e_cal_backend_ews_convert_component_to_updatexml (ESoapMessage *msg,
 
        switch (i_cal_component_isa (icomp)) {
        case I_CAL_VEVENT_COMPONENT:
-               success = convert_vevent_component_to_updatexml (msg, user_data, error);
+               success = convert_vevent_component_to_updatexml (request, user_data, error);
                break;
        case I_CAL_VTODO_COMPONENT:
-               success = convert_vtodo_component_to_updatexml (msg, user_data, error);
+               success = convert_vtodo_component_to_updatexml (request, user_data, error);
                break;
        case I_CAL_VJOURNAL_COMPONENT:
-               success = convert_vjournal_component_to_updatexml (msg, user_data, error);
+               success = convert_vjournal_component_to_updatexml (request, user_data, error);
                break;
        default:
                break;
@@ -2115,52 +2099,51 @@ e_cal_backend_ews_rid_to_index (ICalTimezone *timezone,
 }
 
 gboolean
-e_cal_backend_ews_clear_reminder_is_set (ESoapMessage *msg,
+e_cal_backend_ews_clear_reminder_is_set (ESoapRequest *request,
                                         gpointer user_data,
                                         GError **error)
 {
        EwsCalendarConvertData *convert_data = user_data;
 
-       e_ews_message_start_item_change (
-               msg,
+       e_ews_request_start_item_change (request,
                convert_data->change_type,
                convert_data->item_id,
                convert_data->change_key,
                convert_data->index);
 
-       e_ews_message_start_set_item_field (msg, "ReminderIsSet","item", "CalendarItem");
+       e_ews_request_start_set_item_field (request, "ReminderIsSet","item", "CalendarItem");
 
-       e_ews_message_write_string_parameter (msg, "ReminderIsSet", NULL, "false");
+       e_ews_request_write_string_parameter (request, "ReminderIsSet", NULL, "false");
 
-       e_ews_message_end_set_item_field (msg);
+       e_ews_request_end_set_item_field (request);
 
-       e_ews_message_end_item_change (msg);
+       e_ews_request_end_item_change (request);
 
        return TRUE;
 }
 
 gboolean
-e_cal_backend_ews_prepare_set_free_busy_status (ESoapMessage *msg,
+e_cal_backend_ews_prepare_set_free_busy_status (ESoapRequest *request,
                                                gpointer user_data,
                                                GError **error)
 {
        EwsCalendarConvertData *data = user_data;
 
-       e_ews_message_start_item_change (msg, E_EWS_ITEMCHANGE_TYPE_ITEM, data->item_id, data->change_key, 0);
+       e_ews_request_start_item_change (request, E_EWS_ITEMCHANGE_TYPE_ITEM, data->item_id, 
data->change_key, 0);
 
-       e_ews_message_start_set_item_field (msg, "LegacyFreeBusyStatus", "calendar", "CalendarItem");
+       e_ews_request_start_set_item_field (request, "LegacyFreeBusyStatus", "calendar", "CalendarItem");
 
-       e_ews_message_write_string_parameter (msg, "LegacyFreeBusyStatus", NULL, "Free");
+       e_ews_request_write_string_parameter (request, "LegacyFreeBusyStatus", NULL, "Free");
 
-       e_ews_message_end_set_item_field (msg);
+       e_ews_request_end_set_item_field (request);
 
-       e_ews_message_end_item_change (msg);
+       e_ews_request_end_item_change (request);
 
        return TRUE;
 }
 
 gboolean
-e_cal_backend_ews_prepare_accept_item_request (ESoapMessage *msg,
+e_cal_backend_ews_prepare_accept_item_request (ESoapRequest *request,
                                               gpointer user_data,
                                               GError **error)
 {
@@ -2174,19 +2157,19 @@ e_cal_backend_ews_prepare_accept_item_request (ESoapMessage *msg,
         * Prepare AcceptItem node in the SOAP message */
 
        if (response_type && !g_ascii_strcasecmp (response_type, "ACCEPTED"))
-               e_soap_message_start_element (msg, "AcceptItem", NULL, NULL);
+               e_soap_request_start_element (request, "AcceptItem", NULL, NULL);
        else if (response_type && !g_ascii_strcasecmp (response_type, "DECLINED"))
-               e_soap_message_start_element (msg, "DeclineItem", NULL, NULL);
+               e_soap_request_start_element (request, "DeclineItem", NULL, NULL);
        else
-               e_soap_message_start_element (msg, "TentativelyAcceptItem", NULL, NULL);
+               e_soap_request_start_element (request, "TentativelyAcceptItem", NULL, NULL);
 
-       e_soap_message_start_element (msg, "ReferenceItemId", NULL, NULL);
-       e_soap_message_add_attribute (msg, "Id", data->item_id, NULL, NULL);
-       e_soap_message_add_attribute (msg, "ChangeKey", data->change_key, NULL, NULL);
-       e_soap_message_end_element (msg); /* "ReferenceItemId" */
+       e_soap_request_start_element (request, "ReferenceItemId", NULL, NULL);
+       e_soap_request_add_attribute (request, "Id", data->item_id, NULL, NULL);
+       e_soap_request_add_attribute (request, "ChangeKey", data->change_key, NULL, NULL);
+       e_soap_request_end_element (request); /* "ReferenceItemId" */
 
        /* end of "AcceptItem" */
-       e_soap_message_end_element (msg);
+       e_soap_request_end_element (request);
 
        return TRUE;
 }
diff --git a/src/EWS/calendar/e-cal-backend-ews-utils.h b/src/EWS/calendar/e-cal-backend-ews-utils.h
index 7b84911c..7b2c13b7 100644
--- a/src/EWS/calendar/e-cal-backend-ews-utils.h
+++ b/src/EWS/calendar/e-cal-backend-ews-utils.h
@@ -41,12 +41,12 @@ typedef struct {
 const gchar *e_ews_collect_organizer (ICalComponent *comp);
 void e_ews_collect_attendees (ICalComponent *comp, GSList **required, GSList **optional, GSList **resource, 
gboolean *out_rsvp_requested);
 
-void ewscal_set_timezone (ESoapMessage *msg, const gchar *name, EEwsCalendarTimeZoneDefinition *tzd);
-void ewscal_set_meeting_timezone (ESoapMessage *msg, ICalTimezone *icaltz, ICalComponent *icomp);
-void ewscal_set_reccurence (ESoapMessage *msg, ICalProperty *rrule, ICalTime *dtstart);
-void ewscal_set_reccurence_exceptions (ESoapMessage *msg, ICalComponent *comp);
+void ewscal_set_timezone (ESoapRequest *request, const gchar *name, EEwsCalendarTimeZoneDefinition *tzd);
+void ewscal_set_meeting_timezone (ESoapRequest *request, ICalTimezone *icaltz, ICalComponent *icomp);
+void ewscal_set_reccurence (ESoapRequest *request, ICalProperty *rrule, ICalTime *dtstart);
+void ewscal_set_reccurence_exceptions (ESoapRequest *request, ICalComponent *comp);
 gchar *e_ews_extract_attachment_id_from_uri (const gchar *uri);
-void ews_set_alarm (ESoapMessage *msg, ECalComponent *comp, ETimezoneCache *timezone_cache, ICalComponent 
*vcalendar, gboolean with_due_by);
+void ews_set_alarm (ESoapRequest *request, ECalComponent *comp, ETimezoneCache *timezone_cache, 
ICalComponent *vcalendar, gboolean with_due_by);
 gint ews_get_alarm (ECalComponent *comp);
 void e_ews_clean_icomponent (ICalComponent *icomp);
 
@@ -55,11 +55,11 @@ const gchar *e_cal_backend_ews_tz_util_get_ical_equivalent (const gchar *msdn_tz
 void e_cal_backend_ews_populate_windows_zones (void);
 void e_cal_backend_ews_unref_windows_zones (void);
 
-gboolean e_cal_backend_ews_convert_calcomp_to_xml (ESoapMessage *msg, gpointer user_data, GError **error);
-gboolean e_cal_backend_ews_convert_component_to_updatexml (ESoapMessage *msg, gpointer user_data, GError 
**error);
-gboolean e_cal_backend_ews_clear_reminder_is_set (ESoapMessage *msg, gpointer user_data, GError **error);
-gboolean e_cal_backend_ews_prepare_set_free_busy_status (ESoapMessage *msg,gpointer user_data, GError 
**error);
-gboolean e_cal_backend_ews_prepare_accept_item_request (ESoapMessage *msg, gpointer user_data, GError 
**error);
+gboolean e_cal_backend_ews_convert_calcomp_to_xml (ESoapRequest *request, gpointer user_data, GError 
**error);
+gboolean e_cal_backend_ews_convert_component_to_updatexml (ESoapRequest *request, gpointer user_data, GError 
**error);
+gboolean e_cal_backend_ews_clear_reminder_is_set (ESoapRequest *request, gpointer user_data, GError **error);
+gboolean e_cal_backend_ews_prepare_set_free_busy_status (ESoapRequest *request,gpointer user_data, GError 
**error);
+gboolean e_cal_backend_ews_prepare_accept_item_request (ESoapRequest *request, gpointer user_data, GError 
**error);
 
 guint e_cal_backend_ews_rid_to_index (ICalTimezone *timezone, const gchar *rid, ICalComponent *comp, GError 
**error);
 
diff --git a/src/EWS/calendar/e-cal-backend-ews.c b/src/EWS/calendar/e-cal-backend-ews.c
index ea7c1f78..de719c79 100644
--- a/src/EWS/calendar/e-cal-backend-ews.c
+++ b/src/EWS/calendar/e-cal-backend-ews.c
@@ -528,8 +528,8 @@ ecb_ews_item_to_component_sync (ECalBackendEws *cbews,
                        /* get delegator mail box*/
                        e_ews_connection_resolve_names_sync (
                                cbews->priv->cnc, EWS_PRIORITY_MEDIUM, task_owner,
-                               EWS_SEARCH_AD, NULL, FALSE, &mailboxes, NULL,
-                               &includes_last_item, cancellable, error);
+                               EWS_SEARCH_AD, NULL, FALSE, &includes_last_item, &mailboxes, NULL,
+                               cancellable, error);
 
                        for (l = mailboxes; l != NULL; l = g_slist_next (l)) {
                                EwsMailbox *mb = l->data;
@@ -4546,7 +4546,7 @@ ecb_ews_get_destination_address (EBackend *backend,
                                 guint16 *port)
 {
        CamelEwsSettings *ews_settings;
-       SoupURI *soup_uri;
+       GUri *uri;
        gchar *host_url;
        gboolean result = FALSE;
 
@@ -4564,10 +4564,10 @@ ecb_ews_get_destination_address (EBackend *backend,
        host_url = camel_ews_settings_dup_hosturl (ews_settings);
        g_return_val_if_fail (host_url != NULL, FALSE);
 
-       soup_uri = soup_uri_new (host_url);
-       if (soup_uri) {
-               *host = g_strdup (soup_uri_get_host (soup_uri));
-               *port = soup_uri_get_port (soup_uri);
+       uri = g_uri_parse (host_url, SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
+       if (uri) {
+               *host = g_strdup (g_uri_get_host (uri));
+               *port = g_uri_get_port (uri);
 
                result = *host && **host;
                if (!result) {
@@ -4575,7 +4575,7 @@ ecb_ews_get_destination_address (EBackend *backend,
                        *host = NULL;
                }
 
-               soup_uri_free (soup_uri);
+               g_uri_unref (uri);
        }
 
        g_free (host_url);
diff --git a/src/EWS/camel/camel-ews-folder.c b/src/EWS/camel/camel-ews-folder.c
index 1a5c91b0..924135e1 100644
--- a/src/EWS/camel/camel-ews-folder.c
+++ b/src/EWS/camel/camel-ews-folder.c
@@ -27,7 +27,7 @@ which needs to be better organized via functions */
 #include "common/e-ews-camel-common.h"
 #include "common/e-ews-connection.h"
 #include "common/e-ews-item-change.h"
-#include "common/e-ews-message.h"
+#include "common/e-ews-request.h"
 
 #include "camel-ews-folder.h"
 #include "camel-ews-private.h"
@@ -345,7 +345,7 @@ ews_update_mgtrequest_mime_calendar_itemid (const gchar *mime_fname,
        gint fd_old;
        gchar *mime_fname_new = NULL;
 
-       // original mime file
+       /* original mime file */
        fd_old = open (mime_fname, O_RDONLY);
        if (fd_old == -1) {
                g_set_error (
@@ -485,7 +485,7 @@ ews_update_mgtrequest_mime_calendar_itemid (const gchar *mime_fname,
        g_object_unref (mimeparser);
        close (fd_old);
 
-       // must be freed in the caller
+       /* must be freed in the caller */
        return mime_fname_new;
 }
 
@@ -792,7 +792,7 @@ camel_ews_folder_get_message (CamelFolder *folder,
                cnc, pri, ids, "IdOnly", add_props,
                TRUE, mime_dir, E_EWS_BODY_TYPE_ANY,
                &items,
-               (ESoapProgressFn) camel_operation_progress,
+               (ESoapResponseProgressFn) camel_operation_progress,
                (gpointer) cancellable,
                cancellable, &local_error);
        e_ews_additional_props_free (add_props);
@@ -831,7 +831,7 @@ camel_ews_folder_get_message (CamelFolder *folder,
        g_free (mime_dir);
 
        /* The mime_content actually contains the *filename*, due to the
-        * streaming hack in ESoapMessage */
+        * streaming hack in ESoapResponse */
        mime_content = e_ews_item_get_mime_content (items->data);
        if (!mime_content)
                goto exit;
@@ -858,7 +858,7 @@ camel_ews_folder_get_message (CamelFolder *folder,
                        cnc, pri, ids, "IdOnly", add_props,
                        FALSE, NULL, E_EWS_BODY_TYPE_ANY,
                        &items_req,
-                       (ESoapProgressFn) camel_operation_progress,
+                       (ESoapResponseProgressFn) camel_operation_progress,
                        (gpointer) cancellable,
                        cancellable, &local_error);
 
@@ -894,7 +894,7 @@ camel_ews_folder_get_message (CamelFolder *folder,
                        cnc, pri, html_body_ids, "IdOnly", add_props,
                        FALSE, NULL, E_EWS_BODY_TYPE_BEST,
                        &html_body_resp,
-                       (ESoapProgressFn) camel_operation_progress,
+                       (ESoapResponseProgressFn) camel_operation_progress,
                        (gpointer) cancellable,
                        cancellable, NULL) && html_body_resp && e_ews_item_get_item_type 
(html_body_resp->data) != E_EWS_ITEM_TYPE_ERROR) {
                        EEwsItem *item = html_body_resp->data;
@@ -1263,7 +1263,7 @@ ews_folder_search_free (CamelFolder *folder,
 /********************* folder functions*************************/
 
 static gboolean
-msg_update_flags (ESoapMessage *msg,
+msg_update_flags (ESoapRequest *request,
                   gpointer user_data,
                  GError **error)
 {
@@ -1291,8 +1291,8 @@ msg_update_flags (ESoapMessage *msg,
                mi_flags = camel_message_info_get_flags (mi);
                flags_changed = camel_ews_message_info_get_server_flags (emi) ^ mi_flags;
 
-               e_ews_message_start_item_change (
-                       msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
+               e_ews_request_start_item_change (
+                       request, E_EWS_ITEMCHANGE_TYPE_ITEM,
                        camel_message_info_get_uid (mi), camel_ews_message_info_get_change_key (emi), 0);
                if (flags_changed & CAMEL_MESSAGE_FLAGGED) {
                        const gchar *flag;
@@ -1302,33 +1302,33 @@ msg_update_flags (ESoapMessage *msg,
                        else
                                flag = "Normal";
 
-                       e_soap_message_start_element (msg, "SetItemField", NULL, NULL);
+                       e_soap_request_start_element (request, "SetItemField", NULL, NULL);
 
-                       e_soap_message_start_element (msg, "FieldURI", NULL, NULL);
-                       e_soap_message_add_attribute (msg, "FieldURI", "item:Importance", NULL, NULL);
-                       e_soap_message_end_element (msg);
+                       e_soap_request_start_element (request, "FieldURI", NULL, NULL);
+                       e_soap_request_add_attribute (request, "FieldURI", "item:Importance", NULL, NULL);
+                       e_soap_request_end_element (request);
 
-                       e_soap_message_start_element (msg, "Message", NULL, NULL);
+                       e_soap_request_start_element (request, "Message", NULL, NULL);
 
-                       e_ews_message_write_string_parameter (msg, "Importance", NULL, flag);
+                       e_ews_request_write_string_parameter (request, "Importance", NULL, flag);
 
-                       e_soap_message_end_element (msg); /* Message */
-                       e_soap_message_end_element (msg); /* SetItemField */
+                       e_soap_request_end_element (request); /* Message */
+                       e_soap_request_end_element (request); /* SetItemField */
                }
 
                if (flags_changed & CAMEL_MESSAGE_SEEN) {
-                       e_soap_message_start_element (msg, "SetItemField", NULL, NULL);
+                       e_soap_request_start_element (request, "SetItemField", NULL, NULL);
 
-                       e_soap_message_start_element (msg, "FieldURI", NULL, NULL);
-                       e_soap_message_add_attribute (msg, "FieldURI", "message:IsRead", NULL, NULL);
-                       e_soap_message_end_element (msg);
+                       e_soap_request_start_element (request, "FieldURI", NULL, NULL);
+                       e_soap_request_add_attribute (request, "FieldURI", "message:IsRead", NULL, NULL);
+                       e_soap_request_end_element (request);
 
-                       e_soap_message_start_element (msg, "Message", NULL, NULL);
-                       e_ews_message_write_string_parameter (msg, "IsRead", NULL,
+                       e_soap_request_start_element (request, "Message", NULL, NULL);
+                       e_ews_request_write_string_parameter (request, "IsRead", NULL,
                                (mi_flags & CAMEL_MESSAGE_SEEN) ? "true" : "false");
 
-                       e_soap_message_end_element (msg); /* Message */
-                       e_soap_message_end_element (msg); /* SetItemField */
+                       e_soap_request_end_element (request); /* Message */
+                       e_soap_request_end_element (request); /* SetItemField */
                }
                /* Ick Ick Ick. Why in hell is there a field in the database for the Icon
                 * *anyway*? Why isn't there a better place for forwarded/answered status? */
@@ -1340,41 +1340,41 @@ msg_update_flags (ESoapMessage *msg,
                        if (mi_flags & CAMEL_MESSAGE_FORWARDED)
                                icon = 0x106;
 
-                       e_ews_message_add_set_item_field_extended_tag_int (msg, NULL, "Message", 0x1080, 
icon);
+                       e_ews_request_add_set_item_field_extended_tag_int (request, NULL, "Message", 0x1080, 
icon);
                }
 
                /* now update the Categories */
-               user_flags = ews_utils_gather_server_user_flags (msg, mi);
+               user_flags = ews_utils_gather_server_user_flags (request, mi);
                if (user_flags) {
                        GSList *link;
 
-                       e_soap_message_start_element (msg, "SetItemField", NULL, NULL);
+                       e_soap_request_start_element (request, "SetItemField", NULL, NULL);
 
-                       e_soap_message_start_element (msg, "FieldURI", NULL, NULL);
-                       e_soap_message_add_attribute (msg, "FieldURI", "item:Categories", NULL, NULL);
-                       e_soap_message_end_element (msg);
+                       e_soap_request_start_element (request, "FieldURI", NULL, NULL);
+                       e_soap_request_add_attribute (request, "FieldURI", "item:Categories", NULL, NULL);
+                       e_soap_request_end_element (request);
 
-                       e_soap_message_start_element (msg, "Message", NULL, NULL);
-                       e_soap_message_start_element (msg, "Categories", NULL, NULL);
+                       e_soap_request_start_element (request, "Message", NULL, NULL);
+                       e_soap_request_start_element (request, "Categories", NULL, NULL);
 
                        for (link = user_flags; link; link = g_slist_next (link)) {
                                const gchar *user_flag = link->data;
 
-                               e_ews_message_write_string_parameter (msg, "String", NULL, user_flag);
+                               e_ews_request_write_string_parameter (request, "String", NULL, user_flag);
                        }
 
-                       e_soap_message_end_element (msg); /* Categories */
-                       e_soap_message_end_element (msg); /* Message */
-                       e_soap_message_end_element (msg); /* SetItemField */
+                       e_soap_request_end_element (request); /* Categories */
+                       e_soap_request_end_element (request); /* Message */
+                       e_soap_request_end_element (request); /* SetItemField */
                } else {
-                       e_ews_message_add_delete_item_field (msg, "Categories", "item");
+                       e_ews_request_add_delete_item_field (request, "Categories", "item");
                }
 
                g_slist_free_full (user_flags, g_free);
 
-               ews_utils_update_followup_flags (msg, mi);
+               ews_utils_update_followup_flags (request, mi);
 
-               e_ews_message_end_item_change (msg);
+               e_ews_request_end_item_change (request);
 
                camel_message_info_set_folder_flagged (mi, FALSE);
 
@@ -1388,7 +1388,7 @@ msg_update_flags (ESoapMessage *msg,
 }
 
 static gboolean
-ews_suppress_read_receipt (ESoapMessage *msg,
+ews_suppress_read_receipt (ESoapRequest *request,
                           gpointer user_data,
                           GError **error)
 {
@@ -1411,12 +1411,12 @@ ews_suppress_read_receipt (ESoapMessage *msg,
 
                /* There was requested a read-receipt, but it is handled by evolution-ews,
                   thus prevent an automatic send of it by the server */
-               e_soap_message_start_element (msg, "SuppressReadReceipt", NULL, NULL);
-               e_soap_message_start_element (msg, "ReferenceItemId", NULL, NULL);
-               e_soap_message_add_attribute (msg, "Id", camel_message_info_get_uid (mi), NULL, NULL);
-               e_soap_message_add_attribute (msg, "ChangeKey", camel_ews_message_info_get_change_key 
(CAMEL_EWS_MESSAGE_INFO (mi)), NULL, NULL);
-               e_soap_message_end_element (msg); /* "ReferenceItemId" */
-               e_soap_message_end_element (msg); /* SuppressReadReceipt */
+               e_soap_request_start_element (request, "SuppressReadReceipt", NULL, NULL);
+               e_soap_request_start_element (request, "ReferenceItemId", NULL, NULL);
+               e_soap_request_add_attribute (request, "Id", camel_message_info_get_uid (mi), NULL, NULL);
+               e_soap_request_add_attribute (request, "ChangeKey", camel_ews_message_info_get_change_key 
(CAMEL_EWS_MESSAGE_INFO (mi)), NULL, NULL);
+               e_soap_request_end_element (request); /* "ReferenceItemId" */
+               e_soap_request_end_element (request); /* SuppressReadReceipt */
 
                camel_message_info_set_flags (mi, CAMEL_EWS_MESSAGE_MSGFLAG_RN_PENDING, 0);
 
diff --git a/src/EWS/camel/camel-ews-store.c b/src/EWS/camel/camel-ews-store.c
index 439d61e3..6b2ab320 100644
--- a/src/EWS/camel/camel-ews-store.c
+++ b/src/EWS/camel/camel-ews-store.c
@@ -20,7 +20,7 @@
 
 #include "common/camel-ews-settings.h"
 #include "common/e-ews-item-change.h"
-#include "common/e-ews-message.h"
+#include "common/e-ews-request.h"
 #include "common/e-ews-oof-settings.h"
 
 #include "camel-ews-folder.h"
@@ -2216,7 +2216,7 @@ ews_authenticate_sync (CamelService *service,
 
        g_slist_free_full (created_folder_ids, g_free);
 
-       if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED) &&
+       if (g_error_matches (local_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE) &&
            e_ews_connection_get_ssl_error_details (connection, &certificate_pem, &certificate_errors)) {
                source = e_ews_connection_get_source (connection);
 
@@ -3144,27 +3144,27 @@ struct _rename_cb_data {
 };
 
 static gboolean
-rename_folder_cb (ESoapMessage *msg,
+rename_folder_cb (ESoapRequest *request,
                   gpointer user_data,
                  GError **error)
 {
        struct _rename_cb_data *rename_data = user_data;
 
-       e_ews_message_start_item_change (
-               msg, E_EWS_ITEMCHANGE_TYPE_FOLDER,
+       e_ews_request_start_item_change (
+               request, E_EWS_ITEMCHANGE_TYPE_FOLDER,
                rename_data->folder_id, rename_data->change_key, 0);
-       e_soap_message_start_element (msg, "SetFolderField", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (
-               msg, "FieldURI", NULL, NULL,
+       e_soap_request_start_element (request, "SetFolderField", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (
+               request, "FieldURI", NULL, NULL,
                "FieldURI", "folder:DisplayName");
 
-       e_soap_message_start_element (msg, "Folder", NULL, NULL);
-       e_ews_message_write_string_parameter (msg, "DisplayName", NULL, rename_data->display_name);
-       e_soap_message_end_element (msg); /* Folder */
+       e_soap_request_start_element (request, "Folder", NULL, NULL);
+       e_ews_request_write_string_parameter (request, "DisplayName", NULL, rename_data->display_name);
+       e_soap_request_end_element (request); /* Folder */
 
-       e_soap_message_end_element (msg); /* SetFolderField */
+       e_soap_request_end_element (request); /* SetFolderField */
 
-       e_ews_message_end_item_change (msg);
+       e_ews_request_end_item_change (request);
 
        return TRUE;
 }
diff --git a/src/EWS/camel/camel-ews-utils.c b/src/EWS/camel/camel-ews-utils.c
index d7097c01..0707f726 100644
--- a/src/EWS/camel/camel-ews-utils.c
+++ b/src/EWS/camel/camel-ews-utils.c
@@ -17,7 +17,7 @@
 #include "common/camel-ews-settings.h"
 #include "common/e-ews-camel-common.h"
 #include "common/e-ews-item-change.h"
-#include "common/e-ews-message.h"
+#include "common/e-ews-request.h"
 
 #include "camel-ews-utils.h"
 
@@ -515,7 +515,7 @@ camel_ews_utils_decode_category_name (const gchar *flag)
 /* free with g_slist_free_full (flags, g_free);
    the lists' members are values for the String xml element. */
 GSList *
-ews_utils_gather_server_user_flags (ESoapMessage *msg,
+ews_utils_gather_server_user_flags (ESoapRequest *request,
                                    CamelMessageInfo *mi)
 {
        GSList *out_user_flags = NULL;
@@ -1288,13 +1288,13 @@ camel_ews_utils_get_host_name (CamelSettings *settings)
 }
 
 void
-ews_utils_update_followup_flags (ESoapMessage *msg,
+ews_utils_update_followup_flags (ESoapRequest *request,
                                 CamelMessageInfo *mi)
 {
        const gchar *followup, *completed, *dueby;
        time_t completed_tt = (time_t) 0 , dueby_tt = (time_t) 0;
 
-       g_return_if_fail (msg != NULL);
+       g_return_if_fail (request != NULL);
        g_return_if_fail (mi != NULL);
 
        followup = camel_message_info_get_user_tag (mi, "follow-up");
@@ -1312,66 +1312,66 @@ ews_utils_update_followup_flags (ESoapMessage *msg,
 
        if (followup) {
                /* PidTagFlagStatus */
-               e_ews_message_add_set_item_field_extended_tag_int (msg, NULL, "Message", 0x1090,
+               e_ews_request_add_set_item_field_extended_tag_int (request, NULL, "Message", 0x1090,
                        completed_tt != (time_t) 0 ? 0x01 /* followupComplete */: 0x02 /* followupFlagged */);
 
                /* PidLidFlagRequest */
-               e_ews_message_add_set_item_field_extended_distinguished_tag_string (msg, NULL, "Message", 
"Common", 0x8530, followup);
+               e_ews_request_add_set_item_field_extended_distinguished_tag_string (request, NULL, "Message", 
"Common", 0x8530, followup);
 
                /* PidTagToDoItemFlags */
-               e_ews_message_add_set_item_field_extended_tag_int (msg, NULL, "Message", 0x0e2b, 1);
+               e_ews_request_add_set_item_field_extended_tag_int (request, NULL, "Message", 0x0e2b, 1);
 
                if (completed_tt == (time_t) 0 && dueby_tt == (time_t) 0) {
                        time_t now_tt = time (NULL);
 
                        /* PidLidTaskStatus */
-                       e_ews_message_add_set_item_field_extended_distinguished_tag_int (msg, NULL, 
"Message", "Task", 0x8101, 0);
+                       e_ews_request_add_set_item_field_extended_distinguished_tag_int (request, NULL, 
"Message", "Task", 0x8101, 0);
 
                        /* PidLidPercentComplete */
-                       e_ews_message_add_set_item_field_extended_distinguished_tag_double (msg, NULL, 
"Message", "Task", 0x8102, 0.0);
+                       e_ews_request_add_set_item_field_extended_distinguished_tag_double (request, NULL, 
"Message", "Task", 0x8102, 0.0);
 
                        /* PidLidTaskStartDate */
-                       e_ews_message_add_set_item_field_extended_distinguished_tag_time (msg, NULL, 
"Message", "Task", 0x8104, now_tt);
+                       e_ews_request_add_set_item_field_extended_distinguished_tag_time (request, NULL, 
"Message", "Task", 0x8104, now_tt);
 
                        /* PidLidTaskComplete */
-                       e_ews_message_add_set_item_field_extended_distinguished_tag_boolean (msg, NULL, 
"Message", "Task", 0x811c, FALSE);
+                       e_ews_request_add_set_item_field_extended_distinguished_tag_boolean (request, NULL, 
"Message", "Task", 0x811c, FALSE);
                }
        } else {
                /* PidTagFlagStatus */
-               e_ews_message_add_delete_item_field_extended_tag (msg, 0x1090, E_EWS_MESSAGE_DATA_TYPE_INT);
+               e_ews_request_add_delete_item_field_extended_tag (request, 0x1090, 
E_EWS_MESSAGE_DATA_TYPE_INT);
 
                /* PidTagFlagCompleteTime */
-               e_ews_message_add_delete_item_field_extended_tag (msg, 0x1091, E_EWS_MESSAGE_DATA_TYPE_TIME);
+               e_ews_request_add_delete_item_field_extended_tag (request, 0x1091, 
E_EWS_MESSAGE_DATA_TYPE_TIME);
 
                /* PidTagToDoItemFlags */
-               e_ews_message_add_delete_item_field_extended_tag (msg, 0x0e2b, E_EWS_MESSAGE_DATA_TYPE_INT);
+               e_ews_request_add_delete_item_field_extended_tag (request, 0x0e2b, 
E_EWS_MESSAGE_DATA_TYPE_INT);
 
                /* PidTagFollowupIcon */
-               e_ews_message_add_delete_item_field_extended_tag (msg, 0x1095, E_EWS_MESSAGE_DATA_TYPE_INT);
+               e_ews_request_add_delete_item_field_extended_tag (request, 0x1095, 
E_EWS_MESSAGE_DATA_TYPE_INT);
 
                /* PidLidFlagRequest */
-               e_ews_message_add_delete_item_field_extended_distinguished_tag (msg, "Common", 0x8530, 
E_EWS_MESSAGE_DATA_TYPE_STRING);
+               e_ews_request_add_delete_item_field_extended_distinguished_tag (request, "Common", 0x8530, 
E_EWS_MESSAGE_DATA_TYPE_STRING);
 
                /* PidLidFlagString */
-               e_ews_message_add_delete_item_field_extended_distinguished_tag (msg, "Common", 0x85c0, 
E_EWS_MESSAGE_DATA_TYPE_INT);
+               e_ews_request_add_delete_item_field_extended_distinguished_tag (request, "Common", 0x85c0, 
E_EWS_MESSAGE_DATA_TYPE_INT);
 
                /* PidLidTaskStatus */
-               e_ews_message_add_delete_item_field_extended_distinguished_tag (msg, "Task", 0x8101, 
E_EWS_MESSAGE_DATA_TYPE_INT);
+               e_ews_request_add_delete_item_field_extended_distinguished_tag (request, "Task", 0x8101, 
E_EWS_MESSAGE_DATA_TYPE_INT);
 
                /* PidLidPercentComplete */
-               e_ews_message_add_delete_item_field_extended_distinguished_tag (msg, "Task", 0x8102, 
E_EWS_MESSAGE_DATA_TYPE_DOUBLE);
+               e_ews_request_add_delete_item_field_extended_distinguished_tag (request, "Task", 0x8102, 
E_EWS_MESSAGE_DATA_TYPE_DOUBLE);
 
                /* PidLidTaskStartDate */
-               e_ews_message_add_delete_item_field_extended_distinguished_tag (msg, "Task", 0x8104, 
E_EWS_MESSAGE_DATA_TYPE_TIME);
+               e_ews_request_add_delete_item_field_extended_distinguished_tag (request, "Task", 0x8104, 
E_EWS_MESSAGE_DATA_TYPE_TIME);
 
                /* PidLidTaskDueDate */
-               e_ews_message_add_delete_item_field_extended_distinguished_tag (msg, "Task", 0x8105, 
E_EWS_MESSAGE_DATA_TYPE_TIME);
+               e_ews_request_add_delete_item_field_extended_distinguished_tag (request, "Task", 0x8105, 
E_EWS_MESSAGE_DATA_TYPE_TIME);
 
                /* PidLidTaskDateCompleted */
-               e_ews_message_add_delete_item_field_extended_distinguished_tag (msg, "Task", 0x810f, 
E_EWS_MESSAGE_DATA_TYPE_TIME);
+               e_ews_request_add_delete_item_field_extended_distinguished_tag (request, "Task", 0x810f, 
E_EWS_MESSAGE_DATA_TYPE_TIME);
 
                /* PidLidTaskComplete */
-               e_ews_message_add_delete_item_field_extended_distinguished_tag (msg, "Task", 0x811c, 
E_EWS_MESSAGE_DATA_TYPE_BOOLEAN);
+               e_ews_request_add_delete_item_field_extended_distinguished_tag (request, "Task", 0x811c, 
E_EWS_MESSAGE_DATA_TYPE_BOOLEAN);
        }
 
        if (followup && completed_tt != (time_t) 0) {
@@ -1379,22 +1379,22 @@ ews_utils_update_followup_flags (ESoapMessage *msg,
                completed_tt = completed_tt - (completed_tt % 60);
 
                /* PidTagFlagCompleteTime */
-               e_ews_message_add_set_item_field_extended_tag_time (msg, NULL, "Message", 0x1091, 
completed_tt);
+               e_ews_request_add_set_item_field_extended_tag_time (request, NULL, "Message", 0x1091, 
completed_tt);
 
                /* PidTagFollowupIcon */
-               e_ews_message_add_delete_item_field_extended_tag (msg, 0x1095, E_EWS_MESSAGE_DATA_TYPE_INT);
+               e_ews_request_add_delete_item_field_extended_tag (request, 0x1095, 
E_EWS_MESSAGE_DATA_TYPE_INT);
 
                /* PidLidTaskDateCompleted */
-               e_ews_message_add_set_item_field_extended_distinguished_tag_time (msg, NULL, "Message", 
"Task", 0x810f, completed_tt);
+               e_ews_request_add_set_item_field_extended_distinguished_tag_time (request, NULL, "Message", 
"Task", 0x810f, completed_tt);
 
                /* PidLidTaskStatus */
-               e_ews_message_add_set_item_field_extended_distinguished_tag_int (msg, NULL, "Message", 
"Task", 0x8101, 2);
+               e_ews_request_add_set_item_field_extended_distinguished_tag_int (request, NULL, "Message", 
"Task", 0x8101, 2);
 
                /* PidLidPercentComplete */
-               e_ews_message_add_set_item_field_extended_distinguished_tag_double (msg, NULL, "Message", 
"Task", 0x8102, 1.0);
+               e_ews_request_add_set_item_field_extended_distinguished_tag_double (request, NULL, "Message", 
"Task", 0x8102, 1.0);
 
                /* PidLidTaskComplete */
-               e_ews_message_add_set_item_field_extended_distinguished_tag_boolean (msg, NULL, "Message", 
"Task", 0x811c, TRUE);
+               e_ews_request_add_set_item_field_extended_distinguished_tag_boolean (request, NULL, 
"Message", "Task", 0x811c, TRUE);
        }
 
        if (followup && dueby_tt != (time_t) 0 && completed_tt == (time_t) 0) {
@@ -1404,22 +1404,22 @@ ews_utils_update_followup_flags (ESoapMessage *msg,
                        now_tt = dueby_tt - 1;
 
                /* PidLidTaskStatus */
-               e_ews_message_add_set_item_field_extended_distinguished_tag_int (msg, NULL, "Message", 
"Task", 0x8101, 0);
+               e_ews_request_add_set_item_field_extended_distinguished_tag_int (request, NULL, "Message", 
"Task", 0x8101, 0);
 
                /* PidLidPercentComplete */
-               e_ews_message_add_set_item_field_extended_distinguished_tag_double (msg, NULL, "Message", 
"Task", 0x8102, 0.0);
+               e_ews_request_add_set_item_field_extended_distinguished_tag_double (request, NULL, "Message", 
"Task", 0x8102, 0.0);
 
                /* PidLidTaskStartDate */
-               e_ews_message_add_set_item_field_extended_distinguished_tag_time (msg, NULL, "Message", 
"Task", 0x8104, now_tt);
+               e_ews_request_add_set_item_field_extended_distinguished_tag_time (request, NULL, "Message", 
"Task", 0x8104, now_tt);
 
                /* PidLidTaskDueDate */
-               e_ews_message_add_set_item_field_extended_distinguished_tag_time (msg, NULL, "Message", 
"Task", 0x8105, dueby_tt);
+               e_ews_request_add_set_item_field_extended_distinguished_tag_time (request, NULL, "Message", 
"Task", 0x8105, dueby_tt);
 
                /* PidLidTaskComplete */
-               e_ews_message_add_set_item_field_extended_distinguished_tag_boolean (msg, NULL, "Message", 
"Task", 0x811c, FALSE);
+               e_ews_request_add_set_item_field_extended_distinguished_tag_boolean (request, NULL, 
"Message", "Task", 0x811c, FALSE);
        } else if (followup && dueby_tt == (time_t) 0) {
                /* PidLidTaskDueDate */
-               e_ews_message_add_delete_item_field_extended_distinguished_tag (msg, "Task", 0x8105, 
E_EWS_MESSAGE_DATA_TYPE_TIME);
+               e_ews_request_add_delete_item_field_extended_distinguished_tag (request, "Task", 0x8105, 
E_EWS_MESSAGE_DATA_TYPE_TIME);
        }
 }
 gboolean
diff --git a/src/EWS/camel/camel-ews-utils.h b/src/EWS/camel/camel-ews-utils.h
index db0e6a17..067db64f 100644
--- a/src/EWS/camel/camel-ews-utils.h
+++ b/src/EWS/camel/camel-ews-utils.h
@@ -66,9 +66,9 @@ void          camel_ews_utils_sync_updated_items
                                                 CamelFolderChangeInfo *change_info,
                                                 GCancellable *cancellable);
 GSList *       ews_utils_gather_server_user_flags
-                                               (ESoapMessage *msg,
+                                               (ESoapRequest *request,
                                                 CamelMessageInfo *mi);
-void           ews_utils_update_followup_flags (ESoapMessage *msg,
+void           ews_utils_update_followup_flags (ESoapRequest *request,
                                                 CamelMessageInfo *mi);
 gchar *                camel_ews_utils_get_host_name   (CamelSettings *settings);
 gboolean       camel_ews_utils_delete_folders_from_summary_recursive
diff --git a/src/EWS/common/CMakeLists.txt b/src/EWS/common/CMakeLists.txt
index 2622d248..9901b44e 100644
--- a/src/EWS/common/CMakeLists.txt
+++ b/src/EWS/common/CMakeLists.txt
@@ -21,19 +21,17 @@ set(SOURCES
        e-ews-item.h
        e-ews-item-change.c
        e-ews-item-change.h
-       e-ews-message.c
-       e-ews-message.h
        e-ews-notification.c
        e-ews-notification.h
        e-ews-oof-settings.c
        e-ews-query-to-restriction.c
        e-ews-query-to-restriction.h
+       e-ews-request.c
+       e-ews-request.h
        e-oauth2-service-office365.c
        e-oauth2-service-office365.h
-       e-soup-auth-negotiate.c
-       e-soup-auth-negotiate.h
-       e-soap-message.c
-       e-soap-message.h
+       e-soap-request.c
+       e-soap-request.h
        e-soap-response.c
        e-soap-response.h
        e-source-ews-folder.c
diff --git a/src/EWS/common/camel-ews-settings.c b/src/EWS/common/camel-ews-settings.c
index e2cbb8a5..91ca849d 100644
--- a/src/EWS/common/camel-ews-settings.c
+++ b/src/EWS/common/camel-ews-settings.c
@@ -85,19 +85,19 @@ ews_settings_transform_host_url_to_host_cb (GBinding *binding,
 
        host_url = g_value_get_string (host_url_value);
        if (host_url && *host_url) {
-               SoupURI *uri;
+               GUri *uri;
 
-               uri = soup_uri_new (host_url);
+               uri = g_uri_parse (host_url, SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
                if (uri) {
                        const gchar *host;
 
-                       host = soup_uri_get_host (uri);
+                       host = g_uri_get_host (uri);
                        if (!host || !*host)
                                host = "";
 
                        g_value_set_string (host_value, host);
 
-                       soup_uri_free (uri);
+                       g_uri_unref (uri);
                }
        }
 
diff --git a/src/EWS/common/e-ews-calendar-utils.c b/src/EWS/common/e-ews-calendar-utils.c
index f821dc3a..6deda600 100644
--- a/src/EWS/common/e-ews-calendar-utils.c
+++ b/src/EWS/common/e-ews-calendar-utils.c
@@ -9,7 +9,7 @@
 #include <glib/gi18n-lib.h>
 #include <libecal/libecal.h>
 
-#include "e-ews-message.h"
+#include "e-ews-request.h"
 #include "ews-errors.h"
 
 #include "e-ews-calendar-utils.h"
@@ -199,7 +199,7 @@ number_to_weekday (gint num)
 }
 
 static void
-ewscal_add_availability_rrule (ESoapMessage *msg,
+ewscal_add_availability_rrule (ESoapRequest *request,
                                ICalProperty *prop)
 {
        ICalRecurrence *recur = i_cal_property_get_rrule (prop);
@@ -214,39 +214,39 @@ ewscal_add_availability_rrule (ESoapMessage *msg,
 
        /* expected value is 1..5, inclusive */
        snprintf (buffer, 16, "%d", dayorder);
-       e_ews_message_write_string_parameter (msg, "DayOrder", NULL, buffer);
+       e_ews_request_write_string_parameter (request, "DayOrder", NULL, buffer);
 
        snprintf (buffer, 16, "%d", i_cal_recurrence_get_by_month (recur, 0));
-       e_ews_message_write_string_parameter (msg, "Month", NULL, buffer);
+       e_ews_request_write_string_parameter (request, "Month", NULL, buffer);
 
-       e_ews_message_write_string_parameter (msg, "DayOfWeek", NULL, number_to_weekday 
(i_cal_recurrence_day_day_of_week (i_cal_recurrence_get_by_day (recur, 0))));
+       e_ews_request_write_string_parameter (request, "DayOfWeek", NULL, number_to_weekday 
(i_cal_recurrence_day_day_of_week (i_cal_recurrence_get_by_day (recur, 0))));
 
        g_clear_object (&recur);
 }
 
 static void
-ewscal_add_availability_default_timechange (ESoapMessage *msg)
+ewscal_add_availability_default_timechange (ESoapRequest *request)
 {
 
-       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);
+       e_soap_request_start_element (request, "StandardTime", NULL, NULL);
+       e_ews_request_write_string_parameter (request, "Bias", NULL, "0");
+       e_ews_request_write_string_parameter (request, "Time", NULL, "00:00:00");
+       e_ews_request_write_string_parameter (request, "DayOrder", NULL, "0");
+       e_ews_request_write_string_parameter (request, "Month", NULL, "0");
+       e_ews_request_write_string_parameter (request, "DayOfWeek", NULL, "Sunday");
+       e_soap_request_end_element (request);
+
+       e_soap_request_start_element (request, "DaylightTime", NULL, NULL);
+       e_ews_request_write_string_parameter (request, "Bias", NULL, "0");
+       e_ews_request_write_string_parameter (request, "Time", NULL, "00:00:00");
+       e_ews_request_write_string_parameter (request, "DayOrder", NULL, "0");
+       e_ews_request_write_string_parameter (request, "Month", NULL, "0");
+       e_ews_request_write_string_parameter (request, "DayOfWeek", NULL, "Sunday");
+       e_soap_request_end_element (request);
 }
 
 static void
-ewscal_add_availability_timechange (ESoapMessage *msg,
+ewscal_add_availability_timechange (ESoapRequest *request,
                                     ICalComponent *comp,
                                     gint baseoffs)
 {
@@ -261,7 +261,7 @@ ewscal_add_availability_timechange (ESoapMessage *msg,
                utcoffs = -i_cal_property_get_tzoffsetto (prop) / 60;
                utcoffs -= baseoffs;
                snprintf (buffer, 16, "%d", utcoffs);
-               e_ews_message_write_string_parameter (msg, "Bias", NULL, buffer);
+               e_ews_request_write_string_parameter (request, "Bias", NULL, buffer);
                g_object_unref (prop);
        }
 
@@ -269,20 +269,20 @@ ewscal_add_availability_timechange (ESoapMessage *msg,
        if (prop) {
                dtstart = i_cal_property_get_dtstart (prop);
                snprintf (buffer, 16, "%02d:%02d:%02d", i_cal_time_get_hour (dtstart), i_cal_time_get_minute 
(dtstart), i_cal_time_get_second (dtstart));
-               e_ews_message_write_string_parameter (msg, "Time", NULL, buffer);
+               e_ews_request_write_string_parameter (request, "Time", NULL, buffer);
                g_object_unref (dtstart);
                g_object_unref (prop);
        }
 
        prop = i_cal_component_get_first_property (comp, I_CAL_RRULE_PROPERTY);
        if (prop) {
-               ewscal_add_availability_rrule (msg, prop);
+               ewscal_add_availability_rrule (request, prop);
                g_object_unref (prop);
        }
 }
 
 static void
-ewscal_set_availability_timezone (ESoapMessage *msg,
+ewscal_set_availability_timezone (ESoapRequest *request,
                                   ICalTimezone *icaltz)
 {
        ICalComponent *comp;
@@ -304,7 +304,7 @@ ewscal_set_availability_timezone (ESoapMessage *msg,
        }
 
        /*TimeZone is the root element of GetUserAvailabilityRequest*/
-       e_soap_message_start_element (msg, "TimeZone", NULL, NULL);
+       e_soap_request_start_element (request, "TimeZone", NULL, NULL);
 
        /* Fetch the timezone offsets for the standard (or only) zone.
         * Negate it, because Exchange does it backwards */
@@ -326,24 +326,24 @@ ewscal_set_availability_timezone (ESoapMessage *msg,
         * 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);
+       e_ews_request_write_string_parameter (request, "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" */
+               e_soap_request_start_element (request, "StandardTime", NULL, NULL);
+               ewscal_add_availability_timechange (request, xstd, std_utcoffs);
+               e_soap_request_end_element (request); /* "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" */
+               e_soap_request_start_element (request, "DaylightTime", NULL, NULL);
+               ewscal_add_availability_timechange (request, xdaylight, std_utcoffs);
+               e_soap_request_end_element (request); /* "DaylightTime" */
        } else
                /* Set default values*/
-               ewscal_add_availability_default_timechange (msg);
+               ewscal_add_availability_default_timechange (request);
 
-       e_soap_message_end_element (msg); /* "TimeZone" */
+       e_soap_request_end_element (request); /* "TimeZone" */
 
        g_clear_object (&comp);
        g_clear_object (&xstd);
@@ -351,7 +351,7 @@ ewscal_set_availability_timezone (ESoapMessage *msg,
 }
 
 gboolean
-e_ews_cal_utils_prepare_free_busy_request (ESoapMessage *msg,
+e_ews_cal_utils_prepare_free_busy_request (ESoapRequest *request,
                                           gpointer user_data,
                                           GError **error)
 {
@@ -362,44 +362,44 @@ e_ews_cal_utils_prepare_free_busy_request (ESoapMessage *msg,
 
        g_return_val_if_fail (fbdata != NULL, FALSE);
 
-       ewscal_set_availability_timezone (msg, utc_zone);
+       ewscal_set_availability_timezone (request, utc_zone);
 
-       e_soap_message_start_element (msg, "MailboxDataArray", "messages", NULL);
+       e_soap_request_start_element (request, "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_request_start_element (request, "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_soap_request_start_element (request, "Email", NULL, NULL);
+               e_ews_request_write_string_parameter (request, "Address", NULL, mail);
+               e_soap_request_end_element (request); /* "Email" */
 
-               e_ews_message_write_string_parameter (msg, "AttendeeType", NULL, "Required");
-               e_ews_message_write_string_parameter (msg, "ExcludeConflicts", NULL, "false");
+               e_ews_request_write_string_parameter (request, "AttendeeType", NULL, "Required");
+               e_ews_request_write_string_parameter (request, "ExcludeConflicts", NULL, "false");
 
-               e_soap_message_end_element (msg); /* "MailboxData" */
+               e_soap_request_end_element (request); /* "MailboxData" */
        }
 
-       e_soap_message_end_element (msg); /* "MailboxDataArray" */
+       e_soap_request_end_element (request); /* "MailboxDataArray" */
 
-       e_soap_message_start_element (msg, "FreeBusyViewOptions", NULL, NULL);
+       e_soap_request_start_element (request, "FreeBusyViewOptions", NULL, NULL);
 
        t_start = i_cal_time_new_from_timet_with_zone (fbdata->period_start, 0, utc_zone);
        t_end = i_cal_time_new_from_timet_with_zone (fbdata->period_end, 0, utc_zone);
 
-       e_soap_message_start_element (msg, "TimeWindow", NULL, NULL);
-       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_soap_request_start_element (request, "TimeWindow", NULL, NULL);
+       e_ews_cal_utils_set_time (request, "StartTime", t_start, FALSE);
+       e_ews_cal_utils_set_time (request, "EndTime", t_end, FALSE);
+       e_soap_request_end_element (request); /* "TimeWindow" */
 
        g_clear_object (&t_start);
        g_clear_object (&t_end);
 
-       e_ews_message_write_string_parameter (msg, "MergedFreeBusyIntervalInMinutes", NULL, "60");
-       e_ews_message_write_string_parameter (msg, "RequestedView", NULL, "DetailedMerged");
+       e_ews_request_write_string_parameter (request, "MergedFreeBusyIntervalInMinutes", NULL, "60");
+       e_ews_request_write_string_parameter (request, "RequestedView", NULL, "DetailedMerged");
 
-       e_soap_message_end_element (msg); /* "FreeBusyViewOptions" */
+       e_soap_request_end_element (request); /* "FreeBusyViewOptions" */
 
        return TRUE;
 }
@@ -425,7 +425,7 @@ ews_get_configured_icaltimezone (void)
 }
 
 void
-e_ews_cal_utils_set_time (ESoapMessage *msg,
+e_ews_cal_utils_set_time (ESoapRequest *request,
                          const gchar *name,
                          ICalTime *tt,
                          gboolean with_timezone)
@@ -478,7 +478,7 @@ e_ews_cal_utils_set_time (ESoapMessage *msg,
                i_cal_time_get_second (tt),
                tz_ident ? tz_ident : "");
 
-       e_ews_message_write_string_parameter (msg, name, NULL, str);
+       e_ews_request_write_string_parameter (request, name, NULL, str);
 
        g_clear_object (&local_tt);
        g_free (tz_ident);
@@ -1229,13 +1229,13 @@ e_ews_cal_utils_convert_recurrence (ICalComponent *icomp,
 }
 
 static void
-e_ews_cal_utils_write_days_of_week (ESoapMessage *msg,
+e_ews_cal_utils_write_days_of_week (ESoapRequest *request,
                                    guint32 days_of_week)
 {
        GString *value;
        guint32 weekdays, weekenddays;
 
-       g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+       g_return_if_fail (E_IS_SOAP_REQUEST (request));
 
        if (days_of_week == E_EWS_RECURRENCE_DAYS_OF_WEEK_UNKNOWN)
                return;
@@ -1288,21 +1288,21 @@ e_ews_cal_utils_write_days_of_week (ESoapMessage *msg,
        }
 
        if (value->len) {
-               e_soap_message_start_element (msg, "DaysOfWeek", NULL, NULL);
-               e_soap_message_write_string (msg, value->str);
-               e_soap_message_end_element (msg); /* DaysOfWeek */
+               e_soap_request_start_element (request, "DaysOfWeek", NULL, NULL);
+               e_soap_request_write_string (request, value->str);
+               e_soap_request_end_element (request); /* DaysOfWeek */
        }
 
        g_string_free (value, TRUE);
 }
 
 static void
-e_ews_cal_utils_write_day_of_week_index (ESoapMessage *msg,
+e_ews_cal_utils_write_day_of_week_index (ESoapRequest *request,
                                         EEwsRecurrenceDayOfWeekIndex day_of_week_index)
 {
        const gchar *value = NULL;
 
-       g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+       g_return_if_fail (E_IS_SOAP_REQUEST (request));
 
        /* Do not localize, these are values used in XML */
        switch (day_of_week_index) {
@@ -1326,19 +1326,19 @@ e_ews_cal_utils_write_day_of_week_index (ESoapMessage *msg,
        }
 
        if (value) {
-               e_soap_message_start_element (msg, "DayOfWeekIndex", NULL, NULL);
-               e_soap_message_write_string (msg, value);
-               e_soap_message_end_element (msg); /* DayOfWeekIndex */
+               e_soap_request_start_element (request, "DayOfWeekIndex", NULL, NULL);
+               e_soap_request_write_string (request, value);
+               e_soap_request_end_element (request); /* DayOfWeekIndex */
        }
 }
 
 static void
-e_ews_cal_utils_write_month (ESoapMessage *msg,
+e_ews_cal_utils_write_month (ESoapRequest *request,
                             GDateMonth month)
 {
        const gchar *value = NULL;
 
-       g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+       g_return_if_fail (E_IS_SOAP_REQUEST (request));
 
        /* Do not localize, these are values used in XML */
        switch (month) {
@@ -1383,21 +1383,21 @@ e_ews_cal_utils_write_month (ESoapMessage *msg,
        }
 
        if (value) {
-               e_soap_message_start_element (msg, "Month", NULL, NULL);
-               e_soap_message_write_string (msg, value);
-               e_soap_message_end_element (msg); /* Month */
+               e_soap_request_start_element (request, "Month", NULL, NULL);
+               e_soap_request_write_string (request, value);
+               e_soap_request_end_element (request); /* Month */
        }
 }
 
 static void
-e_ews_cal_util_write_utc_date (ESoapMessage *msg,
+e_ews_cal_util_write_utc_date (ESoapRequest *request,
                               const gchar *name,
                               time_t utc_date)
 {
        ICalTime *itt;
        gchar *value;
 
-       g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+       g_return_if_fail (E_IS_SOAP_REQUEST (request));
        g_return_if_fail (name != NULL);
 
        itt = i_cal_time_new_from_timet_with_zone (utc_date, 1, i_cal_timezone_get_utc_timezone ());
@@ -1407,9 +1407,9 @@ e_ews_cal_util_write_utc_date (ESoapMessage *msg,
                i_cal_time_get_day (itt));
        g_clear_object (&itt);
 
-       e_soap_message_start_element (msg, name, NULL, NULL);
-       e_soap_message_write_string (msg, value);
-       e_soap_message_end_element (msg);
+       e_soap_request_start_element (request, name, NULL, NULL);
+       e_soap_request_write_string (request, value);
+       e_soap_request_end_element (request);
 
        g_free (value);
 }
@@ -1417,14 +1417,14 @@ e_ews_cal_util_write_utc_date (ESoapMessage *msg,
 /* Writes 'Recurrence' element into the @msg. Sets the @error only if the RRULE
    cannot be transformed into Recurrence */
 gboolean
-e_ews_cal_utils_set_recurrence (ESoapMessage *msg,
+e_ews_cal_utils_set_recurrence (ESoapRequest *request,
                                ICalComponent *comp,
                                gboolean server_satisfies_2013,
                                GError **error)
 {
        EEwsRecurrence recur;
 
-       g_return_val_if_fail (E_IS_SOAP_MESSAGE (msg), FALSE);
+       g_return_val_if_fail (E_IS_SOAP_REQUEST (request), FALSE);
        g_return_val_if_fail (comp != NULL, FALSE);
 
        memset (&recur, 0, sizeof (EEwsRecurrence));
@@ -1440,52 +1440,52 @@ e_ews_cal_utils_set_recurrence (ESoapMessage *msg,
                return TRUE;
        }
 
-       e_soap_message_start_element (msg, "Recurrence", NULL, NULL);
+       e_soap_request_start_element (request, "Recurrence", NULL, NULL);
 
        switch (recur.type) {
        case E_EWS_RECURRENCE_UNKNOWN:
                g_warn_if_reached ();
                break;
        case E_EWS_RECURRENCE_RELATIVE_YEARLY:
-               e_soap_message_start_element (msg, "RelativeYearlyRecurrence", NULL, NULL);
-               e_ews_cal_utils_write_days_of_week (msg, recur.recur.relative_yearly.days_of_week);
-               e_ews_cal_utils_write_day_of_week_index (msg, recur.recur.relative_yearly.day_of_week_index);
-               e_ews_cal_utils_write_month (msg, recur.recur.relative_yearly.month);
-               e_soap_message_end_element (msg); /* RelativeYearlyRecurrence */
+               e_soap_request_start_element (request, "RelativeYearlyRecurrence", NULL, NULL);
+               e_ews_cal_utils_write_days_of_week (request, recur.recur.relative_yearly.days_of_week);
+               e_ews_cal_utils_write_day_of_week_index (request, 
recur.recur.relative_yearly.day_of_week_index);
+               e_ews_cal_utils_write_month (request, recur.recur.relative_yearly.month);
+               e_soap_request_end_element (request); /* RelativeYearlyRecurrence */
                break;
        case E_EWS_RECURRENCE_ABSOLUTE_YEARLY:
-               e_soap_message_start_element (msg, "AbsoluteYearlyRecurrence", NULL, NULL);
-               e_soap_message_start_element (msg, "DayOfMonth", NULL, NULL);
-               e_soap_message_write_int (msg, recur.recur.absolute_yearly.day_of_month);
-               e_soap_message_end_element (msg); /* DayOfMonth */
-               e_ews_cal_utils_write_month (msg, recur.recur.absolute_yearly.month);
-               e_soap_message_end_element (msg); /* AbsoluteYearlyRecurrence */
+               e_soap_request_start_element (request, "AbsoluteYearlyRecurrence", NULL, NULL);
+               e_soap_request_start_element (request, "DayOfMonth", NULL, NULL);
+               e_soap_request_write_int (request, recur.recur.absolute_yearly.day_of_month);
+               e_soap_request_end_element (request); /* DayOfMonth */
+               e_ews_cal_utils_write_month (request, recur.recur.absolute_yearly.month);
+               e_soap_request_end_element (request); /* AbsoluteYearlyRecurrence */
                break;
        case E_EWS_RECURRENCE_RELATIVE_MONTHLY:
-               e_soap_message_start_element (msg, "RelativeMonthlyRecurrence", NULL, NULL);
-               e_soap_message_start_element (msg, "Interval", NULL, NULL);
-               e_soap_message_write_int (msg, recur.recur.relative_monthly.interval);
-               e_soap_message_end_element (msg); /* Interval */
-               e_ews_cal_utils_write_days_of_week (msg, recur.recur.relative_monthly.days_of_week);
-               e_ews_cal_utils_write_day_of_week_index (msg, recur.recur.relative_monthly.day_of_week_index);
-               e_soap_message_end_element (msg); /* RelativeMonthlyRecurrence */
+               e_soap_request_start_element (request, "RelativeMonthlyRecurrence", NULL, NULL);
+               e_soap_request_start_element (request, "Interval", NULL, NULL);
+               e_soap_request_write_int (request, recur.recur.relative_monthly.interval);
+               e_soap_request_end_element (request); /* Interval */
+               e_ews_cal_utils_write_days_of_week (request, recur.recur.relative_monthly.days_of_week);
+               e_ews_cal_utils_write_day_of_week_index (request, 
recur.recur.relative_monthly.day_of_week_index);
+               e_soap_request_end_element (request); /* RelativeMonthlyRecurrence */
                break;
        case E_EWS_RECURRENCE_ABSOLUTE_MONTHLY:
-               e_soap_message_start_element (msg, "AbsoluteMonthlyRecurrence", NULL, NULL);
-               e_soap_message_start_element (msg, "Interval", NULL, NULL);
-               e_soap_message_write_int (msg, recur.recur.absolute_monthly.interval);
-               e_soap_message_end_element (msg); /* Interval */
-               e_soap_message_start_element (msg, "DayOfMonth", NULL, NULL);
-               e_soap_message_write_int (msg, recur.recur.absolute_monthly.day_of_month);
-               e_soap_message_end_element (msg); /* DayOfMonth */
-               e_soap_message_end_element (msg); /* AbsoluteMonthlyRecurrence */
+               e_soap_request_start_element (request, "AbsoluteMonthlyRecurrence", NULL, NULL);
+               e_soap_request_start_element (request, "Interval", NULL, NULL);
+               e_soap_request_write_int (request, recur.recur.absolute_monthly.interval);
+               e_soap_request_end_element (request); /* Interval */
+               e_soap_request_start_element (request, "DayOfMonth", NULL, NULL);
+               e_soap_request_write_int (request, recur.recur.absolute_monthly.day_of_month);
+               e_soap_request_end_element (request); /* DayOfMonth */
+               e_soap_request_end_element (request); /* AbsoluteMonthlyRecurrence */
                break;
        case E_EWS_RECURRENCE_WEEKLY:
-               e_soap_message_start_element (msg, "WeeklyRecurrence", NULL, NULL);
-               e_soap_message_start_element (msg, "Interval", NULL, NULL);
-               e_soap_message_write_int (msg, recur.recur.weekly.interval);
-               e_soap_message_end_element (msg); /* Interval */
-               e_ews_cal_utils_write_days_of_week (msg, recur.recur.weekly.days_of_week);
+               e_soap_request_start_element (request, "WeeklyRecurrence", NULL, NULL);
+               e_soap_request_start_element (request, "Interval", NULL, NULL);
+               e_soap_request_write_int (request, recur.recur.weekly.interval);
+               e_soap_request_end_element (request); /* Interval */
+               e_ews_cal_utils_write_days_of_week (request, recur.recur.weekly.days_of_week);
                if (server_satisfies_2013) {
                        const gchar *value = NULL;
 
@@ -1516,47 +1516,47 @@ e_ews_cal_utils_set_recurrence (ESoapMessage *msg,
                        }
 
                        if (value) {
-                               e_soap_message_start_element (msg, "FirstDayOfWeek", NULL, NULL);
-                               e_soap_message_write_string (msg, value);
-                               e_soap_message_end_element (msg); /* FirstDayOfWeek */
+                               e_soap_request_start_element (request, "FirstDayOfWeek", NULL, NULL);
+                               e_soap_request_write_string (request, value);
+                               e_soap_request_end_element (request); /* FirstDayOfWeek */
                        }
                }
-               e_soap_message_end_element (msg); /* WeeklyRecurrence */
+               e_soap_request_end_element (request); /* WeeklyRecurrence */
                break;
        case E_EWS_RECURRENCE_DAILY:
-               e_soap_message_start_element (msg, "DailyRecurrence", NULL, NULL);
-               e_soap_message_start_element (msg, "Interval", NULL, NULL);
-               e_soap_message_write_int (msg, recur.recur.interval);
-               e_soap_message_end_element (msg); /* Interval */
-               e_soap_message_end_element (msg); /* DailyRecurrence */
+               e_soap_request_start_element (request, "DailyRecurrence", NULL, NULL);
+               e_soap_request_start_element (request, "Interval", NULL, NULL);
+               e_soap_request_write_int (request, recur.recur.interval);
+               e_soap_request_end_element (request); /* Interval */
+               e_soap_request_end_element (request); /* DailyRecurrence */
                break;
        case E_EWS_RECURRENCE_DAILY_REGENERATION:
-               e_soap_message_start_element (msg, "DailyRegeneration", NULL, NULL);
-               e_soap_message_start_element (msg, "Interval", NULL, NULL);
-               e_soap_message_write_int (msg, recur.recur.interval);
-               e_soap_message_end_element (msg); /* Interval */
-               e_soap_message_end_element (msg); /* DailyRegeneration */
+               e_soap_request_start_element (request, "DailyRegeneration", NULL, NULL);
+               e_soap_request_start_element (request, "Interval", NULL, NULL);
+               e_soap_request_write_int (request, recur.recur.interval);
+               e_soap_request_end_element (request); /* Interval */
+               e_soap_request_end_element (request); /* DailyRegeneration */
                break;
        case E_EWS_RECURRENCE_WEEKLY_REGENERATION:
-               e_soap_message_start_element (msg, "WeeklyRegeneration", NULL, NULL);
-               e_soap_message_start_element (msg, "Interval", NULL, NULL);
-               e_soap_message_write_int (msg, recur.recur.interval);
-               e_soap_message_end_element (msg); /* Interval */
-               e_soap_message_end_element (msg); /* WeeklyRegeneration */
+               e_soap_request_start_element (request, "WeeklyRegeneration", NULL, NULL);
+               e_soap_request_start_element (request, "Interval", NULL, NULL);
+               e_soap_request_write_int (request, recur.recur.interval);
+               e_soap_request_end_element (request); /* Interval */
+               e_soap_request_end_element (request); /* WeeklyRegeneration */
                break;
        case E_EWS_RECURRENCE_MONTHLY_REGENERATION:
-               e_soap_message_start_element (msg, "MonthlyRegeneration", NULL, NULL);
-               e_soap_message_start_element (msg, "Interval", NULL, NULL);
-               e_soap_message_write_int (msg, recur.recur.interval);
-               e_soap_message_end_element (msg); /* Interval */
-               e_soap_message_end_element (msg); /* MonthlyRegeneration */
+               e_soap_request_start_element (request, "MonthlyRegeneration", NULL, NULL);
+               e_soap_request_start_element (request, "Interval", NULL, NULL);
+               e_soap_request_write_int (request, recur.recur.interval);
+               e_soap_request_end_element (request); /* Interval */
+               e_soap_request_end_element (request); /* MonthlyRegeneration */
                break;
        case E_EWS_RECURRENCE_YEARLY_REGENERATION:
-               e_soap_message_start_element (msg, "YearlyRegeneration", NULL, NULL);
-               e_soap_message_start_element (msg, "Interval", NULL, NULL);
-               e_soap_message_write_int (msg, recur.recur.interval);
-               e_soap_message_end_element (msg); /* Interval */
-               e_soap_message_end_element (msg); /* YearlyRegeneration */
+               e_soap_request_start_element (request, "YearlyRegeneration", NULL, NULL);
+               e_soap_request_start_element (request, "Interval", NULL, NULL);
+               e_soap_request_write_int (request, recur.recur.interval);
+               e_soap_request_end_element (request); /* Interval */
+               e_soap_request_end_element (request); /* YearlyRegeneration */
                break;
        }
 
@@ -1565,27 +1565,27 @@ e_ews_cal_utils_set_recurrence (ESoapMessage *msg,
                g_warn_if_reached ();
                break;
        case E_EWS_RECURRENCE_END_NO_END:
-               e_soap_message_start_element (msg, "NoEndRecurrence", NULL, NULL);
-               e_ews_cal_util_write_utc_date (msg, "StartDate", recur.utc_start_date);
-               e_soap_message_end_element (msg); /* NoEndRecurrence */
+               e_soap_request_start_element (request, "NoEndRecurrence", NULL, NULL);
+               e_ews_cal_util_write_utc_date (request, "StartDate", recur.utc_start_date);
+               e_soap_request_end_element (request); /* NoEndRecurrence */
                break;
        case E_EWS_RECURRENCE_END_DATE:
-               e_soap_message_start_element (msg, "EndDateRecurrence", NULL, NULL);
-               e_ews_cal_util_write_utc_date (msg, "StartDate", recur.utc_start_date);
-               e_ews_cal_util_write_utc_date (msg, "EndDate", recur.end.utc_end_date);
-               e_soap_message_end_element (msg); /* EndDateRecurrence */
+               e_soap_request_start_element (request, "EndDateRecurrence", NULL, NULL);
+               e_ews_cal_util_write_utc_date (request, "StartDate", recur.utc_start_date);
+               e_ews_cal_util_write_utc_date (request, "EndDate", recur.end.utc_end_date);
+               e_soap_request_end_element (request); /* EndDateRecurrence */
                break;
        case E_EWS_RECURRENCE_END_NUMBERED:
-               e_soap_message_start_element (msg, "NumberedRecurrence", NULL, NULL);
-               e_ews_cal_util_write_utc_date (msg, "StartDate", recur.utc_start_date);
-               e_soap_message_start_element (msg, "NumberOfOccurrences", NULL, NULL);
-               e_soap_message_write_int (msg, recur.end.number_of_occurrences);
-               e_soap_message_end_element (msg); /* NumberOfOccurrences */
-               e_soap_message_end_element (msg); /* NumberedRecurrence */
+               e_soap_request_start_element (request, "NumberedRecurrence", NULL, NULL);
+               e_ews_cal_util_write_utc_date (request, "StartDate", recur.utc_start_date);
+               e_soap_request_start_element (request, "NumberOfOccurrences", NULL, NULL);
+               e_soap_request_write_int (request, recur.end.number_of_occurrences);
+               e_soap_request_end_element (request); /* NumberOfOccurrences */
+               e_soap_request_end_element (request); /* NumberedRecurrence */
                break;
        }
 
-       e_soap_message_end_element (msg); /* Recurrence */
+       e_soap_request_end_element (request); /* Recurrence */
 
        return TRUE;
 }
diff --git a/src/EWS/common/e-ews-calendar-utils.h b/src/EWS/common/e-ews-calendar-utils.h
index 4b640df9..880cf652 100644
--- a/src/EWS/common/e-ews-calendar-utils.h
+++ b/src/EWS/common/e-ews-calendar-utils.h
@@ -10,7 +10,7 @@
 #include <time.h>
 #include <libecal/libecal.h>
 
-#include "common/e-soap-message.h"
+#include "common/e-soap-request.h"
 #include "common/e-ews-item.h"
 
 G_BEGIN_DECLS
@@ -26,14 +26,14 @@ typedef struct _EEWSFreeBusyData {
 } EEWSFreeBusyData;
 
 gboolean       e_ews_cal_utils_prepare_free_busy_request
-                                               (ESoapMessage *msg,
+                                               (ESoapRequest *request,
                                                 gpointer user_data, /* EEWSFreeBusyData * */
                                                 GError **error);
-void           e_ews_cal_utils_set_time        (ESoapMessage *msg,
+void           e_ews_cal_utils_set_time        (ESoapRequest *request,
                                                 const gchar *name,
                                                 ICalTime *tt,
                                                 gboolean with_timezone);
-gboolean       e_ews_cal_utils_set_recurrence  (ESoapMessage *msg,
+gboolean       e_ews_cal_utils_set_recurrence  (ESoapRequest *request,
                                                 ICalComponent *comp,
                                                 gboolean server_satisfies_2013,
                                                 GError **error);
diff --git a/src/EWS/common/e-ews-camel-common.c b/src/EWS/common/e-ews-camel-common.c
index 16962444..4337e627 100644
--- a/src/EWS/common/e-ews-camel-common.c
+++ b/src/EWS/common/e-ews-camel-common.c
@@ -9,7 +9,7 @@
 #include <glib/gi18n-lib.h>
 #include <glib/gstdio.h>
 
-#include "common/e-ews-message.h"
+#include "common/e-ews-request.h"
 #include "common/e-ews-item-change.h"
 
 #include "e-ews-camel-common.h"
@@ -63,7 +63,7 @@ filter_recipients (CamelMimeMessage *message,
 }
 
 static void
-write_recipients (ESoapMessage *msg,
+write_recipients (ESoapRequest *request,
                  const gchar *elem_name,
                  GHashTable *recips,
                  gboolean is_resend)
@@ -71,23 +71,23 @@ write_recipients (ESoapMessage *msg,
        GHashTableIter iter;
        gpointer key, value;
 
-       g_return_if_fail (msg != NULL);
+       g_return_if_fail (request != NULL);
        g_return_if_fail (elem_name != NULL);
        g_return_if_fail (recips != NULL);
 
        if (!is_resend && !g_hash_table_size (recips))
                return;
 
-       e_soap_message_start_element (msg, elem_name, NULL, NULL);
+       e_soap_request_start_element (request, elem_name, NULL, NULL);
 
        g_hash_table_iter_init (&iter, recips);
        while (g_hash_table_iter_next (&iter, &key, &value)) {
-               e_soap_message_start_element (msg, "Mailbox", NULL, NULL);
-               e_ews_message_write_string_parameter_with_attribute (msg, "EmailAddress", NULL, key, NULL, 
NULL);
-               e_soap_message_end_element (msg); /* Mailbox */
+               e_soap_request_start_element (request, "Mailbox", NULL, NULL);
+               e_ews_request_write_string_parameter_with_attribute (request, "EmailAddress", NULL, key, 
NULL, NULL);
+               e_soap_request_end_element (request); /* Mailbox */
        }
 
-       e_soap_message_end_element (msg); /* elem_name */
+       e_soap_request_end_element (request); /* elem_name */
 }
 
 static gboolean
@@ -101,7 +101,7 @@ is_any_address_filled (CamelInternetAddress *addrs)
 #define MAPI_MSGFLAG_UNSENT    0x08
 
 static gboolean
-create_mime_message_cb (ESoapMessage *msg,
+create_mime_message_cb (ESoapRequest *request,
                         gpointer user_data,
                        GError **error)
 {
@@ -132,10 +132,10 @@ create_mime_message_cb (ESoapMessage *msg,
                }
        }
 
-       e_soap_message_start_element (msg, "Message", NULL, NULL);
-       e_soap_message_start_element (msg, "MimeContent", NULL, NULL);
+       e_soap_request_start_element (request, "Message", NULL, NULL);
+       e_soap_request_start_element (request, "MimeContent", NULL, NULL);
 
-       /* This is horrid. We really need to extend ESoapMessage to allow us
+       /* This is horrid. We really need to extend ESoapRequest to allow us
         * to stream this directly rather than storing it in RAM. Which right
         * now we are doing about four times: the GByteArray in the mem stream,
         * then the base64 version, then the xmlDoc, then the soup request. */
@@ -160,28 +160,27 @@ create_mime_message_cb (ESoapMessage *msg,
        g_object_unref (mem);
        g_object_unref (filtered);
 
-       e_soap_message_write_string (msg, base64);
+       e_soap_request_write_string (request, base64);
        g_free (base64);
 
-       e_soap_message_end_element (msg); /* MimeContent */
+       e_soap_request_end_element (request); /* MimeContent */
 
        content_type = camel_mime_part_get_content_type (CAMEL_MIME_PART (create_data->message));
        if (content_type && camel_content_type_is (content_type, "multipart", "report") &&
            camel_content_type_param (content_type, "report-type") &&
            g_ascii_strcasecmp (camel_content_type_param (content_type, "report-type"), 
"disposition-notification") == 0) {
                /* it's a disposition notification reply, set ItemClass too */
-               e_soap_message_start_element (msg, "ItemClass", NULL, NULL);
-               e_soap_message_write_string (msg, "REPORT.IPM.NOTE.IPNRN");
-               e_soap_message_end_element (msg); /* ItemClass */
+               e_soap_request_start_element (request, "ItemClass", NULL, NULL);
+               e_soap_request_write_string (request, "REPORT.IPM.NOTE.IPNRN");
+               e_soap_request_end_element (request); /* ItemClass */
        }
 
-       e_ews_message_write_string_parameter_with_attribute (
-                       msg,
-                       "Importance",
-                       NULL,
-                       (message_camel_flags & CAMEL_MESSAGE_FLAGGED) != 0 ? "High" : "Normal",
-                       NULL,
-                       NULL);
+       e_ews_request_write_string_parameter_with_attribute (request,
+               "Importance",
+               NULL,
+               (message_camel_flags & CAMEL_MESSAGE_FLAGGED) != 0 ? "High" : "Normal",
+               NULL,
+               NULL);
 
        /* more MAPI crap.  You can't just set the IsDraft property
         * here you have to use the MAPI MSGFLAG_UNSENT extended
@@ -192,14 +191,14 @@ create_mime_message_cb (ESoapMessage *msg,
        if ((message_camel_flags & CAMEL_MESSAGE_DRAFT) != 0)
                msgflag |= MAPI_MSGFLAG_UNSENT;
 
-       e_ews_message_add_extended_property_tag_int (msg, 0x0e07, msgflag);
+       e_ews_request_add_extended_property_tag_int (request, 0x0e07, msgflag);
 
        if ((message_camel_flags & (CAMEL_MESSAGE_FORWARDED | CAMEL_MESSAGE_ANSWERED)) != 0) {
                gint icon;
 
                icon = (message_camel_flags & CAMEL_MESSAGE_ANSWERED) != 0 ? 0x105 : 0x106;
 
-               e_ews_message_add_extended_property_tag_int (msg, 0x1080, icon);
+               e_ews_request_add_extended_property_tag_int (request, 0x1080, icon);
        }
 
        if (create_data->info) {
@@ -221,15 +220,15 @@ create_mime_message_cb (ESoapMessage *msg,
                        dueby_tt = camel_header_decode_date (dueby, NULL);
 
                /* PidTagFlagStatus */
-               e_ews_message_add_extended_property_tag_int (msg, 0x1090,
+               e_ews_request_add_extended_property_tag_int (request, 0x1090,
                        followup ? (completed_tt != (time_t) 0 ? 0x01 /* followupComplete */: 0x02 /* 
followupFlagged */) : 0x0);
 
                if (followup) {
                        /* PidLidFlagRequest */
-                       e_ews_message_add_extended_property_distinguished_tag_string (msg, "Common", 0x8530, 
followup);
+                       e_ews_request_add_extended_property_distinguished_tag_string (request, "Common", 
0x8530, followup);
 
                        /* PidTagToDoItemFlags */
-                       e_ews_message_add_extended_property_tag_int (msg, 0x0e2b, 1);
+                       e_ews_request_add_extended_property_tag_int (request, 0x0e2b, 1);
                }
 
                if (followup && completed_tt != (time_t) 0) {
@@ -237,33 +236,33 @@ create_mime_message_cb (ESoapMessage *msg,
                        completed_tt = completed_tt - (completed_tt % 60);
 
                        /* PidTagFlagCompleteTime */
-                       e_ews_message_add_extended_property_tag_time (msg, 0x1091, completed_tt);
+                       e_ews_request_add_extended_property_tag_time (request, 0x1091, completed_tt);
 
                        /* PidLidTaskDateCompleted */
-                       e_ews_message_add_extended_property_distinguished_tag_time (msg, "Task", 0x810f, 
completed_tt);
+                       e_ews_request_add_extended_property_distinguished_tag_time (request, "Task", 0x810f, 
completed_tt);
 
                        /* PidLidTaskStatus */
-                       e_ews_message_add_extended_property_distinguished_tag_int (msg, "Task", 0x8101, 2);
+                       e_ews_request_add_extended_property_distinguished_tag_int (request, "Task", 0x8101, 
2);
 
                        /* PidLidPercentComplete */
-                       e_ews_message_add_extended_property_distinguished_tag_double (msg, "Task", 0x8102, 
1.0);
+                       e_ews_request_add_extended_property_distinguished_tag_double (request, "Task", 
0x8102, 1.0);
 
                        /* PidLidTaskComplete */
-                       e_ews_message_add_extended_property_distinguished_tag_boolean (msg, "Task", 0x811c, 
TRUE);
+                       e_ews_request_add_extended_property_distinguished_tag_boolean (request, "Task", 
0x811c, TRUE);
                }
 
                if (followup && dueby_tt != (time_t) 0 && completed_tt == (time_t) 0) {
                        /* PidLidTaskStatus */
-                       e_ews_message_add_extended_property_distinguished_tag_int (msg, "Task", 0x8101, 0);
+                       e_ews_request_add_extended_property_distinguished_tag_int (request, "Task", 0x8101, 
0);
 
                        /* PidLidPercentComplete */
-                       e_ews_message_add_extended_property_distinguished_tag_double (msg, "Task", 0x8102, 
0.0);
+                       e_ews_request_add_extended_property_distinguished_tag_double (request, "Task", 
0x8102, 0.0);
 
                        /* PidLidTaskDueDate */
-                       e_ews_message_add_extended_property_distinguished_tag_time (msg, "Task", 0x8105, 
dueby_tt);
+                       e_ews_request_add_extended_property_distinguished_tag_time (request, "Task", 0x8105, 
dueby_tt);
 
                        /* PidLidTaskComplete */
-                       e_ews_message_add_extended_property_distinguished_tag_boolean (msg, "Task", 0x811c, 
FALSE);
+                       e_ews_request_add_extended_property_distinguished_tag_boolean (request, "Task", 
0x811c, FALSE);
                }
        }
 
@@ -272,13 +271,13 @@ create_mime_message_cb (ESoapMessage *msg,
 
                settings = e_ews_connection_ref_settings (create_data->cnc);
                if (settings) {
-                       e_soap_message_start_element (msg, "Sender", NULL, NULL);
+                       e_soap_request_start_element (request, "Sender", NULL, NULL);
 
-                       e_soap_message_start_element (msg, "Mailbox", NULL, NULL);
-                       e_ews_message_write_string_parameter_with_attribute (msg, "EmailAddress", NULL, 
camel_ews_settings_get_email (settings), NULL, NULL);
-                       e_soap_message_end_element (msg); /* Mailbox */
+                       e_soap_request_start_element (request, "Mailbox", NULL, NULL);
+                       e_ews_request_write_string_parameter_with_attribute (request, "EmailAddress", NULL, 
camel_ews_settings_get_email (settings), NULL, NULL);
+                       e_soap_request_end_element (request); /* Mailbox */
 
-                       e_soap_message_end_element (msg); /* Sender */
+                       e_soap_request_end_element (request); /* Sender */
                }
                g_clear_object (&settings);
        }
@@ -297,9 +296,9 @@ create_mime_message_cb (ESoapMessage *msg,
 
                filter_recipients (create_data->message, create_data->recipients, recip_to, recip_cc, 
recip_bcc);
 
-               write_recipients (msg, "ToRecipients", recip_to, is_resend);
-               write_recipients (msg, "CcRecipients", recip_cc, is_resend);
-               write_recipients (msg, "BccRecipients", recip_bcc, is_resend);
+               write_recipients (request, "ToRecipients", recip_to, is_resend);
+               write_recipients (request, "CcRecipients", recip_cc, is_resend);
+               write_recipients (request, "BccRecipients", recip_bcc, is_resend);
 
                g_hash_table_destroy (recip_to);
                g_hash_table_destroy (recip_cc);
@@ -310,27 +309,27 @@ create_mime_message_cb (ESoapMessage *msg,
                const gchar *from_name = NULL, *from_email = NULL;
 
                if (camel_internet_address_get (CAMEL_INTERNET_ADDRESS (create_data->from), 0, &from_name, 
&from_email) && from_email) {
-                       e_soap_message_start_element (msg, "From", NULL, NULL);
+                       e_soap_request_start_element (request, "From", NULL, NULL);
 
-                       e_soap_message_start_element (msg, "Mailbox", NULL, NULL);
+                       e_soap_request_start_element (request, "Mailbox", NULL, NULL);
                        if (from_name && *from_name)
-                               e_ews_message_write_string_parameter_with_attribute (msg, "Name", NULL, 
from_name, NULL, NULL);
-                       e_ews_message_write_string_parameter_with_attribute (msg, "EmailAddress", NULL, 
from_email, NULL, NULL);
-                       e_soap_message_end_element (msg); /* Mailbox */
+                               e_ews_request_write_string_parameter_with_attribute (request, "Name", NULL, 
from_name, NULL, NULL);
+                       e_ews_request_write_string_parameter_with_attribute (request, "EmailAddress", NULL, 
from_email, NULL, NULL);
+                       e_soap_request_end_element (request); /* Mailbox */
 
-                       e_soap_message_end_element (msg); /* From */
+                       e_soap_request_end_element (request); /* From */
                }
        }
 
-       e_ews_message_write_string_parameter_with_attribute (
-                       msg,
+       e_ews_request_write_string_parameter_with_attribute (
+                       request,
                        "IsRead",
                        NULL,
                        (message_camel_flags & CAMEL_MESSAGE_SEEN) != 0 ? "true" : "false",
                        NULL,
                        NULL);
 
-       e_soap_message_end_element (msg); /* Message */
+       e_soap_request_end_element (request); /* Message */
 
        g_free (create_data);
 
diff --git a/src/EWS/common/e-ews-connection-utils.c b/src/EWS/common/e-ews-connection-utils.c
index ba548774..e8fad0da 100644
--- a/src/EWS/common/e-ews-connection-utils.c
+++ b/src/EWS/common/e-ews-connection-utils.c
@@ -13,9 +13,30 @@
 #include <glib/gstdio.h>
 
 #include "e-ews-connection-utils.h"
-#include "e-soup-auth-negotiate.h"
 #include "camel-ews-settings.h"
 
+void
+e_ews_connection_utils_set_user_agent_header (SoupMessage *message,
+                                             CamelEwsSettings *settings)
+{
+       g_return_if_fail (SOUP_IS_MESSAGE (message));
+       g_return_if_fail (CAMEL_IS_EWS_SETTINGS (settings));
+
+       if (camel_ews_settings_get_override_user_agent (settings)) {
+               gchar *user_agent;
+
+               user_agent = camel_ews_settings_dup_user_agent (settings);
+
+               if (user_agent && *user_agent) {
+                       soup_message_headers_replace (soup_message_get_request_headers (message), 
"User-Agent", user_agent);
+               }
+
+               g_free (user_agent);
+       } else {
+               soup_message_headers_replace (soup_message_get_request_headers (message), "User-Agent", 
"Evolution/" VERSION);
+       }
+}
+
 static gpointer
 ews_unref_in_thread_func (gpointer data)
 {
@@ -195,13 +216,19 @@ e_ews_connection_utils_check_x_ms_credential_headers (SoupMessage *message,
                                                      gboolean *out_expired,
                                                      gchar **out_service_url)
 {
+       SoupMessageHeaders *response_headers;
        gboolean any_found = FALSE;
        const gchar *header;
 
-       if (!message || !message->response_headers)
+       if (!message)
+               return FALSE;
+
+       response_headers = soup_message_get_response_headers (message);
+
+       if (!response_headers)
                return FALSE;
 
-       header = soup_message_headers_get_list (message->response_headers, 
"X-MS-Credential-Service-CredExpired");
+       header = soup_message_headers_get_list (response_headers, "X-MS-Credential-Service-CredExpired");
        if (header && g_ascii_strcasecmp (header, "true") == 0) {
                any_found = TRUE;
 
@@ -209,7 +236,7 @@ e_ews_connection_utils_check_x_ms_credential_headers (SoupMessage *message,
                        *out_expired = TRUE;
        }
 
-       header = soup_message_headers_get_list (message->response_headers, "X-MS-Credentials-Expire");
+       header = soup_message_headers_get_list (response_headers, "X-MS-Credentials-Expire");
        if (header) {
                gint in_days;
 
@@ -223,7 +250,7 @@ e_ews_connection_utils_check_x_ms_credential_headers (SoupMessage *message,
        }
 
        if (any_found && out_service_url) {
-               header = soup_message_headers_get_list (message->response_headers, 
"X-MS-Credential-Service-Url");
+               header = soup_message_headers_get_list (response_headers, "X-MS-Credential-Service-Url");
 
                *out_service_url = g_strdup (header);
        }
@@ -240,7 +267,7 @@ e_ews_connection_utils_prepare_auth_method (SoupSession *soup_session,
         * enabled, which is the default configuration. It's a useful fallback
         * which people may be relying on. */
        if (auth_method == EWS_AUTH_TYPE_GSSAPI) {
-               soup_session_add_feature_by_type (soup_session, E_SOUP_TYPE_AUTH_NEGOTIATE);
+               soup_session_add_feature_by_type (soup_session, SOUP_TYPE_AUTH_NEGOTIATE);
                soup_session_remove_feature_by_type (soup_session, SOUP_TYPE_AUTH_BASIC);
        } else if (auth_method == EWS_AUTH_TYPE_OAUTH2) {
                soup_session_add_feature_by_type (soup_session, E_TYPE_SOUP_AUTH_BEARER);
@@ -249,303 +276,3 @@ e_ews_connection_utils_prepare_auth_method (SoupSession *soup_session,
                soup_session_add_feature_by_type (soup_session, SOUP_TYPE_AUTH_NTLM);
        }
 }
-
-static void
-ews_connection_utils_ensure_bearer_auth_usage (SoupSession *session,
-                                              SoupMessage *message,
-                                              ESoupAuthBearer *bearer)
-{
-       SoupAuthManager *auth_manager;
-       SoupSessionFeature *feature;
-       SoupURI *soup_uri;
-
-       g_return_if_fail (SOUP_IS_SESSION (session));
-
-       /* Preload the SoupAuthManager with a valid "Bearer" token
-        * when using OAuth 2.0. This avoids an extra unauthorized
-        * HTTP round-trip, which apparently Google doesn't like. */
-
-       feature = soup_session_get_feature (SOUP_SESSION (session), SOUP_TYPE_AUTH_MANAGER);
-
-       if (!soup_session_feature_has_feature (feature, E_TYPE_SOUP_AUTH_BEARER)) {
-               /* Add the "Bearer" auth type to support OAuth 2.0. */
-               soup_session_feature_add_feature (feature, E_TYPE_SOUP_AUTH_BEARER);
-       }
-
-       soup_uri = message ? soup_message_get_uri (message) : NULL;
-       if (soup_uri && soup_uri->host && *soup_uri->host) {
-               soup_uri = soup_uri_copy_host (soup_uri);
-       } else {
-               soup_uri = NULL;
-       }
-
-       g_return_if_fail (soup_uri != NULL);
-
-       auth_manager = SOUP_AUTH_MANAGER (feature);
-
-       /* This will make sure the 'bearer' is used regardless of the current 'auth_manager' state.
-          See https://gitlab.gnome.org/GNOME/libsoup/-/issues/196 for more information. */
-       soup_auth_manager_clear_cached_credentials (auth_manager);
-       soup_auth_manager_use_auth (auth_manager, soup_uri, SOUP_AUTH (bearer));
-
-       soup_uri_free (soup_uri);
-}
-
-static gboolean
-ews_connection_utils_setup_bearer_auth (EEwsConnection *cnc,
-                                       SoupSession *session,
-                                       SoupMessage *message,
-                                       gboolean is_in_authenticate_handler,
-                                       ESoupAuthBearer *bearer,
-                                       GCancellable *cancellable,
-                                       GError **error)
-{
-       ESource *source;
-       gchar *access_token = NULL;
-       gint expires_in_seconds = -1;
-       gboolean success = FALSE;
-
-       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
-       g_return_val_if_fail (E_IS_SOUP_AUTH_BEARER (bearer), FALSE);
-
-       source = e_ews_connection_get_source (cnc);
-
-       success = e_source_get_oauth2_access_token_sync (source, cancellable,
-               &access_token, &expires_in_seconds, error);
-
-       if (success) {
-               e_soup_auth_bearer_set_access_token (bearer, access_token, expires_in_seconds);
-
-               if (!is_in_authenticate_handler) {
-                       if (session)
-                               g_object_ref (session);
-                       else
-                               session = e_ews_connection_ref_soup_session (cnc);
-
-                       ews_connection_utils_ensure_bearer_auth_usage (session, message, bearer);
-
-                       g_clear_object (&session);
-               }
-       }
-
-       g_free (access_token);
-
-       return success;
-}
-
-static gboolean
-ews_connection_utils_maybe_prepare_bearer_auth (EEwsConnection *cnc,
-                                               SoupSession *session,
-                                               SoupMessage *message,
-                                               GCancellable *cancellable)
-{
-       ESource *source;
-       ESoupAuthBearer *using_bearer_auth;
-       gchar *auth_method = NULL;
-       gboolean success;
-       GError *local_error = NULL;
-
-       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
-
-       source = e_ews_connection_get_source (cnc);
-       if (!source)
-               return TRUE;
-
-       if (e_source_has_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION)) {
-               ESourceAuthentication *extension;
-
-               extension = e_source_get_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION);
-               auth_method = e_source_authentication_dup_method (extension);
-       } else {
-               CamelEwsSettings *ews_settings;
-
-               ews_settings = e_ews_connection_ref_settings (cnc);
-               if (ews_settings) {
-                       if (camel_ews_settings_get_auth_mechanism (ews_settings) == EWS_AUTH_TYPE_OAUTH2)
-                               auth_method = g_strdup ("OAuth2");
-
-                       g_object_unref (ews_settings);
-               }
-
-               if (!auth_method)
-                       return TRUE;
-       }
-
-       if (g_strcmp0 (auth_method, "OAuth2") != 0 &&
-           g_strcmp0 (auth_method, "Office365") != 0 &&
-           !e_oauth2_services_is_oauth2_alias_static (auth_method)) {
-               g_free (auth_method);
-               return TRUE;
-       }
-
-       g_free (auth_method);
-
-       using_bearer_auth = e_ews_connection_ref_bearer_auth (cnc);
-       if (using_bearer_auth) {
-               success = ews_connection_utils_setup_bearer_auth (cnc, session, message, FALSE, 
using_bearer_auth, cancellable, &local_error);
-               g_clear_object (&using_bearer_auth);
-       } else {
-               SoupAuth *soup_auth;
-               SoupURI *soup_uri;
-
-               soup_uri = message ? soup_message_get_uri (message) : NULL;
-               if (soup_uri && soup_uri->host && *soup_uri->host) {
-                       soup_uri = soup_uri_copy_host (soup_uri);
-               } else {
-                       soup_uri = NULL;
-               }
-
-               g_warn_if_fail (soup_uri != NULL);
-
-               if (!soup_uri) {
-                       soup_message_set_status_full (message, SOUP_STATUS_MALFORMED, "Cannot get host from 
message");
-                       return FALSE;
-               }
-
-               soup_auth = g_object_new (E_TYPE_SOUP_AUTH_BEARER, SOUP_AUTH_HOST, soup_uri->host, NULL);
-
-               success = ews_connection_utils_setup_bearer_auth (cnc, session, message, FALSE, 
E_SOUP_AUTH_BEARER (soup_auth), cancellable, &local_error);
-               if (success)
-                       e_ews_connection_set_bearer_auth (cnc, E_SOUP_AUTH_BEARER (soup_auth));
-
-               g_object_unref (soup_auth);
-               soup_uri_free (soup_uri);
-       }
-
-       if (!success) {
-               if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-                       soup_message_set_status (message, SOUP_STATUS_CANCELLED);
-               else if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED) ||
-                        g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
-                       soup_message_set_status_full (message, SOUP_STATUS_UNAUTHORIZED, 
local_error->message);
-               else
-                       soup_message_set_status_full (message, SOUP_STATUS_MALFORMED, local_error ? 
local_error->message : _("Unknown error"));
-       }
-
-       g_clear_error (&local_error);
-
-       return success;
-}
-
-/* Callback implementation for SoupSession::authenticate */
-void
-e_ews_connection_utils_authenticate (EEwsConnection *cnc,
-                                    SoupSession *session,
-                                    SoupMessage *msg,
-                                    SoupAuth *auth,
-                                    gboolean retrying)
-{
-       CamelNetworkSettings *network_settings;
-       ESoupAuthBearer *using_bearer_auth;
-       gchar *user, *password, *service_url = NULL;
-       gboolean expired = FALSE;
-
-       g_return_if_fail (cnc != NULL);
-
-       using_bearer_auth = e_ews_connection_ref_bearer_auth (cnc);
-
-       if (E_IS_SOUP_AUTH_BEARER (auth)) {
-               g_object_ref (auth);
-               g_warn_if_fail ((gpointer) using_bearer_auth == (gpointer) auth);
-
-               g_clear_object (&using_bearer_auth);
-               using_bearer_auth = E_SOUP_AUTH_BEARER (auth);
-
-               e_ews_connection_set_bearer_auth (cnc, using_bearer_auth);
-       }
-
-       if (retrying)
-               e_ews_connection_set_password (cnc, NULL);
-
-       if (using_bearer_auth) {
-               GError *local_error = NULL;
-
-               ews_connection_utils_setup_bearer_auth (cnc, session, msg, TRUE, E_SOUP_AUTH_BEARER (auth), 
NULL, &local_error);
-
-               if (local_error)
-                       soup_message_set_status_full (msg, SOUP_STATUS_MALFORMED, local_error->message);
-
-               g_object_unref (using_bearer_auth);
-               g_clear_error (&local_error);
-
-               return;
-       }
-
-       if (e_ews_connection_utils_check_x_ms_credential_headers (msg, NULL, &expired, &service_url) && 
expired) {
-               GError *local_error = NULL;
-
-               e_ews_connection_utils_expired_password_to_error (service_url, &local_error);
-
-               if (local_error)
-                       soup_message_set_status_full (msg, SOUP_STATUS_MALFORMED, local_error->message);
-
-               g_clear_error (&local_error);
-               g_free (service_url);
-
-               return;
-       }
-
-       g_free (service_url);
-
-       network_settings = CAMEL_NETWORK_SETTINGS (e_ews_connection_ref_settings (cnc));
-       user = camel_network_settings_dup_user (network_settings);
-
-       password = e_ews_connection_dup_password (cnc);
-       if (password != NULL) {
-               soup_auth_authenticate (auth, user, password);
-       } else {
-               /* The NTLM implementation in libsoup doesn't cope very well
-                * with recovering from authentication failures (bug 703181).
-                * So cancel the message now while it's in-flight, and we'll
-                * get a shiny new connection for the next attempt. */
-               const gchar *scheme = soup_auth_get_scheme_name (auth);
-
-               if (!g_ascii_strcasecmp(scheme, "NTLM")) {
-                       soup_session_cancel_message (session, msg, SOUP_STATUS_UNAUTHORIZED);
-               }
-       }
-
-       g_clear_object (&network_settings);
-       g_free (password);
-       g_free (user);
-}
-
-/* Returns whether succeeded */
-gboolean
-e_ews_connection_utils_prepare_message (EEwsConnection *cnc,
-                                       SoupSession *session,
-                                       SoupMessage *message,
-                                       GCancellable *cancellable)
-{
-       ESoupAuthBearer *using_bearer_auth;
-       ESource *source;
-       GError *local_error = NULL;
-
-       source = e_ews_connection_get_source (cnc);
-       if (source)
-               e_soup_ssl_trust_connect (message, source);
-
-       if (!ews_connection_utils_maybe_prepare_bearer_auth (cnc, session, message, cancellable))
-               return FALSE;
-
-       using_bearer_auth = e_ews_connection_ref_bearer_auth (cnc);
-
-       if (using_bearer_auth &&
-           e_soup_auth_bearer_is_expired (using_bearer_auth) &&
-           !ews_connection_utils_setup_bearer_auth (cnc, session, message, FALSE, using_bearer_auth, 
cancellable, &local_error)) {
-               if (local_error) {
-                       soup_message_set_status_full (message, SOUP_STATUS_BAD_REQUEST, local_error->message);
-                       g_clear_error (&local_error);
-               } else {
-                       soup_message_set_status (message, SOUP_STATUS_BAD_REQUEST);
-               }
-
-               g_object_unref (using_bearer_auth);
-
-               return FALSE;
-       }
-
-       g_clear_object (&using_bearer_auth);
-
-       return TRUE;
-}
diff --git a/src/EWS/common/e-ews-connection-utils.h b/src/EWS/common/e-ews-connection-utils.h
index 95deb9f2..d2365d14 100644
--- a/src/EWS/common/e-ews-connection-utils.h
+++ b/src/EWS/common/e-ews-connection-utils.h
@@ -15,6 +15,9 @@ G_BEGIN_DECLS
 #define E_EWS_CONNECTION_UTILS_CHECK_ELEMENT(element_name, expected_name) \
        (e_ews_connection_utils_check_element (G_STRFUNC, (element_name), (expected_name)))
 
+void           e_ews_connection_utils_set_user_agent_header
+                                                       (SoupMessage *message,
+                                                        CamelEwsSettings *settings);
 void           e_ews_connection_utils_unref_in_thread  (gpointer object);
 gboolean       e_ews_connection_utils_check_element    (const gchar *function_name,
                                                         const gchar *element_name,
@@ -35,15 +38,6 @@ gboolean     e_ews_connection_utils_check_x_ms_credential_headers
 void           e_ews_connection_utils_prepare_auth_method
                                                        (SoupSession *soup_session,
                                                         EwsAuthType auth_method);
-void           e_ews_connection_utils_authenticate     (EEwsConnection *cnc,
-                                                        SoupSession *session,
-                                                        SoupMessage *msg,
-                                                        SoupAuth *auth,
-                                                        gboolean retrying);
-gboolean       e_ews_connection_utils_prepare_message  (EEwsConnection *cnc,
-                                                        SoupSession *session,
-                                                        SoupMessage *message,
-                                                        GCancellable *cancellable);
 
 G_END_DECLS
 
diff --git a/src/EWS/common/e-ews-connection.c b/src/EWS/common/e-ews-connection.c
index f7c26435..690831b2 100644
--- a/src/EWS/common/e-ews-connection.c
+++ b/src/EWS/common/e-ews-connection.c
@@ -23,47 +23,45 @@
 
 #include "e-ews-connection.h"
 #include "e-ews-connection-utils.h"
-#include "e-ews-message.h"
+#include "e-ews-request.h"
 #include "e-ews-item-change.h"
 #include "e-ews-debug.h"
 #include "e-ews-notification.h"
+#include "e-ews-oof-settings.h"
 
-#define d(x) x
+/* A chunk size limit when moving items in chunks. */
+#define EWS_MOVE_ITEMS_CHUNK_SIZE 500
+
+/* For network stream reading */
+#define BUFFER_SIZE 16384
 
 #define EWS_RETRY_IO_ERROR_SECONDS 3
 #define EWS_RETRY_AUTH_ERROR_SECONDS 0.1
 
-/* A chunk size limit when moving items in chunks. */
-#define EWS_MOVE_ITEMS_CHUNK_SIZE 500
-
 #define QUEUE_LOCK(x) (g_rec_mutex_lock(&(x)->priv->queue_lock))
 #define QUEUE_UNLOCK(x) (g_rec_mutex_unlock(&(x)->priv->queue_lock))
 
 #define NOTIFICATION_LOCK(x) (g_mutex_lock(&(x)->priv->notification_lock))
 #define NOTIFICATION_UNLOCK(x) (g_mutex_unlock(&(x)->priv->notification_lock))
 
-struct _EwsNode;
 static GMutex connecting;
 static GHashTable *loaded_connections_permissions = NULL;
-static gint comp_func (gconstpointer a, gconstpointer b);
 
-static void ews_response_cb (SoupSession *session, SoupMessage *msg, gpointer data);
-
-static void    ews_connection_authenticate     (SoupSession *sess,
-                                                SoupMessage *msg,
-                                                SoupAuth *auth,
-                                                gboolean retrying,
-                                                gpointer data);
+struct _EEwsSoupThreadData {
+       GMutex mutex;
+       GCond cond;
+       GMainContext *main_context;
+       GMainLoop *main_loop;
+       SoupSession *session;
+       GThread *thread;
+};
 
 /* Connection APIS */
 
 struct _EEwsConnectionPrivate {
        ESource *source;
-       ESoupAuthBearer *bearer_auth;
-       SoupSession *soup_session;
-       GThread *soup_thread;
-       GMainLoop *soup_loop;
-       GMainContext *soup_context;
+       struct _EEwsSoupThreadData soup;
+
        GProxyResolver *proxy_resolver;
        EEwsNotification *notification;
        guint notification_delay_id;
@@ -76,7 +74,6 @@ struct _EEwsConnectionPrivate {
        gchar *hash_key;
 
        gchar *uri;
-       gchar *password;
        gchar *email;
        gchar *impersonate_user;
 
@@ -98,12 +95,12 @@ struct _EEwsConnectionPrivate {
        /* Set to TRUE when this connection had been disconnected and cannot be used anymore */
        gboolean disconnected_flag;
 
-       /* Do that before a request is sent, rather than on request end, to avoid deadlock in libsoup */
-       gboolean clear_cached_credentials;
-
        gboolean ssl_info_set;
        gchar *ssl_certificate_pem;
        GTlsCertificateFlags ssl_certificate_errors;
+
+       ENamedParameters *credentials;
+       gboolean credentials_changed;
 };
 
 enum {
@@ -126,43 +123,8 @@ static guint signals[LAST_SIGNAL];
 
 static guint notification_key = 1;
 
-typedef struct _EwsNode EwsNode;
-typedef struct _EwsAsyncData EwsAsyncData;
-typedef struct _EwsEventsAsyncData EwsEventsAsyncData;
 typedef struct _EwsUrls EwsUrls;
 
-struct _EwsAsyncData {
-       GSList *items_created;
-       GSList *items_updated;
-       GSList *items_deleted;
-       GSList *tzds; /* EEwsCalendarTimeZoneDefinition */
-
-       gint total_items;
-       const gchar *directory;
-       GSList *items;
-       EwsPhotoAttachmentInfo *photo;
-       gchar *sync_state;
-       gboolean includes_last_item;
-       EwsDelegateDeliver deliver_to;
-       EEwsFolderType folder_type;
-       EEwsConnection *cnc;
-       gchar *custom_data; /* Can be re-used by operations, will be freed with g_free() */
-};
-
-struct _EwsNode {
-       ESoapMessage *msg;
-       EEwsConnection *cnc;
-       GSimpleAsyncResult *simple;
-
-       gint pri;                /* the command priority */
-       EEwsResponseCallback cb;
-
-       GCancellable *cancellable;
-       gulong cancel_handler_id;
-
-       gboolean retrying_after_network_error;
-};
-
 struct _EwsUrls {
        xmlChar *as_url;
        xmlChar *oab_url;
@@ -175,1700 +137,856 @@ struct _EwsUrls {
 
 G_DEFINE_TYPE_WITH_PRIVATE (EEwsConnection, e_ews_connection, G_TYPE_OBJECT)
 
-static guint
-ews_connection_get_concurrent_connections (EEwsConnection *cnc)
+/*
+ * e_ews_debug_handler:
+ *
+ * GLib debug message handler, which is passed all messages from g_debug() calls,
+ * and decides whether to print them.
+ */
+static void
+e_ews_debug_handler (const gchar *log_domain,
+                    GLogLevelFlags log_level,
+                    const gchar *message,
+                    gpointer user_data)
 {
-       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), 1);
-
-       return cnc->priv->concurrent_connections;
+       if (e_ews_debug_get_log_level () >= 4)
+               g_log_default_handler (log_domain, log_level, message, NULL);
 }
 
+/*
+ * e_ews_soup_log_print:
+ *
+ * Log printer for the libsoup logging functionality, which just marshal all soup log
+ * output to the standard GLib logging framework (and thus to debug_handler(), above).
+ */
 static void
-ews_connection_set_concurrent_connections (EEwsConnection *cnc,
-                                          guint concurrent_connections)
+e_ews_soup_log_printer (SoupLogger *logger,
+                       SoupLoggerLogLevel level,
+                       char direction,
+                       const gchar *data,
+                       gpointer user_data)
 {
-       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
+       g_debug ("%c %s", direction, e_ews_debug_redact_headers (direction, data));
+}
 
-       concurrent_connections = CLAMP (
-               concurrent_connections,
-               MIN_CONCURRENT_CONNECTIONS,
-               MAX_CONCURRENT_CONNECTIONS);
+static ESoupSession *
+e_ews_connection_create_soup_session (EEwsConnection *cnc)
+{
+       ESoupSession *session;
+       gint log_level;
 
-       if (cnc->priv->concurrent_connections == concurrent_connections)
-               return;
+       session = g_object_new (E_TYPE_SOUP_SESSION,
+               "source", cnc->priv->source,
+               "timeout", 90,
+               "max-conns", cnc->priv->concurrent_connections,
+               "max-conns-per-host", cnc->priv->concurrent_connections,
+               NULL);
 
-       cnc->priv->concurrent_connections = concurrent_connections;
+       e_binding_bind_property (
+               cnc->priv->settings, "timeout",
+               session, "timeout",
+               G_BINDING_SYNC_CREATE);
 
-       if (cnc->priv->soup_session) {
-               g_object_set (G_OBJECT (cnc->priv->soup_session),
-                       SOUP_SESSION_MAX_CONNS, concurrent_connections,
-                       SOUP_SESSION_MAX_CONNS_PER_HOST, concurrent_connections,
-                       NULL);
+       e_binding_bind_property (
+               cnc, "proxy-resolver",
+               session, "proxy-resolver",
+               G_BINDING_SYNC_CREATE);
+
+       log_level = e_ews_debug_get_log_level ();
+
+       if (log_level >= 1) {
+               SoupLogger *logger;
+
+               logger = soup_logger_new (log_level == 1 ? SOUP_LOGGER_LOG_HEADERS : SOUP_LOGGER_LOG_BODY);
+
+               if (log_level >= 4)
+                       soup_logger_set_printer (logger, e_ews_soup_log_printer, NULL, NULL);
+               else if (log_level == 2)
+                       soup_logger_set_printer (logger, e_ews_debug_soup_log_printer_stdout, NULL, NULL);
+
+               soup_session_add_feature (SOUP_SESSION (session), SOUP_SESSION_FEATURE (logger));
+
+               g_object_unref (logger);
        }
 
-       g_object_notify (G_OBJECT (cnc), "concurrent-connections");
+       soup_session_add_feature_by_type (SOUP_SESSION (session), SOUP_TYPE_COOKIE_JAR);
+
+       return session;
 }
 
-GQuark
-ews_connection_error_quark (void)
+static gpointer
+e_ews_soup_worker_thread (gpointer user_data)
 {
-       static GQuark quark = 0;
+       EEwsConnection *cnc = user_data;
+       CamelEwsSettings *settings;
 
-       if (G_UNLIKELY (quark == 0)) {
-               const gchar *string = "ews-connection-error-quark";
-               quark = g_quark_from_static_string (string);
-       }
+       g_warn_if_fail (cnc->priv->soup.session == NULL);
 
-       return quark;
+       settings = e_ews_connection_ref_settings (cnc);
+
+       g_main_context_push_thread_default (cnc->priv->soup.main_context);
+       g_mutex_lock (&cnc->priv->soup.mutex);
+       cnc->priv->soup.session = SOUP_SESSION (e_ews_connection_create_soup_session (cnc));
+
+       e_ews_connection_utils_prepare_auth_method (cnc->priv->soup.session,
+               camel_ews_settings_get_auth_mechanism (settings));
+
+       g_cond_broadcast (&cnc->priv->soup.cond);
+       g_mutex_unlock (&cnc->priv->soup.mutex);
+
+       g_clear_object (&settings);
+
+       g_main_loop_run (cnc->priv->soup.main_loop);
+
+       soup_session_abort (cnc->priv->soup.session);
+       g_clear_object (&cnc->priv->soup.session);
+
+       g_main_context_pop_thread_default (cnc->priv->soup.main_context);
+
+       return NULL;
 }
 
+typedef struct _ProcessData {
+       GMutex mutex;
+       GCond cond;
+       gboolean done;
+       EEwsConnection *cnc;
+       SoupMessage *message;
+       gpointer prepare_data;
+       GCancellable *cancellable;
+       GInputStream *input_stream;
+       GError *error;
+       gchar **out_certificate_pem;
+       GTlsCertificateFlags *out_certificate_errors;
+} ProcessData;
+
 static void
-async_data_free (EwsAsyncData *async_data)
+e_ews_connection_process_request_ready_cb (GObject *source_object,
+                                          GAsyncResult *result,
+                                          gpointer user_data)
 {
-       g_free (async_data->custom_data);
-       g_slice_free (EwsAsyncData, async_data);
-}
+       ProcessData *pd = user_data;
 
-EEwsNotificationEvent *
-e_ews_notification_event_new (void)
-{
-       return g_new0 (EEwsNotificationEvent, 1);
+       g_mutex_lock (&pd->mutex);
+       pd->input_stream = e_soup_session_send_message_finish (E_SOUP_SESSION (source_object), result, 
pd->out_certificate_pem, pd->out_certificate_errors, &pd->error);
+       pd->done = TRUE;
+       g_cond_signal (&pd->cond);
+       g_mutex_unlock (&pd->mutex);
 }
 
-void
-e_ews_notification_event_free (EEwsNotificationEvent *event)
+static gboolean
+e_ews_connection_process_request_run_cb (gpointer user_data)
 {
-       if (event != NULL) {
-               g_free (event->folder_id);
-               g_free (event->old_folder_id);
-               g_free (event);
+       ProcessData *pd = user_data;
+
+       if (pd->cnc->priv->soup.session) {
+               e_soup_session_send_message (E_SOUP_SESSION (pd->cnc->priv->soup.session), pd->message, 
G_PRIORITY_DEFAULT,
+                       pd->prepare_data, pd->cancellable, e_ews_connection_process_request_ready_cb, pd);
+       } else {
+               g_mutex_lock (&pd->mutex);
+               g_set_error_literal (&pd->error, G_IO_ERROR, G_IO_ERROR_FAILED, "SoupSession missing");
+               pd->done = TRUE;
+               g_cond_signal (&pd->cond);
+               g_mutex_unlock (&pd->mutex);
        }
+
+       return FALSE;
 }
 
-EEwsCalendarTo *
-e_ews_calendar_to_new (void)
+static GInputStream *
+e_ews_connection_process_request_sync (EEwsConnection *cnc,
+                                      ESoapRequest *request,
+                                      SoupMessage **out_message,
+                                      gchar **out_certificate_pem,
+                                      GTlsCertificateFlags *out_certificate_errors,
+                                      GCancellable *cancellable,
+                                      GError **error)
 {
-       return g_new0 (EEwsCalendarTo, 1);
-}
+       ProcessData pd;
+       const gchar *persistent_auth;
+       CamelEwsSettings *settings;
+       GSource *source;
 
-void
-e_ews_calendar_to_free (EEwsCalendarTo *to) {
-       if (to != NULL) {
-               g_free (to->kind);
-               g_free (to->value);
-               g_free (to);
-       }
-}
+       g_return_val_if_fail (E_IS_SOAP_REQUEST (request), NULL);
+       g_return_val_if_fail (out_message != NULL, NULL);
 
-EEwsCalendarAbsoluteDateTransition *
-e_ews_calendar_absolute_date_transition_new (void)
-{
-       return g_new0 (EEwsCalendarAbsoluteDateTransition, 1);
-}
+       *out_message = NULL;
 
-void
-e_ews_calendar_absolute_date_transition_free (EEwsCalendarAbsoluteDateTransition *adt)
-{
-       if (adt != NULL) {
-               e_ews_calendar_to_free (adt->to);
-               g_free (adt->date_time);
-               g_free (adt);
+       settings = e_ews_connection_ref_settings (cnc);
+
+       g_mutex_lock (&cnc->priv->soup.mutex);
+       if (!cnc->priv->soup.thread) {
+               g_mutex_lock (&cnc->priv->property_lock);
+               cnc->priv->credentials_changed = TRUE;
+               g_mutex_unlock (&cnc->priv->property_lock);
+               cnc->priv->soup.thread = g_thread_new ("e_ews_soup_worker_thread", e_ews_soup_worker_thread, 
cnc);
        }
-}
+       while (!cnc->priv->soup.session) {
+               g_cond_wait (&cnc->priv->soup.cond, &cnc->priv->soup.mutex);
+       }
+       g_mutex_unlock (&cnc->priv->soup.mutex);
 
-EEwsCalendarRecurringDayTransition *
-e_ews_calendar_recurring_day_transition_new (void)
-{
-       return g_new0 (EEwsCalendarRecurringDayTransition, 1);
-}
+       pd.message = e_soap_request_persist (request, E_SOUP_SESSION (cnc->priv->soup.session), settings, 
error);
 
-void
-e_ews_calendar_recurring_day_transition_free (EEwsCalendarRecurringDayTransition *rdayt)
-{
-       if (rdayt != NULL) {
-               e_ews_calendar_to_free (rdayt->to);
-               g_free (rdayt->time_offset);
-               g_free (rdayt->month);
-               g_free (rdayt->day_of_week);
-               g_free (rdayt->occurrence);
-               g_free (rdayt);
+       g_clear_object (&settings);
+
+       if (!pd.message)
+               return NULL;
+
+       g_mutex_lock (&cnc->priv->property_lock);
+       if (cnc->priv->credentials_changed) {
+               cnc->priv->credentials_changed = FALSE;
+
+               e_soup_session_set_credentials (E_SOUP_SESSION (cnc->priv->soup.session), 
cnc->priv->credentials);
        }
-}
+       g_mutex_unlock (&cnc->priv->property_lock);
 
-EEwsCalendarRecurringDateTransition *
-e_ews_calendar_recurring_date_transition_new (void)
-{
-       return g_new0 (EEwsCalendarRecurringDateTransition, 1);
-}
+       pd.prepare_data = e_soup_session_prepare_message_send_sync (E_SOUP_SESSION (cnc->priv->soup.session), 
pd.message, cancellable, error);
 
-void
-e_ews_calendar_recurring_date_transition_free (EEwsCalendarRecurringDateTransition *rdatet)
-{
-       if (rdatet != NULL) {
-               e_ews_calendar_to_free (rdatet->to);
-               g_free (rdatet->time_offset);
-               g_free (rdatet->month);
-               g_free (rdatet->day);
-               g_free (rdatet);
+       if (!pd.prepare_data) {
+               if (error && g_error_matches (*error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+                       (*error)->domain = EWS_CONNECTION_ERROR;
+                       (*error)->code = EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED;
+               }
+
+               g_clear_object (&pd.message);
+               return NULL;
        }
-}
 
-EEwsCalendarPeriod *
-e_ews_calendar_period_new (void)
-{
-       return g_new0 (EEwsCalendarPeriod, 1);
-}
+       g_mutex_init (&pd.mutex);
+       g_cond_init (&pd.cond);
+       pd.done = FALSE;
+       pd.cnc = cnc;
+       pd.cancellable = cancellable;
+       pd.input_stream = NULL;
+       pd.error = NULL;
+       pd.out_certificate_pem = out_certificate_pem;
+       pd.out_certificate_errors = out_certificate_errors;
 
-void
-e_ews_calendar_period_free (EEwsCalendarPeriod *period)
-{
-       if (period != NULL) {
-               g_free (period->bias);
-               g_free (period->name);
-               g_free (period->id);
-               g_free (period);
+       g_mutex_lock (&pd.mutex);
+
+       source = g_idle_source_new ();
+       g_source_set_priority (source, G_PRIORITY_DEFAULT);
+       g_source_set_callback (source, e_ews_connection_process_request_run_cb, &pd, NULL);
+       g_source_attach (source, cnc->priv->soup.main_context);
+       g_source_unref (source);
+
+       while (!pd.done) {
+               g_cond_wait (&pd.cond, &pd.mutex);
        }
-}
 
-EEwsCalendarTransitionsGroup *
-e_ews_calendar_transitions_group_new (void)
-{
-       return g_new0 (EEwsCalendarTransitionsGroup, 1);
-}
+       g_mutex_unlock (&pd.mutex);
 
-void
-e_ews_calendar_transitions_group_free (EEwsCalendarTransitionsGroup *tg)
-{
-       if (tg != NULL) {
-               g_free (tg->id);
-               e_ews_calendar_to_free (tg->transition);
-               g_slist_free_full (
-                       tg->absolute_date_transitions,
-                       (GDestroyNotify) e_ews_calendar_absolute_date_transition_free);
-               g_slist_free_full (
-                       tg->recurring_day_transitions,
-                       (GDestroyNotify) e_ews_calendar_recurring_day_transition_free);
-               g_slist_free_full (
-                       tg->recurring_date_transitions,
-                       (GDestroyNotify) e_ews_calendar_recurring_date_transition_free);
-               g_free (tg);
+       persistent_auth = soup_message_headers_get_one (soup_message_get_response_headers (pd.message), 
"Persistent-Auth");
+       if (persistent_auth && g_ascii_strcasecmp (persistent_auth, "false") == 0) {
+               SoupSessionFeature *feature;
+
+               feature = soup_session_get_feature (cnc->priv->soup.session, SOUP_TYPE_AUTH_MANAGER);
+               if (feature) {
+                       soup_auth_manager_clear_cached_credentials (SOUP_AUTH_MANAGER (feature));
+               }
        }
-}
 
-EEwsCalendarTransitions *
-e_ews_calendar_transitions_new (void)
-{
-       return g_new0 (EEwsCalendarTransitions, 1);
-}
+       if (pd.input_stream)
+               *out_message = g_steal_pointer (&pd.message);
 
-void
-e_ews_calendar_transitions_free (EEwsCalendarTransitions *transitions)
-{
-       if (transitions != NULL) {
-               e_ews_calendar_to_free (transitions->transition);
-               g_slist_free_full (
-                       transitions->absolute_date_transitions,
-                       (GDestroyNotify) e_ews_calendar_absolute_date_transition_free);
-               g_slist_free_full (
-                       transitions->recurring_day_transitions,
-                       (GDestroyNotify) e_ews_calendar_recurring_day_transition_free);
-               g_slist_free_full (
-                       transitions->recurring_date_transitions,
-                       (GDestroyNotify) e_ews_calendar_recurring_date_transition_free);
-               g_free (transitions);
-       }
-}
+       g_clear_object (&pd.message);
+       g_mutex_clear (&pd.mutex);
+       g_cond_clear (&pd.cond);
 
-EEwsCalendarTimeZoneDefinition *
-e_ews_calendar_time_zone_definition_new (void)
-{
-       return g_new0 (EEwsCalendarTimeZoneDefinition, 1);
-}
+       g_warn_if_fail ((pd.error == NULL && pd.input_stream != NULL) ||
+                       (pd.error != NULL && pd.input_stream == NULL));
 
-void
-e_ews_calendar_time_zone_definition_free (EEwsCalendarTimeZoneDefinition *tzd)
-{
-       if (tzd != NULL) {
-               g_free (tzd->name);
-               g_free (tzd->id);
-               g_slist_free_full (tzd->periods, (GDestroyNotify) e_ews_calendar_period_free);
-               g_slist_free_full (tzd->transitions_groups, (GDestroyNotify) 
e_ews_calendar_transitions_group_free);
-               e_ews_calendar_transitions_free (tzd->transitions);
-               g_free (tzd);
-       }
-}
+       if (pd.error)
+               g_propagate_error (error, pd.error);
 
-EEwsExtendedFieldURI *
-e_ews_extended_field_uri_new (void)
-{
-       return g_new0 (EEwsExtendedFieldURI, 1);
+       return pd.input_stream;
 }
 
-void
-e_ews_extended_field_uri_free (EEwsExtendedFieldURI *ex_field_uri)
+static gboolean
+ews_connection_credentials_failed (EEwsConnection *connection,
+                                  SoupMessage *message,
+                                  GError **error)
 {
-       if (ex_field_uri != NULL) {
-               g_free (ex_field_uri->distinguished_prop_set_id);
-               g_free (ex_field_uri->prop_set_id);
-               g_free (ex_field_uri->prop_tag);
-               g_free (ex_field_uri->prop_name);
-               g_free (ex_field_uri->prop_id);
-               g_free (ex_field_uri->prop_type);
-               g_free (ex_field_uri);
-       }
-}
+       gint expire_in_days = 0;
+       gboolean expired = FALSE;
+       gchar *service_url = NULL;
 
-EEwsIndexedFieldURI *
-e_ews_indexed_field_uri_new (const gchar *uri,
-                            const gchar *index)
-{
-       EEwsIndexedFieldURI *furi;
+       g_return_val_if_fail (E_IS_EWS_CONNECTION (connection), FALSE);
 
-       furi = g_new0 (EEwsIndexedFieldURI, 1);
-       furi->field_uri = g_strdup (uri);
-       furi->field_index = g_strdup (index);
+       if (!message)
+               return FALSE;
 
-       return furi;
-}
+       if (!e_ews_connection_utils_check_x_ms_credential_headers (message, &expire_in_days, &expired, 
&service_url))
+               return FALSE;
 
-void
-e_ews_indexed_field_uri_free (EEwsIndexedFieldURI *id_field_uri)
-{
-       if (id_field_uri != NULL) {
-               g_free (id_field_uri->field_uri);
-               g_free (id_field_uri->field_index);
-               g_free (id_field_uri);
+       if (expired) {
+               e_ews_connection_utils_expired_password_to_error (service_url, error);
+       } else if (expire_in_days > 0) {
+               g_signal_emit (connection, signals[PASSWORD_WILL_EXPIRE], 0, expire_in_days, service_url);
        }
-}
-
-EEwsAdditionalProps *
-e_ews_additional_props_new (void)
-{
-       return g_new0 (EEwsAdditionalProps, 1);
-}
 
-void
-e_ews_additional_props_free (EEwsAdditionalProps *add_props)
-{
-       if (add_props != NULL) {
-               g_free (add_props->field_uri);
-               g_slist_free_full (add_props->extended_furis, (GDestroyNotify) e_ews_extended_field_uri_free);
-               g_slist_free_full (add_props->indexed_furis, (GDestroyNotify) e_ews_indexed_field_uri_free);
-               g_free (add_props);
-       }
-}
+       g_free (service_url);
 
-static EwsNode *
-ews_node_new (void)
-{
-       return g_slice_new0 (EwsNode);
+       return expired;
 }
 
 static void
-autodiscover_parse_protocol (xmlNode *node,
-                             EwsUrls *urls)
+e_ews_connection_wait_ms (gint wait_ms,
+                         GCancellable *cancellable)
 {
-       for (node = node->children; node; node = node->next) {
-               if (node->type == XML_ELEMENT_NODE &&
-                   !strcmp ((gchar *) node->name, "ASUrl")) {
-                       if (urls->as_url != NULL)
-                               xmlFree (urls->as_url);
+       if (wait_ms > 0) {
+               EFlag *flag;
 
-                       urls->as_url = xmlNodeGetContent (node);
-               } else if (node->type == XML_ELEMENT_NODE &&
-                   !strcmp ((gchar *) node->name, "OABUrl")) {
-                       if (urls->oab_url != NULL)
-                               xmlFree (urls->oab_url);
+               flag = e_flag_new ();
 
-                       urls->oab_url = xmlNodeGetContent (node);
+               while (wait_ms > 0 && !g_cancellable_is_cancelled (cancellable)) {
+                       gint64 now = g_get_monotonic_time ();
+                       gint left_minutes, left_seconds;
+
+                       left_minutes = wait_ms / 60000;
+                       left_seconds = (wait_ms / 1000) % 60;
+
+                       if (left_minutes > 0) {
+                               camel_operation_push_message (cancellable,
+                                       g_dngettext (GETTEXT_PACKAGE,
+                                               "Exchange server is busy, waiting to retry (%d:%02d minute)",
+                                               "Exchange server is busy, waiting to retry (%d:%02d 
minutes)", left_minutes),
+                                       left_minutes, left_seconds);
+                       } else {
+                               camel_operation_push_message (cancellable,
+                                       g_dngettext (GETTEXT_PACKAGE,
+                                               "Exchange server is busy, waiting to retry (%d second)",
+                                               "Exchange server is busy, waiting to retry (%d seconds)", 
left_seconds),
+                                       left_seconds);
+                       }
+
+                       e_flag_wait_until (flag, now + (G_TIME_SPAN_MILLISECOND * (wait_ms > 1000 ? 1000 : 
wait_ms)));
+
+                       now = g_get_monotonic_time () - now;
+                       now = now / G_TIME_SPAN_MILLISECOND;
+
+                       if (now >= wait_ms)
+                               wait_ms = 0;
+                       wait_ms -= now;
+
+                       camel_operation_pop_message (cancellable);
                }
 
-               /* Once we find both, we can stop looking for the URLs */
-               if (urls->as_url && urls->oab_url)
-                       return;
+               e_flag_free (flag);
        }
 }
 
-static xmlChar *
-autodiscover_get_protocol_type (xmlNode *node)
+static gboolean
+e_ews_connection_handle_backoff_policy (EEwsConnection *cnc,
+                                       ESoapResponse *response,
+                                       GCancellable *cancellable,
+                                       GError **error)
 {
-       for (node = node->children; node; node = node->next) {
-               if (node->type == XML_ELEMENT_NODE &&
-                   !strcmp ((gchar *) node->name, "Type")) {
-                       return xmlNodeGetContent (node);
-               }
-       }
+       ESoapParameter *param;
+       gint wait_ms = 0;
+       gboolean repeat = FALSE;
 
-       return NULL;
-}
+       if (e_ews_connection_get_backoff_enabled (cnc))
+               param = e_soap_response_get_first_parameter_by_name (response, "detail", NULL);
+       else
+               param = NULL;
+       if (param)
+               param = e_soap_parameter_get_first_child_by_name (param, "ResponseCode");
+       if (param) {
+               gchar *value;
 
-static gchar *
-autodiscover_dup_element_value (xmlNode *node,
-                               const gchar *element_name)
-{
-       for (node = node->children; node; node = node->next) {
-               if (node->type == XML_ELEMENT_NODE &&
-                   !g_strcmp0 ((gchar *) node->name, element_name)) {
-                       xmlChar *str = xmlNodeGetContent (node);
-                       gchar *res;
+               value = e_soap_parameter_get_string_value (param);
+               if (value && ews_get_error_code (value) == EWS_CONNECTION_ERROR_SERVERBUSY) {
+                       param = e_soap_response_get_first_parameter_by_name (response, "detail", NULL);
+                       if (param)
+                               param = e_soap_parameter_get_first_child_by_name (param, "MessageXml");
+                       if (param) {
+                               param = e_soap_parameter_get_first_child_by_name (param, "Value");
+                               if (param) {
+                                       g_free (value);
 
-                       res = g_strdup ((const gchar *) str);
-                       xmlFree (str);
-                       return res;
+                                       value = e_soap_parameter_get_property (param, "Name");
+                                       if (g_strcmp0 (value, "BackOffMilliseconds") == 0) {
+                                               wait_ms = e_soap_parameter_get_int_value (param);
+                                       }
+                               }
+                       }
                }
+
+               g_free (value);
        }
 
-       return NULL;
-}
+       if (wait_ms > 0) {
+               e_ews_connection_wait_ms (wait_ms, cancellable);
 
-static gint
-comp_func (gconstpointer a,
-           gconstpointer b)
-{
-       EwsNode *node1 = (EwsNode *) a;
-       EwsNode *node2 = (EwsNode *) b;
-       if (node1->pri > node2->pri)
-               return -1;
-       else if (node1->pri < node2->pri)
-               return 1;
-       else
-               return 0;
-}
+               repeat = !g_cancellable_set_error_if_cancelled (cancellable, error);
+       }
 
-typedef enum _EwsScheduleOp {
-       EWS_SCHEDULE_OP_QUEUE_MESSAGE,
-       EWS_SCHEDULE_OP_CANCEL,
-       EWS_SCHEDULE_OP_ABORT
-} EwsScheduleOp;
+       return repeat;
+}
 
-typedef struct _EwsScheduleData
+static ESoapResponse *
+e_ews_connection_send_request_sync (EEwsConnection *cnc,
+                                   ESoapRequest *request,
+                                   GCancellable *cancellable,
+                                   GError **error)
 {
-       EEwsConnection *cnc;
-       SoupMessage *message;
+       ESoapResponse *response = NULL;
+       SoupMessage *message = NULL;
+       GInputStream *input_stream;
+       gchar *certificate_pem = NULL;
+       GTlsCertificateFlags certificate_errors = 0;
+       gboolean retrying_after_io_error = FALSE;
+       gboolean repeat = TRUE;
+       GError *local_error = NULL;
 
-       EwsScheduleOp op;
+       while (repeat) {
+               GError *local_error2 = NULL;
 
-       SoupSessionCallback queue_callback;
-       gpointer queue_user_data;
-} EwsScheduleData;
+               repeat = FALSE;
 
-/* this is run in priv->soup_thread */
-static gboolean
-ews_connection_scheduled_cb (gpointer user_data)
-{
-       EwsScheduleData *sd = user_data;
+               g_clear_error (&local_error);
 
-       g_return_val_if_fail (sd != NULL, FALSE);
+               input_stream = e_ews_connection_process_request_sync (cnc, request, &message, 
&certificate_pem, &certificate_errors, cancellable, &local_error);
 
-       switch (sd->op) {
-       case EWS_SCHEDULE_OP_QUEUE_MESSAGE:
-               if (!e_ews_connection_utils_prepare_message (sd->cnc, NULL, sd->message, NULL)) {
-                       e_ews_debug_dump_raw_soup_request (sd->message);
+               g_mutex_lock (&cnc->priv->property_lock);
+               g_clear_pointer (&cnc->priv->ssl_certificate_pem, g_free);
+               cnc->priv->ssl_info_set = certificate_pem != NULL;
+               cnc->priv->ssl_certificate_pem = g_strdup (certificate_pem);
+               cnc->priv->ssl_certificate_errors = certificate_errors;
+               g_mutex_unlock (&cnc->priv->property_lock);
 
-                       if (sd->queue_callback) {
-                               sd->queue_callback (sd->cnc->priv->soup_session, sd->message, 
sd->queue_user_data);
-                       } else {
-                               /* This should not happen */
-                               g_warn_if_reached ();
+               e_soap_request_take_tls_error_details (request, certificate_pem, certificate_errors);
+
+               if (message && !ews_connection_credentials_failed (cnc, message, &local_error2)) {
+                       if (soup_message_get_status (message) == SOUP_STATUS_UNAUTHORIZED) {
+                               /* This can happen when the server terminated the connection before the 
request started */
+                               if (!retrying_after_io_error &&
+                                   soup_message_get_request_headers (message) &&
+                                   !soup_message_headers_get_one (soup_message_get_request_headers 
(message), "Authorization")) {
+                                       g_clear_error (&local_error2);
+
+                                       e_ews_connection_wait_ms (EWS_RETRY_AUTH_ERROR_SECONDS * 1000, 
cancellable);
+
+                                       retrying_after_io_error = TRUE;
+                                       repeat = !g_cancellable_set_error_if_cancelled (cancellable, 
&local_error);
+                               } else {
+                                       if (soup_message_get_response_headers (message)) {
+                                               const gchar *diagnostics;
+
+                                               diagnostics = soup_message_headers_get_list 
(soup_message_get_response_headers (message), "X-MS-DIAGNOSTICS");
+                                               if (diagnostics && strstr (diagnostics, "invalid_grant")) {
+                                                       g_set_error_literal (&local_error2, 
EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_ACCESSDENIED, diagnostics);
+                                               } else if (diagnostics && *diagnostics) {
+                                                       g_set_error_literal (&local_error2, 
EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED, diagnostics);
+                                               }
+                                       }
 
-                               soup_session_queue_message (
-                                       sd->cnc->priv->soup_session, sd->message,
-                                       sd->queue_callback, sd->queue_user_data);
-                               soup_session_cancel_message (sd->cnc->priv->soup_session, sd->message, 
sd->message->status_code);
+                                       if (!local_error2)
+                                               g_set_error_literal (&local_error2, EWS_CONNECTION_ERROR, 
EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Authentication failed"));
+                               }
                        }
-               } else {
-                       e_ews_debug_dump_raw_soup_request (sd->message);
+               }
 
-                       soup_session_queue_message (
-                               sd->cnc->priv->soup_session, sd->message,
-                               sd->queue_callback, sd->queue_user_data);
+               if (local_error2) {
+                       g_clear_error (&local_error);
+                       local_error = local_error2;
                }
-               break;
-       case EWS_SCHEDULE_OP_CANCEL:
-               soup_session_cancel_message (sd->cnc->priv->soup_session, sd->message, SOUP_STATUS_CANCELLED);
-               break;
-       case EWS_SCHEDULE_OP_ABORT:
-               soup_session_abort (sd->cnc->priv->soup_session);
-               break;
-       }
 
-       if (sd->message)
-               g_object_unref (sd->message);
-       /* in case this is the last reference */
-       e_ews_connection_utils_unref_in_thread (sd->cnc);
-       g_slice_free (EwsScheduleData, sd);
+               if (!local_error) {
+                       ESoapRequestCustomProcessFn custom_process_fn = NULL;
+                       gpointer custom_process_data = NULL;
 
-       return FALSE;
-}
+                       e_soap_request_get_custom_process_fn (request, &custom_process_fn, 
&custom_process_data);
 
-static void
-ews_connection_schedule_queue_message (EEwsConnection *cnc,
-                                       SoupMessage *message,
-                                       SoupSessionCallback callback,
-                                       gpointer user_data)
-{
-       EwsScheduleData *sd;
-       GSource *source;
+                       if (custom_process_fn) {
+                               custom_process_fn (request, message, input_stream, custom_process_data, 
&repeat, cancellable, &local_error);
+                       } else {
+                               response = e_soap_response_new ();
 
-       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
-       g_return_if_fail (SOUP_IS_MESSAGE (message));
+                               e_soap_request_setup_response (request, response);
 
-       sd = g_slice_new0 (EwsScheduleData);
-       sd->cnc = g_object_ref (cnc);
-       sd->message = g_object_ref (message);
-       sd->op = EWS_SCHEDULE_OP_QUEUE_MESSAGE;
-       sd->queue_callback = callback;
-       sd->queue_user_data = user_data;
+                               if (!e_soap_response_from_message_sync (response, message, input_stream, 
cancellable, &local_error)) {
+                                       g_clear_object (&response);
 
-       source = g_idle_source_new ();
-       g_source_set_priority (source, G_PRIORITY_DEFAULT);
-       g_source_set_callback (source, ews_connection_scheduled_cb, sd, NULL);
-       g_source_attach (source, cnc->priv->soup_context);
-       g_source_unref (source);
-}
+                                       if (!local_error) {
+                                               g_set_error (&local_error, EWS_CONNECTION_ERROR, 
EWS_CONNECTION_ERROR_NORESPONSE,
+                                                       _("No response: %s"), soup_message_get_reason_phrase 
(message));
+                                       }
+                               }
 
-static void
-ews_connection_schedule_cancel_message (EEwsConnection *cnc,
-                                        SoupMessage *message)
-{
-       EwsScheduleData *sd;
-       GSource *source;
+                               if (response) {
+                                       repeat = e_ews_connection_handle_backoff_policy (cnc, response, 
cancellable, &local_error);
 
-       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
-       g_return_if_fail (SOUP_IS_MESSAGE (message));
+                                       if (repeat || local_error)
+                                               g_clear_object (&response);
+                               }
+                       }
+               }
 
-       sd = g_slice_new0 (EwsScheduleData);
-       sd->cnc = g_object_ref (cnc);
-       sd->message = g_object_ref (message);
-       sd->op = EWS_SCHEDULE_OP_CANCEL;
+               if (!repeat && !retrying_after_io_error && local_error &&
+                   g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT)) {
+                       g_clear_object (&response);
+                       g_clear_error (&local_error);
 
-       source = g_idle_source_new ();
-       g_source_set_priority (source, G_PRIORITY_DEFAULT);
-       g_source_set_callback (source, ews_connection_scheduled_cb, sd, NULL);
-       g_source_attach (source, cnc->priv->soup_context);
-       g_source_unref (source);
-}
+                       e_ews_connection_wait_ms (EWS_RETRY_IO_ERROR_SECONDS * 1000, cancellable);
 
-static void
-ews_connection_schedule_abort (EEwsConnection *cnc)
-{
-       EwsScheduleData *sd;
-       GSource *source;
-
-       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
-
-       sd = g_slice_new0 (EwsScheduleData);
-       sd->cnc = g_object_ref (cnc);
-       sd->op = EWS_SCHEDULE_OP_ABORT;
-
-       source = g_idle_source_new ();
-       g_source_set_priority (source, G_PRIORITY_DEFAULT);
-       g_source_set_callback (source, ews_connection_scheduled_cb, sd, NULL);
-       g_source_attach (source, cnc->priv->soup_context);
-       g_source_unref (source);
-}
-
-static void ews_cancel_request (GCancellable *cancellable, gpointer user_data);
-
-static void
-ews_discover_server_version (EEwsConnection *cnc,
-                            ESoapResponse *response)
-{
-       ESoapParameter *param;
-       gchar *version;
-
-       g_return_if_fail (cnc != NULL);
-
-       if (cnc->priv->version != E_EWS_EXCHANGE_UNKNOWN)
-               return;
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ServerVersionInfo", NULL);
-       if (!param)
-               return;
-
-       version = e_soap_parameter_get_property (param, "Version");
-
-       e_ews_connection_set_server_version_from_string (cnc, version);
-
-       g_free (version);
-}
-
-/* this is run in priv->soup_thread */
-static gboolean
-ews_next_request (gpointer _cnc)
-{
-       EEwsConnection *cnc = _cnc;
-       GSList *l;
-       EwsNode *node;
-
-       QUEUE_LOCK (cnc);
-
-       l = cnc->priv->jobs;
+                       retrying_after_io_error = TRUE;
+                       repeat = !g_cancellable_set_error_if_cancelled (cancellable, &local_error);
+               }
 
-       if (!l || g_slist_length (cnc->priv->active_job_queue) >= ews_connection_get_concurrent_connections 
(cnc)) {
-               QUEUE_UNLOCK (cnc);
-               return FALSE;
+               g_clear_object (&input_stream);
+               g_clear_object (&message);
        }
 
-       node = (EwsNode *) l->data;
-
-       /* Remove the node from the priority queue */
-       cnc->priv->jobs = g_slist_remove (cnc->priv->jobs, (gconstpointer *) node);
-
-       /* Add to active job queue */
-       cnc->priv->active_job_queue = g_slist_append (cnc->priv->active_job_queue, node);
-
-       QUEUE_UNLOCK (cnc);
-
-       if (cnc->priv->soup_session) {
-               SoupMessage *msg = SOUP_MESSAGE (node->msg);
-
-               if (!e_ews_connection_utils_prepare_message (cnc, NULL, msg, node->cancellable)) {
-                       e_ews_debug_dump_raw_soup_request (msg);
+       if (local_error)
+               g_propagate_error (error, local_error);
 
-                       ews_response_cb (cnc->priv->soup_session, msg, node);
-               } else {
-                       e_ews_debug_dump_raw_soup_request (msg);
+       if (response && cnc->priv->version == E_EWS_EXCHANGE_UNKNOWN) {
+               ESoapParameter *param;
 
-                       if (cnc->priv->clear_cached_credentials) {
-                               SoupSessionFeature *feature;
+               param = e_soap_response_get_first_parameter_by_name (response, "ServerVersionInfo", NULL);
+               if (param) {
+                       gchar *version;
 
-                               cnc->priv->clear_cached_credentials = FALSE;
+                       version = e_soap_parameter_get_property (param, "Version");
 
-                               feature = soup_session_get_feature (cnc->priv->soup_session, 
SOUP_TYPE_AUTH_MANAGER);
-                               if (feature)
-                                       soup_auth_manager_clear_cached_credentials (SOUP_AUTH_MANAGER 
(feature));
-                       }
+                       e_ews_connection_set_server_version_from_string (cnc, version);
 
-                       soup_session_queue_message (cnc->priv->soup_session, msg, ews_response_cb, node);
+                       g_free (version);
                }
-       } else {
-               ews_cancel_request (NULL, node);
        }
 
-       return FALSE;
+       return response;
 }
 
-static void
-ews_trigger_next_request (EEwsConnection *cnc)
+static guint
+ews_connection_get_concurrent_connections (EEwsConnection *cnc)
 {
-       GSource *source;
-
-       g_return_if_fail (cnc != NULL);
+       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), 1);
 
-       if (cnc->priv->soup_session) {
-               source = g_idle_source_new ();
-               g_source_set_priority (source, G_PRIORITY_DEFAULT);
-               g_source_set_callback (source, ews_next_request, cnc, NULL);
-               g_source_attach (source, cnc->priv->soup_context);
-               g_source_unref (source);
-       } else {
-               ews_next_request (cnc);
-       }
+       return cnc->priv->concurrent_connections;
 }
 
-/**
- * ews_active_job_done
- * @cnc:
- * @msg:
- * Removes the node from active Queue and free's the node
- *
- * Returns:
- **/
 static void
-ews_active_job_done (EEwsConnection *cnc,
-                     EwsNode *ews_node)
+ews_connection_set_concurrent_connections (EEwsConnection *cnc,
+                                          guint concurrent_connections)
 {
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (ews_node != NULL);
+       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
 
-       QUEUE_LOCK (cnc);
+       concurrent_connections = CLAMP (
+               concurrent_connections,
+               MIN_CONCURRENT_CONNECTIONS,
+               MAX_CONCURRENT_CONNECTIONS);
 
-       cnc->priv->active_job_queue = g_slist_remove (cnc->priv->active_job_queue, ews_node);
-       if (ews_node->cancellable && ews_node->cancel_handler_id)
-               g_signal_handler_disconnect (ews_node->cancellable, ews_node->cancel_handler_id);
+       if (cnc->priv->concurrent_connections == concurrent_connections)
+               return;
 
-       QUEUE_UNLOCK (cnc);
+       /* Will be updated in the priv->soup.session the next time it's created,
+          because "max-conns" is a construct-only property */
+       cnc->priv->concurrent_connections = concurrent_connections;
 
-       ews_trigger_next_request (cnc);
+       g_object_notify (G_OBJECT (cnc), "concurrent-connections");
+}
 
-       if (ews_node->cancellable)
-               g_object_unref (ews_node->cancellable);
+GQuark
+ews_connection_error_quark (void)
+{
+       static GQuark quark = 0;
 
-       if (ews_node->simple) {
-               /* the 'simple' holds reference on 'cnc' and this function
-                * is called in a dedicated thread, which 'cnc' joins on dispose,
-                * thus to avoid race condition, unref the object in its own thread */
-               e_ews_connection_utils_unref_in_thread (ews_node->simple);
+       if (G_UNLIKELY (quark == 0)) {
+               const gchar *string = "ews-connection-error-quark";
+               quark = g_quark_from_static_string (string);
        }
 
-       g_slice_free (EwsNode, ews_node);
+       return quark;
 }
 
-static void
-ews_cancel_request (GCancellable *cancellable,
-                    gpointer user_data)
+EEwsNotificationEvent *
+e_ews_notification_event_new (void)
 {
-       EwsNode *node = user_data;
-       EEwsConnection *cnc = node->cnc;
-       GSimpleAsyncResult *simple = node->simple;
-       ESoapMessage *msg = node->msg;
-       GSList *found;
-
-       QUEUE_LOCK (cnc);
-       found = g_slist_find (cnc->priv->active_job_queue, node);
-       cnc->priv->jobs = g_slist_remove (cnc->priv->jobs, node);
-       QUEUE_UNLOCK (cnc);
-
-       g_simple_async_result_set_error (
-               simple,
-               G_IO_ERROR,
-               G_IO_ERROR_CANCELLED,
-               _("Operation Cancelled"));
-       if (found) {
-               ews_connection_schedule_cancel_message (cnc, SOUP_MESSAGE (msg));
-       } else {
-               ews_response_cb (cnc->priv->soup_session, SOUP_MESSAGE (msg), node);
-       }
+       return g_new0 (EEwsNotificationEvent, 1);
 }
 
 void
-e_ews_connection_queue_request (EEwsConnection *cnc,
-                                ESoapMessage *msg,
-                                EEwsResponseCallback cb,
-                                gint pri,
-                                GCancellable *cancellable,
-                                GSimpleAsyncResult *simple)
+e_ews_notification_event_free (EEwsNotificationEvent *event)
 {
-       EwsNode *node;
-
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (cb != NULL);
-       g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
-
-       node = ews_node_new ();
-       node->msg = msg;
-       node->pri = pri;
-       node->cb = cb;
-       node->cnc = cnc;
-       node->simple = g_object_ref (simple);
-
-       QUEUE_LOCK (cnc);
-       cnc->priv->jobs = g_slist_insert_sorted (cnc->priv->jobs, (gpointer *) node, (GCompareFunc) 
comp_func);
-       QUEUE_UNLOCK (cnc);
-
-       if (cancellable) {
-               node->cancellable = g_object_ref (cancellable);
-               if (g_cancellable_is_cancelled (cancellable))
-                       ews_cancel_request (cancellable, node);
-               else
-                       node->cancel_handler_id = g_cancellable_connect (
-                               cancellable,
-                               G_CALLBACK (ews_cancel_request),
-                               (gpointer) node, NULL);
+       if (event != NULL) {
+               g_free (event->folder_id);
+               g_free (event->old_folder_id);
+               g_free (event);
        }
-
-       ews_trigger_next_request (cnc);
 }
 
-static gboolean
-ews_connection_credentials_failed (EEwsConnection *connection,
-                                  SoupMessage *message,
-                                  GSimpleAsyncResult *simple)
+EEwsCalendarTo *
+e_ews_calendar_to_new (void)
 {
-       gint expire_in_days = 0;
-       gboolean expired = FALSE;
-       gchar *service_url = NULL;
-
-       g_return_val_if_fail (E_IS_EWS_CONNECTION (connection), FALSE);
-       g_return_val_if_fail (SOUP_IS_MESSAGE (message), FALSE);
-       g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
-
-       if (!e_ews_connection_utils_check_x_ms_credential_headers (message, &expire_in_days, &expired, 
&service_url))
-               return FALSE;
-
-       if (expired) {
-               GError *error = NULL;
+       return g_new0 (EEwsCalendarTo, 1);
+}
 
-               e_ews_connection_utils_expired_password_to_error (service_url, &error);
-               g_simple_async_result_take_error (simple, error);
-       } else if (expire_in_days > 0) {
-               g_signal_emit (connection, signals[PASSWORD_WILL_EXPIRE], 0, expire_in_days, service_url);
+void
+e_ews_calendar_to_free (EEwsCalendarTo *to) {
+       if (to != NULL) {
+               g_free (to->kind);
+               g_free (to->value);
+               g_free (to);
        }
-
-       g_free (service_url);
-
-       return expired;
 }
 
-static void
-ews_connection_check_ssl_error (EEwsConnection *connection,
-                               SoupMessage *message)
+EEwsCalendarAbsoluteDateTransition *
+e_ews_calendar_absolute_date_transition_new (void)
 {
-       g_return_if_fail (E_IS_EWS_CONNECTION (connection));
-       g_return_if_fail (SOUP_IS_MESSAGE (message));
-
-       if (message->status_code == SOUP_STATUS_SSL_FAILED) {
-               GTlsCertificate *certificate = NULL;
-
-               g_mutex_lock (&connection->priv->property_lock);
-
-               g_clear_pointer (&connection->priv->ssl_certificate_pem, g_free);
-               connection->priv->ssl_info_set = FALSE;
-
-               g_object_get (G_OBJECT (message),
-                       "tls-certificate", &certificate,
-                       "tls-errors", &connection->priv->ssl_certificate_errors,
-                       NULL);
-
-               if (certificate) {
-                       g_object_get (certificate, "certificate-pem", &connection->priv->ssl_certificate_pem, 
NULL);
-                       connection->priv->ssl_info_set = TRUE;
-
-                       g_object_unref (certificate);
-               }
+       return g_new0 (EEwsCalendarAbsoluteDateTransition, 1);
+}
 
-               g_mutex_unlock (&connection->priv->property_lock);
+void
+e_ews_calendar_absolute_date_transition_free (EEwsCalendarAbsoluteDateTransition *adt)
+{
+       if (adt != NULL) {
+               e_ews_calendar_to_free (adt->to);
+               g_free (adt->date_time);
+               g_free (adt);
        }
 }
 
-/* Response callbacks */
-
-static void
-ews_response_cb (SoupSession *session,
-                 SoupMessage *msg,
-                 gpointer data)
+EEwsCalendarRecurringDayTransition *
+e_ews_calendar_recurring_day_transition_new (void)
 {
-       EwsNode *enode = (EwsNode *) data;
-       ESoapResponse *response = NULL;
-       ESoapParameter *param;
-       const gchar *persistent_auth;
-       gint log_level;
-       gint wait_ms = 0;
+       return g_new0 (EEwsCalendarRecurringDayTransition, 1);
+}
 
-       persistent_auth = soup_message_headers_get_one (msg->response_headers, "Persistent-Auth");
-       if (persistent_auth && g_ascii_strcasecmp (persistent_auth, "false") == 0) {
-               enode->cnc->priv->clear_cached_credentials = TRUE;
+void
+e_ews_calendar_recurring_day_transition_free (EEwsCalendarRecurringDayTransition *rdayt)
+{
+       if (rdayt != NULL) {
+               e_ews_calendar_to_free (rdayt->to);
+               g_free (rdayt->time_offset);
+               g_free (rdayt->month);
+               g_free (rdayt->day_of_week);
+               g_free (rdayt->occurrence);
+               g_free (rdayt);
        }
+}
 
-       if (g_cancellable_is_cancelled (enode->cancellable))
-               goto exit;
-
-       ews_connection_check_ssl_error (enode->cnc, msg);
-
-       if (ews_connection_credentials_failed (enode->cnc, msg, enode->simple)) {
-               goto exit;
-       } else if (msg->status_code == SOUP_STATUS_SSL_FAILED) {
-               g_simple_async_result_set_error (
-                       enode->simple, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED,
-                       "%s", msg->reason_phrase);
-               goto exit;
-       } else if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
-               /* This can happen when the server terminated the connection before the request started */
-               if (!enode->retrying_after_network_error &&
-                   !soup_message_headers_get_one (msg->request_headers, "Authorization")) {
-                       wait_ms = EWS_RETRY_AUTH_ERROR_SECONDS * 1000;
-                       enode->retrying_after_network_error = TRUE;
-                       goto retrylbl;
-               }
-
-               if (msg->response_headers) {
-                       const gchar *diagnostics;
-
-                       diagnostics = soup_message_headers_get_list (msg->response_headers, 
"X-MS-DIAGNOSTICS");
-                       if (diagnostics && strstr (diagnostics, "invalid_grant")) {
-                               g_simple_async_result_set_error (
-                                       enode->simple,
-                                       EWS_CONNECTION_ERROR,
-                                       EWS_CONNECTION_ERROR_ACCESSDENIED,
-                                       "%s", diagnostics);
-                               goto exit;
-                       } else if (diagnostics && *diagnostics) {
-                               g_simple_async_result_set_error (
-                                       enode->simple,
-                                       EWS_CONNECTION_ERROR,
-                                       EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED,
-                                       "%s", diagnostics);
-                               goto exit;
-                       }
-               }
+EEwsCalendarRecurringDateTransition *
+e_ews_calendar_recurring_date_transition_new (void)
+{
+       return g_new0 (EEwsCalendarRecurringDateTransition, 1);
+}
 
-               g_simple_async_result_set_error (
-                       enode->simple,
-                       EWS_CONNECTION_ERROR,
-                       EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED,
-                       _("Authentication failed"));
-               goto exit;
-       } else if (!enode->retrying_after_network_error &&
-                  msg->status_code == SOUP_STATUS_IO_ERROR) {
-               wait_ms = EWS_RETRY_IO_ERROR_SECONDS * 1000;
-               enode->retrying_after_network_error = TRUE;
-               goto retrylbl;
-       } else if (msg->status_code == SOUP_STATUS_CANT_RESOLVE ||
-                  msg->status_code == SOUP_STATUS_CANT_RESOLVE_PROXY ||
-                  msg->status_code == SOUP_STATUS_CANT_CONNECT ||
-                  msg->status_code == SOUP_STATUS_CANT_CONNECT_PROXY ||
-                  msg->status_code == SOUP_STATUS_IO_ERROR) {
-               g_simple_async_result_set_error (
-                       enode->simple,
-                       EWS_CONNECTION_ERROR,
-                       EWS_CONNECTION_ERROR_UNAVAILABLE,
-                       "%s", msg->reason_phrase);
-               goto exit;
+void
+e_ews_calendar_recurring_date_transition_free (EEwsCalendarRecurringDateTransition *rdatet)
+{
+       if (rdatet != NULL) {
+               e_ews_calendar_to_free (rdatet->to);
+               g_free (rdatet->time_offset);
+               g_free (rdatet->month);
+               g_free (rdatet->day);
+               g_free (rdatet);
        }
+}
 
-       response = e_soap_message_parse_response ((ESoapMessage *) msg);
+EEwsCalendarPeriod *
+e_ews_calendar_period_new (void)
+{
+       return g_new0 (EEwsCalendarPeriod, 1);
+}
 
-       if (response == NULL) {
-               g_simple_async_result_set_error (
-                       enode->simple,
-                       EWS_CONNECTION_ERROR,
-                       EWS_CONNECTION_ERROR_NORESPONSE,
-                       _("No response: %s"), msg->reason_phrase);
-               goto exit;
+void
+e_ews_calendar_period_free (EEwsCalendarPeriod *period)
+{
+       if (period != NULL) {
+               g_free (period->bias);
+               g_free (period->name);
+               g_free (period->id);
+               g_free (period);
        }
+}
 
-       /* TODO: The stdout can be replaced with Evolution's
-        * Logging framework also */
+EEwsCalendarTransitionsGroup *
+e_ews_calendar_transitions_group_new (void)
+{
+       return g_new0 (EEwsCalendarTransitionsGroup, 1);
+}
 
-       log_level = e_ews_debug_get_log_level ();
-       if (log_level >= 1 && log_level < 4) {
-               /* This will dump only the headers, since we stole the body.
-                * And only if EWS_DEBUG=1, since higher levels will have dumped
-                * it directly from libsoup anyway. */
-               if (log_level == 1)
-                       e_ews_debug_dump_raw_soup_response (msg);
-               /* And this will dump the body... */
-               e_soap_response_dump_response (response, stdout);
+void
+e_ews_calendar_transitions_group_free (EEwsCalendarTransitionsGroup *tg)
+{
+       if (tg != NULL) {
+               g_free (tg->id);
+               e_ews_calendar_to_free (tg->transition);
+               g_slist_free_full (
+                       tg->absolute_date_transitions,
+                       (GDestroyNotify) e_ews_calendar_absolute_date_transition_free);
+               g_slist_free_full (
+                       tg->recurring_day_transitions,
+                       (GDestroyNotify) e_ews_calendar_recurring_day_transition_free);
+               g_slist_free_full (
+                       tg->recurring_date_transitions,
+                       (GDestroyNotify) e_ews_calendar_recurring_date_transition_free);
+               g_free (tg);
        }
+}
 
-       if (!wait_ms && e_ews_connection_get_backoff_enabled (enode->cnc))
-               param = e_soap_response_get_first_parameter_by_name (response, "detail", NULL);
-       else
-               param = NULL;
-       if (param)
-               param = e_soap_parameter_get_first_child_by_name (param, "ResponseCode");
-       if (param) {
-               gchar *value;
+EEwsCalendarTransitions *
+e_ews_calendar_transitions_new (void)
+{
+       return g_new0 (EEwsCalendarTransitions, 1);
+}
 
-               value = e_soap_parameter_get_string_value (param);
-               if (value && ews_get_error_code (value) == EWS_CONNECTION_ERROR_SERVERBUSY) {
-                       param = e_soap_response_get_first_parameter_by_name (response, "detail", NULL);
-                       if (param)
-                               param = e_soap_parameter_get_first_child_by_name (param, "MessageXml");
-                       if (param) {
-                               param = e_soap_parameter_get_first_child_by_name (param, "Value");
-                               if (param) {
-                                       g_free (value);
-
-                                       value = e_soap_parameter_get_property (param, "Name");
-                                       if (g_strcmp0 (value, "BackOffMilliseconds") == 0) {
-                                               wait_ms = e_soap_parameter_get_int_value (param);
-                                       }
-                               }
-                       }
-               }
-
-               g_free (value);
-       }
-
- retrylbl:
-       if (wait_ms > 0) {
-               GCancellable *cancellable = enode->cancellable;
-               EFlag *flag;
-
-               if (cancellable)
-                       g_object_ref (cancellable);
-               g_object_ref (msg);
-
-               flag = e_flag_new ();
-               while (wait_ms > 0 && !g_cancellable_is_cancelled (cancellable) && msg->status_code != 
SOUP_STATUS_CANCELLED) {
-                       gint64 now = g_get_monotonic_time ();
-                       gint left_minutes, left_seconds;
-
-                       left_minutes = wait_ms / 60000;
-                       left_seconds = (wait_ms / 1000) % 60;
-
-                       if (left_minutes > 0) {
-                               camel_operation_push_message (cancellable,
-                                       g_dngettext (GETTEXT_PACKAGE,
-                                               "Exchange server is busy, waiting to retry (%d:%02d minute)",
-                                               "Exchange server is busy, waiting to retry (%d:%02d 
minutes)", left_minutes),
-                                       left_minutes, left_seconds);
-                       } else {
-                               camel_operation_push_message (cancellable,
-                                       g_dngettext (GETTEXT_PACKAGE,
-                                               "Exchange server is busy, waiting to retry (%d second)",
-                                               "Exchange server is busy, waiting to retry (%d seconds)", 
left_seconds),
-                                       left_seconds);
-                       }
-
-                       e_flag_wait_until (flag, now + (G_TIME_SPAN_MILLISECOND * (wait_ms > 1000 ? 1000 : 
wait_ms)));
-
-                       now = g_get_monotonic_time () - now;
-                       now = now / G_TIME_SPAN_MILLISECOND;
-
-                       if (now >= wait_ms)
-                               wait_ms = 0;
-                       wait_ms -= now;
-
-                       camel_operation_pop_message (cancellable);
-               }
-
-               e_flag_free (flag);
-
-               g_clear_object (&response);
-
-               if (g_cancellable_is_cancelled (cancellable) ||
-                   msg->status_code == SOUP_STATUS_CANCELLED) {
-                       g_clear_object (&cancellable);
-                       g_object_unref (msg);
-               } else {
-                       EwsNode *new_node;
-
-                       new_node = ews_node_new ();
-                       new_node->msg = E_SOAP_MESSAGE (msg); /* takes ownership */
-                       new_node->pri = enode->pri;
-                       new_node->cb = enode->cb;
-                       new_node->cnc = enode->cnc;
-                       new_node->simple = enode->simple;
-                       new_node->retrying_after_network_error = enode->retrying_after_network_error;
-
-                       enode->simple = NULL;
-
-                       QUEUE_LOCK (enode->cnc);
-                       enode->cnc->priv->jobs = g_slist_prepend (enode->cnc->priv->jobs, new_node);
-                       QUEUE_UNLOCK (enode->cnc);
-
-                       if (cancellable) {
-                               new_node->cancellable = g_object_ref (cancellable);
-                               new_node->cancel_handler_id = g_cancellable_connect (
-                                       cancellable, G_CALLBACK (ews_cancel_request), new_node, NULL);
-                       }
-
-                       g_clear_object (&cancellable);
-               }
-
-               goto exit;
-       }
-
-       if (enode->cb != NULL)
-               enode->cb (response, enode->simple);
-
-       g_clear_object (&response);
-
-exit:
-       if (enode->simple)
-               g_simple_async_result_complete_in_idle (enode->simple);
-
-       ews_active_job_done (enode->cnc, enode);
-}
-
-typedef gpointer (*ItemParser) (ESoapParameter *param);
-
-static void
-sync_xxx_response_cb (ESoapParameter *subparam,
-                      EwsAsyncData *async_data,
-                      ItemParser parser,
-                      const gchar *last_tag,
-                      const gchar *delete_id_tag)
-{
-       ESoapParameter *node;
-       gchar *new_sync_state = NULL, *value, *last;
-       GSList *items_created = NULL, *items_updated = NULL, *items_deleted = NULL;
-       gboolean includes_last_item;
-
-       node = e_soap_parameter_get_first_child_by_name (subparam, "SyncState");
-       new_sync_state = e_soap_parameter_get_string_value (node);
-
-       node = e_soap_parameter_get_first_child_by_name (subparam, last_tag);
-       last = e_soap_parameter_get_string_value (node);
-       /*
-        * Set the includes_last_item to TRUE as default.
-        * It can avoid an infinite loop in caller, when, for some reason,
-        * we don't receive the last_tag property from the server.
-        */
-       includes_last_item = g_strcmp0 (last, "false") != 0;
-       g_free (last);
-
-       node = e_soap_parameter_get_first_child_by_name (subparam, "Changes");
-
-       if (node) {
-               ESoapParameter *subparam1;
-               for (subparam1 = e_soap_parameter_get_first_child_by_name (node, "Create");
-                    subparam1 != NULL;
-                    subparam1 = e_soap_parameter_get_next_child_by_name (subparam1, "Create")) {
-                       GObject *object;
-
-                       object = parser (subparam1);
-                       if (object && (!E_IS_EWS_FOLDER (object) || !e_ews_folder_get_is_hidden (E_EWS_FOLDER 
(object))))
-                               items_created = g_slist_append (items_created, object);
-                       else
-                               g_clear_object (&object);
-               }
-
-               for (subparam1 = e_soap_parameter_get_first_child_by_name (node, "Update");
-                    subparam1 != NULL;
-                    subparam1 = e_soap_parameter_get_next_child_by_name (subparam1, "Update")) {
-                       GObject *object;
-
-                       object = parser (subparam1);
-                       if (object && (!E_IS_EWS_FOLDER (object) || !e_ews_folder_get_is_hidden (E_EWS_FOLDER 
(object))))
-                               items_updated = g_slist_append (items_updated, object);
-                       else
-                               g_clear_object (&object);
-               }
-                 /* Exchange 2007SP1 introduced <ReadFlagChange> which is basically identical
-                  * to <Update>; no idea why they thought it was a good idea. */
-               for (subparam1 = e_soap_parameter_get_first_child_by_name (node, "ReadFlagChange");
-                    subparam1 != NULL;
-                    subparam1 = e_soap_parameter_get_next_child_by_name (subparam1, "ReadFlagChange")) {
-                       GObject *object;
-
-                       object = parser (subparam1);
-                       if (object && (!E_IS_EWS_FOLDER (object) || !e_ews_folder_get_is_hidden (E_EWS_FOLDER 
(object))))
-                               items_updated = g_slist_append (items_updated, object);
-                       else
-                               g_clear_object (&object);
-               }
-
-               for (subparam1 = e_soap_parameter_get_first_child_by_name (node, "Delete");
-                    subparam1 != NULL;
-                    subparam1 = e_soap_parameter_get_next_child_by_name (subparam1, "Delete")) {
-                       ESoapParameter *folder_param;
-
-                       folder_param = e_soap_parameter_get_first_child_by_name (subparam1, delete_id_tag);
-                       value = e_soap_parameter_get_property (folder_param, "Id");
-                       items_deleted = g_slist_append (items_deleted, value);
-               }
-       }
-
-       async_data->items_created = items_created;
-       async_data->items_updated = items_updated;
-       async_data->items_deleted = items_deleted;
-       async_data->sync_state = new_sync_state;
-       async_data->includes_last_item = includes_last_item;
-}
-
-static void
-sync_hierarchy_response_cb (ESoapResponse *response,
-                            GSimpleAsyncResult *simple)
-{
-       EwsAsyncData *async_data;
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       /*
-        * During the first connection, we are able to get the current version of the Exchange server.
-        * For Addressbook/Calendar backends, we are ensuring it happens during the
-        * e_ews_connection_try_credentials_sync(), that calls e_e_ews_connection_get_folder_sync() and then
-        * we are able to get the current version of the server from this first response.
-        *
-        * For Camel, the first connection is done calling e_ews_connection_sync_folder_hierarchy_sync().
-        */
-       ews_discover_server_version (async_data->cnc, response);
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
-
-       subparam = e_soap_parameter_get_first_child (param);
-
-       while (subparam != NULL) {
-               const gchar *name = (const gchar *) subparam->name;
-
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
-
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "SyncFolderHierarchyResponseMessage"))
-                       sync_xxx_response_cb (
-                               subparam, async_data,
-                               (ItemParser) e_ews_folder_new_from_soap_parameter,
-                               "IncludesLastFolderInRange", "FolderId");
-
-               subparam = e_soap_parameter_get_next_child (subparam);
-       }
-}
-
-static void
-sync_folder_items_response_cb (ESoapResponse *response,
-                               GSimpleAsyncResult *simple)
-{
-       EwsAsyncData *async_data;
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
-
-       subparam = e_soap_parameter_get_first_child (param);
-
-       while (subparam != NULL) {
-               const gchar *name = (const gchar *) subparam->name;
-
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
-
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "SyncFolderItemsResponseMessage"))
-                       sync_xxx_response_cb (
-                               subparam, async_data,
-                               (ItemParser) e_ews_item_new_from_soap_parameter,
-                               "IncludesLastItemInRange", "ItemId");
-
-               subparam = e_soap_parameter_get_next_child (subparam);
-       }
-}
-
-static void
-ews_handle_folders_param (ESoapParameter *subparam,
-                          EwsAsyncData *async_data)
-{
-       ESoapParameter *node;
-       EEwsFolder *folder;
-
-       for (node = e_soap_parameter_get_first_child_by_name (subparam, "Folders");
-            node; node = e_soap_parameter_get_next_child_by_name (subparam, "Folders")) {
-               folder = e_ews_folder_new_from_soap_parameter (node);
-               if (!folder) continue;
-               async_data->items = g_slist_append (async_data->items, folder);
-       }
-}
-
-static void
-get_folder_response_cb (ESoapResponse *response,
-                        GSimpleAsyncResult *simple)
-{
-       EwsAsyncData *async_data;
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       /*
-        * During the first connection, we are able to get the current version of the Exchange server.
-        * For Addressbook/Calendar backends, we are ensuring it happens during the
-        * e_ews_connection_try_credentials_sync(), that calls e_e_ews_connection_get_folder_sync() and then
-        * we are able to get the current version of the server from this first response.
-        *
-        * For Camel, the first connection is done calling e_ews_connection_sync_folder_hierarchy_sync().
-        */
-       ews_discover_server_version (async_data->cnc, response);
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
-
-       subparam = e_soap_parameter_get_first_child (param);
-
-       while (subparam != NULL) {
-               const gchar *name = (const gchar *) subparam->name;
-
-               if (!ews_get_response_status (subparam, &error)) {
-                       if (g_strcmp0 (name, "GetFolderResponseMessage") == 0) {
-                               async_data->items = g_slist_append (async_data->items, 
e_ews_folder_new_from_error (error));
-                               g_clear_error (&error);
-                       } else {
-                               g_simple_async_result_take_error (simple, error);
-                               return;
-                       }
-               } else if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "GetFolderResponseMessage"))
-                       ews_handle_folders_param (subparam, async_data);
-
-               subparam = e_soap_parameter_get_next_child (subparam);
-       }
-}
-
-static void
-ews_handle_root_folder_param_items (ESoapParameter *subparam,
-                                   EwsAsyncData *async_data)
-{
-       ESoapParameter *node, *subparam1;
-       gchar *last, *total;
-       gint total_items;
-       EEwsItem *item;
-       gboolean includes_last_item;
-
-       node = e_soap_parameter_get_first_child_by_name (subparam, "RootFolder");
-       total = e_soap_parameter_get_property (node, "TotalItemsInView");
-       total_items = atoi (total);
-       g_free (total);
-       last = e_soap_parameter_get_property (node, "IncludesLastItemInRange");
-       /*
-        * Set the includes_last_item to TRUE as default.
-        * It can avoid an infinite loop in caller, when, for some reason,
-        * we don't receive the last_tag property from the server.
-        */
-       includes_last_item = g_strcmp0 (last, "false") != 0;
-       g_free (last);
-
-       node = e_soap_parameter_get_first_child_by_name (node, "Items");
-       for (subparam1 = e_soap_parameter_get_first_child (node);
-            subparam1; subparam1 = e_soap_parameter_get_next_child (subparam1)) {
-               item = e_ews_item_new_from_soap_parameter (subparam1);
-               if (!item) continue;
-               async_data->items = g_slist_append (async_data->items, item);
-       }
-       async_data->total_items = total_items;
-       async_data->includes_last_item = includes_last_item;
-}
-
-static void
-find_folder_items_response_cb (ESoapResponse *response,
-                               GSimpleAsyncResult *simple)
-{
-       EwsAsyncData *async_data;
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
-
-       subparam = e_soap_parameter_get_first_child (param);
-
-       while (subparam != NULL) {
-               const gchar *name = (const gchar *) subparam->name;
-
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
-
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "FindItemResponseMessage"))
-                       ews_handle_root_folder_param_items (subparam, async_data);
-
-               subparam = e_soap_parameter_get_next_child (subparam);
-       }
-}
-
-/* Used for CreateItems and GetItems */
-static void
-ews_handle_items_param (ESoapParameter *subparam,
-                        EwsAsyncData *async_data,
-                        const GError *error)
+void
+e_ews_calendar_transitions_free (EEwsCalendarTransitions *transitions)
 {
-       ESoapParameter *node;
-       EEwsItem *item;
-
-       for (node = e_soap_parameter_get_first_child_by_name (subparam, "Items");
-            node; node = e_soap_parameter_get_next_child_by_name (subparam, "Items")) {
-               if (node->children)
-                       item = e_ews_item_new_from_soap_parameter (node);
-               else
-                       item = NULL;
-               if (!item && error != NULL)
-                       item = e_ews_item_new_from_error (error);
-               if (!item) continue;
-               async_data->items = g_slist_append (async_data->items, item);
+       if (transitions != NULL) {
+               e_ews_calendar_to_free (transitions->transition);
+               g_slist_free_full (
+                       transitions->absolute_date_transitions,
+                       (GDestroyNotify) e_ews_calendar_absolute_date_transition_free);
+               g_slist_free_full (
+                       transitions->recurring_day_transitions,
+                       (GDestroyNotify) e_ews_calendar_recurring_day_transition_free);
+               g_slist_free_full (
+                       transitions->recurring_date_transitions,
+                       (GDestroyNotify) e_ews_calendar_recurring_date_transition_free);
+               g_free (transitions);
        }
 }
 
-static void
-handle_get_items_response_cb (EwsAsyncData *async_data, ESoapParameter *param)
+EEwsCalendarTimeZoneDefinition *
+e_ews_calendar_time_zone_definition_new (void)
 {
-       ESoapParameter *subparam;
-       GError *error = NULL;
-
-       subparam = e_soap_parameter_get_first_child (param);
-
-       while (subparam != NULL) {
-               const gchar *name = (const gchar *) subparam->name;
-
-               if (g_str_has_suffix (name, "ResponseMessage")) {
-                       if (ews_get_response_status (subparam, &error))
-                               error = NULL;
-
-                       ews_handle_items_param (subparam, async_data, error);
-               } else {
-                       g_warning (
-                               "%s: Unexpected element <%s>",
-                               G_STRFUNC, name);
-               }
-
-               /* Do not stop on errors. */
-               if (error != NULL)
-                       g_clear_error (&error);
-
-               subparam = e_soap_parameter_get_next_child (subparam);
-       }
+       return g_new0 (EEwsCalendarTimeZoneDefinition, 1);
 }
 
-static void
-get_items_response_cb (ESoapResponse *response,
-                       GSimpleAsyncResult *simple)
+void
+e_ews_calendar_time_zone_definition_free (EEwsCalendarTimeZoneDefinition *tzd)
 {
-       EwsAsyncData *async_data;
-       ESoapParameter *param;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+       if (tzd != NULL) {
+               g_free (tzd->name);
+               g_free (tzd->id);
+               g_slist_free_full (tzd->periods, (GDestroyNotify) e_ews_calendar_period_free);
+               g_slist_free_full (tzd->transitions_groups, (GDestroyNotify) 
e_ews_calendar_transitions_group_free);
+               e_ews_calendar_transitions_free (tzd->transitions);
+               g_free (tzd);
        }
-
-       handle_get_items_response_cb (async_data, param);
 }
 
-static void
-ews_handle_resolution_set_param (ESoapParameter *subparam,
-                                 EwsAsyncData *async_data)
+EEwsExtendedFieldURI *
+e_ews_extended_field_uri_new (void)
 {
-       ESoapParameter *node;
-       gchar *prop;
-       gboolean includes_last_item;
-       GSList *mailboxes = NULL, *contact_items = NULL;
-
-       subparam = e_soap_parameter_get_first_child_by_name (subparam, "ResolutionSet");
-       prop = e_soap_parameter_get_property (subparam, "IncludesLastItemInRange");
-       /*
-        * Set the includes_last_item to TRUE as default.
-        * It can avoid an infinite loop in caller, when, for some reason,
-        * we don't receive the last_tag property from the server.
-        */
-       includes_last_item = g_strcmp0 (prop, "false") != 0;
-       g_free (prop);
-
-       for (subparam = e_soap_parameter_get_first_child_by_name (subparam, "Resolution");
-               subparam != NULL;
-               subparam = e_soap_parameter_get_next_child_by_name (subparam, "Resolution")) {
-               EwsMailbox *mb;
-
-               node = e_soap_parameter_get_first_child_by_name (subparam, "Mailbox");
-               mb = e_ews_item_mailbox_from_soap_param (node);
-               if (mb) {
-                       EEwsItem *contact_item;
-
-                       mailboxes = g_slist_prepend (mailboxes, mb);
-
-                       /* 'mailboxes' and 'contact_items' match 1:1, but if the contact information
-                        * wasn't found, then NULL is stored in the corresponding position */
-                       node = e_soap_parameter_get_first_child_by_name (subparam, "Contact");
-                       if (node) {
-                               contact_item = e_ews_item_new_from_soap_parameter (node);
-                               contact_items = g_slist_prepend (contact_items, contact_item);
-                       } else {
-                               contact_items = g_slist_prepend (contact_items, NULL);
-                       }
-               }
-       }
-
-       /* Reuse existing variables */
-       async_data->items = g_slist_reverse (mailboxes);
-       async_data->includes_last_item = includes_last_item;
-       async_data->items_created = g_slist_reverse (contact_items);
+       return g_new0 (EEwsExtendedFieldURI, 1);
 }
 
-static void
-resolve_names_response_cb (ESoapResponse *response,
-                           GSimpleAsyncResult *simple)
+void
+e_ews_extended_field_uri_free (EEwsExtendedFieldURI *ex_field_uri)
 {
-       EwsAsyncData *async_data;
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
-
-       subparam = e_soap_parameter_get_first_child (param);
-
-       while (subparam != NULL) {
-               const gchar *name = (const gchar *) subparam->name;
-
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
-
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "ResolveNamesResponseMessage"))
-                       ews_handle_resolution_set_param (subparam, async_data);
-
-               subparam = e_soap_parameter_get_next_child (subparam);
+       if (ex_field_uri != NULL) {
+               g_free (ex_field_uri->distinguished_prop_set_id);
+               g_free (ex_field_uri->prop_set_id);
+               g_free (ex_field_uri->prop_tag);
+               g_free (ex_field_uri->prop_name);
+               g_free (ex_field_uri->prop_id);
+               g_free (ex_field_uri->prop_type);
+               g_free (ex_field_uri);
        }
 }
 
-static void
-ews_handle_dl_expansion_param (ESoapParameter *subparam,
-                               EwsAsyncData *async_data)
+EEwsIndexedFieldURI *
+e_ews_indexed_field_uri_new (const gchar *uri,
+                            const gchar *index)
 {
-       gboolean includes_last_item;
-       GSList *mailboxes = NULL;
-       gchar *prop;
-
-       subparam = e_soap_parameter_get_first_child_by_name (subparam, "DLExpansion");
-       prop = e_soap_parameter_get_property (subparam, "IncludesLastItemInRange");
-       /*
-        * Set the includes_last_item to TRUE as default.
-        * It can avoid an infinite loop in caller, when, for some reason,
-        * we don't receive the last_tag property from the server.
-        */
-       includes_last_item = g_strcmp0 (prop, "false") != 0;
-       g_free (prop);
-
-       for (subparam = e_soap_parameter_get_first_child_by_name (subparam, "Mailbox");
-               subparam != NULL;
-               subparam = e_soap_parameter_get_next_child_by_name (subparam, "Mailbox")) {
-               EwsMailbox *mb;
+       EEwsIndexedFieldURI *furi;
 
-               mb = e_ews_item_mailbox_from_soap_param (subparam);
-               if (mb)
-                       mailboxes = g_slist_append (mailboxes, mb);
-       }
+       furi = g_new0 (EEwsIndexedFieldURI, 1);
+       furi->field_uri = g_strdup (uri);
+       furi->field_index = g_strdup (index);
 
-       /* Reuse existing variables */
-       async_data->items = mailboxes;
-       async_data->includes_last_item = includes_last_item;
+       return furi;
 }
 
-static void
-expand_dl_response_cb (ESoapResponse *response,
-                       GSimpleAsyncResult *simple)
+void
+e_ews_indexed_field_uri_free (EEwsIndexedFieldURI *id_field_uri)
 {
-       EwsAsyncData *async_data;
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
-
-       subparam = e_soap_parameter_get_first_child (param);
-
-       while (subparam != NULL) {
-               const gchar *name = (const gchar *) subparam->name;
-
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
-
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "ExpandDLResponseMessage"))
-                       ews_handle_dl_expansion_param (subparam, async_data);
-
-               subparam = e_soap_parameter_get_next_child (subparam);
+       if (id_field_uri != NULL) {
+               g_free (id_field_uri->field_uri);
+               g_free (id_field_uri->field_index);
+               g_free (id_field_uri);
        }
 }
 
-/* TODO scan all folders if we support creating multiple folders in the request */
-static void
-ews_handle_create_folders_param (ESoapParameter *soapparam,
-                                 EwsAsyncData *async_data)
+EEwsAdditionalProps *
+e_ews_additional_props_new (void)
 {
-       ESoapParameter *param, *node;
-       EwsFolderId *fid = NULL;
-       GSList *fids = NULL;
-       const gchar *folder_element;
-
-       switch (async_data->folder_type) {
-               case E_EWS_FOLDER_TYPE_MAILBOX:
-               case E_EWS_FOLDER_TYPE_MEMOS:
-                       folder_element = "Folder";
-                       break;
-               case E_EWS_FOLDER_TYPE_CALENDAR:
-                       folder_element = "CalendarFolder";
-                       break;
-               case E_EWS_FOLDER_TYPE_CONTACTS:
-                       folder_element = "ContactsFolder";
-                       break;
-               case E_EWS_FOLDER_TYPE_SEARCH:
-                       folder_element = "SearchFolder";
-                       break;
-               case E_EWS_FOLDER_TYPE_TASKS:
-                       folder_element = "TasksFolder";
-                       break;
-               default:
-                       g_warn_if_reached ();
-                       folder_element = "Folder";
-                       break;
-       }
-
-       node = e_soap_parameter_get_first_child_by_name (soapparam, "Folders");
-       node = e_soap_parameter_get_first_child_by_name (node, folder_element);
-       param = e_soap_parameter_get_first_child_by_name (node, "FolderId");
-
-       fid = g_new0 (EwsFolderId, 1);
-       fid->id = e_soap_parameter_get_property (param, "Id");
-       fid->change_key = e_soap_parameter_get_property (param, "ChangeKey");
-       fids = g_slist_append (fids, fid);
-
-       async_data->items_created = fids;
+       return g_new0 (EEwsAdditionalProps, 1);
 }
 
-static void
-create_folder_response_cb (ESoapResponse *response,
-                           GSimpleAsyncResult *simple)
+void
+e_ews_additional_props_free (EEwsAdditionalProps *add_props)
 {
-       EwsAsyncData *async_data;
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+       if (add_props != NULL) {
+               g_free (add_props->field_uri);
+               g_slist_free_full (add_props->extended_furis, (GDestroyNotify) e_ews_extended_field_uri_free);
+               g_slist_free_full (add_props->indexed_furis, (GDestroyNotify) e_ews_indexed_field_uri_free);
+               g_free (add_props);
        }
+}
 
-       subparam = e_soap_parameter_get_first_child (param);
+static void
+autodiscover_parse_protocol (xmlNode *node,
+                             EwsUrls *urls)
+{
+       for (node = node->children; node; node = node->next) {
+               if (node->type == XML_ELEMENT_NODE &&
+                   !strcmp ((gchar *) node->name, "ASUrl")) {
+                       if (urls->as_url != NULL)
+                               xmlFree (urls->as_url);
 
-       while (subparam != NULL) {
-               const gchar *name = (const gchar *) subparam->name;
+                       urls->as_url = xmlNodeGetContent (node);
+               } else if (node->type == XML_ELEMENT_NODE &&
+                   !strcmp ((gchar *) node->name, "OABUrl")) {
+                       if (urls->oab_url != NULL)
+                               xmlFree (urls->oab_url);
 
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
+                       urls->oab_url = xmlNodeGetContent (node);
                }
 
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "CreateFolderResponseMessage"))
-                       ews_handle_create_folders_param (subparam, async_data);
-
-               subparam = e_soap_parameter_get_next_child (subparam);
+               /* Once we find both, we can stop looking for the URLs */
+               if (urls->as_url && urls->oab_url)
+                       return;
        }
 }
 
-static gpointer
-e_ews_soup_thread (gpointer user_data)
+static xmlChar *
+autodiscover_get_protocol_type (xmlNode *node)
 {
-       EEwsConnection *cnc = user_data;
-
-       g_main_context_push_thread_default (cnc->priv->soup_context);
-       g_main_loop_run (cnc->priv->soup_loop);
-       g_main_context_pop_thread_default (cnc->priv->soup_context);
-
-       /* abort any pending operations */
-       soup_session_abort (cnc->priv->soup_session);
-
-       g_object_unref (cnc->priv->soup_session);
-       cnc->priv->soup_session = NULL;
+       for (node = node->children; node; node = node->next) {
+               if (node->type == XML_ELEMENT_NODE &&
+                   !strcmp ((gchar *) node->name, "Type")) {
+                       return xmlNodeGetContent (node);
+               }
+       }
 
        return NULL;
 }
 
-/*
- * e_ews_debug_handler:
- *
- * GLib debug message handler, which is passed all messages from g_debug() calls,
- * and decides whether to print them.
- */
-static void
-e_ews_debug_handler (const gchar *log_domain,
-                    GLogLevelFlags log_level,
-                    const gchar *message,
-                    gpointer user_data)
+static gchar *
+autodiscover_dup_element_value (xmlNode *node,
+                               const gchar *element_name)
 {
-       if (e_ews_debug_get_log_level () >= 4)
-               g_log_default_handler (log_domain, log_level, message, NULL);
-}
+       for (node = node->children; node; node = node->next) {
+               if (node->type == XML_ELEMENT_NODE &&
+                   !g_strcmp0 ((gchar *) node->name, element_name)) {
+                       xmlChar *str = xmlNodeGetContent (node);
+                       gchar *res;
 
-/*
- * e_ews_soup_log_print:
- *
- * Log printer for the libsoup logging functionality, which just marshal all soup log
- * output to the standard GLib logging framework (and thus to debug_handler(), above).
- */
-static void
-e_ews_soup_log_printer (SoupLogger *logger,
-                       SoupLoggerLogLevel level,
-                       char direction,
-                       const gchar *data,
-                       gpointer user_data)
-{
-       g_debug ("%c %s", direction, e_ews_debug_redact_headers (direction, data));
+                       res = g_strdup ((const gchar *) str);
+                       xmlFree (str);
+                       return res;
+               }
+       }
+
+       return NULL;
 }
 
 static void
@@ -1983,69 +1101,6 @@ ews_connection_get_property (GObject *object,
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 }
 
-static void
-ews_connection_constructed (GObject *object)
-{
-       EEwsConnection *cnc = E_EWS_CONNECTION (object);
-       gint log_level;
-
-       /* Chain up to parent's method. */
-       G_OBJECT_CLASS (e_ews_connection_parent_class)->constructed (object);
-
-       cnc->priv->soup_thread = g_thread_new (NULL, e_ews_soup_thread, cnc);
-
-       cnc->priv->soup_session = soup_session_async_new_with_options (
-               SOUP_SESSION_TIMEOUT, 90,
-               SOUP_SESSION_SSL_STRICT, TRUE,
-               SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE,
-               SOUP_SESSION_ASYNC_CONTEXT, cnc->priv->soup_context,
-               SOUP_SESSION_MAX_CONNS, cnc->priv->concurrent_connections,
-               SOUP_SESSION_MAX_CONNS_PER_HOST, cnc->priv->concurrent_connections,
-               NULL);
-
-       /* Do not use G_BINDING_SYNC_CREATE because the property_lock is
-        * not initialized and we don't have a GProxyResolver yet anyway. */
-       e_binding_bind_property (
-               cnc, "proxy-resolver",
-               cnc->priv->soup_session, "proxy-resolver",
-               G_BINDING_DEFAULT);
-
-       cnc->priv->version = E_EWS_EXCHANGE_UNKNOWN;
-
-       log_level = e_ews_debug_get_log_level ();
-
-       if (log_level >= 2) {
-               SoupLogger *logger;
-               logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, -1);
-
-               if (log_level >= 4) {
-                       soup_logger_set_printer (logger, e_ews_soup_log_printer, NULL, NULL);
-                       g_log_set_handler (
-                               G_LOG_DOMAIN,
-                               G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
-                               G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO,
-                               e_ews_debug_handler, cnc);
-               } else if (log_level == 2) {
-                       soup_logger_set_printer (logger, e_ews_debug_soup_log_printer_stdout, NULL, NULL);
-               }
-
-               soup_session_add_feature (
-                       cnc->priv->soup_session,
-                       SOUP_SESSION_FEATURE (logger));
-               g_object_unref (logger);
-       }
-
-       soup_session_add_feature_by_type (cnc->priv->soup_session,
-                                         SOUP_TYPE_COOKIE_JAR);
-
-       g_signal_connect (
-               cnc->priv->soup_session, "authenticate",
-               G_CALLBACK (ews_connection_authenticate), cnc);
-
-       e_ews_connection_utils_prepare_auth_method (cnc->priv->soup_session,
-               camel_ews_settings_get_auth_mechanism (cnc->priv->settings));
-}
-
 static void
 ews_connection_dispose (GObject *object)
 {
@@ -2077,21 +1132,28 @@ ews_connection_dispose (GObject *object)
        }
        NOTIFICATION_UNLOCK (cnc);
 
-       if (cnc->priv->soup_session) {
-               g_signal_handlers_disconnect_by_func (
-                       cnc->priv->soup_session,
-                       ews_connection_authenticate, object);
+       g_mutex_lock (&cnc->priv->soup.mutex);
+
+       if (cnc->priv->soup.main_loop) {
+               g_main_loop_quit (cnc->priv->soup.main_loop);
 
-               g_main_loop_quit (cnc->priv->soup_loop);
-               g_thread_join (cnc->priv->soup_thread);
-               cnc->priv->soup_thread = NULL;
+               if (cnc->priv->soup.thread) {
+                       g_thread_join (cnc->priv->soup.thread);
+                       cnc->priv->soup.thread = NULL;
+               }
+
+               g_main_loop_unref (cnc->priv->soup.main_loop);
+               g_main_context_unref (cnc->priv->soup.main_context);
 
-               g_main_loop_unref (cnc->priv->soup_loop);
-               cnc->priv->soup_loop = NULL;
-               g_main_context_unref (cnc->priv->soup_context);
-               cnc->priv->soup_context = NULL;
+               cnc->priv->soup.main_loop = NULL;
+               cnc->priv->soup.main_context = NULL;
+
+               /* The soup thread creates and frees the session */
+               g_warn_if_fail (cnc->priv->soup.session == NULL);
        }
 
+       g_mutex_unlock (&cnc->priv->soup.mutex);
+
        g_clear_object (&cnc->priv->proxy_resolver);
        g_clear_object (&cnc->priv->source);
        g_clear_object (&cnc->priv->settings);
@@ -2123,20 +1185,21 @@ ews_connection_finalize (GObject *object)
 {
        EEwsConnection *cnc = E_EWS_CONNECTION (object);
 
+       e_named_parameters_free (cnc->priv->credentials);
        g_free (cnc->priv->uri);
-       g_free (cnc->priv->password);
        g_free (cnc->priv->email);
        g_free (cnc->priv->hash_key);
        g_free (cnc->priv->impersonate_user);
        g_free (cnc->priv->ssl_certificate_pem);
        g_free (cnc->priv->last_subscription_id);
 
-       g_clear_object (&cnc->priv->bearer_auth);
-
        g_mutex_clear (&cnc->priv->property_lock);
        g_rec_mutex_clear (&cnc->priv->queue_lock);
        g_mutex_clear (&cnc->priv->notification_lock);
 
+       g_mutex_clear (&cnc->priv->soup.mutex);
+       g_cond_clear (&cnc->priv->soup.cond);
+
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (e_ews_connection_parent_class)->finalize (object);
 }
@@ -2149,7 +1212,6 @@ e_ews_connection_class_init (EEwsConnectionClass *class)
        object_class = G_OBJECT_CLASS (class);
        object_class->set_property = ews_connection_set_property;
        object_class->get_property = ews_connection_get_property;
-       object_class->constructed = ews_connection_constructed;
        object_class->dispose = ews_connection_dispose;
        object_class->finalize = ews_connection_finalize;
 
@@ -2241,6 +1303,14 @@ e_ews_connection_class_init (EEwsConnectionClass *class)
                g_cclosure_marshal_VOID__STRING,
                G_TYPE_NONE, 1,
                G_TYPE_STRING);
+
+       if (e_ews_debug_get_log_level () >= 4) {
+               g_log_set_handler (
+                       G_LOG_DOMAIN,
+                       G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
+                       G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO,
+                       e_ews_debug_handler, NULL);
+       }
 }
 
 static void
@@ -2254,11 +1324,15 @@ e_ews_connection_init (EEwsConnection *cnc)
 {
        cnc->priv = e_ews_connection_get_instance_private (cnc);
 
-       cnc->priv->soup_context = g_main_context_new ();
-       cnc->priv->soup_loop = g_main_loop_new (cnc->priv->soup_context, FALSE);
+       g_mutex_init (&cnc->priv->soup.mutex);
+       g_cond_init (&cnc->priv->soup.cond);
+       cnc->priv->soup.main_context = g_main_context_new ();
+       cnc->priv->soup.main_loop = g_main_loop_new (cnc->priv->soup.main_context, FALSE);
+
        cnc->priv->backoff_enabled = TRUE;
        cnc->priv->disconnected_flag = FALSE;
        cnc->priv->concurrent_connections = 1;
+       cnc->priv->version = E_EWS_EXCHANGE_UNKNOWN;
 
        cnc->priv->subscriptions = g_hash_table_new_full (
                        g_direct_hash, g_direct_equal,
@@ -2269,20 +1343,6 @@ e_ews_connection_init (EEwsConnection *cnc)
        g_mutex_init (&cnc->priv->notification_lock);
 }
 
-static void
-ews_connection_authenticate (SoupSession *sess,
-                             SoupMessage *msg,
-                             SoupAuth *auth,
-                             gboolean retrying,
-                             gpointer data)
-{
-       EEwsConnection *cnc = data;
-
-       g_return_if_fail (cnc != NULL);
-
-       e_ews_connection_utils_authenticate (cnc, sess, msg, auth, retrying);
-}
-
 void
 ews_oal_free (EwsOAL *oal)
 {
@@ -2640,11 +1700,6 @@ e_ews_connection_new_full (ESource *source,
                cnc->priv->impersonate_user = NULL;
        }
 
-       e_binding_bind_property (
-               settings, "timeout",
-               cnc->priv->soup_session, "timeout",
-               G_BINDING_SYNC_CREATE);
-
        if (allow_connection_reuse) {
                /* add the connection to the loaded_connections_permissions hash table */
                if (loaded_connections_permissions == NULL)
@@ -2719,13 +1774,6 @@ e_ews_connection_update_credentials (EEwsConnection *cnc,
        g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
 
        if (credentials) {
-               const gchar *password;
-
-               /* Update password only if it's provided, otherwise keep the previously set, if any */
-               password = e_named_parameters_get (credentials, E_SOURCE_CREDENTIAL_PASSWORD);
-               if (password && *password)
-                       e_ews_connection_set_password (cnc, password);
-
                if (e_named_parameters_get (credentials, E_SOURCE_CREDENTIAL_USERNAME)) {
                        CamelNetworkSettings *network_settings;
 
@@ -2735,6 +1783,12 @@ e_ews_connection_update_credentials (EEwsConnection *cnc,
        } else {
                e_ews_connection_set_password (cnc, NULL);
        }
+
+       g_mutex_lock (&cnc->priv->property_lock);
+       cnc->priv->credentials_changed = TRUE;
+       e_named_parameters_free (cnc->priv->credentials);
+       cnc->priv->credentials = credentials ? e_named_parameters_new_clone (credentials) : NULL;
+       g_mutex_unlock (&cnc->priv->property_lock);
 }
 
 ESourceAuthenticationResult
@@ -2784,15 +1838,13 @@ e_ews_connection_try_credentials_sync (EEwsConnection *cnc,
 
        if (local_error == NULL) {
                result = E_SOURCE_AUTHENTICATION_ACCEPTED;
-       } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED) &&
+       } else if (g_error_matches (local_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE) &&
                   e_ews_connection_get_ssl_error_details (cnc, out_certificate_pem, out_certificate_errors)) 
{
                result = E_SOURCE_AUTHENTICATION_ERROR_SSL_FAILED;
        } else {
                gboolean auth_failed;
 
-               auth_failed = g_error_matches (
-                       local_error, EWS_CONNECTION_ERROR,
-                       EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED);
+               auth_failed = g_error_matches (local_error, EWS_CONNECTION_ERROR, 
EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED);
 
                if (auth_failed) {
                        g_clear_error (&local_error);
@@ -2854,63 +1906,18 @@ e_ews_connection_get_uri (EEwsConnection *cnc)
        return cnc->priv->uri;
 }
 
-ESoupAuthBearer *
-e_ews_connection_ref_bearer_auth (EEwsConnection *cnc)
-{
-       ESoupAuthBearer *bearer_auth;
-
-       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), NULL);
-
-       g_mutex_lock (&cnc->priv->property_lock);
-       bearer_auth = cnc->priv->bearer_auth;
-       if (bearer_auth)
-               g_object_ref (bearer_auth);
-       g_mutex_unlock (&cnc->priv->property_lock);
-
-       return bearer_auth;
-}
-
-void
-e_ews_connection_set_bearer_auth (EEwsConnection *cnc,
-                                 ESoupAuthBearer *bearer_auth)
-{
-       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
-       if (bearer_auth)
-               g_return_if_fail (E_IS_SOUP_AUTH_BEARER (bearer_auth));
-
-       g_mutex_lock (&cnc->priv->property_lock);
-
-       if (bearer_auth != cnc->priv->bearer_auth) {
-               g_clear_object (&cnc->priv->bearer_auth);
-               cnc->priv->bearer_auth = bearer_auth;
-
-               if (cnc->priv->bearer_auth)
-                       g_object_ref (cnc->priv->bearer_auth);
-       }
-
-       g_mutex_unlock (&cnc->priv->property_lock);
-}
-
-const gchar *
-e_ews_connection_get_password (EEwsConnection *cnc)
-{
-       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), NULL);
-
-       return cnc->priv->password;
-}
-
 gchar *
 e_ews_connection_dup_password (EEwsConnection *cnc)
 {
-       const gchar *protected;
+       const gchar *password;
        gchar *duplicate;
 
        g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), NULL);
 
        g_mutex_lock (&cnc->priv->property_lock);
 
-       protected = e_ews_connection_get_password (cnc);
-       duplicate = g_strdup (protected);
+       password = cnc->priv->credentials ? e_named_parameters_get (cnc->priv->credentials, 
E_SOURCE_CREDENTIAL_PASSWORD) : NULL;
+       duplicate = g_strdup (password && *password ? password : NULL);
 
        g_mutex_unlock (&cnc->priv->property_lock);
 
@@ -2925,12 +1932,18 @@ e_ews_connection_set_password (EEwsConnection *cnc,
 
        g_mutex_lock (&cnc->priv->property_lock);
 
-       /* Zero-fill the old password before freeing it. */
-       if (cnc->priv->password != NULL && *cnc->priv->password != '\0')
-               memset (cnc->priv->password, 0, strlen (cnc->priv->password));
+       if (cnc->priv->credentials) {
+               cnc->priv->credentials_changed = TRUE;
 
-       g_free (cnc->priv->password);
-       cnc->priv->password = g_strdup (password);
+               if (password && *password)
+                       e_named_parameters_set (cnc->priv->credentials, E_SOURCE_CREDENTIAL_PASSWORD, 
password);
+               else
+                       e_named_parameters_set (cnc->priv->credentials, E_SOURCE_CREDENTIAL_PASSWORD, NULL);
+       } else if (password && *password) {
+               cnc->priv->credentials_changed = TRUE;
+               cnc->priv->credentials = e_named_parameters_new ();
+               e_named_parameters_set (cnc->priv->credentials, E_SOURCE_CREDENTIAL_PASSWORD, password);
+       }
 
        g_mutex_unlock (&cnc->priv->property_lock);
 
@@ -3000,14 +2013,6 @@ e_ews_connection_ref_settings (EEwsConnection *cnc)
        return g_object_ref (cnc->priv->settings);
 }
 
-SoupSession *
-e_ews_connection_ref_soup_session (EEwsConnection *cnc)
-{
-       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), NULL);
-
-       return g_object_ref (cnc->priv->soup_session);
-}
-
 gboolean
 e_ews_connection_get_backoff_enabled (EEwsConnection *cnc)
 {
@@ -3033,45 +2038,185 @@ e_ews_connection_get_disconnected_flag (EEwsConnection *cnc)
        return cnc->priv->disconnected_flag;
 }
 
-void
-e_ews_connection_set_disconnected_flag (EEwsConnection *cnc,
-                                       gboolean disconnected_flag)
+void
+e_ews_connection_set_disconnected_flag (EEwsConnection *cnc,
+                                       gboolean disconnected_flag)
+{
+       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
+
+       cnc->priv->disconnected_flag = disconnected_flag;
+}
+
+gchar *
+e_ews_connection_dup_last_subscription_id (EEwsConnection *cnc)
+{
+       gchar *res;
+
+       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), NULL);
+
+       g_mutex_lock (&cnc->priv->property_lock);
+
+       res = g_strdup (cnc->priv->last_subscription_id);
+
+       g_mutex_unlock (&cnc->priv->property_lock);
+
+       return res;
+}
+
+void
+e_ews_connection_set_last_subscription_id (EEwsConnection *cnc,
+                                          const gchar *subscription_id)
+{
+       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
+
+       g_mutex_lock (&cnc->priv->property_lock);
+
+       if (g_strcmp0 (subscription_id, cnc->priv->last_subscription_id) != 0) {
+               g_free (cnc->priv->last_subscription_id);
+               cnc->priv->last_subscription_id = g_strdup (subscription_id);
+       }
+
+       g_mutex_unlock (&cnc->priv->property_lock);
+}
+
+static gboolean
+e_ews_process_generic_response (EEwsConnection *cnc,
+                               ESoapResponse *response,
+                               GError **error)
+{
+       ESoapParameter *param;
+       ESoapParameter *subparam;
+       GError *local_error = NULL;
+
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
+
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
+
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
+       }
+
+       subparam = e_soap_parameter_get_first_child (param);
+
+       while (subparam != NULL) {
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
+
+               subparam = e_soap_parameter_get_next_child (subparam);
+       }
+
+       return TRUE;
+}
+
+typedef gpointer (*ItemParser) (ESoapParameter *param);
+
+static void
+e_ews_process_sync_xxx_response (ESoapParameter *subparam,
+                                ItemParser parser,
+                                const gchar *last_tag,
+                                const gchar *delete_id_tag,
+                                gchar **out_new_sync_state,
+                                gboolean *out_includes_last_item,
+                                GSList **out_items_created,
+                                GSList **out_items_updated,
+                                GSList **out_items_deleted)
 {
-       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
+       ESoapParameter *node;
+       gchar *new_sync_state = NULL, *value, *last;
+       GSList *items_created = NULL, *items_updated = NULL, *items_deleted = NULL;
+       gboolean includes_last_item;
 
-       cnc->priv->disconnected_flag = disconnected_flag;
-}
+       node = e_soap_parameter_get_first_child_by_name (subparam, "SyncState");
+       new_sync_state = e_soap_parameter_get_string_value (node);
 
-gchar *
-e_ews_connection_dup_last_subscription_id (EEwsConnection *cnc)
-{
-       gchar *res;
+       node = e_soap_parameter_get_first_child_by_name (subparam, last_tag);
+       last = e_soap_parameter_get_string_value (node);
+       /*
+        * Set the includes_last_item to TRUE as default.
+        * It can avoid an infinite loop in caller, when, for some reason,
+        * we don't receive the last_tag property from the server.
+        */
+       includes_last_item = g_strcmp0 (last, "false") != 0;
+       g_free (last);
 
-       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), NULL);
+       node = e_soap_parameter_get_first_child_by_name (subparam, "Changes");
 
-       g_mutex_lock (&cnc->priv->property_lock);
+       if (node) {
+               ESoapParameter *subparam1;
+               for (subparam1 = e_soap_parameter_get_first_child_by_name (node, "Create");
+                    subparam1 != NULL;
+                    subparam1 = e_soap_parameter_get_next_child_by_name (subparam1, "Create")) {
+                       GObject *object;
 
-       res = g_strdup (cnc->priv->last_subscription_id);
+                       object = parser (subparam1);
+                       if (object && (!E_IS_EWS_FOLDER (object) || !e_ews_folder_get_is_hidden (E_EWS_FOLDER 
(object))))
+                               items_created = g_slist_prepend (items_created, object);
+                       else
+                               g_clear_object (&object);
+               }
 
-       g_mutex_unlock (&cnc->priv->property_lock);
+               for (subparam1 = e_soap_parameter_get_first_child_by_name (node, "Update");
+                    subparam1 != NULL;
+                    subparam1 = e_soap_parameter_get_next_child_by_name (subparam1, "Update")) {
+                       GObject *object;
 
-       return res;
-}
+                       object = parser (subparam1);
+                       if (object && (!E_IS_EWS_FOLDER (object) || !e_ews_folder_get_is_hidden (E_EWS_FOLDER 
(object))))
+                               items_updated = g_slist_prepend (items_updated, object);
+                       else
+                               g_clear_object (&object);
+               }
+                 /* Exchange 2007SP1 introduced <ReadFlagChange> which is basically identical
+                  * to <Update>; no idea why they thought it was a good idea. */
+               for (subparam1 = e_soap_parameter_get_first_child_by_name (node, "ReadFlagChange");
+                    subparam1 != NULL;
+                    subparam1 = e_soap_parameter_get_next_child_by_name (subparam1, "ReadFlagChange")) {
+                       GObject *object;
 
-void
-e_ews_connection_set_last_subscription_id (EEwsConnection *cnc,
-                                          const gchar *subscription_id)
-{
-       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
+                       object = parser (subparam1);
+                       if (object && (!E_IS_EWS_FOLDER (object) || !e_ews_folder_get_is_hidden (E_EWS_FOLDER 
(object))))
+                               items_updated = g_slist_prepend (items_updated, object);
+                       else
+                               g_clear_object (&object);
+               }
 
-       g_mutex_lock (&cnc->priv->property_lock);
+               for (subparam1 = e_soap_parameter_get_first_child_by_name (node, "Delete");
+                    subparam1 != NULL;
+                    subparam1 = e_soap_parameter_get_next_child_by_name (subparam1, "Delete")) {
+                       ESoapParameter *folder_param;
 
-       if (g_strcmp0 (subscription_id, cnc->priv->last_subscription_id) != 0) {
-               g_free (cnc->priv->last_subscription_id);
-               cnc->priv->last_subscription_id = g_strdup (subscription_id);
+                       folder_param = e_soap_parameter_get_first_child_by_name (subparam1, delete_id_tag);
+                       value = e_soap_parameter_get_property (folder_param, "Id");
+                       items_deleted = g_slist_prepend (items_deleted, value);
+               }
        }
 
-       g_mutex_unlock (&cnc->priv->property_lock);
+       if (out_new_sync_state)
+               *out_new_sync_state = new_sync_state;
+       else
+               g_free (new_sync_state);
+
+       if (out_includes_last_item)
+               *out_includes_last_item = includes_last_item;
+
+       if (out_items_created)
+               *out_items_created = g_slist_reverse (items_created);
+       else
+               g_slist_free_full (items_created, g_object_unref);
+
+       if (out_items_updated)
+               *out_items_updated = g_slist_reverse (items_updated);
+       else
+               g_slist_free_full (items_updated, g_object_unref);
+
+       if (out_items_deleted)
+               *out_items_deleted = g_slist_reverse (items_deleted);
+       else
+               g_slist_free_full (items_deleted, g_free);
 }
 
 static xmlDoc *
@@ -3099,57 +2244,42 @@ e_ews_autodiscover_ws_xml (const gchar *email_address)
        return doc;
 }
 
-struct _autodiscover_data {
-       EEwsConnection *cnc;
-       xmlOutputBuffer *buf;
-       SoupMessage *msgs[6];
+typedef struct _AutodiscoverData {
+       guint n_pending;
 
+       /* Borrowed */
+       GMainLoop *main_loop;
+       CamelEwsSettings *settings;
+       ESoupSession *session;
        GCancellable *cancellable;
-       gulong cancel_id;
 
-       GError *error;
+       /* Allocated */
+       xmlOutputBuffer *buf;
+
        gchar *redirect_addr;
        gchar *redirect_url;
        gint n_redirects;
 
        /* Results */
+       gboolean success;
+       gchar *certificate_pem;
+       GTlsCertificateFlags certificate_errors;
+       GError *error;
        gchar *as_url;
        gchar *oab_url;
-};
+} AutodiscoverData;
 
 static void
-autodiscover_data_free (struct _autodiscover_data *ad)
+autodiscover_data_clear (AutodiscoverData *ad)
 {
-       xmlOutputBufferClose (ad->buf);
-
-       if (ad->cancellable != NULL) {
-               g_cancellable_disconnect (ad->cancellable, ad->cancel_id);
-               g_object_unref (ad->cancellable);
-       }
-
-       /* Unref the connection after the cancellable is disconnected,
-          to avoid race condition when the connection is freed inside
-          the g_cancellable_disconnect() function, which holds the
-          cancellable lock and blocks all other threads, while at
-          the same time the connection can wait for the finish of
-          its worker thread. */
-       g_object_unref (ad->cnc);
-
+       g_clear_pointer (&ad->buf, xmlOutputBufferClose);
        g_clear_error (&ad->error);
 
        g_free (ad->redirect_addr);
        g_free (ad->redirect_url);
+       g_free (ad->certificate_pem);
        g_free (ad->as_url);
        g_free (ad->oab_url);
-
-       g_slice_free (struct _autodiscover_data, ad);
-}
-
-static void
-autodiscover_cancelled_cb (GCancellable *cancellable,
-                           EEwsConnection *cnc)
-{
-       ews_connection_schedule_abort (cnc);
 }
 
 /* Frees only the content, not the 'urls' structure itself */
@@ -3169,79 +2299,37 @@ ews_urls_free_content (EwsUrls *urls)
 }
 
 static gboolean
-e_ews_discover_prepare_messages_and_send (GSimpleAsyncResult *simple,
-                                         const gchar *email_address,
-                                         const gchar *override_url,
-                                         GError **error);
+e_ews_autodiscover_prepare_requests_and_send_sync (AutodiscoverData *ad,
+                                                  const gchar *email_address,
+                                                  const gchar *override_url,
+                                                  GCancellable *cancellable);
 
-/* Called when each soup message completes */
 static void
-autodiscover_response_cb (SoupSession *session,
-                          SoupMessage *msg,
-                          gpointer data)
+ews_process_autodiscover_response (AutodiscoverData *ad,
+                                  GByteArray *bytes,
+                                  GError **error)
 
 {
-       GSimpleAsyncResult *simple = data;
-       struct _autodiscover_data *ad;
        EwsUrls exch_urls, expr_urls;
-       guint status = msg->status_code;
        xmlDoc *doc;
        xmlNode *node;
        gchar *str;
-       gint idx;
-       GError *error = NULL;
+
+       g_return_if_fail (bytes != NULL);
 
        memset (&exch_urls, 0, sizeof (EwsUrls));
        memset (&expr_urls, 0, sizeof (EwsUrls));
 
-       ad = g_simple_async_result_get_op_res_gpointer (simple);
-
-       for (idx = 0; idx < 6; idx++) {
-               if (ad->msgs[idx] == msg)
-                       break;
-       }
-       if (idx == 6 || (idx == 5 && !ad->msgs[5])) {
-               /* We already got removed (cancelled). Do nothing */
-               goto unref;
-       }
-
-       ad->msgs[idx] = NULL;
-
-       if (status != 200) {
-               gboolean expired = FALSE;
-               gchar *service_url = NULL;
-
-               if (e_ews_connection_utils_check_x_ms_credential_headers (msg, NULL, &expired, &service_url) 
&& expired) {
-                       e_ews_connection_utils_expired_password_to_error (service_url, &error);
-               } else {
-                       g_set_error (
-                               &error, SOUP_HTTP_ERROR, status,
-                               "%d %s", status, msg->reason_phrase);
-
-                       if (status == SOUP_STATUS_SSL_FAILED)
-                               ews_connection_check_ssl_error (ad->cnc, msg);
-               }
-
-               g_free (service_url);
-
-               goto failed;
-       }
+       doc = xmlReadMemory ((const gchar *) bytes->data, bytes->len, "autodiscover.xml", NULL, 0);
 
-       e_ews_debug_dump_raw_soup_response (msg);
-       doc = xmlReadMemory (
-               msg->response_body->data,
-               msg->response_body->length,
-               "autodiscover.xml", NULL, 0);
        if (!doc) {
-               g_set_error (
-                       &error, EWS_CONNECTION_ERROR, -1,
+               g_set_error_literal (error, EWS_CONNECTION_ERROR, -1,
                        _("Failed to parse autodiscover response XML"));
-               goto failed;
+               return;
        }
        node = xmlDocGetRootElement (doc);
        if (strcmp ((gchar *) node->name, "Autodiscover")) {
-               g_set_error (
-                       &error, EWS_CONNECTION_ERROR, -1,
+               g_set_error_literal (error, EWS_CONNECTION_ERROR, -1,
                        _("Failed to find <Autodiscover> element"));
                goto failed;
        }
@@ -3251,8 +2339,7 @@ autodiscover_response_cb (SoupSession *session,
                        break;
        }
        if (!node) {
-               g_set_error (
-                       &error, EWS_CONNECTION_ERROR, -1,
+               g_set_error_literal (error, EWS_CONNECTION_ERROR, -1,
                        _("Failed to find <Response> element"));
                goto failed;
        }
@@ -3262,8 +2349,7 @@ autodiscover_response_cb (SoupSession *session,
                        break;
        }
        if (!node) {
-               g_set_error (
-                       &error, EWS_CONNECTION_ERROR, -1,
+               g_set_error_literal (error, EWS_CONNECTION_ERROR, -1,
                        _("Failed to find <Account> element"));
                goto failed;
        }
@@ -3308,38 +2394,29 @@ autodiscover_response_cb (SoupSession *session,
        if (!exch_urls.as_url && !expr_urls.as_url) {
                ews_urls_free_content (&exch_urls);
                ews_urls_free_content (&expr_urls);
-               g_set_error (
-                       &error, EWS_CONNECTION_ERROR, -1,
+               g_set_error_literal (error, EWS_CONNECTION_ERROR, -1,
                        _("Failed to find <ASUrl> in autodiscover response"));
                goto failed;
        }
 
-       /* We have a good response; cancel all the others */
-       for (idx = 0; idx < 6; idx++) {
-               if (ad->msgs[idx]) {
-                       SoupMessage *m = ad->msgs[idx];
-                       ad->msgs[idx] = NULL;
-                       ews_connection_schedule_cancel_message (ad->cnc, m);
-               }
-       }
+       ad->success = TRUE;
+
+       /* It's a good response, cancel all pending */
+       g_cancellable_cancel (ad->cancellable);
 
        if (expr_urls.as_url) {
-               if (ad->as_url)
-                       g_free (ad->as_url);
+               g_free (ad->as_url);
                ad->as_url = g_strdup ((gchar *) expr_urls.as_url);
        } else if (exch_urls.as_url) {
-               if (ad->as_url)
-                       g_free (ad->as_url);
+               g_free (ad->as_url);
                ad->as_url = g_strdup ((gchar *) exch_urls.as_url);
        }
 
        if (expr_urls.as_url && expr_urls.oab_url) {
-               if (ad->oab_url)
-                       g_free (ad->oab_url);
+               g_free (ad->oab_url);
                ad->oab_url = g_strdup ((gchar *) expr_urls.oab_url);
        } else if (!expr_urls.as_url && exch_urls.oab_url) {
-               if (ad->oab_url)
-                       g_free (ad->oab_url);
+               g_free (ad->oab_url);
                ad->oab_url = g_strdup ((gchar *) exch_urls.oab_url);
        }
 
@@ -3349,59 +2426,11 @@ autodiscover_response_cb (SoupSession *session,
        goto exit;
 
  failed:
-       for (idx = 0; idx < 6; idx++) {
-               if (ad->msgs[idx]) {
-                       /* Preserve any Unauthorized/SSL failed errors */
-                       if (!g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_NONE) &&
-                           !g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) &&
-                           !g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED) &&
-                           (!ad->error ||
-                           g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) ||
-                           g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED) ||
-                           g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_NONE) ||
-                           g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_CANT_RESOLVE) ||
-                           g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_CANT_RESOLVE_PROXY) ||
-                           g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_CANT_CONNECT) ||
-                           g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_CANT_CONNECT_PROXY))) {
-                               g_clear_error (&ad->error);
-                               ad->error = error;
-                               error = NULL;
-                       } else {
-                               g_clear_error (&error);
-                       }
-
-                       /* There's another request outstanding.
-                        * Hope that it has better luck. */
-                       goto unref;
-               }
-       }
-
-       /* Preserve any Unauthorized/SSL failed errors */
-       if (!g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_NONE) &&
-           !g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) &&
-           !g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED) &&
-           (!ad->error ||
-           g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) ||
-           g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED) ||
-           g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_NONE) ||
-           g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_CANT_RESOLVE) ||
-           g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_CANT_RESOLVE_PROXY) ||
-           g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_CANT_CONNECT) ||
-           g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_CANT_CONNECT_PROXY))) {
-               g_clear_error (&ad->error);
-               ad->error = error;
-               error = NULL;
-       }
-
-       g_clear_error (&error);
-
        if (!g_cancellable_is_cancelled (ad->cancellable) &&
            (!ad->as_url || !ad->oab_url) && ad->n_redirects < 11 &&
            (ad->redirect_url || ad->redirect_addr) &&
-           !g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) &&
-           !g_error_matches (ad->error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED)) {
-               CamelEwsSettings *settings = NULL;
-               gboolean re_scheduled;
+           !g_error_matches (ad->error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED) &&
+           (!ad->error || (ad->error->domain != G_IO_ERROR && ad->error->domain != G_TLS_ERROR))) {
                const gchar *host_url;
                gchar *redirect_addr, *redirect_url;
                GError *local_error;
@@ -3417,81 +2446,27 @@ autodiscover_response_cb (SoupSession *session,
                ad->error = NULL;
 
                host_url = redirect_url;
-               settings = e_ews_connection_ref_settings (ad->cnc);
 
                if (!host_url)
-                       host_url = camel_ews_settings_get_hosturl (settings);
+                       host_url = camel_ews_settings_get_hosturl (ad->settings);
 
-               re_scheduled = e_ews_discover_prepare_messages_and_send (simple, redirect_addr, host_url, 
NULL);
-
-               g_clear_object (&settings);
+               e_ews_autodiscover_prepare_requests_and_send_sync (ad, redirect_addr, host_url, 
ad->cancellable);
 
+               g_clear_error (&local_error);
                g_free (redirect_addr);
                g_free (redirect_url);
-
-               if (re_scheduled) {
-                       g_clear_error (&local_error);
-                       goto unref;
-               }
-
-               ad->error = local_error;
        }
 
-       /* FIXME: We're actually returning the *last* error here,
-        * and in some cases (stupid firewalls causing timeouts)
-        * that's going to be the least interesting one. We probably
-        * want the *first* error */
-       g_simple_async_result_take_error (simple, ad->error);
-
-       ad->error = NULL;
-
  exit:
-       g_simple_async_result_complete_in_idle (simple);
-
- unref:
-       /* This function is processed within e_ews_soup_thread() and the 'simple'
-        * holds reference to EEwsConnection. For cases when this is the last
-        * reference to 'simple' the unref would cause crash, because of g_thread_join()
-        * in connection's dispose, trying to wait on the end of itself, thus it's
-        * safer to unref the 'simple' in a dedicated thread.
-       */
-       e_ews_connection_utils_unref_in_thread (simple);
-}
-
-static void
-post_restarted (SoupMessage *msg,
-               gpointer data)
-{
-       xmlOutputBuffer *buf = data;
-
-       /* Not all restarts are due to a redirect; some are for auth */
-       if (msg->status_code == 401)
-               return;
-
-       /* In violation of RFC2616, libsoup will change a POST request to
-        * a GET on receiving a 302 redirect. */
-       printf ("Working around libsoup bug with redirect\n");
-       g_object_set (msg, SOUP_MESSAGE_METHOD, "POST", NULL);
-
-       soup_message_set_request (
-               msg, "text/xml; charset=utf-8", SOUP_MEMORY_COPY,
-               (gchar *)
-                       #ifdef LIBXML2_NEW_BUFFER
-                       xmlOutputBufferGetContent (buf), xmlOutputBufferGetSize (buf)
-                       #else
-                       buf->buffer->content, buf->buffer->use
-                       #endif
-               );
+       xmlFreeDoc (doc);
 }
 
-static SoupMessage *
-e_ews_get_msg_for_url (EEwsConnection *cnc,
-                      const gchar *url,
-                       xmlOutputBuffer *buf,
-                       GError **error)
+static ESoapRequest *
+e_ews_create_request_for_url (const gchar *url,
+                             xmlOutputBuffer *buf,
+                             GError **error)
 {
-       SoupMessage *msg;
-       CamelEwsSettings *settings;
+       ESoapRequest *request;
 
        if (url == NULL) {
                g_set_error_literal (
@@ -3500,176 +2475,57 @@ e_ews_get_msg_for_url (EEwsConnection *cnc,
                return NULL;
        }
 
-       msg = soup_message_new (buf != NULL ? "POST" : "GET", url);
-       if (!msg) {
-               g_set_error (
-                       error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
-                       _("URL ā€œ%sā€ is not valid"), url);
+       request = e_soap_request_new (buf ? SOUP_METHOD_POST : SOUP_METHOD_GET, url, FALSE, NULL, NULL, NULL, 
error);
+       if (!request)
                return NULL;
-       }
 
-       if (cnc->priv->source)
-               e_soup_ssl_trust_connect (msg, cnc->priv->source);
-
-       e_ews_message_attach_chunk_allocator (msg);
-
-       settings = e_ews_connection_ref_settings (cnc);
-       e_ews_message_set_user_agent_header (msg, settings);
-       g_clear_object (&settings);
-
-       if (buf != NULL) {
-               soup_message_set_request (
-                       msg, "text/xml; charset=utf-8", SOUP_MEMORY_COPY,
-                       (gchar *)
+       if (buf) {
+               e_soap_request_set_custom_body (request, "text/xml; charset=utf-8",
                        #ifdef LIBXML2_NEW_BUFFER
                        xmlOutputBufferGetContent (buf), xmlOutputBufferGetSize (buf)
                        #else
                        buf->buffer->content, buf->buffer->use
                        #endif
                        );
-               g_signal_connect (
-                       msg, "restarted",
-                       G_CALLBACK (post_restarted), buf);
-       }
-
-       e_ews_debug_dump_raw_soup_request (msg);
-
-       return msg;
-}
-
-static void
-autodiscover_srv_record_resolved_cb (GObject *source,
-                                    GAsyncResult *result,
-                                    gpointer user_data)
-{
-       GList *targets, *link;
-       GSimpleAsyncResult *simple = user_data;
-       struct _autodiscover_data *ad;
-       gchar *new_uri = NULL;
-       gboolean success;
-
-       ad = g_simple_async_result_get_op_res_gpointer (simple);
-
-       g_return_if_fail (ad != NULL);
-
-       targets = g_resolver_lookup_service_finish (G_RESOLVER (source), result, NULL);
-
-       success = ad->msgs[5] && targets;
-
-       for (link = targets; link && success; link = g_list_next (link)) {
-               GSrvTarget *target = link->data;
-               const gchar *hostname;
-
-               hostname = g_srv_target_get_hostname (target);
-
-               switch (g_srv_target_get_port (target)) {
-               case 80:
-                       link = NULL;
-                       new_uri = g_strdup_printf ("http://%s/autodiscover/autodiscover.xml";, hostname);
-                       break;
-               case 443:
-                       link = NULL;
-                       new_uri = g_strdup_printf ("https://%s/autodiscover/autodiscover.xml";, hostname);
-                       break;
-               }
-       }
-
-       g_list_free_full (targets, (GDestroyNotify) g_srv_target_free);
-
-       if (new_uri && success) {
-               SoupURI *suri;
-
-               suri = soup_uri_new (new_uri);
-               if (suri) {
-                       soup_message_set_uri (ad->msgs[5], suri);
-                       /* The autodiscover_response_cb will free the 'simple' */
-                       ews_connection_schedule_queue_message (ad->cnc, ad->msgs[5], 
autodiscover_response_cb, simple);
-                       soup_uri_free (suri);
-               } else {
-                       success = FALSE;
-               }
        } else {
-               success = FALSE;
-       }
-
-       if (!success) {
-               /* The callback also frees the 'simple' */
-               autodiscover_response_cb (NULL, ad->msgs[5], simple);
+               /* No body set for the GET request */
+               e_soap_request_set_custom_body (request, "", NULL, 0);
        }
 
-       g_free (new_uri);
-}
-
-gboolean
-e_ews_autodiscover_ws_url_sync (ESource *source,
-                               CamelEwsSettings *settings,
-                                const gchar *email_address,
-                                const gchar *password,
-                               gchar **out_certificate_pem,
-                               GTlsCertificateFlags *out_certificate_errors,
-                                GCancellable *cancellable,
-                                GError **error)
-{
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
-
-       g_return_val_if_fail (CAMEL_IS_EWS_SETTINGS (settings), FALSE);
-       g_return_val_if_fail (email_address != NULL, FALSE);
-       g_return_val_if_fail (password != NULL, FALSE);
-
-       closure = e_async_closure_new ();
-
-       e_ews_autodiscover_ws_url (source, settings, email_address, password, cancellable,
-               e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_autodiscover_ws_url_finish (settings, result, out_certificate_pem, 
out_certificate_errors, error);
-
-       e_async_closure_free (closure);
-
-       return success;
+       return request;
 }
 
-static gboolean
-e_ews_discover_prepare_messages_and_send (GSimpleAsyncResult *simple,
-                                         const gchar *email_address,
-                                         const gchar *override_url,
-                                         GError **error)
+static GSList * /* ESoapRequest * */
+e_ews_autodiscover_prepare_requests (AutodiscoverData *ad,
+                                    const gchar *email_address,
+                                    const gchar *override_url,
+                                    gchar **out_srv_lookup_domain,
+                                    GError **error)
 {
-       SoupURI *soup_uri = NULL;
+       GUri *uri = NULL;
        gboolean use_secure = TRUE;
        gboolean is_outlook = FALSE;
        gchar *url1, *url2, *url3, *url4;
        const gchar *url5, *domain = NULL;
-       struct _autodiscover_data *ad;
+       GSList *requests = NULL;
+       xmlDoc *doc;
+       xmlOutputBuffer *buf;
        GError *local_error = NULL;
 
-       ad = g_simple_async_result_get_op_res_gpointer (simple);
-       g_return_val_if_fail (ad != NULL, FALSE);
-
-       if (email_address) {
-               xmlDoc *doc;
-
-               if (ad->buf)
-                       xmlOutputBufferClose (ad->buf);
-
-               doc = e_ews_autodiscover_ws_xml (email_address);
-               ad->buf = xmlAllocOutputBuffer (NULL);
-               xmlNodeDumpOutput (ad->buf, doc, xmlDocGetRootElement (doc), 0, 1, NULL);
-               xmlOutputBufferFlush (ad->buf);
-
-               xmlFreeDoc (doc);
+       g_return_val_if_fail (email_address && *email_address, FALSE);
 
-               domain = strchr (email_address, '@');
-               if (domain)
-                       domain++;
-       }
+       domain = strchr (email_address, '@');
+       if (domain)
+               domain++;
 
-       g_return_val_if_fail (ad->buf != NULL, FALSE);
        g_return_val_if_fail ((domain && *domain) || (override_url && *override_url), FALSE);
 
+       doc = e_ews_autodiscover_ws_xml (email_address);
+       buf = xmlAllocOutputBuffer (NULL);
+       xmlNodeDumpOutput (buf, doc, xmlDocGetRootElement (doc), 0, 1, NULL);
+       xmlOutputBufferFlush (buf);
+       xmlFreeDoc (doc);
+
        url1 = NULL;
        url2 = NULL;
        url3 = NULL;
@@ -3677,11 +2533,11 @@ e_ews_discover_prepare_messages_and_send (GSimpleAsyncResult *simple,
        url5 = NULL;
 
        if (override_url)
-               soup_uri = soup_uri_new (override_url);
+               uri = g_uri_parse (override_url, SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
 
-       if (soup_uri) {
-               const gchar *host = soup_uri_get_host (soup_uri);
-               const gchar *scheme = soup_uri_get_scheme (soup_uri);
+       if (uri) {
+               const gchar *host = g_uri_get_host (uri);
+               const gchar *scheme = g_uri_get_scheme (uri);
 
                use_secure = g_strcmp0 (scheme, "https") == 0;
 
@@ -3711,7 +2567,7 @@ e_ews_discover_prepare_messages_and_send (GSimpleAsyncResult *simple,
                        #undef ON_MICROSOFT_COM_TEXT
                }
 
-               soup_uri_free (soup_uri);
+               g_uri_unref (uri);
        }
 
        is_outlook = is_outlook || (domain && g_ascii_strcasecmp (domain, "outlook.com") == 0);
@@ -3721,46 +2577,29 @@ e_ews_discover_prepare_messages_and_send (GSimpleAsyncResult *simple,
                url4 = g_strdup_printf ("http%s://autodiscover.%s/autodiscover/autodiscover.xml", use_secure 
? "s" : "", domain);
        }
 
-       /* Passing a NULL URL string returns NULL. */
-       ad->msgs[0] = e_ews_get_msg_for_url (ad->cnc, url1, ad->buf, &local_error);
-       ad->msgs[1] = e_ews_get_msg_for_url (ad->cnc, url2, ad->buf, local_error ? NULL : &local_error);
-       ad->msgs[2] = e_ews_get_msg_for_url (ad->cnc, url3, ad->buf, local_error ? NULL : &local_error);
-       ad->msgs[3] = e_ews_get_msg_for_url (ad->cnc, url4, ad->buf, local_error ? NULL : &local_error);
-       ad->msgs[4] = e_ews_get_msg_for_url (ad->cnc, url5, ad->buf, local_error ? NULL : &local_error);
+       #define process_url(_url) G_STMT_START { \
+               if (_url) { \
+                       ESoapRequest *request = e_ews_create_request_for_url (_url, buf, local_error ? NULL : 
&local_error); \
+                       if (request) \
+                               requests = g_slist_prepend (requests, request); \
+               } \
+       } G_STMT_END
 
-       if (!is_outlook && domain && (ad->msgs[0] || ad->msgs[1] || ad->msgs[2] || ad->msgs[3] || 
ad->msgs[4])) {
-               gchar *tmp;
-
-               tmp = g_strdup_printf ("http%s://%s/", use_secure ? "s" : "", domain);
-
-               /* Fake SoupMessage, for the autodiscovery with SRV record help */
-               ad->msgs[5] = e_ews_get_msg_for_url (ad->cnc, tmp, ad->buf, local_error ? NULL : 
&local_error);
-
-               if (ad->msgs[5]) {
-                       g_resolver_lookup_service_async (g_resolver_get_default (), "autodiscover", "tcp", 
domain, ad->cancellable,
-                               autodiscover_srv_record_resolved_cb, g_object_ref (simple));
-               }
+       process_url (url1);
+       process_url (url2);
+       process_url (url3);
+       process_url (url4);
+       process_url (url5);
 
-               g_free (tmp);
-       } else {
-               ad->msgs[5] = NULL;
-       }
+       #undef process_url
 
-       if (local_error && (ad->msgs[0] || ad->msgs[1] || ad->msgs[2] || ad->msgs[3] || ad->msgs[4]))
+       if (local_error && requests)
                g_clear_error (&local_error);
 
-       /* These have to be submitted only after they're both set in ad->msgs[]
-        * or there will be races with fast completion */
-       if (ad->msgs[0] != NULL)
-               ews_connection_schedule_queue_message (ad->cnc, ad->msgs[0], autodiscover_response_cb, 
g_object_ref (simple));
-       if (ad->msgs[1] != NULL)
-               ews_connection_schedule_queue_message (ad->cnc, ad->msgs[1], autodiscover_response_cb, 
g_object_ref (simple));
-       if (ad->msgs[2] != NULL)
-               ews_connection_schedule_queue_message (ad->cnc, ad->msgs[2], autodiscover_response_cb, 
g_object_ref (simple));
-       if (ad->msgs[3] != NULL)
-               ews_connection_schedule_queue_message (ad->cnc, ad->msgs[3], autodiscover_response_cb, 
g_object_ref (simple));
-       if (ad->msgs[4] != NULL)
-               ews_connection_schedule_queue_message (ad->cnc, ad->msgs[4], autodiscover_response_cb, 
g_object_ref (simple));
+       if (!is_outlook && !local_error && domain && requests && out_srv_lookup_domain)
+               *out_srv_lookup_domain = g_strdup (domain);
+       else if (out_srv_lookup_domain)
+               *out_srv_lookup_domain = NULL;
 
        g_free (url1);
        g_free (url2);
@@ -3768,84 +2607,237 @@ e_ews_discover_prepare_messages_and_send (GSimpleAsyncResult *simple,
        g_free (url4);
 
        if (local_error) {
+               xmlOutputBufferClose (buf);
                g_propagate_error (error, local_error);
-               return FALSE;
+               return NULL;
        }
 
-       return TRUE;
+       g_clear_pointer (&ad->buf, xmlOutputBufferClose);
+       ad->buf = buf;
+
+       return requests;
 }
 
-void
-e_ews_autodiscover_ws_url (ESource *source,
-                          CamelEwsSettings *settings,
-                           const gchar *email_address,
-                           const gchar *password,
-                           GCancellable *cancellable,
-                           GAsyncReadyCallback callback,
-                           gpointer user_data)
-{
-       GSimpleAsyncResult *simple;
-       struct _autodiscover_data *ad;
-       const gchar *domain;
-       const gchar *host_url;
-       GError *error = NULL;
+typedef struct _AutodiscoverResponseData {
+       AutodiscoverData *ad;
+       SoupMessage *message;
+} AutodiscoverResponseData;
 
-       g_return_if_fail (CAMEL_IS_EWS_SETTINGS (settings));
-       g_return_if_fail (email_address != NULL);
-       g_return_if_fail (password != NULL);
+static void
+ews_autodiscover_response_ready_cb (GObject *source_object,
+                                   GAsyncResult *result,
+                                   gpointer user_data)
+{
+       AutodiscoverResponseData *ard = user_data;
+       AutodiscoverData *ad;
+       gchar *certificate_pem = NULL;
+       GTlsCertificateFlags certificate_errors = 0;
+       GInputStream *input_stream;
+       GError *local_error = NULL;
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (settings), callback,
-               user_data, e_ews_autodiscover_ws_url);
+       g_return_if_fail (ard != NULL);
 
-       domain = strchr (email_address, '@');
-       /* if it's non-NULL, then domain[0] == '@' */
-       if (!domain || !domain[1]) {
-               g_simple_async_result_set_error (
-                       simple, EWS_CONNECTION_ERROR, -1,
-                       "%s", _("Email address is missing a domain part"));
-               g_simple_async_result_complete_in_idle (simple);
-               g_object_unref (simple);
-               return;
+       ad = ard->ad;
+
+       input_stream = e_soup_session_send_message_finish (E_SOUP_SESSION (source_object), result,
+               &certificate_pem, &certificate_errors, &local_error);
+
+       if (input_stream) {
+               GByteArray *bytes;
+               gint expected_length;
+               gpointer buffer;
+               gsize nread = 0;
+               gboolean success;
+
+               expected_length = soup_message_headers_get_content_length (soup_message_get_response_headers 
(ard->message));
+               if (expected_length > 0)
+                       bytes = g_byte_array_sized_new (expected_length > 1024 * 1024 * 10 ? 1024 * 1024 * 10 
: expected_length);
+               else
+                       bytes = g_byte_array_new ();
+
+               buffer = g_malloc (BUFFER_SIZE);
+
+               while (success = g_input_stream_read_all (input_stream, buffer, BUFFER_SIZE, &nread, 
ad->cancellable, &local_error),
+                      success && nread > 0) {
+                       g_byte_array_append (bytes, buffer, nread);
+               }
+
+               if (success)
+                       ews_process_autodiscover_response (ad, bytes, &local_error);
+
+               g_free (buffer);
+               g_byte_array_free (bytes, TRUE);
+               g_object_unref (input_stream);
        }
 
-       /*
-        * http://msdn.microsoft.com/en-us/library/ee332364.aspx says we are
-        * supposed to try $domain and then autodiscover.$domain. But some
-        * people have broken firewalls on the former which drop packets
-        * instead of rejecting connections, and make the request take ages
-        * to time out. So run both queries in parallel and let the fastest
-        * (successful) one win.
-        */
-       ad = g_slice_new0 (struct _autodiscover_data);
-       ad->cnc = e_ews_connection_new (source, domain + 1, settings); /* Fake URI, it's not used here */
-       g_object_set (ad->cnc->priv->soup_session, SOUP_SESSION_TIMEOUT, 20, NULL);
-       e_ews_connection_set_password (ad->cnc, password);
+       if (local_error && (!ad->error ||
+           (!g_error_matches (ad->error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED) &&
+           (!ad->error || (ad->error->domain != G_IO_ERROR && ad->error->domain != G_TLS_ERROR))))) {
+               g_clear_pointer (&ad->certificate_pem, g_free);
+               ad->certificate_pem = certificate_pem;
+               ad->certificate_errors = certificate_errors;
+               ad->error = local_error;
+       } else {
+               g_free (certificate_pem);
+               g_clear_error (&local_error);
+       }
 
-       if (G_IS_CANCELLABLE (cancellable)) {
-               ad->cancellable = g_object_ref (cancellable);
-               ad->cancel_id = g_cancellable_connect (
-                       ad->cancellable,
-                       G_CALLBACK (autodiscover_cancelled_cb),
-                       g_object_ref (ad->cnc),
-                       g_object_unref);
+       if (!g_atomic_int_dec_and_test (&ad->n_pending))
+               g_main_loop_quit (ad->main_loop);
+
+       g_object_unref (ard->message);
+       g_slice_free (AutodiscoverResponseData, ard);
+}
+
+static void
+ews_autodiscover_send_request (AutodiscoverData *ad,
+                              ESoapRequest *request,
+                              GCancellable *cancellable,
+                              GError **error)
+{
+       SoupMessage *message;
+
+       message = e_soap_request_persist (request, ad->session, ad->settings, error);
+
+       if (message) {
+               gpointer prepare_data;
+
+               prepare_data = e_soup_session_prepare_message_send_sync (ad->session, message, cancellable, 
error);
+
+               if (prepare_data) {
+                       AutodiscoverResponseData *ard;
+
+                       g_atomic_int_inc (&ad->n_pending);
+
+                       ard = g_slice_new (AutodiscoverResponseData);
+                       ard->ad = ad;
+                       ard->message = g_object_ref (message);
+
+                       e_soup_session_send_message (ad->session, message, G_PRIORITY_DEFAULT, prepare_data,
+                               ad->cancellable, ews_autodiscover_response_ready_cb, ard);
+               }
+
+               g_object_unref (message);
        }
+}
+
+static void
+autodiscover_srv_record_resolved_cb (GObject *source,
+                                    GAsyncResult *result,
+                                    gpointer user_data)
+{
+       GList *targets, *link;
+       AutodiscoverData *ad = user_data;
+       gchar *new_uri = NULL;
+       gboolean success;
 
-       g_simple_async_result_set_op_res_gpointer (
-               simple, ad, (GDestroyNotify) autodiscover_data_free);
+       g_return_if_fail (ad != NULL);
 
-       host_url = camel_ews_settings_get_hosturl (settings);
+       targets = g_resolver_lookup_service_finish (G_RESOLVER (source), result, NULL);
+
+       success = !g_cancellable_is_cancelled (ad->cancellable) && targets;
+
+       for (link = targets; link && success; link = g_list_next (link)) {
+               GSrvTarget *target = link->data;
+               const gchar *hostname;
+
+               hostname = g_srv_target_get_hostname (target);
+
+               switch (g_srv_target_get_port (target)) {
+               case 80:
+                       link = NULL;
+                       new_uri = g_strdup_printf ("http://%s/autodiscover/autodiscover.xml";, hostname);
+                       break;
+               case 443:
+                       link = NULL;
+                       new_uri = g_strdup_printf ("https://%s/autodiscover/autodiscover.xml";, hostname);
+                       break;
+               }
+       }
+
+       g_list_free_full (targets, (GDestroyNotify) g_srv_target_free);
 
-       if (!e_ews_discover_prepare_messages_and_send (simple, email_address, host_url, &error)) {
-               g_simple_async_result_take_error (simple, error);
-               g_simple_async_result_complete_in_idle (simple);
+       if (new_uri && success) {
+               ESoapRequest *request = e_ews_create_request_for_url (new_uri, ad->buf, ad->error ? NULL : 
&ad->error);
+               if (request) {
+                       ews_autodiscover_send_request (ad, request, ad->cancellable, ad->error ? NULL : 
&ad->error);
+                       g_object_unref (request);
+               } else {
+                       success = FALSE;
+               }
        } else {
-               g_clear_error (&error);
+               success = FALSE;
+       }
+
+       if (!success && !g_atomic_int_dec_and_test (&ad->n_pending))
+               g_main_loop_quit (ad->main_loop);
+
+       g_free (new_uri);
+}
+
+static gboolean
+e_ews_autodiscover_prepare_requests_and_send_sync (AutodiscoverData *ad,
+                                                  const gchar *email_address,
+                                                  const gchar *override_url,
+                                                  GCancellable *cancellable)
+{
+       GSList *requests, *link;
+       gchar *srv_lookup_domain = NULL;
+       GError *local_error = NULL;
+
+       g_return_val_if_fail (ad != NULL, FALSE);
+
+       /* to not have the main loop quit while doing this */
+       g_atomic_int_inc (&ad->n_pending);
+
+       /* This is starting a new round, the last error and others are obsolete */
+       g_clear_error (&ad->error);
+       g_clear_pointer (&ad->as_url, g_free);
+       g_clear_pointer (&ad->oab_url, g_free);
+       g_clear_pointer (&ad->certificate_pem, g_free);
+       ad->certificate_errors = 0;
+
+       requests = e_ews_autodiscover_prepare_requests (ad, email_address, override_url, &srv_lookup_domain, 
&local_error);
 
-               /* each request holds a reference to 'simple',
-                * thus remove one, to have it actually freed */
-               g_object_unref (simple);
+       if (!local_error && srv_lookup_domain && *srv_lookup_domain) {
+               g_atomic_int_inc (&ad->n_pending);
+
+               g_resolver_lookup_service_async (g_resolver_get_default (), "autodiscover", "tcp", 
srv_lookup_domain, cancellable,
+                       autodiscover_srv_record_resolved_cb, ad);
+       }
+
+       for (link = requests; link; link = g_slist_next (link)) {
+               ESoapRequest *request = link->data;
+
+               ews_autodiscover_send_request (ad, request, cancellable, local_error ? NULL : &local_error);
+       }
+
+       if (local_error && (!ad->error ||
+           (!g_error_matches (ad->error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED) &&
+           (!ad->error || (ad->error->domain != G_IO_ERROR && ad->error->domain != G_TLS_ERROR))))) {
+               g_clear_error (&ad->error);
+               g_propagate_error (&ad->error, local_error);
+       } else {
+               g_clear_error (&local_error);
        }
+
+       /* pair decrement for the increment at the beginning of the function */
+       if (!g_atomic_int_dec_and_test (&ad->n_pending))
+               g_main_loop_quit (ad->main_loop);
+
+       g_slist_free_full (requests, g_object_unref);
+       g_free (srv_lookup_domain);
+
+       return requests != NULL;
+}
+
+static void
+e_ews_cancel_cancellable_cb (GCancellable *cancellable,
+                            gpointer user_data)
+{
+       GCancellable *op_cancellable = user_data;
+
+       g_cancellable_cancel (op_cancellable);
 }
 
 static gboolean
@@ -3873,104 +2865,135 @@ has_suffix_icmp (const gchar *text,
 }
 
 gboolean
-e_ews_autodiscover_ws_url_finish (CamelEwsSettings *settings,
-                                  GAsyncResult *result,
-                                 gchar **out_certificate_pem,
-                                 GTlsCertificateFlags *out_certificate_errors,
-                                  GError **error)
+e_ews_autodiscover_ws_url_sync (ESource *source,
+                               CamelEwsSettings *settings,
+                                const gchar *email_address,
+                                const gchar *password,
+                               gchar **out_certificate_pem,
+                               GTlsCertificateFlags *out_certificate_errors,
+                                GCancellable *cancellable,
+                                GError **error)
 {
-       GSimpleAsyncResult *simple;
-       struct _autodiscover_data *ad;
-       GError *local_error = NULL;
+       AutodiscoverData ad;
+       gulong cancelled_id = 0;
+       EEwsConnection *tmp_cnc;
+       GMainContext *main_context;
+       const gchar *domain;
+       const gchar *host_url;
 
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (settings),
-               e_ews_autodiscover_ws_url), FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       ad = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (g_simple_async_result_propagate_error (simple, &local_error)) {
-               if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED)) {
-                       if (!e_ews_connection_get_ssl_error_details (ad->cnc, out_certificate_pem, 
out_certificate_errors)) {
-                               if (out_certificate_pem)
-                                       *out_certificate_pem = NULL;
-                               if (out_certificate_errors)
-                                       *out_certificate_errors = 0;
-                       }
-               }
+       g_return_val_if_fail (CAMEL_IS_EWS_SETTINGS (settings), FALSE);
+       g_return_val_if_fail (email_address != NULL, FALSE);
+       g_return_val_if_fail (password != NULL, FALSE);
 
-               g_propagate_error (error, local_error);
+       domain = strchr (email_address, '@');
 
+       /* if it's non-NULL, then domain[0] == '@' */
+       if (!domain || !domain[1]) {
+               g_set_error_literal (error, EWS_CONNECTION_ERROR, -1, _("Email address is missing a domain 
part"));
                return FALSE;
        }
 
-       g_warn_if_fail (ad->as_url != NULL);
-       g_warn_if_fail (ad->oab_url != NULL);
+       memset (&ad, 0, sizeof (AutodiscoverData));
 
-       camel_ews_settings_set_hosturl (settings, ad->as_url);
+       ad.settings = settings;
+       ad.cancellable = g_cancellable_new ();
 
-       if (!has_suffix_icmp (ad->oab_url, "oab.xml")) {
-               gchar *tmp;
+       if (G_IS_CANCELLABLE (cancellable)) {
+               cancelled_id = g_cancellable_connect (cancellable, G_CALLBACK (e_ews_cancel_cancellable_cb),
+                       ad.cancellable, NULL);
+       }
 
-               if (g_str_has_suffix (ad->oab_url, "/"))
-                       tmp = g_strconcat (ad->oab_url, "oab.xml", NULL);
-               else
-                       tmp = g_strconcat (ad->oab_url, "/", "oab.xml", NULL);
+       main_context = g_main_context_new ();
+       ad.main_loop = g_main_loop_new (main_context, FALSE);
+       g_main_context_push_thread_default (main_context);
 
-               camel_ews_settings_set_oaburl (settings, tmp);
-               g_free (tmp);
-       } else {
-               camel_ews_settings_set_oaburl (settings, ad->oab_url);
-       }
+       /*
+        * http://msdn.microsoft.com/en-us/library/ee332364.aspx says we are
+        * supposed to try $domain and then autodiscover.$domain. But some
+        * people have broken firewalls on the former which drop packets
+        * instead of rejecting connections, and make the request take ages
+        * to time out. So run both queries in parallel and let the fastest
+        * (successful) one win.
+        */
+       tmp_cnc = e_ews_connection_new_full (source, "https://autodiscover.domain";, settings, FALSE);
+       ad.session = e_ews_connection_create_soup_session (tmp_cnc);
+       g_object_set (ad.session, "timeout", 20, NULL);
+       e_ews_connection_set_password (tmp_cnc, password);
 
-       return TRUE;
-}
+       host_url = camel_ews_settings_get_hosturl (settings);
 
-struct _oal_req_data {
-       EEwsConnection *cnc;
-       SoupMessage *soup_message;
-       gchar *oal_id;
-       gchar *oal_element;
+       if (e_ews_autodiscover_prepare_requests_and_send_sync (&ad, email_address, host_url, cancellable))
+               g_main_loop_run (ad.main_loop);
 
-       GSList *oals;
-       GSList *elements;
-       gchar *etag;
+       g_main_context_pop_thread_default (main_context);
 
-       GCancellable *cancellable;
-       gulong cancel_id;
+       g_main_context_unref (main_context);
+       g_main_loop_unref (ad.main_loop);
+       g_clear_object (&tmp_cnc);
+       g_clear_object (&ad.session);
 
-       /* for dowloading oal file */
-       gchar *cache_filename;
-       GError *error;
-       EwsProgressFn progress_fn;
-       gpointer progress_data;
-       gsize response_size;
-       gsize received_size;
-};
+       if (cancelled_id)
+               g_cancellable_disconnect (cancellable, cancelled_id);
 
-static void
-oal_req_data_free (struct _oal_req_data *data)
-{
-       /* The SoupMessage is owned by the SoupSession. */
-       g_object_unref (data->cnc);
+       if (ad.success) {
+               camel_ews_settings_set_hosturl (settings, ad.as_url);
+
+               if (ad.oab_url && !has_suffix_icmp (ad.oab_url, "oab.xml")) {
+                       gchar *tmp;
 
-       g_free (data->oal_id);
-       g_free (data->oal_element);
-       g_free (data->etag);
+                       if (g_str_has_suffix (ad.oab_url, "/"))
+                               tmp = g_strconcat (ad.oab_url, "oab.xml", NULL);
+                       else
+                               tmp = g_strconcat (ad.oab_url, "/", "oab.xml", NULL);
 
-       g_slist_free_full (data->oals, (GDestroyNotify) ews_oal_free);
-       g_slist_free_full (data->elements, (GDestroyNotify) ews_oal_details_free);
+                       camel_ews_settings_set_oaburl (settings, tmp);
+                       g_free (tmp);
+               } else {
+                       camel_ews_settings_set_oaburl (settings, ad.oab_url);
+               }
 
-       if (data->cancellable != NULL) {
-               g_cancellable_disconnect (data->cancellable, data->cancel_id);
-               g_object_unref (data->cancellable);
+               if (out_certificate_pem)
+                       *out_certificate_pem = NULL;
+               if (out_certificate_errors)
+                       *out_certificate_errors = 0;
+       } else {
+               if (ad.error) {
+                       g_propagate_error (error, ad.error);
+                       ad.error = NULL;
+               }
+               if (out_certificate_pem)
+                       *out_certificate_pem = g_steal_pointer (&ad.certificate_pem);
+               if (out_certificate_errors)
+                       *out_certificate_errors = ad.certificate_errors;
        }
 
-       g_free (data->cache_filename);
+       autodiscover_data_clear (&ad);
+
+       return ad.success;
+}
+
+typedef struct _OalRequestData {
+       const gchar *oal_id;
+       const gchar *oal_element;
 
-       g_slice_free (struct _oal_req_data, data);
+       GSList *oals; /* EwsOAL * */
+       GSList *elements; /* EwsOALDetails */
+       gchar *etag;
+} OalRequestData;
+
+static void
+oal_request_data_init (OalRequestData *req_data)
+{
+       memset (req_data, 0, sizeof (OalRequestData));
+}
+
+static void
+oal_request_data_clear (OalRequestData *req_data)
+{
+       g_free (req_data->etag);
+
+       g_slist_free_full (req_data->oals, (GDestroyNotify) ews_oal_free);
+       g_slist_free_full (req_data->elements, (GDestroyNotify) ews_oal_details_free);
 }
 
 static gchar *
@@ -4048,573 +3071,299 @@ parse_oal_full_details (xmlNode *node,
        return elements;
 }
 
-/* this is run in cnc->priv->soup_thread */
 static void
-oal_response_cb (SoupSession *soup_session,
-                 SoupMessage *soup_message,
-                 gpointer user_data)
+e_ews_process_oal_data_response (ESoapRequest *request,
+                                SoupMessage *message,
+                                GInputStream *input_stream,
+                                gpointer user_data,
+                                gboolean *out_repeat,
+                                GCancellable *cancellable,
+                                GError **error)
 {
-       GSimpleAsyncResult *simple;
-       struct _oal_req_data *data;
+       OalRequestData *req_data = user_data;
+       ESoapResponse *response;
        const gchar *etag;
        xmlDoc *doc;
        xmlNode *node;
 
-       simple = G_SIMPLE_ASYNC_RESULT (user_data);
-       data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       ews_connection_check_ssl_error (data->cnc, soup_message);
-
-       if (ews_connection_credentials_failed (data->cnc, soup_message, simple)) {
-               goto exit;
-       } else if (soup_message->status_code != 200) {
-               if (soup_message->status_code == SOUP_STATUS_UNAUTHORIZED &&
-                   soup_message->response_headers) {
-                       const gchar *diagnostics;
-
-                       diagnostics = soup_message_headers_get_list (soup_message->response_headers, 
"X-MS-DIAGNOSTICS");
-                       if (diagnostics && strstr (diagnostics, "invalid_grant")) {
-                               g_simple_async_result_set_error (
-                                       simple,
-                                       EWS_CONNECTION_ERROR,
-                                       EWS_CONNECTION_ERROR_ACCESSDENIED,
-                                       "%s", diagnostics);
-                               goto exit;
-                       } else if (diagnostics && *diagnostics) {
-                               g_simple_async_result_set_error (
-                                       simple,
-                                       EWS_CONNECTION_ERROR,
-                                       EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED,
-                                       "%s", diagnostics);
-                               goto exit;
-                       }
-               }
-               g_simple_async_result_set_error (
-                       simple, SOUP_HTTP_ERROR,
-                       soup_message->status_code,
-                       "%d %s",
-                       soup_message->status_code,
-                       soup_message->reason_phrase);
-               goto exit;
-       }
-
-       etag = soup_message_headers_get_one(soup_message->response_headers,
-                                           "ETag");
-       if (etag)
-               data->etag = g_strdup(etag);
-
-       e_ews_debug_dump_raw_soup_response (soup_message);
-
-       doc = xmlReadMemory (
-               soup_message->response_body->data,
-               soup_message->response_body->length,
-               "oab.xml", NULL, 0);
-       if (doc == NULL) {
-               g_simple_async_result_set_error (
-                       simple, EWS_CONNECTION_ERROR, -1,
-                       "%s", _("Failed to parse oab XML"));
-               goto exit;
-       }
-
-       node = xmlDocGetRootElement (doc);
-       if (strcmp ((gchar *) node->name, "OAB") != 0) {
-               g_simple_async_result_set_error (
-                       simple, EWS_CONNECTION_ERROR, -1,
-                       "%s", _("Failed to find <OAB> element\n"));
-               goto exit_doc;
-       }
-
-       for (node = node->children; node; node = node->next) {
-               if (node->type == XML_ELEMENT_NODE && strcmp ((gchar *) node->name, "OAL") == 0) {
-                       if (data->oal_id == NULL) {
-                               EwsOAL *oal = g_new0 (EwsOAL, 1);
-
-                               oal->id = get_property (node, "id");
-                               oal->dn = get_property (node, "dn");
-                               oal->name = get_property (node, "name");
+       response = e_soap_response_new ();
 
-                               data->oals = g_slist_prepend (data->oals, oal);
-                       } else {
-                               gchar *id = get_property (node, "id");
+       e_soap_request_setup_response (request, response);
 
-                               if (strcmp (id, data->oal_id) == 0) {
-                                       /* parse details of full_details file */
-                                       data->elements = parse_oal_full_details (node, data->oal_element);
+       doc = e_soap_response_xmldoc_from_message_sync (response, message, input_stream, cancellable, error);
 
-                                       g_free (id);
-                                       break;
-                               }
+       g_clear_object (&response);
 
-                               g_free (id);
-                       }
-               }
+       if (!doc) {
+               if (error && !*error)
+                       g_set_error_literal (error, EWS_CONNECTION_ERROR, -1, _("Failed to parse oab XML"));
+               return;
        }
 
-       data->oals = g_slist_reverse (data->oals);
-
- exit_doc:
-       xmlFreeDoc (doc);
- exit:
-       g_simple_async_result_complete_in_idle (simple);
-       /* This is run in cnc->priv->soup_thread, and the cnc is held by simple, thus
-        * for cases when the complete_in_idle is finished before the unref call, when
-        * the cnc will be left with the last reference and thus cannot join the soup_thread
-        * while still in it, the unref is done in a dedicated thread. */
-       e_ews_connection_utils_unref_in_thread (simple);
-}
-
-static void
-ews_cancel_msg (GCancellable *cancellable,
-                struct _oal_req_data *data)
-{
-       ews_connection_schedule_cancel_message (data->cnc, data->soup_message);
-}
-
-gboolean
-e_ews_connection_get_oal_list_sync (EEwsConnection *cnc,
-                                    GSList **oals,
-                                    GCancellable *cancellable,
-                                    GError **error)
-{
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
-
-       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
-
-       closure = e_async_closure_new ();
-
-       e_ews_connection_get_oal_list (
-               cnc, cancellable, e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_connection_get_oal_list_finish (
-               cnc, result, oals, error);
-
-       e_async_closure_free (closure);
-
-       return success;
-}
+       etag = soup_message_headers_get_one (soup_message_get_response_headers (message), "ETag");
+       if (etag)
+               req_data->etag = g_strdup (etag);
 
-void
-e_ews_connection_get_oal_list (EEwsConnection *cnc,
-                               GCancellable *cancellable,
-                               GAsyncReadyCallback callback,
-                               gpointer user_data)
-{
-       GSimpleAsyncResult *simple;
-       SoupMessage *soup_message;
-       struct _oal_req_data *data;
-       GError *error = NULL;
+       node = xmlDocGetRootElement (doc);
+       if (strcmp ((gchar *) node->name, "OAB") == 0) {
+               for (node = node->children; node; node = node->next) {
+                       if (node->type == XML_ELEMENT_NODE && strcmp ((gchar *) node->name, "OAL") == 0) {
+                               if (req_data->oal_id == NULL) {
+                                       EwsOAL *oal = g_new0 (EwsOAL, 1);
 
-       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
+                                       oal->id = get_property (node, "id");
+                                       oal->dn = get_property (node, "dn");
+                                       oal->name = get_property (node, "name");
 
-       soup_message = e_ews_get_msg_for_url (cnc, cnc->priv->uri, NULL, &error);
+                                       req_data->oals = g_slist_prepend (req_data->oals, oal);
+                               } else {
+                                       gchar *id = get_property (node, "id");
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_get_oal_list);
+                                       if (strcmp (id, req_data->oal_id) == 0) {
+                                               /* parse details of full_details file */
+                                               req_data->elements = parse_oal_full_details (node, 
req_data->oal_element);
 
-       if (!soup_message) {
-               g_simple_async_result_take_error (simple, error);
-               g_simple_async_result_complete_in_idle (simple);
-               return;
-       }
+                                               g_free (id);
+                                               break;
+                                       }
 
-       data = g_slice_new0 (struct _oal_req_data);
-       data->cnc = g_object_ref (cnc);
-       data->soup_message = soup_message;  /* the session owns this */
+                                       g_free (id);
+                               }
+                       }
+               }
 
-       if (G_IS_CANCELLABLE (cancellable)) {
-               data->cancellable = g_object_ref (cancellable);
-               data->cancel_id = g_cancellable_connect (
-                       data->cancellable,
-                       G_CALLBACK (ews_cancel_msg),
-                       data, (GDestroyNotify) NULL);
+               req_data->oals = g_slist_reverse (req_data->oals);
+       } else {
+               g_set_error_literal (error, EWS_CONNECTION_ERROR, -1, _("Failed to find <OAB> element\n"));
        }
 
-       g_simple_async_result_set_op_res_gpointer (
-               simple, data, (GDestroyNotify) oal_req_data_free);
-
-       ews_connection_schedule_queue_message (cnc, soup_message, oal_response_cb, simple);
+       xmlFreeDoc (doc);
 }
 
 gboolean
-e_ews_connection_get_oal_list_finish (EEwsConnection *cnc,
-                                      GAsyncResult *result,
-                                      GSList **oals,
-                                      GError **error)
+e_ews_connection_get_oal_list_sync (EEwsConnection *cnc,
+                                    GSList **out_oals,
+                                    GCancellable *cancellable,
+                                    GError **error)
 {
-       GSimpleAsyncResult *simple;
-       struct _oal_req_data *data;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       OalRequestData req_data;
+       GError *local_error = NULL;
 
        g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
+       g_return_val_if_fail (out_oals != NULL, FALSE);
 
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_get_oal_list),
-               FALSE);
+       *out_oals = NULL;
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       data = g_simple_async_result_get_op_res_gpointer (simple);
+       request = e_ews_create_request_for_url (cnc->priv->uri, NULL, error);
 
-       if (g_simple_async_result_propagate_error (simple, error))
+       if (!request)
                return FALSE;
 
-       if (oals != NULL) {
-               *oals = data->oals;
-               data->oals = NULL;
+       oal_request_data_init (&req_data);
+
+       e_soap_request_set_custom_process_fn (request, e_ews_process_oal_data_response, &req_data);
+
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, &local_error);
+       g_warn_if_fail (response == NULL);
+
+       g_clear_object (&request);
+       g_clear_object (&response);
+
+       if (!local_error)
+               *out_oals = g_steal_pointer (&req_data.oals);
+
+       oal_request_data_clear (&req_data);
+
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
        return TRUE;
 }
 
-/**
- * e_ews_connection_get_oal_detail 
- * @cnc: 
- * @oal_id: 
- * @oal_element: 
- * @elements: "Full" "Diff" "Template" are the possible values.
- * @cancellable: 
- * @error: 
- * 
- * 
- * Returns: 
- **/
 gboolean
 e_ews_connection_get_oal_detail_sync (EEwsConnection *cnc,
                                       const gchar *oal_id,
                                       const gchar *oal_element,
                                      const gchar *old_etag,
-                                      GSList **elements,
-                                     gchar **etag,
+                                      GSList **out_elements,
+                                     gchar **out_etag,
                                       GCancellable *cancellable,
                                       GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       OalRequestData req_data;
+       gchar *tmp_oal_id = NULL;
+       GError *local_error = NULL;
 
        g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
+       g_return_val_if_fail (oal_id, FALSE);
 
-       closure = e_async_closure_new ();
-
-       e_ews_connection_get_oal_detail (
-               cnc, oal_id, oal_element, old_etag,
-               cancellable, e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_connection_get_oal_detail_finish (
-               cnc, result, elements, etag, error);
-
-       e_async_closure_free (closure);
-
-       return success;
-}
-
-void
-e_ews_connection_get_oal_detail (EEwsConnection *cnc,
-                                 const gchar *oal_id,
-                                 const gchar *oal_element,
-                                const gchar *etag,
-                                 GCancellable *cancellable,
-                                 GAsyncReadyCallback callback,
-                                 gpointer user_data)
-{
-       GSimpleAsyncResult *simple;
-       SoupMessage *soup_message;
-       struct _oal_req_data *data;
-       gchar *sep;
-       GError *error = NULL;
+       if (out_elements)
+               *out_elements = NULL;
+       if (out_etag)
+               *out_etag = NULL;
 
-       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
+       request = e_ews_create_request_for_url (cnc->priv->uri, NULL, error);
 
-       soup_message = e_ews_get_msg_for_url (cnc, cnc->priv->uri, NULL, &error);
+       if (!request)
+               return FALSE;
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_get_oal_detail);
+       /* oal_id can be of form "GUID:name", but here is compared only GUID */
+       if (strchr (oal_id, ':')) {
+               gchar *sep;
 
-       if (!soup_message) {
-               g_simple_async_result_take_error (simple, error);
-               g_simple_async_result_complete_in_idle (simple);
-               return;
+               tmp_oal_id = g_strdup (oal_id);
+               sep = strchr (tmp_oal_id, ':');
+               if (sep)
+                       *sep = '\0';
        }
 
-       if (etag && *etag)
-               soup_message_headers_append (soup_message->request_headers,
-                                            "If-None-Match", etag);
-
-       data = g_slice_new0 (struct _oal_req_data);
-       data->cnc = g_object_ref (cnc);
-       data->soup_message = soup_message;  /* the session owns this */
-       data->oal_id = g_strdup (oal_id);
-       data->oal_element = g_strdup (oal_element);
-
-       /* oal_id can be of form "GUID:name", but here is compared only GUID */
-       sep = strchr (data->oal_id, ':');
-       if (sep)
-               *sep = '\0';
+       oal_request_data_init (&req_data);
 
-       if (G_IS_CANCELLABLE (cancellable)) {
-               data->cancellable = g_object_ref (cancellable);
-               data->cancel_id = g_cancellable_connect (
-                       data->cancellable,
-                       G_CALLBACK (ews_cancel_msg),
-                       data, (GDestroyNotify) NULL);
-       }
+       req_data.oal_id = tmp_oal_id ? tmp_oal_id : oal_id;
+       req_data.oal_element = oal_element;
 
-       g_simple_async_result_set_op_res_gpointer (
-               simple, data, (GDestroyNotify) oal_req_data_free);
+       e_soap_request_set_custom_process_fn (request, e_ews_process_oal_data_response, &req_data);
+       e_soap_request_set_etag (request, old_etag);
 
-       ews_connection_schedule_queue_message (cnc, soup_message, oal_response_cb, simple);
-}
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, &local_error);
+       g_warn_if_fail (response == NULL);
 
-gboolean
-e_ews_connection_get_oal_detail_finish (EEwsConnection *cnc,
-                                        GAsyncResult *result,
-                                        GSList **elements,
-                                       gchar **etag,
-                                        GError **error)
-{
-       GSimpleAsyncResult *simple;
-       struct _oal_req_data *data;
+       g_clear_object (&request);
+       g_clear_object (&response);
+       g_free (tmp_oal_id);
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_get_oal_detail),
-               FALSE);
+       if (!local_error) {
+               if (out_elements)
+                       *out_elements = g_steal_pointer (&req_data.elements);
+               if (out_etag)
+                       *out_etag = g_steal_pointer (&req_data.etag);
+       }
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       data = g_simple_async_result_get_op_res_gpointer (simple);
+       oal_request_data_clear (&req_data);
 
-       if (g_simple_async_result_propagate_error (simple, error))
+       if (local_error) {
+               g_propagate_error (error, local_error);
                return FALSE;
-
-       if (elements != NULL) {
-               *elements = data->elements;
-               data->elements = NULL;
-       }
-       if (etag != NULL) {
-               *etag = data->etag;
-               data->etag = NULL;
        }
 
        return TRUE;
-
 }
 
-static void
-oal_download_response_cb (SoupSession *soup_session,
-                          SoupMessage *soup_message,
-                          gpointer user_data)
-{
-       GSimpleAsyncResult *simple;
-       struct _oal_req_data *data;
-
-       simple = G_SIMPLE_ASYNC_RESULT (user_data);
-       data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       ews_connection_check_ssl_error (data->cnc, soup_message);
-
-       if (ews_connection_credentials_failed (data->cnc, soup_message, simple)) {
-               g_unlink (data->cache_filename);
-       } else if (soup_message->status_code != 200) {
-               g_simple_async_result_set_error (
-                       simple, SOUP_HTTP_ERROR,
-                       soup_message->status_code,
-                       "%d %s",
-                       soup_message->status_code,
-                       soup_message->reason_phrase);
-               g_unlink (data->cache_filename);
-
-       } else if (data->error != NULL) {
-               g_simple_async_result_take_error (simple, data->error);
-               data->error = NULL;
-               g_unlink (data->cache_filename);
-       }
-
-       e_ews_debug_dump_raw_soup_response (soup_message);
-
-       g_simple_async_result_complete_in_idle (simple);
-       e_ews_connection_utils_unref_in_thread (simple);
-}
+typedef struct _DownloadOalData {
+       const gchar *cache_filename;
+       gint fd;
+} DownloadOalData;
 
 static void
-ews_soup_got_headers (SoupMessage *msg,
-                      gpointer user_data)
+e_ews_process_download_oal_file_response (ESoapRequest *request,
+                                         SoupMessage *message,
+                                         GInputStream *input_stream,
+                                         gpointer user_data,
+                                         gboolean *out_repeat,
+                                         GCancellable *cancellable,
+                                         GError **error)
 {
-       struct _oal_req_data *data = (struct _oal_req_data *) user_data;
+       DownloadOalData *dod = user_data;
+       ESoapResponseProgressFn progress_fn = NULL;
+       gpointer progress_data = NULL;
        const gchar *size;
+       gpointer buffer;
+       gsize response_size = 0;
+       gsize response_received = 0;
+       gsize progress_percent = 0;
+       gsize nread = 0;
+       gboolean success;
 
-       size = soup_message_headers_get_one (
-               msg->response_headers,
-               "Content-Length");
-
-       if (size)
-               data->response_size = strtol (size, NULL, 10);
-}
+       g_return_if_fail (dod != NULL);
+       g_return_if_fail (dod->fd != -1);
 
-static void
-ews_soup_restarted (SoupMessage *msg,
-                    gpointer user_data)
-{
-       struct _oal_req_data *data = (struct _oal_req_data *) user_data;
+       e_soap_request_get_progress_fn (request, &progress_fn, &progress_data);
 
-       data->response_size = 0;
-       data->received_size = 0;
-}
+       size = soup_message_headers_get_one (soup_message_get_response_headers (message), "Content-Length");
 
-static void
-ews_soup_got_chunk (SoupMessage *msg,
-                    SoupBuffer *chunk,
-                    gpointer user_data)
-{
-       struct _oal_req_data *data = (struct _oal_req_data *) user_data;
-       gint fd;
+       if (size)
+               response_size = g_ascii_strtoll (size, NULL, 10);
 
-       if (msg->status_code != 200)
-               return;
+       buffer = g_malloc (BUFFER_SIZE);
 
-       data->received_size += chunk->length;
+       while (success = g_input_stream_read_all (input_stream, buffer, BUFFER_SIZE, &nread, cancellable, 
error),
+              success && nread > 0) {
+               response_received += nread;
 
-       if (data->response_size && data->progress_fn) {
-               gint pc = data->received_size * 100 / data->response_size;
-               data->progress_fn (data->progress_data, pc);
-       }
+               if (response_size && progress_fn) {
+                       gint pc = response_received * 100 / response_size;
+                       if (progress_percent != pc) {
+                               progress_percent = pc;
+                               progress_fn (progress_data, progress_percent);
+                       }
+               }
 
-       fd = g_open (data->cache_filename, O_RDONLY | O_WRONLY | O_APPEND | O_CREAT, 0600);
-       if (fd != -1) {
-               if (write (fd, (const gchar *) chunk->data, chunk->length) != chunk->length) {
-                       g_set_error (
-                               &data->error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_UNKNOWN,
-                               "Failed to write streaming data to file '%s': %s", data->cache_filename, 
g_strerror (errno));
+               if (write (dod->fd, (const gchar *) buffer, nread) != nread) {
+                       g_set_error (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_UNKNOWN,
+                               "Failed to write streaming data to file '%s': %s", dod->cache_filename, 
g_strerror (errno));
+                       break;
                }
-               close (fd);
-       } else {
-               g_set_error (
-                       &data->error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_UNKNOWN,
-                       "Failed to open the cache file '%s': %s", data->cache_filename, g_strerror (errno));
        }
+
+       g_free (buffer);
 }
 
 gboolean
 e_ews_connection_download_oal_file_sync (EEwsConnection *cnc,
                                          const gchar *cache_filename,
-                                         EwsProgressFn progress_fn,
+                                         ESoapResponseProgressFn progress_fn,
                                          gpointer progress_data,
                                          GCancellable *cancellable,
                                          GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       DownloadOalData dod;
+       GError *local_error = NULL;
 
        g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
 
-       closure = e_async_closure_new ();
-
-       e_ews_connection_download_oal_file (
-               cnc, cache_filename,
-               progress_fn, progress_data, cancellable,
-               e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_connection_download_oal_file_finish (
-               cnc, result, error);
-
-       e_async_closure_free (closure);
-
-       return success;
-}
-
-void
-e_ews_connection_download_oal_file (EEwsConnection *cnc,
-                                    const gchar *cache_filename,
-                                    EwsProgressFn progress_fn,
-                                    gpointer progress_data,
-                                    GCancellable *cancellable,
-                                    GAsyncReadyCallback callback,
-                                    gpointer user_data)
-{
-       GSimpleAsyncResult *simple;
-       SoupMessage *soup_message;
-       struct _oal_req_data *data;
-       GError *error = NULL;
-
-       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
-
-       soup_message = e_ews_get_msg_for_url (cnc, cnc->priv->uri, NULL, &error);
+       request = e_ews_create_request_for_url (cnc->priv->uri, NULL, error);
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_download_oal_file);
+       if (!request)
+               return FALSE;
 
-       if (!soup_message) {
-               g_simple_async_result_take_error (simple, error);
-               g_simple_async_result_complete_in_idle (simple);
-               return;
-       }
+       /* Prepare the file */
+       g_unlink (cache_filename);
 
-       data = g_slice_new0 (struct _oal_req_data);
-       data->cnc = g_object_ref (cnc);
-       data->soup_message = soup_message;  /* the session owns this */
-       data->cache_filename = g_strdup (cache_filename);
-       data->progress_fn = progress_fn;
-       data->progress_data = progress_data;
+       dod.cache_filename = cache_filename;
+       dod.fd = g_open (cache_filename, O_RDONLY | O_WRONLY | O_APPEND | O_CREAT, 0600);
+       if (dod.fd == -1) {
+               g_set_error (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_UNKNOWN,
+                       "Failed to open the cache file '%s': %s", cache_filename, g_strerror (errno));
+               g_clear_object (&request);
 
-       if (G_IS_CANCELLABLE (cancellable)) {
-               data->cancellable = g_object_ref (cancellable);
-               data->cancel_id = g_cancellable_connect (
-                       data->cancellable,
-                       G_CALLBACK (ews_cancel_msg),
-                       data, (GDestroyNotify) NULL);
+               return FALSE;
        }
 
-       g_simple_async_result_set_op_res_gpointer (
-               simple, data, (GDestroyNotify) oal_req_data_free);
-
-       /*
-        * Don't use streaming-based messages when we are loggin the traffic
-        * to generate trace files for tests
-        */
-       if (e_ews_debug_get_log_level () <= 3)
-               soup_message_body_set_accumulate (soup_message->response_body, FALSE);
+       e_soap_request_set_progress_fn (request, progress_fn, progress_data);
 
-       g_signal_connect (
-               soup_message, "got-headers",
-               G_CALLBACK (ews_soup_got_headers), data);
-       g_signal_connect (
-               soup_message, "got-chunk",
-               G_CALLBACK (ews_soup_got_chunk), data);
-       g_signal_connect (
-               soup_message, "restarted",
-               G_CALLBACK (ews_soup_restarted), data);
-
-       ews_connection_schedule_queue_message (cnc, soup_message, oal_download_response_cb, simple);
-}
+       e_soap_request_set_custom_process_fn (request, e_ews_process_download_oal_file_response, &dod);
 
-gboolean
-e_ews_connection_download_oal_file_finish (EEwsConnection *cnc,
-                                           GAsyncResult *result,
-                                           GError **error)
-{
-       GSimpleAsyncResult *simple;
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, &local_error);
+       g_warn_if_fail (response == NULL);
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc),
-               e_ews_connection_download_oal_file), FALSE);
+       g_clear_object (&request);
+       g_clear_object (&response);
+       close (dod.fd);
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
+       }
 
-       /* Assume success unless a GError is set. */
-       return !g_simple_async_result_propagate_error (simple, error);
+       return TRUE;
 }
 
 const gchar *
@@ -4640,7 +3389,7 @@ e_ews_connection_set_mailbox (EEwsConnection *cnc,
 }
 
 static void
-ews_append_additional_props_to_msg (ESoapMessage *msg,
+ews_append_additional_props_to_msg (ESoapRequest *request,
                                     const EEwsAdditionalProps *add_props)
 {
        GSList *l;
@@ -4648,14 +3397,14 @@ ews_append_additional_props_to_msg (ESoapMessage *msg,
        if (!add_props)
                return;
 
-       e_soap_message_start_element (msg, "AdditionalProperties", NULL, NULL);
+       e_soap_request_start_element (request, "AdditionalProperties", NULL, NULL);
 
        if (add_props->field_uri) {
                gchar **prop = g_strsplit (add_props->field_uri, " ", 0);
                gint i = 0;
 
                while (prop[i]) {
-                       e_ews_message_write_string_parameter_with_attribute (msg, "FieldURI", NULL, NULL, 
"FieldURI", prop[i]);
+                       e_ews_request_write_string_parameter_with_attribute (request, "FieldURI", NULL, NULL, 
"FieldURI", prop[i]);
                        i++;
                }
 
@@ -4666,27 +3415,27 @@ ews_append_additional_props_to_msg (ESoapMessage *msg,
                for (l = add_props->extended_furis; l != NULL; l = g_slist_next (l)) {
                        EEwsExtendedFieldURI *ex_furi = l->data;
 
-                       e_soap_message_start_element (msg, "ExtendedFieldURI", NULL, NULL);
+                       e_soap_request_start_element (request, "ExtendedFieldURI", NULL, NULL);
 
                        if (ex_furi->distinguished_prop_set_id)
-                               e_soap_message_add_attribute (msg, "DistinguishedPropertySetId", 
ex_furi->distinguished_prop_set_id, NULL, NULL);
+                               e_soap_request_add_attribute (request, "DistinguishedPropertySetId", 
ex_furi->distinguished_prop_set_id, NULL, NULL);
 
                        if (ex_furi->prop_tag)
-                               e_soap_message_add_attribute (msg, "PropertyTag", ex_furi->prop_tag, NULL, 
NULL);
+                               e_soap_request_add_attribute (request, "PropertyTag", ex_furi->prop_tag, 
NULL, NULL);
 
                        if (ex_furi->prop_set_id)
-                               e_soap_message_add_attribute (msg, "PropertySetId", ex_furi->prop_set_id, 
NULL, NULL);
+                               e_soap_request_add_attribute (request, "PropertySetId", ex_furi->prop_set_id, 
NULL, NULL);
 
                        if (ex_furi->prop_name)
-                               e_soap_message_add_attribute (msg, "PropertyName", ex_furi->prop_name, NULL, 
NULL);
+                               e_soap_request_add_attribute (request, "PropertyName", ex_furi->prop_name, 
NULL, NULL);
 
                        if (ex_furi->prop_id)
-                               e_soap_message_add_attribute (msg, "PropertyId", ex_furi->prop_id, NULL, 
NULL);
+                               e_soap_request_add_attribute (request, "PropertyId", ex_furi->prop_id, NULL, 
NULL);
 
                        if (ex_furi->prop_type)
-                               e_soap_message_add_attribute (msg, "PropertyType", ex_furi->prop_type, NULL, 
NULL);
+                               e_soap_request_add_attribute (request, "PropertyType", ex_furi->prop_type, 
NULL, NULL);
 
-                       e_soap_message_end_element (msg);
+                       e_soap_request_end_element (request);
                }
        }
 
@@ -4694,168 +3443,104 @@ ews_append_additional_props_to_msg (ESoapMessage *msg,
                for (l = add_props->indexed_furis; l != NULL; l = g_slist_next (l)) {
                        EEwsIndexedFieldURI *in_furi = l->data;
 
-                       e_soap_message_start_element (msg, "IndexedFieldURI", NULL, NULL);
+                       e_soap_request_start_element (request, "IndexedFieldURI", NULL, NULL);
 
-                       e_soap_message_add_attribute (msg, "FieldURI", in_furi->field_uri, NULL, NULL);
-                       e_soap_message_add_attribute (msg, "FieldIndex", in_furi->field_index, NULL, NULL);
+                       e_soap_request_add_attribute (request, "FieldURI", in_furi->field_uri, NULL, NULL);
+                       e_soap_request_add_attribute (request, "FieldIndex", in_furi->field_index, NULL, 
NULL);
 
-                       e_soap_message_end_element (msg);
+                       e_soap_request_end_element (request);
                }
        }
 
-       e_soap_message_end_element (msg);
+       e_soap_request_end_element (request);
 }
 
 static void
-ews_write_sort_order_to_msg (ESoapMessage *msg,
+ews_write_sort_order_to_msg (ESoapRequest *request,
                              EwsSortOrder *sort_order)
 {
        if (!sort_order)
                return;
 
-       e_soap_message_start_element (msg, "SortOrder", NULL, NULL);
-       e_soap_message_start_element (msg, "FieldOrder", NULL, NULL);
-       e_soap_message_add_attribute (msg, "Order", sort_order->order, NULL, NULL);
+       e_soap_request_start_element (request, "SortOrder", NULL, NULL);
+       e_soap_request_start_element (request, "FieldOrder", NULL, NULL);
+       e_soap_request_add_attribute (request, "Order", sort_order->order, NULL, NULL);
 
        if (sort_order->uri_type == NORMAL_FIELD_URI)
-               e_ews_message_write_string_parameter_with_attribute (msg, "FieldURI", NULL, NULL, "FieldURI", 
(gchar *) sort_order->field_uri);
+               e_ews_request_write_string_parameter_with_attribute (request, "FieldURI", NULL, NULL, 
"FieldURI", (gchar *) sort_order->field_uri);
        else if (sort_order->uri_type == INDEXED_FIELD_URI) {
                EEwsIndexedFieldURI *in_furi = sort_order->field_uri;
 
-               e_soap_message_start_element (msg, "IndexedFieldURI", NULL, NULL);
-               e_soap_message_add_attribute (msg, "FieldURI", in_furi->field_uri, NULL, NULL);
-               e_soap_message_add_attribute (msg, "FieldIndex", in_furi->field_index, NULL, NULL);
-               e_soap_message_end_element (msg);
+               e_soap_request_start_element (request, "IndexedFieldURI", NULL, NULL);
+               e_soap_request_add_attribute (request, "FieldURI", in_furi->field_uri, NULL, NULL);
+               e_soap_request_add_attribute (request, "FieldIndex", in_furi->field_index, NULL, NULL);
+               e_soap_request_end_element (request);
        } else if (sort_order->uri_type == EXTENDED_FIELD_URI) {
                EEwsExtendedFieldURI *ex_furi = sort_order->field_uri;
 
-               e_soap_message_start_element (msg, "ExtendedFieldURI", NULL, NULL);
+               e_soap_request_start_element (request, "ExtendedFieldURI", NULL, NULL);
 
                if (ex_furi->distinguished_prop_set_id)
-                       e_soap_message_add_attribute (msg, "DistinguishedPropertySetId", 
ex_furi->distinguished_prop_set_id, NULL, NULL);
+                       e_soap_request_add_attribute (request, "DistinguishedPropertySetId", 
ex_furi->distinguished_prop_set_id, NULL, NULL);
                if (ex_furi->prop_set_id)
-                       e_soap_message_add_attribute (msg, "PropertySetId", ex_furi->prop_set_id, NULL, NULL);
+                       e_soap_request_add_attribute (request, "PropertySetId", ex_furi->prop_set_id, NULL, 
NULL);
                if (ex_furi->prop_name)
-                       e_soap_message_add_attribute (msg, "PropertyName", ex_furi->prop_name, NULL, NULL);
+                       e_soap_request_add_attribute (request, "PropertyName", ex_furi->prop_name, NULL, 
NULL);
                if (ex_furi->prop_id)
-                       e_soap_message_add_attribute (msg, "PropertyId", ex_furi->prop_id, NULL, NULL);
+                       e_soap_request_add_attribute (request, "PropertyId", ex_furi->prop_id, NULL, NULL);
                if (ex_furi->prop_type)
-                       e_soap_message_add_attribute (msg, "PropertyType", ex_furi->prop_type, NULL, NULL);
+                       e_soap_request_add_attribute (request, "PropertyType", ex_furi->prop_type, NULL, 
NULL);
 
-               e_soap_message_end_element (msg);
+               e_soap_request_end_element (request);
        }
 
-       e_soap_message_end_element (msg);
-       e_soap_message_end_element (msg);
+       e_soap_request_end_element (request);
+       e_soap_request_end_element (request);
 }
 
-/**
- * e_ews_connection_sync_folder_items:
- * @cnc: The EWS Connection
- * @pri: The priority associated with the request
- * @last_sync_state: To sync with the previous requests
- * @folder_id: The folder to which the items belong
- * @default_props: Can take one of the values: IdOnly,Default or AllProperties
- * @additional_props: Specify any additional properties to be fetched
- * @max_entries: Maximum number of items to be returned
- * @cancellable: a GCancellable to monitor cancelled operations
- * @callback: Responses are parsed and returned to this callback
- * @user_data: user data passed to callback
- **/
-void
-e_ews_connection_sync_folder_items (EEwsConnection *cnc,
-                                    gint pri,
-                                    const gchar *last_sync_state,
-                                    const gchar *fid,
-                                    const gchar *default_props,
-                                   const EEwsAdditionalProps *add_props,
-                                    guint max_entries,
-                                    GCancellable *cancellable,
-                                    GAsyncReadyCallback callback,
-                                    gpointer user_data)
+static gboolean
+e_ews_process_sync_folder_items_response (EEwsConnection *cnc,
+                                         ESoapResponse *response,
+                                         gchar **out_new_sync_state,
+                                         gboolean *out_includes_last_item,
+                                         GSList **out_items_created,
+                                         GSList **out_items_updated,
+                                         GSList **out_items_deleted,
+                                         GError **error)
 {
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_if_fail (cnc != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "SyncFolderItems",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
-       e_soap_message_start_element (msg, "ItemShape", "messages", NULL);
-       e_ews_message_write_string_parameter (msg, "BaseShape", NULL, default_props);
-
-       ews_append_additional_props_to_msg (msg, add_props);
-
-       e_soap_message_end_element (msg);
-
-       e_soap_message_start_element (msg, "SyncFolderId", "messages", NULL);
-       e_ews_message_write_string_parameter_with_attribute (msg, "FolderId", NULL, NULL, "Id", fid);
-       e_soap_message_end_element (msg);
-
-       if (last_sync_state)
-               e_ews_message_write_string_parameter (msg, "SyncState", "messages", last_sync_state);
-
-       /* Max changes requested */
-       e_ews_message_write_int_parameter (msg, "MaxChangesReturned", "messages", max_entries);
-
-       /* Complete the footer and print the request */
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_sync_folder_items);
+       ESoapParameter *param;
+       ESoapParameter *subparam;
+       GError *local_error = NULL;
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
-       e_ews_connection_queue_request (
-               cnc, msg, sync_folder_items_response_cb,
-               pri, cancellable, simple);
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       g_object_unref (simple);
-}
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
+       }
 
-gboolean
-e_ews_connection_sync_folder_items_finish (EEwsConnection *cnc,
-                                           GAsyncResult *result,
-                                           gchar **new_sync_state,
-                                           gboolean *includes_last_item,
-                                           GSList **items_created,
-                                           GSList **items_updated,
-                                           GSList **items_deleted,
-                                           GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       subparam = e_soap_parameter_get_first_child (param);
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_sync_folder_items),
-               FALSE);
+       while (subparam != NULL) {
+               const gchar *name = (const gchar *) subparam->name;
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
 
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "SyncFolderItemsResponseMessage")) {
+                       e_ews_process_sync_xxx_response (
+                               subparam,  (ItemParser) e_ews_item_new_from_soap_parameter,
+                               "IncludesLastItemInRange", "ItemId",
+                               out_new_sync_state, out_includes_last_item, out_items_created, 
out_items_updated, out_items_deleted);
+               }
 
-       *new_sync_state = async_data->sync_state;
-       *includes_last_item = async_data->includes_last_item;
-       *items_created = async_data->items_created;
-       *items_updated = async_data->items_updated;
-       *items_deleted = async_data->items_deleted;
+               subparam = e_soap_parameter_get_next_child (subparam);
+       }
 
        return TRUE;
 }
@@ -4868,40 +3553,72 @@ e_ews_connection_sync_folder_items_sync (EEwsConnection *cnc,
                                          const gchar *default_props,
                                         const EEwsAdditionalProps *add_props,
                                          guint max_entries,
-                                         gchar **new_sync_state,
-                                         gboolean *includes_last_item,
-                                         GSList **items_created,
-                                         GSList **items_updated,
-                                         GSList **items_deleted,
+                                         gchar **out_new_sync_state,
+                                         gboolean *out_includes_last_item,
+                                         GSList **out_items_created,
+                                         GSList **out_items_updated,
+                                         GSList **out_items_deleted,
                                          GCancellable *cancellable,
                                          GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       closure = e_async_closure_new ();
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "SyncFolderItems",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
+
+       if (!request)
+               return FALSE;
+
+       e_soap_request_start_element (request, "ItemShape", "messages", NULL);
+       e_ews_request_write_string_parameter (request, "BaseShape", NULL, default_props);
+
+       ews_append_additional_props_to_msg (request, add_props);
 
-       e_ews_connection_sync_folder_items (
-               cnc, pri, old_sync_state, fid, default_props,
-               add_props, max_entries, cancellable,
-               e_async_closure_callback, closure);
+       e_soap_request_end_element (request);
 
-       result = e_async_closure_wait (closure);
+       e_soap_request_start_element (request, "SyncFolderId", "messages", NULL);
+       e_ews_request_write_string_parameter_with_attribute (request, "FolderId", NULL, NULL, "Id", fid);
+       e_soap_request_end_element (request);
 
-       success = e_ews_connection_sync_folder_items_finish (
-               cnc, result, new_sync_state, includes_last_item,
-               items_created, items_updated, items_deleted, error);
+       if (old_sync_state)
+               e_ews_request_write_string_parameter (request, "SyncState", "messages", old_sync_state);
 
-       e_async_closure_free (closure);
+       /* Max changes requested */
+       e_ews_request_write_int_parameter (request, "MaxChangesReturned", "messages", max_entries);
+
+       e_ews_request_write_footer (request);
+
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
+
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
+
+       success = e_ews_process_sync_folder_items_response (cnc, response,
+               out_new_sync_state, out_includes_last_item, out_items_created,
+               out_items_updated, out_items_deleted, error);
+
+       g_clear_object (&request);
+       g_clear_object (&response);
 
        return success;
 }
 
 static void
-ews_append_folder_ids_to_msg (ESoapMessage *msg,
+ews_append_folder_ids_to_msg (ESoapRequest *request,
                               const gchar *email,
                               GSList *folder_ids)
 {
@@ -4910,163 +3627,92 @@ ews_append_folder_ids_to_msg (ESoapMessage *msg,
        for (l = folder_ids; l != NULL; l = g_slist_next (l)) {
                const EwsFolderId *fid = l->data;
 
-               e_ews_folder_id_append_to_msg (msg, email, fid);
+               e_ews_folder_id_append_to_request (request, email, fid);
        }
 }
 
 static void
-ews_connection_write_only_ids_restriction (ESoapMessage *msg,
+ews_connection_write_only_ids_restriction (ESoapRequest *request,
                                           GPtrArray *only_ids)
 {
        guint ii;
 
-       g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+       g_return_if_fail (E_IS_SOAP_REQUEST (request));
        g_return_if_fail (only_ids && only_ids->len);
 
        for (ii = 0; ii < only_ids->len; ii++) {
                const gchar *itemid = g_ptr_array_index (only_ids, ii);
 
-               e_soap_message_start_element (msg, "IsEqualTo", NULL, NULL);
-               e_ews_message_write_string_parameter_with_attribute (msg, "FieldURI", NULL, NULL, "FieldURI", 
"item:ItemId");
-               e_soap_message_start_element (msg, "FieldURIOrConstant", NULL, NULL);
-               e_ews_message_write_string_parameter_with_attribute (msg, "Constant", NULL, NULL, "Value", 
itemid);
-               e_soap_message_end_element (msg); /* FieldURIOrConstant */
-               e_soap_message_end_element (msg); /* IsEqualTo */
+               e_soap_request_start_element (request, "IsEqualTo", NULL, NULL);
+               e_ews_request_write_string_parameter_with_attribute (request, "FieldURI", NULL, NULL, 
"FieldURI", "item:ItemId");
+               e_soap_request_start_element (request, "FieldURIOrConstant", NULL, NULL);
+               e_ews_request_write_string_parameter_with_attribute (request, "Constant", NULL, NULL, 
"Value", itemid);
+               e_soap_request_end_element (request); /* FieldURIOrConstant */
+               e_soap_request_end_element (request); /* IsEqualTo */
        }
 }
 
-/**
- * e_ews_connection_find_folder_items:
- * @cnc: The EWS Connection
- * @pri: The priority associated with the request
- * @fid: The folder id to which the items belong
- * @default_props: Can take one of the values: IdOnly,Default or AllProperties
- * @add_props: Specify any additional properties to be fetched
- * @sort_order: Specific sorting order for items
- * @query: evo query based on which items will be fetched
- * @only_ids: (element-type utf8) (nullable): a gchar * with item IDs, to check with only; can be %NULL
- * @type: type of folder
- * @convert_query_cb: a callback method to convert query to ews restiction
- * @cancellable: a GCancellable to monitor cancelled operations
- * @callback: Responses are parsed and returned to this callback
- * @user_data: user data passed to callback
- **/
-void
-e_ews_connection_find_folder_items (EEwsConnection *cnc,
-                                    gint pri,
-                                    EwsFolderId *fid,
-                                    const gchar *default_props,
-                                    const EEwsAdditionalProps *add_props,
-                                    EwsSortOrder *sort_order,
-                                    const gchar *query,
-                                   GPtrArray *only_ids, /* element-type utf8 */
-                                    EEwsFolderType type,
-                                    EwsConvertQueryCallback convert_query_cb,
-                                    GCancellable *cancellable,
-                                    GAsyncReadyCallback callback,
-                                    gpointer user_data)
+static gboolean
+e_ews_process_find_folder_items_response (EEwsConnection *cnc,
+                                         ESoapResponse *response,
+                                         gboolean *out_includes_last_item,
+                                         GSList **out_items,
+                                         GError **error)
 {
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_if_fail (cnc != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "FindItem",
-                       "Traversal",
-                       "Shallow",
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
-       e_soap_message_start_element (msg, "ItemShape", "messages", NULL);
-       e_ews_message_write_string_parameter (msg, "BaseShape", NULL, default_props);
-
-       ews_append_additional_props_to_msg (msg, add_props);
-
-       e_soap_message_end_element (msg);
-
-       /*write restriction message based on query*/
-       if (convert_query_cb) {
-               e_soap_message_start_element (msg, "Restriction", "messages", NULL);
-
-               if (only_ids && only_ids->len) {
-                       e_soap_message_start_element (msg, "And", "messages", NULL);
-                       e_soap_message_start_element (msg, "Or", "messages", NULL);
-                       ews_connection_write_only_ids_restriction (msg, only_ids);
-                       e_soap_message_end_element (msg); /* Or */
-               }
+       ESoapParameter *param;
+       ESoapParameter *subparam;
+       GError *local_error = NULL;
 
-               convert_query_cb (msg, query, type);
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
-               if (only_ids && only_ids->len)
-                       e_soap_message_end_element (msg); /* And */
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-               e_soap_message_end_element (msg); /* Restriction */
-       } else if (only_ids && only_ids->len) {
-               e_soap_message_start_element (msg, "Restriction", "messages", NULL);
-               ews_connection_write_only_ids_restriction (msg, only_ids);
-               e_soap_message_end_element (msg);
+       if (local_error != NULL) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
-       if (sort_order)
-               ews_write_sort_order_to_msg (msg, sort_order);
-
-       e_soap_message_start_element (msg, "ParentFolderIds", "messages", NULL);
-
-       if (fid->is_distinguished_id)
-               e_ews_message_write_string_parameter_with_attribute (msg, "DistinguishedFolderId", NULL, 
NULL, "Id", fid->id);
-       else
-               e_ews_message_write_string_parameter_with_attribute (msg, "FolderId", NULL, NULL, "Id", 
fid->id);
-
-       e_soap_message_end_element (msg);
-
-       /* Complete the footer and print the request */
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_find_folder_items);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
-
-       e_ews_connection_queue_request (
-               cnc, msg, find_folder_items_response_cb,
-               pri, cancellable, simple);
-
-       g_object_unref (simple);
-}
+       subparam = e_soap_parameter_get_first_child (param);
 
-gboolean
-e_ews_connection_find_folder_items_finish (EEwsConnection *cnc,
-                                           GAsyncResult *result,
-                                           gboolean *includes_last_item,
-                                           GSList **items,
-                                           GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       while (subparam != NULL) {
+               const gchar *name = (const gchar *) subparam->name;
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_find_folder_items),
-               FALSE);
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "FindItemResponseMessage")) {
+                       ESoapParameter *node, *subparam1;
+                       gchar *last;
+                       EEwsItem *item;
+                       gboolean includes_last_item;
+
+                       node = e_soap_parameter_get_first_child_by_name (subparam, "RootFolder");
+                       last = e_soap_parameter_get_property (node, "IncludesLastItemInRange");
+                       /*
+                        * Set the includes_last_item to TRUE as default.
+                        * It can avoid an infinite loop in caller, when, for some reason,
+                        * we don't receive the last_tag property from the server.
+                        */
+                       includes_last_item = g_strcmp0 (last, "false") != 0;
+                       g_free (last);
+
+                       node = e_soap_parameter_get_first_child_by_name (node, "Items");
+                       for (subparam1 = e_soap_parameter_get_first_child (node);
+                            subparam1; subparam1 = e_soap_parameter_get_next_child (subparam1)) {
+                               item = e_ews_item_new_from_soap_parameter (subparam1);
+                               if (item)
+                                       *out_items = g_slist_prepend (*out_items, item);
+                       }
 
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+                       if (out_includes_last_item)
+                               *out_includes_last_item = includes_last_item;
+               }
 
-       *includes_last_item = async_data->includes_last_item;
-       *items = async_data->items;
+               subparam = e_soap_parameter_get_next_child (subparam);
+       }
 
        return TRUE;
 }
@@ -5081,122 +3727,143 @@ e_ews_connection_find_folder_items_sync (EEwsConnection *cnc,
                                          const gchar *query,
                                         GPtrArray *only_ids, /* element-type utf8 */
                                          EEwsFolderType type,
-                                         gboolean *includes_last_item,
-                                         GSList **items,
+                                         gboolean *out_includes_last_item,
+                                         GSList **out_items,
                                          EwsConvertQueryCallback convert_query_cb,
                                          GCancellable *cancellable,
                                          GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (out_items != NULL, FALSE);
 
-       closure = e_async_closure_new ();
+       *out_items = NULL;
 
-       e_ews_connection_find_folder_items (
-               cnc, pri, fid, default_props,
-               add_props, sort_order, query,
-               only_ids, type, convert_query_cb, NULL,
-               e_async_closure_callback, closure);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "FindItem",
+               "Traversal",
+               "Shallow",
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       result = e_async_closure_wait (closure);
+       if (!request)
+               return FALSE;
 
-       success = e_ews_connection_find_folder_items_finish (
-               cnc, result, includes_last_item, items, error);
+       e_soap_request_start_element (request, "ItemShape", "messages", NULL);
+       e_ews_request_write_string_parameter (request, "BaseShape", NULL, default_props);
 
-       e_async_closure_free (closure);
+       ews_append_additional_props_to_msg (request, add_props);
 
-       return success;
-}
+       e_soap_request_end_element (request);
 
-void
-e_ews_connection_sync_folder_hierarchy (EEwsConnection *cnc,
-                                        gint pri,
-                                        const gchar *sync_state,
-                                        GCancellable *cancellable,
-                                        GAsyncReadyCallback callback,
-                                        gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       /*write restriction message based on query*/
+       if (convert_query_cb) {
+               e_soap_request_start_element (request, "Restriction", "messages", NULL);
 
-       g_return_if_fail (cnc != NULL);
+               if (only_ids && only_ids->len) {
+                       e_soap_request_start_element (request, "And", "messages", NULL);
+                       e_soap_request_start_element (request, "Or", "messages", NULL);
+                       ews_connection_write_only_ids_restriction (request, only_ids);
+                       e_soap_request_end_element (request); /* Or */
+               }
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "SyncFolderHierarchy",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
-       e_soap_message_start_element (msg, "FolderShape", "messages", NULL);
-       e_ews_message_write_string_parameter (msg, "BaseShape", NULL, "AllProperties");
-       e_soap_message_start_element (msg, "AdditionalProperties", NULL, NULL);
-       e_soap_message_start_element (msg, "ExtendedFieldURI", NULL, NULL);
-       e_soap_message_add_attribute (msg, "PropertyTag", "4340", NULL, NULL); /* PidTagAttributeHidden */
-       e_soap_message_add_attribute (msg, "PropertyType", "Boolean", NULL, NULL);
-       e_soap_message_end_element (msg); /* ExtendedFieldURI */
-       e_soap_message_end_element (msg); /* AdditionalProperties */
-       e_soap_message_end_element (msg); /* FolderShape */
+               convert_query_cb (request, query, type);
+
+               if (only_ids && only_ids->len)
+                       e_soap_request_end_element (request); /* And */
+
+               e_soap_request_end_element (request); /* Restriction */
+       } else if (only_ids && only_ids->len) {
+               e_soap_request_start_element (request, "Restriction", "messages", NULL);
+               ews_connection_write_only_ids_restriction (request, only_ids);
+               e_soap_request_end_element (request);
+       }
+
+       if (sort_order)
+               ews_write_sort_order_to_msg (request, sort_order);
 
-       if (sync_state)
-               e_ews_message_write_string_parameter (msg, "SyncState", "messages", sync_state);
+       e_soap_request_start_element (request, "ParentFolderIds", "messages", NULL);
 
-       e_ews_message_write_footer (msg);
+       if (fid->is_distinguished_id)
+               e_ews_request_write_string_parameter_with_attribute (request, "DistinguishedFolderId", NULL, 
NULL, "Id", fid->id);
+       else
+               e_ews_request_write_string_parameter_with_attribute (request, "FolderId", NULL, NULL, "Id", 
fid->id);
+
+       e_soap_request_end_element (request);
+
+       e_ews_request_write_footer (request);
+
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
+
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_sync_folder_hierarchy);
+       success = e_ews_process_find_folder_items_response (cnc, response, out_includes_last_item, out_items, 
error);
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       async_data->cnc = cnc;
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       e_ews_connection_queue_request (
-               cnc, msg, sync_hierarchy_response_cb,
-               pri, cancellable, simple);
+       if (success) {
+               *out_items = g_slist_reverse (*out_items);
+       } else {
+               g_slist_free_full (*out_items, g_object_unref);
+               *out_items = NULL;
+       }
 
-       g_object_unref (simple);
+       return success;
 }
 
-gboolean
-e_ews_connection_sync_folder_hierarchy_finish (EEwsConnection *cnc,
-                                               GAsyncResult *result,
-                                               gchar **sync_state,
-                                               gboolean *includes_last_folder,
-                                               GSList **folders_created,
-                                               GSList **folders_updated,
-                                               GSList **folders_deleted,
-                                               GError **error)
+static gboolean
+e_ews_process_sync_hierarchy_response (EEwsConnection *cnc,
+                                      ESoapResponse *response,
+                                      gchar **out_new_sync_state,
+                                      gboolean *out_includes_last_item,
+                                      GSList **out_items_created,
+                                      GSList **out_items_updated,
+                                      GSList **out_items_deleted,
+                                      GError **error)
 {
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       ESoapParameter *param;
+       ESoapParameter *subparam;
+       GError *local_error = NULL;
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_sync_folder_hierarchy),
-               FALSE);
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       if (g_simple_async_result_propagate_error (simple, error))
+       if (local_error != NULL) {
+               g_propagate_error (error, local_error);
                return FALSE;
+       }
+
+       subparam = e_soap_parameter_get_first_child (param);
+
+       while (subparam != NULL) {
+               const gchar *name = (const gchar *) subparam->name;
+
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
+
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "SyncFolderHierarchyResponseMessage")) {
+                       e_ews_process_sync_xxx_response (subparam, (ItemParser) 
e_ews_folder_new_from_soap_parameter,
+                               "IncludesLastFolderInRange", "FolderId",
+                               out_new_sync_state, out_includes_last_item, out_items_created, 
out_items_updated, out_items_deleted);
+               }
 
-       *sync_state = async_data->sync_state;
-       *includes_last_folder = async_data->includes_last_item;
-       *folders_created = async_data->items_created;
-       *folders_updated = async_data->items_updated;
-       *folders_deleted = async_data->items_deleted;
+               subparam = e_soap_parameter_get_next_child (subparam);
+       }
 
        return TRUE;
 }
@@ -5205,37 +3872,61 @@ gboolean
 e_ews_connection_sync_folder_hierarchy_sync (EEwsConnection *cnc,
                                              gint pri,
                                             const gchar *old_sync_state,
-                                             gchar **new_sync_state,
-                                             gboolean *includes_last_folder,
-                                             GSList **folders_created,
-                                             GSList **folders_updated,
-                                             GSList **folders_deleted,
+                                             gchar **out_new_sync_state,
+                                             gboolean *out_includes_last_folder,
+                                             GSList **out_folders_created,
+                                             GSList **out_folders_updated,
+                                             GSList **out_folders_deleted,
                                              GCancellable *cancellable,
                                              GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       closure = e_async_closure_new ();
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "SyncFolderHierarchy",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
+
+       if (!request)
+               return FALSE;
 
-       e_ews_connection_sync_folder_hierarchy (
-               cnc, pri, old_sync_state, cancellable,
-               e_async_closure_callback, closure);
+       e_soap_request_start_element (request, "FolderShape", "messages", NULL);
+       e_ews_request_write_string_parameter (request, "BaseShape", NULL, "AllProperties");
+       e_soap_request_start_element (request, "AdditionalProperties", NULL, NULL);
+       e_soap_request_start_element (request, "ExtendedFieldURI", NULL, NULL);
+       e_soap_request_add_attribute (request, "PropertyTag", "4340", NULL, NULL); /* PidTagAttributeHidden */
+       e_soap_request_add_attribute (request, "PropertyType", "Boolean", NULL, NULL);
+       e_soap_request_end_element (request); /* ExtendedFieldURI */
+       e_soap_request_end_element (request); /* AdditionalProperties */
+       e_soap_request_end_element (request); /* FolderShape */
 
-       result = e_async_closure_wait (closure);
+       if (old_sync_state)
+               e_ews_request_write_string_parameter (request, "SyncState", "messages", old_sync_state);
 
-       success = e_ews_connection_sync_folder_hierarchy_finish (
-               cnc, result, new_sync_state,
-               includes_last_folder,
-               folders_created,
-               folders_updated,
-               folders_deleted,
-               error);
+       e_ews_request_write_footer (request);
 
-       e_async_closure_free (closure);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
+
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
+
+       success = e_ews_process_sync_hierarchy_response (cnc, response, out_new_sync_state, 
out_includes_last_folder,
+               out_folders_created, out_folders_updated, out_folders_deleted, error);
+
+       g_clear_object (&request);
+       g_clear_object (&response);
 
        return success;
 }
@@ -5298,122 +3989,77 @@ e_ews_connection_satisfies_server_version (EEwsConnection *cnc,
        return cnc->priv->version >= version;
 }
 
-void
-e_ews_connection_get_items (EEwsConnection *cnc,
-                            gint pri,
-                            const GSList *ids,
-                            const gchar *default_props,
-                           const EEwsAdditionalProps *add_props,
-                            gboolean include_mime,
-                            const gchar *mime_directory,
-                           EEwsBodyType body_type,
-                            ESoapProgressFn progress_fn,
-                            gpointer progress_data,
-                            GCancellable *cancellable,
-                            GAsyncReadyCallback callback,
-                            gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       const GSList *l;
-
-       g_return_if_fail (cnc != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "GetItem",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
-
-       if (progress_fn && progress_data)
-               e_soap_message_set_progress_fn (msg, progress_fn, progress_data);
+static gboolean
+e_ews_process_get_items_response (EEwsConnection *cnc,
+                                 ESoapResponse *response,
+                                 GSList **out_items,
+                                 GError **error)
+{
+       ESoapParameter *param;
+       ESoapParameter *subparam;
+       GError *local_error = NULL;
 
-       e_soap_message_start_element (msg, "ItemShape", "messages", NULL);
-       e_ews_message_write_string_parameter (msg, "BaseShape", NULL, default_props);
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
-       if (include_mime)
-               e_ews_message_write_string_parameter (msg, "IncludeMimeContent", NULL, "true");
-       else
-               e_ews_message_write_string_parameter (msg, "IncludeMimeContent", NULL, "false");
-       if (mime_directory)
-               e_soap_message_store_node_data (msg, "MimeContent", mime_directory, TRUE);
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       switch (body_type) {
-       case E_EWS_BODY_TYPE_BEST:
-               e_ews_message_write_string_parameter (msg, "BodyType", NULL, "Best");
-               break;
-       case E_EWS_BODY_TYPE_HTML:
-               e_ews_message_write_string_parameter (msg, "BodyType", NULL, "HTML");
-               break;
-       case E_EWS_BODY_TYPE_TEXT:
-               e_ews_message_write_string_parameter (msg, "BodyType", NULL, "Text");
-               break;
-       case E_EWS_BODY_TYPE_ANY:
-               break;
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
-       ews_append_additional_props_to_msg (msg, add_props);
-
-       e_soap_message_end_element (msg);
-
-       e_soap_message_start_element (msg, "ItemIds", "messages", NULL);
-
-       for (l = ids; l != NULL; l = g_slist_next (l))
-               e_ews_message_write_string_parameter_with_attribute (msg, "ItemId", NULL, NULL, "Id", 
l->data);
-
-       e_soap_message_end_element (msg);
-
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_get_items);
+       subparam = e_soap_parameter_get_first_child (param);
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       while (subparam != NULL) {
+               const gchar *name = (const gchar *) subparam->name;
 
-       e_ews_connection_queue_request (
-               cnc, msg, get_items_response_cb,
-               pri, cancellable, simple);
+               if (g_str_has_suffix (name, "ResponseMessage")) {
+                       ESoapParameter *node;
+                       EEwsItem *item;
+
+                       if (ews_get_response_status (subparam, &local_error))
+                               local_error = NULL;
+
+                       for (node = e_soap_parameter_get_first_child_by_name (subparam, "Items");
+                            node;
+                            node = e_soap_parameter_get_next_child_by_name (subparam, "Items")) {
+                               if (node->children)
+                                       item = e_ews_item_new_from_soap_parameter (node);
+                               else
+                                       item = NULL;
+                               if (!item && local_error != NULL)
+                                       item = e_ews_item_new_from_error (local_error);
+                               if (item)
+                                       *out_items = g_slist_prepend (*out_items, item);
+                       }
+               } else {
+                       g_warning ("%s: Unexpected element <%s>", G_STRFUNC, name);
+               }
 
-       g_object_unref (simple);
-}
+               /* Do not stop on errors. */
+               g_clear_error (&local_error);
 
-gboolean
-e_ews_connection_get_items_finish (EEwsConnection *cnc,
-                                   GAsyncResult *result,
-                                   GSList **items,
-                                   GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+               subparam = e_soap_parameter_get_next_child (subparam);
+       }
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_get_items),
-               FALSE);
+       /* if there is only one item, then check whether it's an error */
+       if (*out_items && (*out_items)->data && !(*out_items)->next) {
+               EEwsItem *item = (*out_items)->data;
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+               if (item && e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_ERROR) {
+                       g_propagate_error (error, g_error_copy (e_ews_item_get_error (item)));
 
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+                       g_slist_free_full (*out_items, g_object_unref);
+                       *out_items = NULL;
 
-       if (!async_data->items) {
-               g_set_error_literal (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_ITEMNOTFOUND, _("No 
items found"));
-               return FALSE;
+                       return FALSE;
+               }
        }
 
-       *items = async_data->items;
+       *out_items = g_slist_reverse (*out_items);
 
        return TRUE;
 }
@@ -5427,273 +4073,137 @@ e_ews_connection_get_items_sync (EEwsConnection *cnc,
                                  gboolean include_mime,
                                  const gchar *mime_directory,
                                 EEwsBodyType body_type,
-                                 GSList **items,
-                                 ESoapProgressFn progress_fn,
+                                 GSList **out_items,
+                                 ESoapResponseProgressFn progress_fn,
                                  gpointer progress_data,
                                  GCancellable *cancellable,
                                  GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       const GSList *link;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (out_items != NULL, FALSE);
 
-       closure = e_async_closure_new ();
-
-       e_ews_connection_get_items (
-               cnc, pri,ids, default_props,
-               add_props, include_mime,
-               mime_directory, body_type, progress_fn,
-               progress_data, cancellable,
-               e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_connection_get_items_finish (
-               cnc, result, items, error);
-
-       e_async_closure_free (closure);
-
-       return success;
-}
-
-static const gchar *
-ews_delete_type_to_str (EwsDeleteType delete_type)
-{
-       switch (delete_type) {
-               case EWS_HARD_DELETE:
-                       return "HardDelete";
-               case EWS_SOFT_DELETE:
-                       return "SoftDelete";
-               case EWS_MOVE_TO_DELETED_ITEMS:
-                       return "MoveToDeletedItems";
-       }
-       return NULL;
-}
-
-static const gchar *
-ews_send_cancels_to_str (EwsSendMeetingCancellationsType send_cancels)
-{
-       switch (send_cancels) {
-               case EWS_SEND_TO_NONE:
-                       return "SendToNone";
-               case EWS_SEND_ONLY_TO_ALL:
-                       return "SendOnlyToAll";
-               case EWS_SEND_TO_ALL_AND_SAVE_COPY:
-                       return "SendToAllAndSaveCopy";
-       }
-       return NULL;
-}
-
-static const gchar *
-ews_affected_tasks_to_str (EwsAffectedTaskOccurrencesType affected_tasks)
-{
-       switch (affected_tasks) {
-               case EWS_NONE_OCCURRENCES:
-                       return NULL;
-               case EWS_ALL_OCCURRENCES:
-                       return "AllOccurrences";
-               case EWS_SPECIFIED_OCCURRENCE_ONLY:
-                       return "SpecifiedOccurrenceOnly";
-       }
-       return NULL;
-}
-
-static void
-delete_item_response_cb (ESoapResponse *response,
-                         GSimpleAsyncResult *simple)
-{
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
-
-       subparam = e_soap_parameter_get_first_child (param);
-
-       while (subparam != NULL) {
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
-
-               subparam = e_soap_parameter_get_next_child (subparam);
-       }
-}
-
-void
-e_ews_connection_delete_items (EEwsConnection *cnc,
-                               gint pri,
-                               const GSList *ids,
-                               EwsDeleteType delete_type,
-                               EwsSendMeetingCancellationsType send_cancels,
-                               EwsAffectedTaskOccurrencesType affected_tasks,
-                               GCancellable *cancellable,
-                               GAsyncReadyCallback callback,
-                               gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       const GSList *iter;
-
-       g_return_if_fail (cnc != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "DeleteItem",
-                       "DeleteType",
-                       ews_delete_type_to_str (delete_type),
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
-
-       if (send_cancels)
-               e_soap_message_add_attribute (
-                       msg, "SendMeetingCancellations",
-                       ews_send_cancels_to_str (send_cancels), NULL, NULL);
-
-       if (affected_tasks)
-               e_soap_message_add_attribute (
-                       msg, "AffectedTaskOccurrences",
-                       ews_affected_tasks_to_str (affected_tasks), NULL, NULL);
+       *out_items = NULL;
 
-       e_soap_message_start_element (msg, "ItemIds", "messages", NULL);
-
-       for (iter = ids; iter != NULL; iter = g_slist_next (iter))
-               e_ews_message_write_string_parameter_with_attribute (msg, "ItemId", NULL, NULL, "Id", 
iter->data);
-
-       e_soap_message_end_element (msg);
-
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_delete_items);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetItem",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       e_ews_connection_queue_request (
-               cnc, msg, delete_item_response_cb,
-               pri, cancellable, simple);
+       if (!request)
+               return FALSE;
 
-       g_object_unref (simple);
-}
+       if (progress_fn && progress_data)
+               e_soap_request_set_progress_fn (request, progress_fn, progress_data);
 
-void
-e_ews_connection_delete_item (EEwsConnection *cnc,
-                              gint pri,
-                              EwsId *item_id,
-                              guint index,
-                              EwsDeleteType delete_type,
-                              EwsSendMeetingCancellationsType send_cancels,
-                              EwsAffectedTaskOccurrencesType affected_tasks,
-                              GCancellable *cancellable,
-                              GAsyncReadyCallback callback,
-                              gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       gchar buffer[32];
+       e_soap_request_start_element (request, "ItemShape", "messages", NULL);
+       e_ews_request_write_string_parameter (request, "BaseShape", NULL, default_props);
 
-       g_return_if_fail (cnc != NULL);
+       if (include_mime)
+               e_ews_request_write_string_parameter (request, "IncludeMimeContent", NULL, "true");
+       else
+               e_ews_request_write_string_parameter (request, "IncludeMimeContent", NULL, "false");
+       if (mime_directory)
+               e_soap_request_set_store_node_data (request, "MimeContent", mime_directory, TRUE);
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "DeleteItem",
-                       "DeleteType",
-                       ews_delete_type_to_str (delete_type),
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
+       switch (body_type) {
+       case E_EWS_BODY_TYPE_BEST:
+               e_ews_request_write_string_parameter (request, "BodyType", NULL, "Best");
+               break;
+       case E_EWS_BODY_TYPE_HTML:
+               e_ews_request_write_string_parameter (request, "BodyType", NULL, "HTML");
+               break;
+       case E_EWS_BODY_TYPE_TEXT:
+               e_ews_request_write_string_parameter (request, "BodyType", NULL, "Text");
+               break;
+       case E_EWS_BODY_TYPE_ANY:
+               break;
+       }
 
-       if (send_cancels)
-               e_soap_message_add_attribute (
-                       msg, "SendMeetingCancellations",
-                       ews_send_cancels_to_str (send_cancels), NULL, NULL);
+       ews_append_additional_props_to_msg (request, add_props);
 
-       if (affected_tasks != EWS_NONE_OCCURRENCES)
-               e_soap_message_add_attribute (
-                       msg, "AffectedTaskOccurrences",
-                       ews_affected_tasks_to_str (affected_tasks), NULL, NULL);
+       e_soap_request_end_element (request);
 
-       e_soap_message_start_element (msg, "ItemIds", "messages", NULL);
+       e_soap_request_start_element (request, "ItemIds", "messages", NULL);
 
-       if (index) {
-               e_soap_message_start_element (msg, "OccurrenceItemId", NULL, NULL);
-               e_soap_message_add_attribute (msg, "RecurringMasterId", item_id->id, NULL, NULL);
-               if (item_id->change_key)
-                       e_soap_message_add_attribute (msg, "ChangeKey", item_id->change_key, NULL, NULL);
-               snprintf (buffer, 32, "%u", index);
-               e_soap_message_add_attribute (msg, "InstanceIndex", buffer, NULL, NULL);
-               e_soap_message_end_element (msg);
-       } else {
-               e_soap_message_start_element (msg, "ItemId", NULL, NULL);
-               e_soap_message_add_attribute (msg, "Id", item_id->id, NULL, NULL);
-               if (item_id->change_key)
-                       e_soap_message_add_attribute (msg, "ChangeKey", item_id->change_key, NULL, NULL);
-               e_soap_message_end_element (msg);
+       for (link = ids; link; link = g_slist_next (link)) {
+               e_ews_request_write_string_parameter_with_attribute (request, "ItemId", NULL, NULL, "Id", 
link->data);
        }
 
-       e_soap_message_end_element (msg);
+       e_soap_request_end_element (request);
 
-       e_ews_message_write_footer (msg);
+       e_ews_request_write_footer (request);
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_delete_items);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       e_ews_connection_queue_request (
-               cnc, msg, delete_item_response_cb,
-               pri, cancellable, simple);
+       success = e_ews_process_get_items_response (cnc, response, out_items, error);
 
-       g_object_unref (simple);
-}
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-gboolean
-e_ews_connection_delete_items_finish (EEwsConnection *cnc,
-                                      GAsyncResult *result,
-                                      GError **error)
-{
-       GSimpleAsyncResult *simple;
+       if (!success) {
+               g_slist_free_full (*out_items, g_object_unref);
+               *out_items = NULL;
+       }
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_delete_items),
-               FALSE);
+       return success;
+}
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
+static const gchar *
+ews_delete_type_to_str (EwsDeleteType delete_type)
+{
+       switch (delete_type) {
+               case EWS_HARD_DELETE:
+                       return "HardDelete";
+               case EWS_SOFT_DELETE:
+                       return "SoftDelete";
+               case EWS_MOVE_TO_DELETED_ITEMS:
+                       return "MoveToDeletedItems";
+       }
+       return NULL;
+}
 
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+static const gchar *
+ews_send_cancels_to_str (EwsSendMeetingCancellationsType send_cancels)
+{
+       switch (send_cancels) {
+               case EWS_SEND_TO_NONE:
+                       return "SendToNone";
+               case EWS_SEND_ONLY_TO_ALL:
+                       return "SendOnlyToAll";
+               case EWS_SEND_TO_ALL_AND_SAVE_COPY:
+                       return "SendToAllAndSaveCopy";
+       }
+       return NULL;
+}
 
-       return TRUE;
+static const gchar *
+ews_affected_tasks_to_str (EwsAffectedTaskOccurrencesType affected_tasks)
+{
+       switch (affected_tasks) {
+               case EWS_NONE_OCCURRENCES:
+                       return NULL;
+               case EWS_ALL_OCCURRENCES:
+                       return "AllOccurrences";
+               case EWS_SPECIFIED_OCCURRENCE_ONLY:
+                       return "SpecifiedOccurrenceOnly";
+       }
+       return NULL;
 }
 
 gboolean
@@ -5706,24 +4216,56 @@ e_ews_connection_delete_items_sync (EEwsConnection *cnc,
                                     GCancellable *cancellable,
                                     GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       const GSList *link;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       closure = e_async_closure_new ();
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "DeleteItem",
+               "DeleteType",
+               ews_delete_type_to_str (delete_type),
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
+
+       if (!request)
+               return FALSE;
+
+       if (send_cancels)
+               e_soap_request_add_attribute (request, "SendMeetingCancellations",
+                       ews_send_cancels_to_str (send_cancels), NULL, NULL);
+
+       if (affected_tasks)
+               e_soap_request_add_attribute (request, "AffectedTaskOccurrences",
+                       ews_affected_tasks_to_str (affected_tasks), NULL, NULL);
+
+       e_soap_request_start_element (request, "ItemIds", "messages", NULL);
 
-       e_ews_connection_delete_items (
-               cnc, pri, ids, delete_type,
-               send_cancels, affected_tasks, cancellable,
-               e_async_closure_callback, closure);
+       for (link = ids; link; link = g_slist_next (link)) {
+               e_ews_request_write_string_parameter_with_attribute (request, "ItemId", NULL, NULL, "Id", 
link->data);
+       }
+
+       e_soap_request_end_element (request);
+
+       e_ews_request_write_footer (request);
+
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       result = e_async_closure_wait (closure);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       success = e_ews_connection_delete_items_finish (cnc, result, error);
+       success = e_ews_process_generic_response (cnc, response, error);
 
-       e_async_closure_free (closure);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
        return success;
 }
@@ -5739,24 +4281,69 @@ e_ews_connection_delete_item_sync (EEwsConnection *cnc,
                                    GCancellable *cancellable,
                                    GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       gchar buffer[32];
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (id != NULL, FALSE);
+
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "DeleteItem",
+               "DeleteType",
+               ews_delete_type_to_str (delete_type),
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
+
+       if (!request)
+               return FALSE;
+
+       if (send_cancels)
+               e_soap_request_add_attribute (request, "SendMeetingCancellations",
+                       ews_send_cancels_to_str (send_cancels), NULL, NULL);
+
+       if (affected_tasks != EWS_NONE_OCCURRENCES)
+               e_soap_request_add_attribute (request, "AffectedTaskOccurrences",
+                       ews_affected_tasks_to_str (affected_tasks), NULL, NULL);
+
+       e_soap_request_start_element (request, "ItemIds", "messages", NULL);
 
-       closure = e_async_closure_new ();
+       if (index) {
+               e_soap_request_start_element (request, "OccurrenceItemId", NULL, NULL);
+               e_soap_request_add_attribute (request, "RecurringMasterId", id->id, NULL, NULL);
+               if (id->change_key)
+                       e_soap_request_add_attribute (request, "ChangeKey", id->change_key, NULL, NULL);
+               snprintf (buffer, 32, "%u", index);
+               e_soap_request_add_attribute (request, "InstanceIndex", buffer, NULL, NULL);
+               e_soap_request_end_element (request);
+       } else {
+               e_soap_request_start_element (request, "ItemId", NULL, NULL);
+               e_soap_request_add_attribute (request, "Id", id->id, NULL, NULL);
+               if (id->change_key)
+                       e_soap_request_add_attribute (request, "ChangeKey", id->change_key, NULL, NULL);
+               e_soap_request_end_element (request);
+       }
 
-       e_ews_connection_delete_item (
-               cnc, pri, id, index, delete_type,
-               send_cancels, affected_tasks, cancellable,
-               e_async_closure_callback, closure);
+       e_soap_request_end_element (request);
 
-       result = e_async_closure_wait (closure);
+       e_ews_request_write_footer (request);
+
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
+
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       success = e_ews_connection_delete_items_finish (cnc, result, error);
+       success = e_ews_process_generic_response (cnc, response, error);
 
-       e_async_closure_free (closure);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
        return success;
 }
@@ -5855,7 +4442,7 @@ xpath_eval (xmlXPathContextPtr ctx,
 }
 
 static gboolean
-element_has_child (ESoapMessage *message,
+element_has_child (ESoapRequest *request,
                   const gchar *path)
 {
        xmlDocPtr doc;
@@ -5865,7 +4452,7 @@ element_has_child (ESoapMessage *message,
        xmlNodePtr node;
        gboolean ret = FALSE;
 
-       doc = e_soap_message_get_xml_doc (message);
+       doc = e_soap_request_get_xml_doc (request);
        xpctx = xmlXPathNewContext (doc);
 
        xmlXPathRegisterNs (
@@ -5904,144 +4491,6 @@ exit:
        return ret;
 }
 
-void
-e_ews_connection_update_items (EEwsConnection *cnc,
-                               gint pri,
-                               const gchar *conflict_res,
-                               const gchar *msg_disposition,
-                               const gchar *send_invites,
-                               const gchar *folder_id,
-                               EEwsRequestCreationCallback create_cb,
-                               gpointer create_user_data,
-                               GCancellable *cancellable,
-                               GAsyncReadyCallback callback,
-                               gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       gboolean success;
-       GError *local_error = NULL;
-
-       g_return_if_fail (cnc != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "UpdateItem",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
-
-       if (conflict_res)
-               e_soap_message_add_attribute (
-                       msg, "ConflictResolution",
-                       conflict_res, NULL, NULL);
-       if (msg_disposition)
-               e_soap_message_add_attribute (
-                       msg, "MessageDisposition",
-                       msg_disposition, NULL, NULL);
-       if (send_invites)
-               e_soap_message_add_attribute (
-                       msg, "SendMeetingInvitationsOrCancellations",
-                       send_invites, NULL, NULL);
-
-       if (folder_id) {
-               e_soap_message_start_element (msg, "SavedItemFolderId", "messages", NULL);
-               e_ews_message_write_string_parameter_with_attribute (
-                       msg, "FolderId",
-                       NULL, NULL, "Id", folder_id);
-               e_soap_message_end_element (msg);
-       }
-
-       e_soap_message_start_element (msg, "ItemChanges", "messages", NULL);
-
-       success = create_cb (msg, create_user_data, &local_error);
-
-       e_soap_message_end_element (msg); /* ItemChanges */
-
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_update_items);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
-
-       if (!success) {
-               if (local_error)
-                       g_simple_async_result_take_error (simple, local_error);
-               g_simple_async_result_complete_in_idle (simple);
-               g_clear_object (&msg);
-
-       /*
-        * We need to check for both namespaces, because, the message is being wrote without use the types
-        * namespace. Maybe it is wrong, but the server doesn't complain about that. But this is the reason
-        * for the first check. The second one, is related to "how it should be" accord with EWS 
specifications.
-        */
-       } else if (!element_has_child (msg, 
"/s:Envelope/s:Body/m:UpdateItem/m:ItemChanges/ItemChange/Updates") &&
-               !element_has_child (msg, 
"/s:Envelope/s:Body/m:UpdateItem/m:ItemChanges/t:ItemChange/t:Updates")) {
-               g_simple_async_result_complete_in_idle (simple);
-               g_clear_object (&msg);
-       } else {
-               e_ews_connection_queue_request (
-                       cnc, msg, get_items_response_cb,
-                       pri, cancellable, simple);
-       }
-
-       g_object_unref (simple);
-}
-
-gboolean
-e_ews_connection_update_items_finish (EEwsConnection *cnc,
-                                      GAsyncResult *result,
-                                      GSList **ids,
-                                      GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_update_items),
-               FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
-
-       /* if there is only one item, then check whether it's an error */
-       if (async_data->items && !async_data->items->next) {
-               EEwsItem *item = async_data->items->data;
-
-               if (item && e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_ERROR) {
-                       if (error)
-                               *error = g_error_copy (e_ews_item_get_error (item));
-
-                       g_slist_free_full (async_data->items, g_object_unref);
-                       async_data->items = NULL;
-
-                       return FALSE;
-               }
-       }
-
-       if (ids)
-               *ids = async_data->items;
-       else
-               g_slist_free_full (async_data->items, g_object_unref);
-
-       return TRUE;
-}
-
 gboolean
 e_ews_connection_update_items_sync (EEwsConnection *cnc,
                                     gint pri,
@@ -6051,151 +4500,84 @@ e_ews_connection_update_items_sync (EEwsConnection *cnc,
                                     const gchar *folder_id,
                                     EEwsRequestCreationCallback create_cb,
                                     gpointer create_user_data,
-                                    GSList **ids,
+                                    GSList **out_items,
                                     GCancellable *cancellable,
                                     GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       GSList *items = NULL;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       closure = e_async_closure_new ();
-
-       e_ews_connection_update_items (
-               cnc, pri, conflict_res,
-               msg_disposition, send_invites,
-               folder_id, create_cb,
-               create_user_data, cancellable,
-               e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_connection_update_items_finish (
-               cnc, result, ids, error);
-
-       e_async_closure_free (closure);
-
-       return success;
-}
-
-void
-e_ews_connection_create_items (EEwsConnection *cnc,
-                               gint pri,
-                               const gchar *msg_disposition,
-                               const gchar *send_invites,
-                               const EwsFolderId *fid,
-                               EEwsRequestCreationCallback create_cb,
-                               gpointer create_user_data,
-                               GCancellable *cancellable,
-                               GAsyncReadyCallback callback,
-                               gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       gboolean success;
-       GError *local_error = NULL;
-
-       g_return_if_fail (cnc != NULL);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "UpdateItem",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "CreateItem",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
+       if (!request)
+               return FALSE;
 
+       if (conflict_res)
+               e_soap_request_add_attribute (request, "ConflictResolution", conflict_res, NULL, NULL);
        if (msg_disposition)
-               e_soap_message_add_attribute (
-                       msg, "MessageDisposition",
-                       msg_disposition, NULL, NULL);
+               e_soap_request_add_attribute (request, "MessageDisposition", msg_disposition, NULL, NULL);
        if (send_invites)
-               e_soap_message_add_attribute (
-                       msg, "SendMeetingInvitations",
-                       send_invites, NULL, NULL);
+               e_soap_request_add_attribute (request, "SendMeetingInvitationsOrCancellations", send_invites, 
NULL, NULL);
 
-       if (fid) {
-               e_soap_message_start_element (msg, "SavedItemFolderId", "messages", NULL);
-               e_ews_folder_id_append_to_msg (msg, cnc->priv->email, fid);
-               e_soap_message_end_element (msg);
+       if (folder_id) {
+               e_soap_request_start_element (request, "SavedItemFolderId", "messages", NULL);
+               e_ews_request_write_string_parameter_with_attribute (request, "FolderId", NULL, NULL, "Id", 
folder_id);
+               e_soap_request_end_element (request);
        }
 
-       e_soap_message_start_element (msg, "Items", "messages", NULL);
+       e_soap_request_start_element (request, "ItemChanges", "messages", NULL);
 
-       success = create_cb (msg, create_user_data, &local_error);
-
-       e_soap_message_end_element (msg); /* Items */
-
-       e_ews_message_write_footer (msg); /* CreateItem */
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_create_items);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
-
-       if (success) {
-               e_ews_connection_queue_request (
-                       cnc, msg, get_items_response_cb,
-                       pri, cancellable, simple);
-       } else {
-               if (local_error)
-                       g_simple_async_result_take_error (simple, local_error);
-               g_simple_async_result_complete_in_idle (simple);
-               g_clear_object (&msg);
+       if (!create_cb (request, create_user_data, error)) {
+               g_clear_object (&request);
+               return FALSE;
        }
 
-       g_object_unref (simple);
-}
+       e_soap_request_end_element (request); /* ItemChanges */
 
-gboolean
-e_ews_connection_create_items_finish (EEwsConnection *cnc,
-                                      GAsyncResult *result,
-                                      GSList **ids,
-                                      GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       e_ews_request_write_footer (request);
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_create_items),
-               FALSE);
+       /*
+        * We need to check for both namespaces, because, the message is being wrote without use the types
+        * namespace. Maybe it is wrong, but the server doesn't complain about that. But this is the reason
+        * for the first check. The second one, is related to "how it should be" accord with EWS 
specifications.
+        */
+       if (!element_has_child (request, "/s:Envelope/s:Body/m:UpdateItem/m:ItemChanges/ItemChange/Updates") 
&&
+           !element_has_child (request, 
"/s:Envelope/s:Body/m:UpdateItem/m:ItemChanges/t:ItemChange/t:Updates")) {
+               g_clear_object (&request);
+               return TRUE;
+       }
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       if (g_simple_async_result_propagate_error (simple, error))
+       if (!response) {
+               g_clear_object (&request);
                return FALSE;
+       }
 
-       /* if there is only one item, then check whether it's an error */
-       if (async_data->items && !async_data->items->next) {
-               EEwsItem *item = async_data->items->data;
-
-               if (item && e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_ERROR) {
-                       if (error)
-                               *error = g_error_copy (e_ews_item_get_error (item));
-
-                       g_slist_free_full (async_data->items, g_object_unref);
-                       async_data->items = NULL;
+       success = e_ews_process_get_items_response (cnc, response, &items, error);
 
-                       return FALSE;
-               }
-       }
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       *ids = async_data->items;
+       if (success && out_items)
+               *out_items = items;
+       else
+               g_slist_free_full (items, g_object_unref);
 
-       return TRUE;
+       return success;
 }
 
 gboolean
@@ -6206,31 +4588,69 @@ e_ews_connection_create_items_sync (EEwsConnection *cnc,
                                     const EwsFolderId *fid,
                                     EEwsRequestCreationCallback create_cb,
                                     gpointer create_user_data,
-                                    GSList **ids,
+                                    GSList **out_items,
                                     GCancellable *cancellable,
                                     GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       GSList *items = NULL;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       closure = e_async_closure_new ();
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "CreateItem",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
+
+       if (!request)
+               return FALSE;
+
+       if (msg_disposition)
+               e_soap_request_add_attribute (request, "MessageDisposition", msg_disposition, NULL, NULL);
+       if (send_invites)
+               e_soap_request_add_attribute (request, "SendMeetingInvitations", send_invites, NULL, NULL);
+
+       if (fid) {
+               e_soap_request_start_element (request, "SavedItemFolderId", "messages", NULL);
+               e_ews_folder_id_append_to_request (request, cnc->priv->email, fid);
+               e_soap_request_end_element (request);
+       }
 
-       e_ews_connection_create_items (
-               cnc, pri, msg_disposition,
-               send_invites, fid,
-               create_cb, create_user_data,
-               cancellable,
-               e_async_closure_callback, closure);
+       e_soap_request_start_element (request, "Items", "messages", NULL);
 
-       result = e_async_closure_wait (closure);
+       if (!create_cb (request, create_user_data, error)) {
+               g_clear_object (&request);
+               return FALSE;
+       }
+
+       e_soap_request_end_element (request); /* Items */
+
+       e_ews_request_write_footer (request);
+
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
+
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       success = e_ews_connection_create_items_finish (
-               cnc, result, ids, error);
+       success = e_ews_process_get_items_response (cnc, response, &items, error);
 
-       e_async_closure_free (closure);
+       g_clear_object (&request);
+       g_clear_object (&response);
+
+       if (success && out_items)
+               *out_items = items;
+       else
+               g_slist_free_full (items, g_object_unref);
 
        return success;
 }
@@ -6254,101 +4674,84 @@ get_search_scope_str (EwsContactsSearchScope scope)
        }
 }
 
-void
-e_ews_connection_resolve_names (EEwsConnection *cnc,
-                                gint pri,
-                                const gchar *resolve_name,
-                                EwsContactsSearchScope scope,
-                                GSList *parent_folder_ids,
-                                gboolean fetch_contact_data,
-                                GCancellable *cancellable,
-                                GAsyncReadyCallback callback,
-                                gpointer user_data)
+static gboolean
+e_ews_process_resolve_names_response (EEwsConnection *cnc,
+                                     ESoapResponse *response,
+                                     gboolean *out_includes_last_item,
+                                     GSList **out_mailboxes,
+                                     GSList **out_contact_items,
+                                     GError **error)
 {
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_if_fail (cnc != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "ResolveNames",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
+       ESoapParameter *param;
+       ESoapParameter *subparam;
+       GError *local_error = NULL;
 
-       e_soap_message_add_attribute (msg, "SearchScope", get_search_scope_str (scope), NULL, NULL);
+       *out_includes_last_item = TRUE;
+       *out_contact_items = NULL;
+       *out_mailboxes = NULL;
 
-       if (fetch_contact_data) {
-               e_soap_message_add_attribute (msg, "ReturnFullContactData", "true", NULL, NULL);
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
-               if (e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2010_SP2))
-                       e_soap_message_add_attribute (msg, "ContactDataShape", "AllProperties", NULL, NULL);
-       } else {
-               e_soap_message_add_attribute (msg, "ReturnFullContactData", "false", NULL, NULL);
-       }
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       if (parent_folder_ids) {
-               e_soap_message_start_element (msg, "ParentFolderIds", "messages", NULL);
-               ews_append_folder_ids_to_msg (msg, cnc->priv->email, parent_folder_ids);
-               e_soap_message_end_element (msg);
+       if (local_error != NULL) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
-       e_ews_message_write_string_parameter (msg, "UnresolvedEntry", "messages", resolve_name);
-
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_resolve_names);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
-
-       e_ews_connection_queue_request (
-               cnc, msg, resolve_names_response_cb,
-               pri, cancellable, simple);
-
-       g_object_unref (simple);
-}
-
-gboolean
-e_ews_connection_resolve_names_finish (EEwsConnection *cnc,
-                                       GAsyncResult *result,
-                                       GSList **mailboxes,
-                                       GSList **contact_items,
-                                       gboolean *includes_last_item,
-                                       GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_resolve_names),
-               FALSE);
+       subparam = e_soap_parameter_get_first_child (param);
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       while (subparam != NULL) {
+               const gchar *name = (const gchar *) subparam->name;
 
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+               if (!ews_get_response_status (subparam, error)) {
+                       return FALSE;
+               }
 
-       *includes_last_item = async_data->includes_last_item;
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "ResolveNamesResponseMessage")) {
+                       ESoapParameter *node;
+                       gchar *prop;
+
+                       subparam = e_soap_parameter_get_first_child_by_name (subparam, "ResolutionSet");
+                       prop = e_soap_parameter_get_property (subparam, "IncludesLastItemInRange");
+                       /*
+                        * Set the includes_last_item to TRUE as default.
+                        * It can avoid an infinite loop in caller, when, for some reason,
+                        * we don't receive the last_tag property from the server.
+                        */
+                       *out_includes_last_item = g_strcmp0 (prop, "false") != 0;
+                       g_free (prop);
+
+                       for (subparam = e_soap_parameter_get_first_child_by_name (subparam, "Resolution");
+                            subparam != NULL;
+                            subparam = e_soap_parameter_get_next_child_by_name (subparam, "Resolution")) {
+                               EwsMailbox *mb;
+
+                               node = e_soap_parameter_get_first_child_by_name (subparam, "Mailbox");
+                               mb = e_ews_item_mailbox_from_soap_param (node);
+                               if (mb) {
+                                       EEwsItem *contact_item;
+
+                                       *out_mailboxes = g_slist_prepend (*out_mailboxes, mb);
+
+                                       /* 'mailboxes' and 'contact_items' match 1:1, but if the contact 
information
+                                        * wasn't found, then NULL is stored in the corresponding position */
+                                       node = e_soap_parameter_get_first_child_by_name (subparam, "Contact");
+                                       if (node) {
+                                               contact_item = e_ews_item_new_from_soap_parameter (node);
+                                               *out_contact_items = g_slist_prepend (*out_contact_items, 
contact_item);
+                                       } else {
+                                               *out_contact_items = g_slist_prepend (*out_contact_items, 
NULL);
+                                       }
+                               }
+                       }
+               }
 
-       if (contact_items)
-               *contact_items = async_data->items_created;
-       else
-               e_util_free_nullable_object_slist (async_data->items_created);
-       *mailboxes = async_data->items;
+               subparam = e_soap_parameter_get_next_child (subparam);
+       }
 
        return TRUE;
 }
@@ -6360,35 +4763,79 @@ e_ews_connection_resolve_names_sync (EEwsConnection *cnc,
                                      EwsContactsSearchScope scope,
                                      GSList *parent_folder_ids,
                                      gboolean fetch_contact_data,
-                                     GSList **mailboxes,
-                                     GSList **contact_items,
-                                     gboolean *includes_last_item,
+                                     gboolean *out_includes_last_item,
+                                     GSList **out_mailboxes,
+                                     GSList **out_contact_items,
                                      GCancellable *cancellable,
                                      GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       gboolean includes_last_item = TRUE;
+       GSList *mailboxes = NULL, *contact_items = NULL;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       closure = e_async_closure_new ();
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "ResolveNames",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
+
+       if (!request)
+               return FALSE;
+
+       e_soap_request_add_attribute (request, "SearchScope", get_search_scope_str (scope), NULL, NULL);
+
+       if (fetch_contact_data) {
+               e_soap_request_add_attribute (request, "ReturnFullContactData", "true", NULL, NULL);
+
+               if (e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2010_SP2))
+                       e_soap_request_add_attribute (request, "ContactDataShape", "AllProperties", NULL, 
NULL);
+       } else {
+               e_soap_request_add_attribute (request, "ReturnFullContactData", "false", NULL, NULL);
+       }
+
+       if (parent_folder_ids) {
+               e_soap_request_start_element (request, "ParentFolderIds", "messages", NULL);
+               ews_append_folder_ids_to_msg (request, cnc->priv->email, parent_folder_ids);
+               e_soap_request_end_element (request);
+       }
+
+       e_ews_request_write_string_parameter (request, "UnresolvedEntry", "messages", resolve_name);
 
-       e_ews_connection_resolve_names (
-               cnc, pri, resolve_name,
-               scope, parent_folder_ids,
-               fetch_contact_data,
-               cancellable,
-               e_async_closure_callback, closure);
+       e_ews_request_write_footer (request);
 
-       result = e_async_closure_wait (closure);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       success = e_ews_connection_resolve_names_finish (
-               cnc, result,
-               mailboxes, contact_items,
-               includes_last_item, error);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
+
+       success = e_ews_process_resolve_names_response (cnc, response, &includes_last_item, &mailboxes, 
&contact_items, error);
+
+       g_clear_object (&request);
+       g_clear_object (&response);
+
+       if (success && out_includes_last_item)
+               *out_includes_last_item = includes_last_item;
+
+       if (success && out_mailboxes)
+               *out_mailboxes = g_slist_reverse (mailboxes);
+       else
+               g_slist_free_full (mailboxes, (GDestroyNotify) e_ews_mailbox_free);
 
-       e_async_closure_free (closure);
+       if (success && out_contact_items)
+               *out_contact_items = g_slist_reverse (contact_items);
+       else
+               e_util_free_nullable_object_slist (contact_items);
 
        return success;
 }
@@ -6421,8 +4868,8 @@ ews_connection_resolve_by_name (EEwsConnection *cnc,
        /* use the first error, not the guess-part error */
        e_ews_connection_resolve_names_sync (
                cnc, pri, usename,
-               EWS_SEARCH_AD_CONTACTS, NULL, TRUE, &mailboxes, &contacts,
-               &includes_last_item, cancellable, NULL);
+               EWS_SEARCH_AD_CONTACTS, NULL, TRUE, &includes_last_item, &mailboxes, &contacts,
+               cancellable, NULL);
 
        for (miter = mailboxes; miter; miter = miter->next) {
                const EwsMailbox *mailbox = miter->data;
@@ -6502,8 +4949,8 @@ e_ews_connection_ex_to_smtp_sync (EEwsConnection *cnc,
 
        e_ews_connection_resolve_names_sync (
                cnc, pri, ex_address,
-               EWS_SEARCH_AD_CONTACTS, NULL, TRUE, &mailboxes, &contacts,
-               &includes_last_item, cancellable, error);
+               EWS_SEARCH_AD_CONTACTS, NULL, TRUE, &includes_last_item, &mailboxes, &contacts,
+               cancellable, error);
 
        /* only one mailbox matches */
        if (mailboxes && !mailboxes->next && mailboxes->data) {
@@ -6558,382 +5005,194 @@ e_ews_connection_ex_to_smtp_sync (EEwsConnection *cnc,
        return *smtp_address != NULL;
 }
 
-void
-e_ews_connection_expand_dl (EEwsConnection *cnc,
-                            gint pri,
-                            const EwsMailbox *mb,
-                            GCancellable *cancellable,
-                            GAsyncReadyCallback callback,
-                            gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_if_fail (cnc != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "ExpandDL",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
-
-       e_soap_message_start_element (msg, "Mailbox", "messages", NULL);
-
-       if (mb->item_id) {
-               e_soap_message_start_element (msg, "ItemId", NULL, NULL);
-
-               e_soap_message_add_attribute (msg, "Id", mb->item_id->id, NULL, NULL);
-               e_soap_message_add_attribute (msg, "ChangeKey", mb->item_id->change_key, NULL, NULL);
-
-               e_soap_message_end_element (msg); /* Mailbox */
-
-       } else if (mb->email)
-               e_ews_message_write_string_parameter (msg, "EmailAddress", NULL, mb->email);
-
-       e_soap_message_end_element (msg); /* Mailbox */
-
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_expand_dl);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
-
-       e_ews_connection_queue_request (
-               cnc, msg, expand_dl_response_cb,
-               pri, cancellable, simple);
-
-       g_object_unref (simple);
-}
-
-/* includes_last_item does not make sense as expand_dl does not support recursive 
- * fetch, wierd */
-gboolean
-e_ews_connection_expand_dl_finish (EEwsConnection *cnc,
-                                   GAsyncResult *result,
-                                   GSList **mailboxes,
-                                   gboolean *includes_last_item,
-                                   GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_expand_dl),
-               FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
-
-       *includes_last_item = async_data->includes_last_item;
-       *mailboxes = async_data->items;
-
-       return TRUE;
-
-}
-
-gboolean
-e_ews_connection_expand_dl_sync (EEwsConnection *cnc,
-                                 gint pri,
-                                 const EwsMailbox *mb,
-                                 GSList **mailboxes,
-                                 gboolean *includes_last_item,
-                                 GCancellable *cancellable,
-                                 GError **error)
-{
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-
-       closure = e_async_closure_new ();
-
-       e_ews_connection_expand_dl (
-               cnc, pri, mb, cancellable,
-               e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_connection_expand_dl_finish (
-               cnc, result, mailboxes, includes_last_item, error);
-
-       e_async_closure_free (closure);
-
-       return success;
-}
-
-static void
-update_folder_response_cb (ESoapResponse *response,
-                           GSimpleAsyncResult *simple)
+static gboolean
+e_ews_process_expand_dl_response (EEwsConnection *cnc,
+                                 ESoapResponse *response,
+                                 gboolean *out_includes_last_item,
+                                 GSList **out_mailboxes,
+                                 GError **error)
 {
        ESoapParameter *param;
        ESoapParameter *subparam;
-       GError *error = NULL;
+       GError *local_error = NULL;
 
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
+       *out_includes_last_item = TRUE;
+       *out_mailboxes = NULL;
+
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
        /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
        subparam = e_soap_parameter_get_first_child (param);
 
        while (subparam != NULL) {
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
-
-               subparam = e_soap_parameter_get_next_child (param);
-       }
-}
-
-void
-e_ews_connection_update_folder (EEwsConnection *cnc,
-                                gint pri,
-                                EEwsRequestCreationCallback create_cb,
-                                gpointer create_user_data,
-                                GCancellable *cancellable,
-                                GAsyncReadyCallback callback,
-                                gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       gboolean success;
-       GError *local_error = NULL;
-
-       g_return_if_fail (cnc != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "UpdateFolder",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
-
-       e_soap_message_start_element (msg, "FolderChanges", "messages", NULL);
-
-       success = create_cb (msg, create_user_data, &local_error);
-
-       e_soap_message_end_element (msg); /* FolderChanges */
-
-       e_ews_message_write_footer (msg);
+               const gchar *name = (const gchar *) subparam->name;
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_update_folder);
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "ExpandDLResponseMessage")) {
+                       gchar *prop;
+
+                       subparam = e_soap_parameter_get_first_child_by_name (subparam, "DLExpansion");
+                       prop = e_soap_parameter_get_property (subparam, "IncludesLastItemInRange");
+                       /*
+                        * Set the includes_last_item to TRUE as default.
+                        * It can avoid an infinite loop in caller, when, for some reason,
+                        * we don't receive the last_tag property from the server.
+                        */
+                       *out_includes_last_item = g_strcmp0 (prop, "false") != 0;
+                       g_free (prop);
+
+                       for (subparam = e_soap_parameter_get_first_child_by_name (subparam, "Mailbox");
+                               subparam != NULL;
+                               subparam = e_soap_parameter_get_next_child_by_name (subparam, "Mailbox")) {
+                               EwsMailbox *mb;
+
+                               mb = e_ews_item_mailbox_from_soap_param (subparam);
+                               if (mb)
+                                       *out_mailboxes = g_slist_prepend (*out_mailboxes, mb);
+                       }
+               }
 
-       if (success) {
-               e_ews_connection_queue_request (
-                       cnc, msg, update_folder_response_cb,
-                       pri, cancellable, simple);
-       } else {
-               if (local_error)
-                       g_simple_async_result_take_error (simple, local_error);
-               g_simple_async_result_complete_in_idle (simple);
-               g_clear_object (&msg);
+               subparam = e_soap_parameter_get_next_child (subparam);
        }
 
-       g_object_unref (simple);
-}
-
-gboolean
-e_ews_connection_update_folder_finish (EEwsConnection *cnc,
-                                       GAsyncResult *result,
-                                       GError **error)
-{
-       GSimpleAsyncResult *simple;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_update_folder),
-               FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
-
        return TRUE;
 }
 
 gboolean
-e_ews_connection_update_folder_sync (EEwsConnection *cnc,
-                                     gint pri,
-                                     EEwsRequestCreationCallback create_cb,
-                                     gpointer create_user_data,
-                                     GCancellable *cancellable,
-                                     GError **error)
-{
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-
-       closure = e_async_closure_new ();
-
-       e_ews_connection_update_folder (
-               cnc, pri, create_cb, create_user_data, cancellable,
-               e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_connection_update_folder_finish (cnc, result, error);
-
-       e_async_closure_free (closure);
-
-       return success;
-}
-
-static void
-move_folder_response_cb (ESoapResponse *response,
-                         GSimpleAsyncResult *simple)
+e_ews_connection_expand_dl_sync (EEwsConnection *cnc,
+                                 gint pri,
+                                 const EwsMailbox *mb,
+                                 gboolean *out_includes_last_item,
+                                 GSList **out_mailboxes,
+                                 GCancellable *cancellable,
+                                 GError **error)
 {
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       gboolean includes_last_item = TRUE;
+       GSList *mailboxes = NULL;
+       gboolean success;
 
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
+       g_return_val_if_fail (cnc != NULL, FALSE);
 
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "ExpandDL",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
+       if (!request)
+               return FALSE;
 
-       subparam = e_soap_parameter_get_first_child (param);
+       e_soap_request_start_element (request, "Mailbox", "messages", NULL);
 
-       while (subparam != NULL) {
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
+       if (mb->item_id) {
+               e_soap_request_start_element (request, "ItemId", NULL, NULL);
 
-               subparam = e_soap_parameter_get_next_child (subparam);
-       }
-}
+               e_soap_request_add_attribute (request, "Id", mb->item_id->id, NULL, NULL);
+               e_soap_request_add_attribute (request, "ChangeKey", mb->item_id->change_key, NULL, NULL);
 
-void
-e_ews_connection_move_folder (EEwsConnection *cnc,
-                              gint pri,
-                              const gchar *to_folder,
-                              const gchar *folder,
-                              GCancellable *cancellable,
-                              GAsyncReadyCallback callback,
-                              gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+               e_soap_request_end_element (request); /* Mailbox */
 
-       g_return_if_fail (cnc != NULL);
+       } else if (mb->email)
+               e_ews_request_write_string_parameter (request, "EmailAddress", NULL, mb->email);
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "MoveFolder",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
+       e_soap_request_end_element (request); /* Mailbox */
 
-       e_soap_message_start_element (msg, "ToFolderId", "messages", NULL);
-       if (to_folder)
-               e_ews_message_write_string_parameter_with_attribute (
-                       msg, "FolderId", NULL,
-                       NULL, "Id", to_folder);
-       else
-               e_ews_message_write_string_parameter_with_attribute (
-                       msg, "DistinguishedFolderId", NULL,
-                       NULL, "Id", "msgfolderroot");
+       e_ews_request_write_footer (request);
 
-       e_soap_message_end_element (msg);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       e_soap_message_start_element (msg, "FolderIds", "messages", NULL);
-       e_ews_message_write_string_parameter_with_attribute (
-               msg, "FolderId", NULL,
-               NULL, "Id", folder);
-       e_soap_message_end_element (msg);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       e_ews_message_write_footer (msg);
+       success = e_ews_process_expand_dl_response (cnc, response, &includes_last_item, &mailboxes, error);
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_move_folder);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       if (success && out_includes_last_item)
+               *out_includes_last_item = includes_last_item;
 
-       e_ews_connection_queue_request (
-               cnc, msg, move_folder_response_cb,
-               pri, cancellable, simple);
+       if (success && out_mailboxes)
+               *out_mailboxes = g_slist_reverse (mailboxes);
+       else
+               g_slist_free_full (mailboxes, (GDestroyNotify) e_ews_mailbox_free);
 
-       g_object_unref (simple);
+       return success;
 }
 
 gboolean
-e_ews_connection_move_folder_finish (EEwsConnection *cnc,
-                                     GAsyncResult *result,
+e_ews_connection_update_folder_sync (EEwsConnection *cnc,
+                                     gint pri,
+                                     EEwsRequestCreationCallback create_cb,
+                                     gpointer create_user_data,
+                                     GCancellable *cancellable,
                                      GError **error)
 {
-       GSimpleAsyncResult *simple;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_move_folder),
-               FALSE);
+       g_return_val_if_fail (create_cb != NULL, FALSE);
+
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "UpdateFolder",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
+
+       if (!request)
+               return FALSE;
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
+       e_soap_request_start_element (request, "FolderChanges", "messages", NULL);
 
-       if (g_simple_async_result_propagate_error (simple, error))
+       if (!create_cb (request, create_user_data, error)) {
+               g_clear_object (&request);
                return FALSE;
+       }
 
-       return TRUE;
+       e_soap_request_end_element (request); /* FolderChanges */
+
+       e_ews_request_write_footer (request);
+
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
+
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
+
+       success = e_ews_process_generic_response (cnc, response, error);
+
+       g_clear_object (&request);
+       g_clear_object (&response);
+
+       return success;
 }
 
 gboolean
@@ -6944,110 +5203,107 @@ e_ews_connection_move_folder_sync (EEwsConnection *cnc,
                                    GCancellable *cancellable,
                                    GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       closure = e_async_closure_new ();
-
-       e_ews_connection_move_folder (
-               cnc, pri, to_folder, folder, cancellable,
-               e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_connection_move_folder_finish (cnc, result, error);
-
-       e_async_closure_free (closure);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "MoveFolder",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       return success;
-}
+       if (!request)
+               return FALSE;
 
-void
-e_ews_connection_get_folder (EEwsConnection *cnc,
-                             gint pri,
-                             const gchar *folder_shape,
-                             const EEwsAdditionalProps *add_props,
-                             GSList *folder_ids,
-                             GCancellable *cancellable,
-                             GAsyncReadyCallback callback,
-                             gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       e_soap_request_start_element (request, "ToFolderId", "messages", NULL);
+       if (to_folder)
+               e_ews_request_write_string_parameter_with_attribute (request, "FolderId", NULL, NULL, "Id", 
to_folder);
+       else
+               e_ews_request_write_string_parameter_with_attribute (request, "DistinguishedFolderId", NULL, 
NULL, "Id", "msgfolderroot");
 
-       g_return_if_fail (cnc != NULL);
+       e_soap_request_end_element (request);
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "GetFolder",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       TRUE,
-                       TRUE);
+       e_soap_request_start_element (request, "FolderIds", "messages", NULL);
+       e_ews_request_write_string_parameter_with_attribute (request, "FolderId", NULL, NULL, "Id", folder);
+       e_soap_request_end_element (request);
 
-       e_soap_message_start_element (msg, "FolderShape", "messages", NULL);
-       e_ews_message_write_string_parameter (msg, "BaseShape", NULL, folder_shape);
+       e_ews_request_write_footer (request);
 
-       ews_append_additional_props_to_msg (msg, add_props);
-       e_soap_message_end_element (msg);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       if (folder_ids) {
-               e_soap_message_start_element (msg, "FolderIds", "messages", NULL);
-               ews_append_folder_ids_to_msg (msg, cnc->priv->email, folder_ids);
-               e_soap_message_end_element (msg);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
        }
 
-       e_ews_message_write_footer (msg);
+       success = e_ews_process_generic_response (cnc, response, error);
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_get_folder);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       async_data->cnc = cnc;
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
-
-       e_ews_connection_queue_request (
-               cnc, msg, get_folder_response_cb,
-               pri, cancellable, simple);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       g_object_unref (simple);
+       return success;
 }
 
-gboolean
-e_ews_connection_get_folder_finish (EEwsConnection *cnc,
-                                    GAsyncResult *result,
-                                    GSList **folders,
-                                    GError **error)
+static gboolean
+e_ews_process_get_folder_response (EEwsConnection *cnc,
+                                  ESoapResponse *response,
+                                  GSList **out_folders, /* EEwsFolder * */
+                                  GError **error)
 {
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       ESoapParameter *param;
+       ESoapParameter *subparam;
+       GError *local_error = NULL;
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_get_folder),
-               FALSE);
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       if (g_simple_async_result_propagate_error (simple, error))
+       if (local_error != NULL) {
+               g_propagate_error (error, local_error);
                return FALSE;
+       }
 
-       if (folders != NULL)
-               *folders = async_data->items;
-       else
-               g_slist_free_full (async_data->items, g_object_unref);
+       subparam = e_soap_parameter_get_first_child (param);
+
+       while (subparam != NULL) {
+               const gchar *name = (const gchar *) subparam->name;
+
+               if (!ews_get_response_status (subparam, &local_error)) {
+                       if (g_strcmp0 (name, "GetFolderResponseMessage") == 0) {
+                               if (out_folders)
+                                       *out_folders = g_slist_prepend (*out_folders, 
e_ews_folder_new_from_error (local_error));
+                               g_clear_error (&local_error);
+                       } else {
+                               g_propagate_error (error, local_error);
+                               return FALSE;
+                       }
+               } else if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "GetFolderResponseMessage") && 
out_folders) {
+                       ESoapParameter *node;
+                       EEwsFolder *folder;
+
+                       for (node = e_soap_parameter_get_first_child_by_name (subparam, "Folders");
+                            node;
+                            node = e_soap_parameter_get_next_child_by_name (subparam, "Folders")) {
+                               folder = e_ews_folder_new_from_soap_parameter (node);
+                               if (!folder)
+                                       continue;
+                               *out_folders = g_slist_prepend (*out_folders, folder);
+                       }
+               }
+
+               subparam = e_soap_parameter_get_next_child (subparam);
+       }
 
        return TRUE;
 }
@@ -7058,166 +5314,144 @@ e_ews_connection_get_folder_sync (EEwsConnection *cnc,
                                   const gchar *folder_shape,
                                   const EEwsAdditionalProps *add_props,
                                   GSList *folder_ids,
-                                  GSList **folders,
+                                  GSList **out_folders,
                                   GCancellable *cancellable,
                                   GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       closure = e_async_closure_new ();
-
-       e_ews_connection_get_folder (
-               cnc, pri, folder_shape, add_props,
-               folder_ids, cancellable,
-               e_async_closure_callback, closure);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetFolder",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               TRUE,
+               error);
 
-       result = e_async_closure_wait (closure);
+       if (!request)
+               return FALSE;
 
-       success = e_ews_connection_get_folder_finish (
-               cnc, result, folders, error);
+       e_soap_request_start_element (request, "FolderShape", "messages", NULL);
+       e_ews_request_write_string_parameter (request, "BaseShape", NULL, folder_shape);
 
-       e_async_closure_free (closure);
+       ews_append_additional_props_to_msg (request, add_props);
+       e_soap_request_end_element (request);
 
-       return success;
-}
+       if (folder_ids) {
+               e_soap_request_start_element (request, "FolderIds", "messages", NULL);
+               ews_append_folder_ids_to_msg (request, cnc->priv->email, folder_ids);
+               e_soap_request_end_element (request);
+       }
 
-void
-e_ews_connection_create_folder (EEwsConnection *cnc,
-                                gint pri,
-                                const gchar *parent_folder_id,
-                                gboolean is_distinguished_id,
-                                const gchar *folder_name,
-                                EEwsFolderType folder_type,
-                                GCancellable *cancellable,
-                                GAsyncReadyCallback callback,
-                                gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       const gchar *folder_element;
-       const gchar *folder_class;
+       e_ews_request_write_footer (request);
 
-       g_return_if_fail (cnc != NULL);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "CreateFolder",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       e_soap_message_start_element (msg, "ParentFolderId", "messages", NULL);
+       if (out_folders)
+               *out_folders = NULL;
 
-       /* If NULL passed for parent_folder_id, use "msgfolderroot" */
-       if (is_distinguished_id || !parent_folder_id) {
-               e_soap_message_start_element (msg, "DistinguishedFolderId", NULL, NULL);
-               e_soap_message_add_attribute (
-                               msg, "Id", parent_folder_id ? parent_folder_id : "msgfolderroot", NULL, NULL);
-               if (is_distinguished_id && cnc->priv->email) {
-                       e_soap_message_start_element (msg, "Mailbox", NULL, NULL);
-                       e_ews_message_write_string_parameter(
-                                       msg, "EmailAddress", NULL, cnc->priv->email);
-                       e_soap_message_end_element (msg);
-               }
-               e_soap_message_end_element (msg);
-       } else {
-               e_ews_message_write_string_parameter_with_attribute (msg, "FolderId", NULL, NULL, "Id", 
parent_folder_id);
-       }
+       success = e_ews_process_get_folder_response (cnc, response, out_folders, error);
 
-       e_soap_message_end_element (msg);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       switch (folder_type) {
-               default:
-                       g_warn_if_reached ();
-                       /* fall through */
-               case E_EWS_FOLDER_TYPE_MAILBOX:
-                       folder_element = "Folder";
-                       folder_class = "IPF.Note";
-                       break;
-               case E_EWS_FOLDER_TYPE_CALENDAR:
-                       folder_element = "CalendarFolder";
-                       folder_class = "IPF.Appointment";
-                       break;
-               case E_EWS_FOLDER_TYPE_CONTACTS:
-                       folder_element = "ContactsFolder";
-                       folder_class = "IPF.Contact";
-                       break;
-               case E_EWS_FOLDER_TYPE_SEARCH:
-                       folder_element = "SearchFolder";
-                       folder_class = "IPF.Note";
-                       break;
-               case E_EWS_FOLDER_TYPE_TASKS:
-                       folder_element = "TasksFolder";
-                       folder_class = "IPF.Task";
-                       break;
-               case E_EWS_FOLDER_TYPE_MEMOS:
-                       folder_element = "Folder";
-                       folder_class = "IPF.StickyNote";
-                       break;
+       if (success && out_folders) {
+               *out_folders = g_slist_reverse (*out_folders);
+       } else if (out_folders) {
+               g_slist_free_full (*out_folders, g_object_unref);
+               *out_folders = NULL;
        }
 
-       e_soap_message_start_element (msg, "Folders", "messages", NULL);
-       e_soap_message_start_element (msg, folder_element, NULL, NULL);
-       e_ews_message_write_string_parameter (msg, "FolderClass", NULL, folder_class);
-       e_ews_message_write_string_parameter (msg, "DisplayName", NULL, folder_name);
+       return success;
+}
+
+static gboolean
+e_ews_process_create_folder_response (EEwsConnection *cnc,
+                                     ESoapResponse *response,
+                                     EEwsFolderType folder_type,
+                                     GSList **out_folder_ids, /* EwsFolderId * */
+                                     GError **error)
+{
+       ESoapParameter *param;
+       ESoapParameter *subparam;
+       GError *local_error = NULL;
 
-       e_soap_message_end_element (msg);
-       e_soap_message_end_element (msg);
+       *out_folder_ids = NULL;
 
-       e_ews_message_write_footer (msg);
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_create_folder);
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       async_data->folder_type = folder_type;
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
+       }
 
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       subparam = e_soap_parameter_get_first_child (param);
 
-       e_ews_connection_queue_request (
-               cnc, msg, create_folder_response_cb,
-               pri, cancellable, simple);
+       while (subparam != NULL) {
+               const gchar *name = (const gchar *) subparam->name;
 
-       g_object_unref (simple);
-}
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
 
-gboolean
-e_ews_connection_create_folder_finish (EEwsConnection *cnc,
-                                       GAsyncResult *result,
-                                       EwsFolderId **fid,
-                                       GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "CreateFolderResponseMessage")) {
+                       ESoapParameter *param, *node;
+                       EwsFolderId *fid = NULL;
+                       const gchar *folder_element;
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_create_folder),
-               FALSE);
+                       switch (folder_type) {
+                               case E_EWS_FOLDER_TYPE_MAILBOX:
+                               case E_EWS_FOLDER_TYPE_MEMOS:
+                                       folder_element = "Folder";
+                                       break;
+                               case E_EWS_FOLDER_TYPE_CALENDAR:
+                                       folder_element = "CalendarFolder";
+                                       break;
+                               case E_EWS_FOLDER_TYPE_CONTACTS:
+                                       folder_element = "ContactsFolder";
+                                       break;
+                               case E_EWS_FOLDER_TYPE_SEARCH:
+                                       folder_element = "SearchFolder";
+                                       break;
+                               case E_EWS_FOLDER_TYPE_TASKS:
+                                       folder_element = "TasksFolder";
+                                       break;
+                               default:
+                                       g_warn_if_reached ();
+                                       folder_element = "Folder";
+                                       break;
+                       }
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+                       node = e_soap_parameter_get_first_child_by_name (subparam, "Folders");
+                       node = e_soap_parameter_get_first_child_by_name (node, folder_element);
+                       param = e_soap_parameter_get_first_child_by_name (node, "FolderId");
 
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+                       fid = g_new0 (EwsFolderId, 1);
+                       fid->id = e_soap_parameter_get_property (param, "Id");
+                       fid->change_key = e_soap_parameter_get_property (param, "ChangeKey");
+                       *out_folder_ids = g_slist_prepend (*out_folder_ids, fid);
+               }
 
-       *fid = (EwsFolderId *) async_data->items_created->data;
-       g_slist_free (async_data->items_created);
+               subparam = e_soap_parameter_get_next_child (subparam);
+       }
 
-       return TRUE;
+       return *out_folder_ids != NULL;
 }
 
 gboolean
@@ -7227,143 +5461,117 @@ e_ews_connection_create_folder_sync (EEwsConnection *cnc,
                                      gboolean is_distinguished_id,
                                      const gchar *folder_name,
                                      EEwsFolderType folder_type,
-                                     EwsFolderId **folder_id,
+                                     EwsFolderId **out_folder_id,
                                      GCancellable *cancellable,
                                      GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       GSList *folder_ids = NULL;
+       const gchar *folder_element;
+       const gchar *folder_class;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       closure = e_async_closure_new ();
-
-       e_ews_connection_create_folder (
-               cnc, pri, parent_folder_id,
-               is_distinguished_id, folder_name,
-               folder_type, cancellable,
-               e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "CreateFolder",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       success = e_ews_connection_create_folder_finish (
-               cnc, result, folder_id, error);
+       if (!request)
+               return FALSE;
 
-       e_async_closure_free (closure);
+       e_soap_request_start_element (request, "ParentFolderId", "messages", NULL);
 
-       return success;
-}
+       /* If NULL passed for parent_folder_id, use "msgfolderroot" */
+       if (is_distinguished_id || !parent_folder_id) {
+               e_soap_request_start_element (request, "DistinguishedFolderId", NULL, NULL);
+               e_soap_request_add_attribute (request, "Id", parent_folder_id ? parent_folder_id : 
"msgfolderroot", NULL, NULL);
+               if (is_distinguished_id && cnc->priv->email) {
+                       e_soap_request_start_element (request, "Mailbox", NULL, NULL);
+                       e_ews_request_write_string_parameter (request, "EmailAddress", NULL, 
cnc->priv->email);
+                       e_soap_request_end_element (request);
+               }
+               e_soap_request_end_element (request);
+       } else {
+               e_ews_request_write_string_parameter_with_attribute (request, "FolderId", NULL, NULL, "Id", 
parent_folder_id);
+       }
 
-void
-e_ews_connection_move_items (EEwsConnection *cnc,
-                             gint pri,
-                             const gchar *folder_id,
-                             gboolean docopy,
-                             const GSList *ids,
-                             GCancellable *cancellable,
-                             GAsyncReadyCallback callback,
-                             gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       const GSList *iter;
+       e_soap_request_end_element (request);
 
-       g_return_if_fail (cnc != NULL);
+       switch (folder_type) {
+               default:
+                       g_warn_if_reached ();
+                       /* fall through */
+               case E_EWS_FOLDER_TYPE_MAILBOX:
+                       folder_element = "Folder";
+                       folder_class = "IPF.Note";
+                       break;
+               case E_EWS_FOLDER_TYPE_CALENDAR:
+                       folder_element = "CalendarFolder";
+                       folder_class = "IPF.Appointment";
+                       break;
+               case E_EWS_FOLDER_TYPE_CONTACTS:
+                       folder_element = "ContactsFolder";
+                       folder_class = "IPF.Contact";
+                       break;
+               case E_EWS_FOLDER_TYPE_SEARCH:
+                       folder_element = "SearchFolder";
+                       folder_class = "IPF.Note";
+                       break;
+               case E_EWS_FOLDER_TYPE_TASKS:
+                       folder_element = "TasksFolder";
+                       folder_class = "IPF.Task";
+                       break;
+               case E_EWS_FOLDER_TYPE_MEMOS:
+                       folder_element = "Folder";
+                       folder_class = "IPF.StickyNote";
+                       break;
+       }
 
-       if (docopy)
-               msg = e_ews_message_new_with_header (
-                               cnc->priv->settings,
-                               cnc->priv->uri,
-                               cnc->priv->impersonate_user,
-                               "CopyItem",
-                               NULL,
-                               NULL,
-                               cnc->priv->version,
-                               E_EWS_EXCHANGE_2007_SP1,
-                               FALSE,
-                               TRUE);
-       else
-               msg = e_ews_message_new_with_header (
-                               cnc->priv->settings,
-                               cnc->priv->uri,
-                               cnc->priv->impersonate_user,
-                               "MoveItem",
-                               NULL,
-                               NULL,
-                               cnc->priv->version,
-                               E_EWS_EXCHANGE_2007_SP1,
-                               FALSE,
-                               TRUE);
-
-       e_soap_message_start_element (msg, "ToFolderId", "messages", NULL);
-       e_soap_message_start_element (msg, "FolderId", NULL, NULL);
-       e_soap_message_add_attribute (msg, "Id", folder_id, NULL, NULL);
-       e_soap_message_end_element (msg); /* FolderId */
-       e_soap_message_end_element (msg); /* ToFolderId */
-
-       e_soap_message_start_element (msg, "ItemIds", "messages", NULL);
-       for (iter = ids; iter != NULL; iter = g_slist_next (iter))
-               e_ews_message_write_string_parameter_with_attribute (msg, "ItemId", NULL, NULL, "Id", 
iter->data);
-       e_soap_message_end_element (msg); /* ItemIds */
-
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_move_items);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
-
-       e_ews_connection_queue_request (
-               cnc, msg, get_items_response_cb,
-               pri, cancellable, simple);
-
-       g_object_unref (simple);
-}
+       e_soap_request_start_element (request, "Folders", "messages", NULL);
+       e_soap_request_start_element (request, folder_element, NULL, NULL);
+       e_ews_request_write_string_parameter (request, "FolderClass", NULL, folder_class);
+       e_ews_request_write_string_parameter (request, "DisplayName", NULL, folder_name);
 
-gboolean
-e_ews_connection_move_items_finish (EEwsConnection *cnc,
-                                    GAsyncResult *result,
-                                    GSList **items,
-                                    GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       e_soap_request_end_element (request);
+       e_soap_request_end_element (request);
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_move_items),
-               FALSE);
+       e_ews_request_write_footer (request);
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       if (g_simple_async_result_propagate_error (simple, error))
+       if (!response) {
+               g_clear_object (&request);
                return FALSE;
+       }
 
-       /* if there is only one item, then check whether it's an error */
-       if (async_data->items && !async_data->items->next) {
-               EEwsItem *item = async_data->items->data;
+       success = e_ews_process_create_folder_response (cnc, response, folder_type, &folder_ids, error);
 
-               if (item && e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_ERROR) {
-                       if (error)
-                               *error = g_error_copy (e_ews_item_get_error (item));
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-                       g_slist_free_full (async_data->items, g_object_unref);
-                       async_data->items = NULL;
+       if (success) {
+               folder_ids = g_slist_reverse (folder_ids);
+               g_warn_if_fail (g_slist_length (folder_ids) <= 1);
 
-                       return FALSE;
-               }
+               if (out_folder_id)
+                       *out_folder_id = folder_ids ? folder_ids->data : NULL;
+
+               if (folder_ids && out_folder_id)
+                       folder_ids->data = NULL;
        }
 
-       *items = async_data->items;
+       g_slist_free_full (folder_ids, (GDestroyNotify) e_ews_folder_id_free);
 
-       return TRUE;
+       return success;
 }
 
 gboolean
@@ -7372,28 +5580,74 @@ e_ews_connection_move_items_sync (EEwsConnection *cnc,
                                   const gchar *folder_id,
                                   gboolean docopy,
                                   const GSList *ids,
-                                  GSList **items,
+                                  GSList **out_items,
                                   GCancellable *cancellable,
                                   GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       const GSList *link;
+       GSList *items = NULL;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       closure = e_async_closure_new ();
+       if (docopy)
+               request = e_ews_request_new_with_header (
+                       cnc->priv->uri,
+                       cnc->priv->impersonate_user,
+                       "CopyItem",
+                       NULL,
+                       NULL,
+                       cnc->priv->version,
+                       E_EWS_EXCHANGE_2007_SP1,
+                       FALSE,
+                       error);
+       else
+               request = e_ews_request_new_with_header (
+                       cnc->priv->uri,
+                       cnc->priv->impersonate_user,
+                       "MoveItem",
+                       NULL,
+                       NULL,
+                       cnc->priv->version,
+                       E_EWS_EXCHANGE_2007_SP1,
+                       FALSE,
+                       error);
+
+       if (!request)
+               return FALSE;
+
+       e_soap_request_start_element (request, "ToFolderId", "messages", NULL);
+       e_soap_request_start_element (request, "FolderId", NULL, NULL);
+       e_soap_request_add_attribute (request, "Id", folder_id, NULL, NULL);
+       e_soap_request_end_element (request); /* FolderId */
+       e_soap_request_end_element (request); /* ToFolderId */
+
+       e_soap_request_start_element (request, "ItemIds", "messages", NULL);
+       for (link = ids; link; link = g_slist_next (link)) {
+               e_ews_request_write_string_parameter_with_attribute (request, "ItemId", NULL, NULL, "Id", 
link->data);
+       }
+       e_soap_request_end_element (request); /* ItemIds */
+
+       e_ews_request_write_footer (request);
+
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       e_ews_connection_move_items (
-               cnc, pri, folder_id, docopy, ids, cancellable,
-               e_async_closure_callback, closure);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       result = e_async_closure_wait (closure);
+       success = e_ews_process_get_items_response (cnc, response, &items, error);
 
-       success = e_ews_connection_move_items_finish (
-               cnc, result, items, error);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       e_async_closure_free (closure);
+       if (success && out_items)
+               *out_items = items;
+       else
+               g_slist_free_full (items, g_object_unref);
 
        return success;
 }
@@ -7467,147 +5721,6 @@ e_ews_connection_move_items_in_chunks_sync (EEwsConnection *cnc,
        return success;
 }
 
-static void
-delete_folder_response_cb (ESoapResponse *response,
-                           GSimpleAsyncResult *simple)
-{
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
-
-       subparam = e_soap_parameter_get_first_child (param);
-
-       while (subparam != NULL) {
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
-
-               subparam = e_soap_parameter_get_next_child (subparam);
-       }
-}
-
-/**
- * e_ews_connection_delete_folder:
- * @cnc:
- * @pri:
- * @folder_id: folder to be deleted
- * @is_distinguished_id:
- * @delete_type: "HardDelete", "SoftDelete", "MoveToDeletedItems"
- * @cancellable:
- * @callback:
- * @user_data:
- **/
-void
-e_ews_connection_delete_folder (EEwsConnection *cnc,
-                                gint pri,
-                                const gchar *folder_id,
-                                gboolean is_distinguished_id,
-                                const gchar *delete_type,
-                                GCancellable *cancellable,
-                                GAsyncReadyCallback callback,
-                                gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_if_fail (cnc != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "DeleteFolder",
-                       "DeleteType",
-                       delete_type,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
-
-       e_soap_message_start_element (msg, "FolderIds", "messages", NULL);
-
-       e_soap_message_start_element (
-                       msg,
-                       is_distinguished_id ? "DistinguishedFolderId" : "FolderId",
-                       NULL,
-                       NULL);
-       e_soap_message_add_attribute (msg, "Id", folder_id, NULL, NULL);
-
-       /* This element is required for delegate access */
-       if (is_distinguished_id && cnc->priv->email) {
-               e_soap_message_start_element (msg, "Mailbox", NULL, NULL);
-               e_ews_message_write_string_parameter(
-                               msg, "EmailAddress", NULL, cnc->priv->email);
-               e_soap_message_end_element (msg);
-       }
-
-       e_soap_message_end_element (msg); /* </DistinguishedFolderId> || </FolderId> */
-
-       e_soap_message_end_element (msg); /* </FolderIds> */
-
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_delete_folder);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
-
-       e_ews_connection_queue_request (
-               cnc, msg, delete_folder_response_cb,
-               pri, cancellable, simple);
-
-       g_object_unref (simple);
-}
-
-gboolean
-e_ews_connection_delete_folder_finish (EEwsConnection *cnc,
-                                       GAsyncResult *result,
-                                       GError **error)
-{
-       GSimpleAsyncResult *simple;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_delete_folder),
-               FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
-
-       return TRUE;
-}
-
-/**
- * e_ews_connection_delete_folder_sync:
- * @cnc:
- * @pri:
- * @folder_id: folder to be deleted
- * @is_distinguished_id:
- * @delete_type: "HardDelete", "SoftDelete", "MoveToDeletedItems"
- * @cancellable:
- * @error:
- **/
 gboolean
 e_ews_connection_delete_folder_sync (EEwsConnection *cnc,
                                      gint pri,
@@ -7617,151 +5730,60 @@ e_ews_connection_delete_folder_sync (EEwsConnection *cnc,
                                      GCancellable *cancellable,
                                      GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       closure = e_async_closure_new ();
-
-       e_ews_connection_delete_folder (
-               cnc, pri, folder_id,
-               is_distinguished_id,
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "DeleteFolder",
+               "DeleteType",
                delete_type,
-               cancellable,
-               e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_connection_delete_folder_finish (cnc, result, error);
-
-       e_async_closure_free (closure);
-
-       return success;
-}
-
-static void
-empty_folder_response_cb (ESoapResponse *response,
-                         GSimpleAsyncResult *simple)
-{
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
-
-       subparam = e_soap_parameter_get_first_child (param);
-
-       while (subparam != NULL) {
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
-
-               subparam = e_soap_parameter_get_next_child (subparam);
-       }
-}
-
-void
-e_ews_connection_empty_folder (EEwsConnection *cnc,
-                              gint pri,
-                              const gchar *folder_id,
-                              gboolean is_distinguished_id,
-                              const gchar *delete_type,
-                              gboolean delete_subfolders,
-                              GCancellable *cancellable,
-                              GAsyncReadyCallback callback,
-                              gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_if_fail (cnc != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "EmptyFolder",
-                       "DeleteType",
-                       delete_type,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2010,
-                       FALSE,
-                       TRUE);
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       e_soap_message_add_attribute (msg, "DeleteSubFolders", delete_subfolders ? "true" : "false", NULL, 
NULL);
+       if (!request)
+               return FALSE;
 
-       e_soap_message_start_element (msg, "FolderIds", "messages", NULL);
+       e_soap_request_start_element (request, "FolderIds", "messages", NULL);
 
-       e_soap_message_start_element (
-                       msg,
+       e_soap_request_start_element (request,
                        is_distinguished_id ? "DistinguishedFolderId" : "FolderId",
                        NULL,
                        NULL);
-       e_soap_message_add_attribute (msg, "Id", folder_id, NULL, NULL);
+       e_soap_request_add_attribute (request, "Id", folder_id, NULL, NULL);
 
        /* This element is required for delegate access */
        if (is_distinguished_id && cnc->priv->email) {
-               e_soap_message_start_element (msg, "Mailbox", NULL, NULL);
-               e_ews_message_write_string_parameter(
-                               msg, "EmailAddress", NULL, cnc->priv->email);
-               e_soap_message_end_element (msg);
+               e_soap_request_start_element (request, "Mailbox", NULL, NULL);
+               e_ews_request_write_string_parameter (request, "EmailAddress", NULL, cnc->priv->email);
+               e_soap_request_end_element (request);
        }
 
-       e_soap_message_end_element (msg); /* </DistinguishedFolderId> || </FolderId> */
-
-       e_soap_message_end_element (msg); /* </FolderIds> */
-
-       e_ews_message_write_footer (msg);
+       e_soap_request_end_element (request); /* </DistinguishedFolderId> || </FolderId> */
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_empty_folder);
+       e_soap_request_end_element (request); /* </FolderIds> */
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       e_ews_request_write_footer (request);
 
-       e_ews_connection_queue_request (
-               cnc, msg, empty_folder_response_cb,
-               pri, cancellable, simple);
-
-       g_object_unref (simple);
-}
-
-gboolean
-e_ews_connection_empty_folder_finish (EEwsConnection *cnc,
-                                     GAsyncResult *result,
-                                     GError **error)
-{
-       GSimpleAsyncResult *simple;
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_empty_folder),
-               FALSE);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
+       success = e_ews_process_generic_response (cnc, response, error);
 
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       return TRUE;
+       return success;
 }
 
 gboolean
@@ -7770,101 +5792,129 @@ e_ews_connection_empty_folder_sync (EEwsConnection *cnc,
                                    const gchar *folder_id,
                                    gboolean is_distinguished_id,
                                    const gchar *delete_type,
-                                   gboolean delete_subfolder,
+                                   gboolean delete_subfolders,
                                    GCancellable *cancellable,
                                    GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       closure = e_async_closure_new ();
-
-       e_ews_connection_empty_folder (
-               cnc, pri, folder_id,
-               is_distinguished_id,
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "EmptyFolder",
+               "DeleteType",
                delete_type,
-               delete_subfolder,
-               cancellable,
-               e_async_closure_callback, closure);
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2010,
+               FALSE,
+               error);
 
-       result = e_async_closure_wait (closure);
+       if (!request)
+               return FALSE;
 
-       success = e_ews_connection_empty_folder_finish (cnc, result, error);
+       e_soap_request_add_attribute (request, "DeleteSubFolders", delete_subfolders ? "true" : "false", 
NULL, NULL);
 
-       e_async_closure_free (closure);
+       e_soap_request_start_element (request, "FolderIds", "messages", NULL);
 
-       return success;
-}
+       e_soap_request_start_element (request,
+                       is_distinguished_id ? "DistinguishedFolderId" : "FolderId",
+                       NULL,
+                       NULL);
+       e_soap_request_add_attribute (request, "Id", folder_id, NULL, NULL);
 
-static void
-ews_handle_create_attachments_param (ESoapParameter *param,
-                                     EwsAsyncData *async_data)
-{
-       /* http://msdn.microsoft.com/en-us/library/aa565877%28v=EXCHG.80%29.aspx */
-       ESoapParameter *subparam, *attspara, *last_relevant = NULL, *attparam;
+       /* This element is required for delegate access */
+       if (is_distinguished_id && cnc->priv->email) {
+               e_soap_request_start_element (request, "Mailbox", NULL, NULL);
+               e_ews_request_write_string_parameter (request, "EmailAddress", NULL, cnc->priv->email);
+               e_soap_request_end_element (request);
+       }
 
-       attspara = e_soap_parameter_get_first_child_by_name (param, "Attachments");
+       e_soap_request_end_element (request); /* </DistinguishedFolderId> || </FolderId> */
 
-       for (subparam = e_soap_parameter_get_first_child (attspara); subparam != NULL; subparam = 
e_soap_parameter_get_next_child (subparam)) {
-               if (!g_ascii_strcasecmp (e_soap_parameter_get_name (subparam), "FileAttachment")) {
-                       attparam = e_soap_parameter_get_first_child (subparam);
-                       last_relevant = attparam;
+       e_soap_request_end_element (request); /* </FolderIds> */
 
-                       async_data->items = g_slist_append (async_data->items, e_soap_parameter_get_property 
(attparam, "Id"));
-               }
-       }
+       e_ews_request_write_footer (request);
 
-       if (last_relevant != NULL) {
-               async_data->sync_state = e_soap_parameter_get_property (last_relevant, "RootItemChangeKey");
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
+
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
        }
+
+       success = e_ews_process_generic_response (cnc, response, error);
+
+       g_clear_object (&request);
+       g_clear_object (&response);
+
+       return success;
 }
 
-static void
-create_attachments_response_cb (ESoapResponse *response,
-                                GSimpleAsyncResult *simple)
+static gboolean
+e_ews_process_create_attachments_response (EEwsConnection *cnc,
+                                          ESoapResponse *response,
+                                          gchar **out_change_key,
+                                          GSList **out_attachments_ids,
+                                          GError **error)
 {
-       EwsAsyncData *async_data;
        ESoapParameter *param;
        ESoapParameter *subparam;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       GError *local_error = NULL;
 
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
        /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
-       subparam = e_soap_parameter_get_first_child (param);
+       subparam = e_soap_parameter_get_first_child (param);
+
+       while (subparam != NULL) {
+               const gchar *name = (const gchar *) subparam->name;
+
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
+
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "CreateAttachmentResponseMessage")) {
+                       /* http://msdn.microsoft.com/en-us/library/aa565877%28v=EXCHG.80%29.aspx */
+                       ESoapParameter *subparam, *attspara, *last_relevant = NULL, *attparam;
+
+                       attspara = e_soap_parameter_get_first_child_by_name (param, "Attachments");
+
+                       for (subparam = e_soap_parameter_get_first_child (attspara); subparam != NULL; 
subparam = e_soap_parameter_get_next_child (subparam)) {
+                               if (!g_ascii_strcasecmp (e_soap_parameter_get_name (subparam), 
"FileAttachment")) {
+                                       attparam = e_soap_parameter_get_first_child (subparam);
+                                       last_relevant = attparam;
 
-       while (subparam != NULL) {
-               const gchar *name = (const gchar *) subparam->name;
+                                       if (out_attachments_ids)
+                                               *out_attachments_ids = g_slist_prepend (*out_attachments_ids, 
e_soap_parameter_get_property (attparam, "Id"));
+                               }
+                       }
 
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
+                       if (last_relevant != NULL && out_change_key) {
+                               g_free (*out_change_key);
+                               *out_change_key = e_soap_parameter_get_property (last_relevant, 
"RootItemChangeKey");
+                       }
                }
 
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "CreateAttachmentResponseMessage"))
-                       ews_handle_create_attachments_param (subparam, async_data);
-
                subparam = e_soap_parameter_get_next_child (subparam);
        }
+
+       return TRUE;
 }
 
 static gboolean
-e_ews_connection_attach_file (ESoapMessage *msg,
+e_ews_connection_attach_file (ESoapRequest *request,
                               EEwsAttachmentInfo *info,
                              gboolean contact_photo,
                              GError **error)
@@ -7916,16 +5966,16 @@ e_ews_connection_attach_file (ESoapMessage *msg,
                        return FALSE;
        }
 
-       e_soap_message_start_element (msg, "FileAttachment", NULL, NULL);
+       e_soap_request_start_element (request, "FileAttachment", NULL, NULL);
 
        prefer_filename = e_ews_attachment_info_get_prefer_filename (info);
-       e_ews_message_write_string_parameter (msg, "Name", NULL, prefer_filename ? prefer_filename : 
filename);
+       e_ews_request_write_string_parameter (request, "Name", NULL, prefer_filename ? prefer_filename : 
filename);
        if (contact_photo)
-               e_ews_message_write_string_parameter (msg, "IsContactPhoto", NULL, "true");
-       e_soap_message_start_element (msg, "Content", NULL, NULL);
-       e_soap_message_write_base64 (msg, content, length);
-       e_soap_message_end_element (msg); /* "Content" */
-       e_soap_message_end_element (msg); /* "FileAttachment" */
+               e_ews_request_write_string_parameter (request, "IsContactPhoto", NULL, "true");
+       e_soap_request_start_element (request, "Content", NULL, NULL);
+       e_soap_request_write_base64 (request, content, length);
+       e_soap_request_end_element (request); /* "Content" */
+       e_soap_request_end_element (request); /* "FileAttachment" */
 
        g_free (filename);
        g_free (buffer);
@@ -7933,183 +5983,116 @@ e_ews_connection_attach_file (ESoapMessage *msg,
        return TRUE;
 }
 
-void
-e_ews_connection_create_attachments (EEwsConnection *cnc,
-                                     gint pri,
-                                     const EwsId *parent,
-                                     const GSList *files,
-                                    gboolean is_contact_photo,
-                                     GCancellable *cancellable,
-                                     GAsyncReadyCallback callback,
-                                     gpointer user_data)
+gboolean
+e_ews_connection_create_attachments_sync (EEwsConnection *cnc,
+                                         gint pri,
+                                         const EwsId *parent,
+                                         const GSList *files,
+                                         gboolean is_contact_photo,
+                                         gchar **out_change_key,
+                                         GSList **out_attachments_ids,
+                                         GCancellable *cancellable,
+                                         GError **error)
 {
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       const GSList *l;
-       GError *local_error = NULL;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       const GSList *link;
+       gboolean success;
 
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (parent != NULL);
+       g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (parent != NULL, FALSE);
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_create_attachments);
+       if (out_change_key)
+               *out_change_key = NULL;
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       if (out_attachments_ids)
+               *out_attachments_ids = NULL;
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "CreateAttachment",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "CreateAttachment",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
+
+       if (!request)
+               return FALSE;
 
-       e_soap_message_start_element (msg, "ParentItemId", "messages", NULL);
-       e_soap_message_add_attribute (msg, "Id", parent->id, NULL, NULL);
+       e_soap_request_start_element (request, "ParentItemId", "messages", NULL);
+       e_soap_request_add_attribute (request, "Id", parent->id, NULL, NULL);
        if (parent->change_key)
-               e_soap_message_add_attribute (msg, "ChangeKey", parent->change_key, NULL, NULL);
-       e_soap_message_end_element (msg);
+               e_soap_request_add_attribute (request, "ChangeKey", parent->change_key, NULL, NULL);
+       e_soap_request_end_element (request);
 
        /* start interation over all items to get the attachemnts */
-       e_soap_message_start_element (msg, "Attachments", "messages", NULL);
-
-       for (l = files; l != NULL; l = g_slist_next (l))
-               if (!e_ews_connection_attach_file (msg, l->data, is_contact_photo, &local_error)) {
-                       if (local_error != NULL)
-                               g_simple_async_result_take_error (simple, local_error);
-                       g_simple_async_result_complete_in_idle (simple);
-                       g_object_unref (simple);
+       e_soap_request_start_element (request, "Attachments", "messages", NULL);
 
-                       return;
+       for (link = files; link; link = g_slist_next (link)) {
+               if (!e_ews_connection_attach_file (request, link->data, is_contact_photo, error)) {
+                       g_clear_object (&request);
+                       return FALSE;
                }
+       }
 
-       e_soap_message_end_element (msg); /* "Attachments" */
-
-       e_ews_message_write_footer (msg);
-
-       e_ews_connection_queue_request (
-               cnc, msg, create_attachments_response_cb,
-               pri, cancellable, simple);
-
-       g_object_unref (simple);
-}
-
-gboolean
-e_ews_connection_create_attachments_finish (EEwsConnection *cnc,
-                                            gchar **change_key,
-                                           GSList **attachments_ids,
-                                            GAsyncResult *result,
-                                            GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       e_soap_request_end_element (request); /* "Attachments" */
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_create_attachments),
-               FALSE);
+       e_ews_request_write_footer (request);
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       if (g_simple_async_result_propagate_error (simple, error))
+       if (!response) {
+               g_clear_object (&request);
                return FALSE;
+       }
 
-       if (attachments_ids)
-               *attachments_ids = async_data->items;
-       else
-               g_slist_free_full (async_data->items, g_free);
-
-       if (change_key)
-               *change_key = async_data->sync_state;
-       else
-               g_free (async_data->sync_state);
-
-       return TRUE;
-}
-
-gboolean
-e_ews_connection_create_attachments_sync (EEwsConnection *cnc,
-                                          gint pri,
-                                          const EwsId *parent,
-                                          const GSList *files,
-                                         gboolean is_contact_photo,
-                                          gchar **change_key,
-                                         GSList **attachments_ids,
-                                          GCancellable *cancellable,
-                                          GError **error)
-{
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean ret;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (parent != NULL, FALSE);
-
-       closure = e_async_closure_new ();
-
-       e_ews_connection_create_attachments (
-               cnc, pri, parent, files, is_contact_photo, cancellable,
-               e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       ret = e_ews_connection_create_attachments_finish (
-               cnc, change_key, attachments_ids, result, error);
-
-       e_async_closure_free (closure);
-
-       return ret;
-}
+       success = e_ews_process_create_attachments_response (cnc, response, out_change_key, 
out_attachments_ids, error);
 
-/* Delete attachemnts */
-static void
-ews_handle_root_item_id_param (ESoapParameter *subparam,
-                               EwsAsyncData *async_data)
-{
-       /* http://msdn.microsoft.com/en-us/library/aa580782%28v=EXCHG.80%29.aspx */
-       ESoapParameter *attspara;
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       attspara = e_soap_parameter_get_first_child_by_name (
-               subparam, "RootItemId");
+       if (success) {
+               if (out_attachments_ids)
+                       *out_attachments_ids = g_slist_reverse (*out_attachments_ids);
+       } else {
+               if (out_change_key)
+                       g_clear_pointer (out_change_key, g_free);
 
-       if (attspara == NULL)
-               return;
+               if (out_attachments_ids) {
+                       g_slist_free_full (*out_attachments_ids, g_free);
+                       *out_attachments_ids = NULL;
+               }
+       }
 
-       async_data->sync_state = e_soap_parameter_get_property (attspara, "RootItemChangeKey");
+       return success;
 }
 
-static void
-delete_attachments_response_cb (ESoapResponse *response,
-                                GSimpleAsyncResult *simple)
+static gboolean
+e_ews_process_delete_attachments_response (EEwsConnection *cnc,
+                                          ESoapResponse *response,
+                                          gchar **out_new_change_key,
+                                          GError **error)
 {
-       EwsAsyncData *async_data;
        ESoapParameter *param;
        ESoapParameter *subparam;
-       GError *error = NULL;
+       GError *local_error = NULL;
 
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       if (out_new_change_key)
+               *out_new_change_key = NULL;
 
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
        /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
        subparam = e_soap_parameter_get_first_child (param);
@@ -8117,97 +6100,22 @@ delete_attachments_response_cb (ESoapResponse *response,
        while (subparam != NULL) {
                const gchar *name = (const gchar *) subparam->name;
 
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
-
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "DeleteAttachmentResponseMessage"))
-                       ews_handle_root_item_id_param (subparam, async_data);
-
-               subparam = e_soap_parameter_get_next_child (subparam);
-       }
-}
-
-void
-e_ews_connection_delete_attachments (EEwsConnection *cnc,
-                                     gint pri,
-                                     const GSList *attachments_ids,
-                                     GCancellable *cancellable,
-                                     GAsyncReadyCallback callback,
-                                     gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       const GSList *l;
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
 
-       g_return_if_fail (cnc != NULL);
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "DeleteAttachmentResponseMessage")) {
+                       /* http://msdn.microsoft.com/en-us/library/aa580782%28v=EXCHG.80%29.aspx */
+                       ESoapParameter *attspara;
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "DeleteAttachment",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
+                       attspara = e_soap_parameter_get_first_child_by_name (subparam, "RootItemId");
 
-       /* start interation over all items to get the attachemnts */
-       e_soap_message_start_element (msg, "AttachmentIds", "messages", NULL);
+                       if (attspara != NULL && out_new_change_key)
+                               *out_new_change_key = e_soap_parameter_get_property (attspara, 
"RootItemChangeKey");
+               }
 
-       for (l = attachments_ids; l != NULL; l = l->next) {
-               e_ews_message_write_string_parameter_with_attribute (msg, "AttachmentId", NULL, NULL, "Id", 
l->data);
+               subparam = e_soap_parameter_get_next_child (subparam);
        }
 
-       e_soap_message_end_element (msg); /* "AttachmentIds" */
-
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_delete_attachments);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
-
-       e_ews_connection_queue_request (
-               cnc, msg, delete_attachments_response_cb,
-               pri, cancellable, simple);
-
-       g_object_unref (simple);
-}
-
-gboolean
-e_ews_connection_delete_attachments_finish (EEwsConnection *cnc,
-                                            GAsyncResult *result,
-                                           gchar **new_change_key,
-                                            GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_delete_attachments),
-               FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
-
-       if (new_change_key)
-               *new_change_key = async_data->sync_state;
-       else
-               g_free (async_data->sync_state);
-
        return TRUE;
 }
 
@@ -8215,87 +6123,85 @@ gboolean
 e_ews_connection_delete_attachments_sync (EEwsConnection *cnc,
                                           gint pri,
                                           const GSList *attachments_ids,
-                                         gchar **new_change_key,
+                                         gchar **out_new_change_key,
                                           GCancellable *cancellable,
                                           GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean ret;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       const GSList *link;
+       gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       closure = e_async_closure_new ();
-
-       e_ews_connection_delete_attachments (
-               cnc, pri, attachments_ids, cancellable,
-               e_async_closure_callback, closure);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "DeleteAttachment",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       result = e_async_closure_wait (closure);
+       if (!request)
+               return FALSE;
 
-       ret = e_ews_connection_delete_attachments_finish (
-               cnc, result, new_change_key, error);
+       /* start interation over all items to get the attachemnts */
+       e_soap_request_start_element (request, "AttachmentIds", "messages", NULL);
 
-       e_async_closure_free (closure);
+       for (link = attachments_ids; link; link = g_slist_next (link)) {
+               e_ews_request_write_string_parameter_with_attribute (request, "AttachmentId", NULL, NULL, 
"Id", link->data);
+       }
 
-       return ret;
-}
+       e_soap_request_end_element (request); /* "AttachmentIds" */
 
-static void
-ews_handle_attachments_param (ESoapParameter *param,
-                              EwsAsyncData *async_data)
-{
-       ESoapParameter *subparam, *attspara;
-       EEwsAttachmentInfo *info = NULL;
-       EEwsItem *item;
-       const gchar *name;
+       e_ews_request_write_footer (request);
 
-       attspara = e_soap_parameter_get_first_child_by_name (param, "Attachments");
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       for (subparam = e_soap_parameter_get_first_child (attspara); subparam != NULL; subparam = 
e_soap_parameter_get_next_child (subparam)) {
-               name = e_soap_parameter_get_name (subparam);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-               if (!g_ascii_strcasecmp (name, "ItemAttachment")) {
-                       item = e_ews_item_new_from_soap_parameter (subparam);
-                       info = e_ews_item_dump_mime_content (item, async_data->directory);
-                       g_clear_object (&item);
+       success = e_ews_process_delete_attachments_response (cnc, response, out_new_change_key, error);
 
-               } else if (!g_ascii_strcasecmp (name, "FileAttachment")) {
-                       info = e_ews_dump_file_attachment_from_soap_parameter (
-                                       subparam,
-                                       async_data->directory,
-                                       async_data->sync_state);
-               }
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-               if (info)
-                       async_data->items = g_slist_append (async_data->items, info);
+       if (!success && out_new_change_key)
+               g_clear_pointer (out_new_change_key, g_free);
 
-               info = NULL;
-       }
+       return success;
 }
 
-static void
-get_attachments_response_cb (ESoapResponse *response,
-                             GSimpleAsyncResult *simple)
+static gboolean
+e_ews_process_get_attachments_response (EEwsConnection *cnc,
+                                       ESoapResponse *response,
+                                       const gchar *uid,
+                                       const gchar *cache_directory,
+                                       GSList **out_attachments,
+                                       GError **error)
 {
-       EwsAsyncData *async_data;
        ESoapParameter *param;
        ESoapParameter *subparam;
-       GError *error = NULL;
+       GError *local_error = NULL;
 
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       if (out_attachments)
+               *out_attachments = NULL;
 
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
        /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
        subparam = e_soap_parameter_get_first_child (param);
@@ -8303,114 +6209,39 @@ get_attachments_response_cb (ESoapResponse *response,
        while (subparam != NULL) {
                const gchar *name = (const gchar *) subparam->name;
 
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
-
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "GetAttachmentResponseMessage"))
-                       ews_handle_attachments_param (subparam, async_data);
-
-               subparam = e_soap_parameter_get_next_child (subparam);
-       }
-}
-
-void
-e_ews_connection_get_attachments (EEwsConnection *cnc,
-                                  gint pri,
-                                  const gchar *uid,
-                                  const GSList *ids,
-                                  const gchar *cache,
-                                  gboolean include_mime,
-                                  ESoapProgressFn progress_fn,
-                                  gpointer progress_data,
-                                  GCancellable *cancellable,
-                                  GAsyncReadyCallback callback,
-                                  gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       const GSList *l;
-
-       g_return_if_fail (cnc != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "GetAttachment",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
-
-       /* not sure why I need it, need to check */
-       if (progress_fn && progress_data)
-               e_soap_message_set_progress_fn (msg, progress_fn, progress_data);
-
-       if (cache)
-               e_soap_message_store_node_data (msg, "MimeContent Content", cache, TRUE);
-
-       /* wrtie empty attachments shape, need to discover maybe usefull in some cases*/
-       e_soap_message_start_element (msg, "AttachmentShape", "messages", NULL);
-       e_ews_message_write_string_parameter (msg, "IncludeMimeContent", NULL, "true");
-       e_soap_message_end_element (msg);
-
-       /* start interation over all items to get the attachemnts */
-       e_soap_message_start_element (msg, "AttachmentIds", "messages", NULL);
-
-       for (l = ids; l != NULL; l = g_slist_next (l))
-               e_ews_message_write_string_parameter_with_attribute (msg, "AttachmentId", NULL, NULL, "Id", 
l->data);
-
-       e_soap_message_end_element (msg);
-
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_get_attachments);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       async_data->directory = cache;
-       async_data->sync_state = (gchar *) uid;
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
-
-       e_ews_connection_queue_request (
-               cnc, msg, get_attachments_response_cb,
-               pri, cancellable, simple);
-
-       g_object_unref (simple);
-}
-
-gboolean
-e_ews_connection_get_attachments_finish (EEwsConnection *cnc,
-                                         GAsyncResult *result,
-                                         GSList **items,
-                                         GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_get_attachments),
-               FALSE);
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "GetAttachmentResponseMessage") && 
out_attachments) {
+                       ESoapParameter *subattsparam, *attspara;
+                       EEwsAttachmentInfo *info = NULL;
+                       EEwsItem *item;
+                       const gchar *name;
+
+                       attspara = e_soap_parameter_get_first_child_by_name (subparam, "Attachments");
+
+                       for (subattsparam = e_soap_parameter_get_first_child (attspara);
+                            subattsparam;
+                            subattsparam = e_soap_parameter_get_next_child (subattsparam)) {
+                               name = e_soap_parameter_get_name (subattsparam);
+
+                               if (!g_ascii_strcasecmp (name, "ItemAttachment")) {
+                                       item = e_ews_item_new_from_soap_parameter (subattsparam);
+                                       info = e_ews_item_dump_mime_content (item, cache_directory);
+                                       g_clear_object (&item);
+                               } else if (!g_ascii_strcasecmp (name, "FileAttachment")) {
+                                       info = e_ews_dump_file_attachment_from_soap_parameter (subattsparam, 
cache_directory, uid);
+                               }
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+                               if (info)
+                                       *out_attachments = g_slist_prepend (*out_attachments, info);
 
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+                               info = NULL;
+                       }
+               }
 
-       if (items)
-               *items = async_data->items;
-       else
-               g_slist_free_full (async_data->items, (GDestroyNotify) e_ews_attachment_info_free);
+               subparam = e_soap_parameter_get_next_child (subparam);
+       }
 
        return TRUE;
 }
@@ -8420,40 +6251,86 @@ e_ews_connection_get_attachments_sync (EEwsConnection *cnc,
                                        gint pri,
                                        const gchar *uid,
                                        const GSList *ids,
-                                       const gchar *cache,
+                                       const gchar *cache_directory,
                                        gboolean include_mime,
-                                       GSList **items,
-                                       ESoapProgressFn progress_fn,
+                                       GSList **out_attachments,
+                                       ESoapResponseProgressFn progress_fn,
                                        gpointer progress_data,
                                        GCancellable *cancellable,
                                        GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean ret;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       const GSList *link;
+       gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (out_attachments != NULL, FALSE);
+
+       *out_attachments = NULL;
 
-       closure = e_async_closure_new ();
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetAttachment",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       e_ews_connection_get_attachments (
-               cnc, pri, uid, ids, cache, include_mime,
-               progress_fn, progress_data, cancellable,
-               e_async_closure_callback, closure);
+       if (!request)
+               return FALSE;
 
-       result = e_async_closure_wait (closure);
+       /* not sure why I need it, need to check */
+       if (progress_fn && progress_data)
+               e_soap_request_set_progress_fn (request, progress_fn, progress_data);
 
-       ret = e_ews_connection_get_attachments_finish (
-               cnc, result, items, error);
+       if (cache_directory)
+               e_soap_request_set_store_node_data (request, "MimeContent Content", cache_directory, TRUE);
 
-       e_async_closure_free (closure);
+       /* write empty attachments shape, need to discover maybe usefull in some cases */
+       e_soap_request_start_element (request, "AttachmentShape", "messages", NULL);
+       e_ews_request_write_string_parameter (request, "IncludeMimeContent", NULL, "true");
+       e_soap_request_end_element (request);
 
-       return ret;
+       /* start interation over all items to get the attachemnts */
+       e_soap_request_start_element (request, "AttachmentIds", "messages", NULL);
+
+       for (link = ids; link; link = g_slist_next (link)) {
+               e_ews_request_write_string_parameter_with_attribute (request, "AttachmentId", NULL, NULL, 
"Id", link->data);
+       }
+
+       e_soap_request_end_element (request);
+
+       e_ews_request_write_footer (request);
+
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
+
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
+
+       success = e_ews_process_get_attachments_response (cnc, response, uid, cache_directory, 
out_attachments, error);
+
+       g_clear_object (&request);
+       g_clear_object (&response);
+
+       if (out_attachments && success) {
+               *out_attachments = g_slist_reverse (*out_attachments);
+       } else if (out_attachments) {
+               g_slist_free_full (*out_attachments, (GDestroyNotify) e_ews_attachment_info_free);
+               *out_attachments = NULL;
+       }
+
+       return success;
 }
 
 static void
 ews_handle_free_busy_view (ESoapParameter *param,
-                           EwsAsyncData *async_data)
+                          GSList **out_components)
 {
        /*parse the response to create a free_busy data
        http://msdn.microsoft.com / en - us / library / aa564001 % 28v = EXCHG.140 % 29.aspx */
@@ -8468,6 +6345,7 @@ ews_handle_free_busy_view (ESoapParameter *param,
        viewparam = e_soap_parameter_get_first_child_by_name (param, "FreeBusyView");
        if (!viewparam)
                return;
+
        vfb = i_cal_component_new_vfreebusy ();
        eventarray = e_soap_parameter_get_first_child_by_name (viewparam, "CalendarEventArray");
        for (event_param = eventarray ? e_soap_parameter_get_first_child (eventarray) : NULL;
@@ -8578,31 +6456,29 @@ ews_handle_free_busy_view (ESoapParameter *param,
                g_clear_object (&ipt);
        }
 
-       async_data->items = g_slist_append (async_data->items, vfb);
+       *out_components = g_slist_prepend (*out_components, vfb);
 }
 
-static void
-get_free_busy_response_cb (ESoapResponse *response,
-                           GSimpleAsyncResult *simple)
+static gboolean
+e_ews_process_get_free_busy_response (EEwsConnection *cnc,
+                                     ESoapResponse *response,
+                                     GSList **out_components,
+                                     GError **error)
 {
-       EwsAsyncData *async_data;
        ESoapParameter *param;
        ESoapParameter *subparam;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       GError *local_error = NULL;
 
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "FreeBusyResponseArray", &error);
+       param = e_soap_response_get_first_parameter_by_name (response, "FreeBusyResponseArray", &local_error);
 
        /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
        subparam = e_soap_parameter_get_first_child (param);
@@ -8614,94 +6490,15 @@ get_free_busy_response_cb (ESoapResponse *response,
                        subparam, "ResponseMessage");
 
                if (subsubparam) {
-                       if (!ews_get_response_status (subsubparam, &error)) {
-                               g_simple_async_result_take_error (simple, error);
-                               return;
-                       }
+                       if (!ews_get_response_status (subsubparam, error))
+                               return FALSE;
 
-                       ews_handle_free_busy_view (subparam, async_data);
+                       if (out_components)
+                               ews_handle_free_busy_view (subparam, out_components);
                }
 
                subparam = e_soap_parameter_get_next_child (subparam);
        }
-}
-
-void
-e_ews_connection_get_free_busy (EEwsConnection *cnc,
-                                gint pri,
-                                EEwsRequestCreationCallback free_busy_cb,
-                                gpointer free_busy_user_data,
-                                GCancellable *cancellable,
-                                GAsyncReadyCallback callback,
-                                gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       gboolean success;
-       GError *local_error = NULL;
-
-       g_return_if_fail (cnc != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "GetUserAvailabilityRequest",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
-
-       success = free_busy_cb (msg, free_busy_user_data, &local_error);
-
-       e_ews_message_write_footer (msg); /*GetUserAvailabilityRequest  */
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_get_free_busy);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
-
-       if (success) {
-               e_ews_connection_queue_request (
-                       cnc, msg, get_free_busy_response_cb,
-                       pri, cancellable, simple);
-       } else {
-               if (local_error)
-                       g_simple_async_result_take_error (simple, local_error);
-               g_simple_async_result_complete_in_idle (simple);
-               g_clear_object (&msg);
-       }
-
-       g_object_unref (simple);
-}
-
-gboolean
-e_ews_connection_get_free_busy_finish (EEwsConnection *cnc,
-                                       GAsyncResult *result,
-                                       GSList **free_busy, /* ICalComponent * */
-                                       GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_get_free_busy),
-               FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
-       *free_busy = async_data->items;
 
        return TRUE;
 }
@@ -8711,29 +6508,58 @@ e_ews_connection_get_free_busy_sync (EEwsConnection *cnc,
                                      gint pri,
                                      EEwsRequestCreationCallback free_busy_cb,
                                      gpointer free_busy_user_data,
-                                     GSList **free_busy, /* ICalComponent * */
+                                     GSList **out_free_busy, /* ICalComponent * */
                                      GCancellable *cancellable,
                                      GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (out_free_busy != NULL, FALSE);
+
+       *out_free_busy = NULL;
+
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetUserAvailabilityRequest",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
+
+       if (!request)
+               return FALSE;
 
-       closure = e_async_closure_new ();
+       if (!free_busy_cb (request, free_busy_user_data, error)) {
+               g_clear_object (&request);
+               return FALSE;
+       }
+
+       e_ews_request_write_footer (request);
+
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       e_ews_connection_get_free_busy (
-               cnc, pri, free_busy_cb,
-               free_busy_user_data, cancellable,
-               e_async_closure_callback, closure);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       result = e_async_closure_wait (closure);
+       success = e_ews_process_get_free_busy_response (cnc, response, out_free_busy, error);
 
-       success = e_ews_connection_get_free_busy_finish (
-               cnc, result, free_busy, error);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       e_async_closure_free (closure);
+       if (success && out_free_busy) {
+               *out_free_busy = g_slist_reverse (*out_free_busy);
+       } else if (out_free_busy) {
+               g_slist_free_full (*out_free_busy, g_object_unref);
+               *out_free_busy = NULL;
+       }
 
        return success;
 }
@@ -8758,7 +6584,7 @@ get_permission_from_string (const gchar *permission)
 
 static void
 ews_handle_delegate_user_param (ESoapParameter *param,
-                                EwsAsyncData *async_data)
+                               GSList **out_delegates)
 {
        ESoapParameter *subparam, *node, *child;
        EwsDelegateInfo *data;
@@ -8845,150 +6671,75 @@ ews_handle_delegate_user_param (ESoapParameter *param,
                g_free (value);
        }
 
-       async_data->items = g_slist_append (async_data->items, data);
+       *out_delegates = g_slist_prepend (*out_delegates, data);
 }
 
-static void
-get_delegate_response_cb (ESoapResponse *response,
-                          GSimpleAsyncResult *simple)
+static gboolean
+e_ews_process_get_delegate_response (EEwsConnection *cnc,
+                                    ESoapResponse *response,
+                                    EwsDelegateDeliver *out_deliver_to,
+                                    GSList **out_delegates,
+                                    GError **error)
 {
-       EwsAsyncData *async_data;
        ESoapParameter *param;
        ESoapParameter *subparam;
-       gchar *value;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       GError *local_error = NULL;
 
-       if (ews_get_response_status (e_soap_response_get_parameter (response), &error))
-               param = e_soap_response_get_first_parameter_by_name (
-                       response, "DeliverMeetingRequests", &error);
+       if (ews_get_response_status (e_soap_response_get_parameter (response), &local_error))
+               param = e_soap_response_get_first_parameter_by_name (response, "DeliverMeetingRequests", 
&local_error);
        else
                param = NULL;
 
        /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
-       value = e_soap_parameter_get_string_value (param);
-       if (g_strcmp0 (value, "DelegatesOnly") == 0)
-               async_data->deliver_to = EwsDelegateDeliver_DelegatesOnly;
-       else if (g_strcmp0 (value, "DelegatesAndMe") == 0)
-               async_data->deliver_to = EwsDelegateDeliver_DelegatesAndMe;
-       else if (g_strcmp0 (value, "DelegatesAndSendInformationToMe") == 0)
-               async_data->deliver_to = EwsDelegateDeliver_DelegatesAndSendInformationToMe;
-       else {
-               g_message ("%s: Unknown deliver-to value '%s'", G_STRFUNC, value ? value : "[null]");
-               async_data->deliver_to = EwsDelegateDeliver_DelegatesAndSendInformationToMe;
-       }
-       g_free (value);
+       if (out_deliver_to) {
+               gchar *value;
+
+               value = e_soap_parameter_get_string_value (param);
+
+               if (g_strcmp0 (value, "DelegatesOnly") == 0)
+                       *out_deliver_to = EwsDelegateDeliver_DelegatesOnly;
+               else if (g_strcmp0 (value, "DelegatesAndMe") == 0)
+                       *out_deliver_to = EwsDelegateDeliver_DelegatesAndMe;
+               else if (g_strcmp0 (value, "DelegatesAndSendInformationToMe") == 0)
+                       *out_deliver_to = EwsDelegateDeliver_DelegatesAndSendInformationToMe;
+               else {
+                       g_message ("%s: Unknown deliver-to value '%s'", G_STRFUNC, value ? value : "[null]");
+                       *out_deliver_to = EwsDelegateDeliver_DelegatesAndSendInformationToMe;
+               }
+
+               g_free (value);
+       }
 
        param = e_soap_response_get_first_parameter_by_name (
                response, "ResponseMessages", NULL);
+
        /* it's OK to not have set any delegate */
        if (!param)
-               return;
+               return TRUE;
 
        subparam = e_soap_parameter_get_first_child (param);
 
        while (subparam != NULL) {
                const gchar *name = (const gchar *) subparam->name;
 
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
 
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "DelegateUserResponseMessageType"))
-                       ews_handle_delegate_user_param (subparam, async_data);
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "DelegateUserResponseMessageType")) {
+                       ews_handle_delegate_user_param (subparam, out_delegates);
+               }
 
                subparam = e_soap_parameter_get_next_child (subparam);
        }
-}
-
-void
-e_ews_connection_get_delegate (EEwsConnection *cnc,
-                               gint pri,
-                               const gchar *mail_id,
-                               gboolean include_permissions,
-                               GCancellable *cancellable,
-                               GAsyncReadyCallback callback,
-                               gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_if_fail (cnc != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "GetDelegate",
-                       "IncludePermissions",
-                       include_permissions ? "true" : "false",
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
-
-       e_soap_message_start_element (msg, "Mailbox", "messages", NULL);
-
-       e_ews_message_write_string_parameter (msg, "EmailAddress", NULL, mail_id ? mail_id : 
cnc->priv->email);
-
-       e_soap_message_end_element (msg);
-
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_get_delegate);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
-
-       e_ews_connection_queue_request (
-               cnc, msg, get_delegate_response_cb,
-               pri, cancellable, simple);
-
-       g_object_unref (simple);
-}
-
-gboolean
-e_ews_connection_get_delegate_finish (EEwsConnection *cnc,
-                                      GAsyncResult *result,
-                                      EwsDelegateDeliver *deliver_to,
-                                      GSList **delegates, /* EwsDelegateInfo * */
-                                      GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (delegates != NULL, FALSE);
-       g_return_val_if_fail (deliver_to != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_get_delegate),
-               FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
-
-       *deliver_to = async_data->deliver_to;
-       *delegates = async_data->items;
-       async_data->items = NULL;
 
        return TRUE;
 }
@@ -8998,77 +6749,107 @@ e_ews_connection_get_delegate_sync (EEwsConnection *cnc,
                                     gint pri,
                                     const gchar *mail_id,
                                     gboolean include_permissions,
-                                    EwsDelegateDeliver *deliver_to,
-                                    GSList **delegates, /* EwsDelegateInfo * */
+                                    EwsDelegateDeliver *out_deliver_to,
+                                    GSList **out_delegates, /* EwsDelegateInfo * */
                                     GCancellable *cancellable,
                                     GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
        gboolean success;
 
        g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
-       g_return_val_if_fail (deliver_to != NULL, FALSE);
-       g_return_val_if_fail (delegates != NULL, FALSE);
+       g_return_val_if_fail (out_deliver_to != NULL, FALSE);
+       g_return_val_if_fail (out_delegates != NULL, FALSE);
+
+       *out_delegates = NULL;
+
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetDelegate",
+               "IncludePermissions",
+               include_permissions ? "true" : "false",
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
+
+       if (!request)
+               return FALSE;
+
+       e_soap_request_start_element (request, "Mailbox", "messages", NULL);
+
+       e_ews_request_write_string_parameter (request, "EmailAddress", NULL, mail_id ? mail_id : 
cnc->priv->email);
+
+       e_soap_request_end_element (request);
 
-       closure = e_async_closure_new ();
+       e_ews_request_write_footer (request);
 
-       e_ews_connection_get_delegate (
-               cnc, pri, mail_id,
-               include_permissions, cancellable,
-               e_async_closure_callback, closure);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       result = e_async_closure_wait (closure);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       success = e_ews_connection_get_delegate_finish (
-               cnc, result, deliver_to, delegates, error);
+       success = e_ews_process_get_delegate_response (cnc, response, out_deliver_to, out_delegates, error);
+
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       e_async_closure_free (closure);
+       if (success) {
+               *out_delegates = g_slist_reverse (*out_delegates);
+       } else {
+               g_slist_free_full (*out_delegates, (GDestroyNotify) ews_delegate_info_free);
+               *out_delegates = NULL;
+       }
 
        return success;
 }
 
-static void
-update_delegate_response_cb (ESoapResponse *response,
-                             GSimpleAsyncResult *simple)
+static gboolean
+e_ews_process_update_delegate_response (EEwsConnection *cnc,
+                                       ESoapResponse *response,
+                                       GError **error)
 {
        ESoapParameter *param;
        ESoapParameter *subparam;
-       GError *error = NULL;
+       GError *local_error = NULL;
 
-       if (ews_get_response_status (e_soap_response_get_parameter (response), &error)) {
-               param = e_soap_response_get_first_parameter_by_name (
-                       response, "ResponseMessages", NULL);
+       if (ews_get_response_status (e_soap_response_get_parameter (response), &local_error)) {
+               param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", NULL);
                /* that's OK to not receive any ResponseMessages here */
                if (!param)
-                       return;
-       } else
+                       return TRUE;
+       } else {
                param = NULL;
+       }
 
        /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
        subparam = e_soap_parameter_get_first_child (param);
 
        while (subparam != NULL) {
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
 
                subparam = e_soap_parameter_get_next_child (param);
        }
+
+       return TRUE;
 }
 
 static void
-set_delegate_permission (ESoapMessage *msg,
+set_delegate_permission (ESoapRequest *request,
                          const gchar *elem_name,
                          EwsPermissionLevel perm_level)
 {
@@ -9086,415 +6867,265 @@ set_delegate_permission (ESoapMessage *msg,
        if (!level_name)
                return;
 
-       e_ews_message_write_string_parameter (msg, elem_name, NULL, level_name);
+       e_ews_request_write_string_parameter (request, elem_name, NULL, level_name);
 }
 
-void
-e_ews_connection_add_delegate (EEwsConnection *cnc,
-                               gint pri,
-                               const gchar *mail_id,
-                               const GSList *delegates, /* EwsDelegateInfo * */
-                               GCancellable *cancellable,
-                               GAsyncReadyCallback callback,
-                               gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       const GSList *iter;
+gboolean
+e_ews_connection_add_delegate_sync (EEwsConnection *cnc,
+                                    gint pri,
+                                    const gchar *mail_id,
+                                    const GSList *delegates, /* EwsDelegateInfo * */
+                                    GCancellable *cancellable,
+                                    GError **error)
+{
+       ESoapRequest *request;
+       ESoapResponse *response;
+       const GSList *link;
+       gboolean success;
 
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (delegates != NULL);
+       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
+       g_return_val_if_fail (delegates != NULL, FALSE);
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "AddDelegate",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "AddDelegate",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
+
+       if (!request)
+               return FALSE;
 
-       e_soap_message_start_element (msg, "Mailbox", "messages", NULL);
-       e_ews_message_write_string_parameter (msg, "EmailAddress", NULL, mail_id ? mail_id : 
cnc->priv->email);
-       e_soap_message_end_element (msg);
+       e_soap_request_start_element (request, "Mailbox", "messages", NULL);
+       e_ews_request_write_string_parameter (request, "EmailAddress", NULL, mail_id ? mail_id : 
cnc->priv->email);
+       e_soap_request_end_element (request);
 
-       e_soap_message_start_element (msg, "DelegateUsers", "messages", NULL);
-       for (iter = delegates; iter; iter = iter->next) {
-               const EwsDelegateInfo *di = iter->data;
+       e_soap_request_start_element (request, "DelegateUsers", "messages", NULL);
+       for (link = delegates; link; link = g_slist_next (link)) {
+               const EwsDelegateInfo *di = link->data;
 
                if (!di)
                        continue;
 
-               e_soap_message_start_element (msg, "DelegateUser", NULL, NULL);
+               e_soap_request_start_element (request, "DelegateUser", NULL, NULL);
 
-               e_soap_message_start_element (msg, "UserId", NULL, NULL);
-               e_ews_message_write_string_parameter (msg, "PrimarySmtpAddress", NULL, 
di->user_id->primary_smtp);
-               e_soap_message_end_element (msg); /* UserId */
+               e_soap_request_start_element (request, "UserId", NULL, NULL);
+               e_ews_request_write_string_parameter (request, "PrimarySmtpAddress", NULL, 
di->user_id->primary_smtp);
+               e_soap_request_end_element (request); /* UserId */
 
-               e_soap_message_start_element (msg, "DelegatePermissions", NULL, NULL);
-               set_delegate_permission (msg, "CalendarFolderPermissionLevel", di->calendar);
-               set_delegate_permission (msg, "TasksFolderPermissionLevel", di->tasks);
-               set_delegate_permission (msg, "InboxFolderPermissionLevel", di->inbox);
-               set_delegate_permission (msg, "ContactsFolderPermissionLevel", di->contacts);
-               set_delegate_permission (msg, "NotesFolderPermissionLevel", di->notes);
-               set_delegate_permission (msg, "JournalFolderPermissionLevel", di->journal);
-               e_soap_message_end_element (msg); /* DelegatePermissions */
+               e_soap_request_start_element (request, "DelegatePermissions", NULL, NULL);
+               set_delegate_permission (request, "CalendarFolderPermissionLevel", di->calendar);
+               set_delegate_permission (request, "TasksFolderPermissionLevel", di->tasks);
+               set_delegate_permission (request, "InboxFolderPermissionLevel", di->inbox);
+               set_delegate_permission (request, "ContactsFolderPermissionLevel", di->contacts);
+               set_delegate_permission (request, "NotesFolderPermissionLevel", di->notes);
+               set_delegate_permission (request, "JournalFolderPermissionLevel", di->journal);
+               e_soap_request_end_element (request); /* DelegatePermissions */
 
-               e_ews_message_write_string_parameter (
-                       msg, "ReceiveCopiesOfMeetingMessages", NULL,
-                       di->meetingcopies ? "true" : "false");
-               e_ews_message_write_string_parameter (
-                       msg, "ViewPrivateItems", NULL,
-                       di->view_priv_items ? "true" : "false");
+               e_ews_request_write_string_parameter (request, "ReceiveCopiesOfMeetingMessages", NULL, 
di->meetingcopies ? "true" : "false");
+               e_ews_request_write_string_parameter (request, "ViewPrivateItems", NULL, di->view_priv_items 
? "true" : "false");
 
-               e_soap_message_end_element (msg); /* DelegateUser */
+               e_soap_request_end_element (request); /* DelegateUser */
        }
 
-       e_soap_message_end_element (msg); /* DelegateUsers */
-
-       e_ews_message_write_footer (msg);
+       e_soap_request_end_element (request); /* DelegateUsers */
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_add_delegate);
+       e_ews_request_write_footer (request);
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       e_ews_connection_queue_request (
-               cnc, msg, update_delegate_response_cb,
-               pri, cancellable, simple);
-
-       g_object_unref (simple);
-}
-
-gboolean
-e_ews_connection_add_delegate_finish (EEwsConnection *cnc,
-                                      GAsyncResult *result,
-                                      GError **error)
-{
-       GSimpleAsyncResult *simple;
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_add_delegate),
-               FALSE);
+       success = e_ews_process_update_delegate_response (cnc, response, error);
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       return !g_simple_async_result_propagate_error (simple, error);
+       return success;
 }
 
 gboolean
-e_ews_connection_add_delegate_sync (EEwsConnection *cnc,
-                                    gint pri,
-                                    const gchar *mail_id,
-                                    const GSList *delegates, /* EwsDelegateInfo * */
-                                    GCancellable *cancellable,
-                                    GError **error)
+e_ews_connection_remove_delegate_sync (EEwsConnection *cnc,
+                                       gint pri,
+                                       const gchar *mail_id,
+                                       const GSList *delegate_ids, /* EwsUserId * */
+                                       GCancellable *cancellable,
+                                       GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       const GSList *link;
        gboolean success;
 
        g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
-       g_return_val_if_fail (delegates != NULL, FALSE);
-
-       closure = e_async_closure_new ();
-
-       e_ews_connection_add_delegate (
-               cnc, pri, mail_id, delegates, cancellable,
-               e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_connection_add_delegate_finish (cnc, result, error);
-
-       e_async_closure_free (closure);
-
-       return success;
-}
-
-void
-e_ews_connection_remove_delegate (EEwsConnection *cnc,
-                                  gint pri,
-                                  const gchar *mail_id,
-                                  const GSList *delegate_ids, /* EwsUserId * */
-                                  GCancellable *cancellable,
-                                  GAsyncReadyCallback callback,
-                                  gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       const GSList *iter;
+       g_return_val_if_fail (delegate_ids != NULL, FALSE);
 
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (delegate_ids != NULL);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "RemoveDelegate",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "RemoveDelegate",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
+       if (!request)
+               return FALSE;
+
+       e_soap_request_start_element (request, "Mailbox", "messages", NULL);
+       e_ews_request_write_string_parameter (request, "EmailAddress", NULL, mail_id ? mail_id : 
cnc->priv->email);
+       e_soap_request_end_element (request);
 
-       e_soap_message_start_element (msg, "Mailbox", "messages", NULL);
-       e_ews_message_write_string_parameter (msg, "EmailAddress", NULL, mail_id ? mail_id : 
cnc->priv->email);
-       e_soap_message_end_element (msg);
+       e_soap_request_start_element (request, "UserIds", "messages", NULL);
 
-       e_soap_message_start_element (msg, "UserIds", "messages", NULL);
-       for (iter = delegate_ids; iter; iter = iter->next) {
-               const EwsUserId *user_id = iter->data;
+       for (link = delegate_ids; link; link = g_slist_next (link)) {
+               const EwsUserId *user_id = link->data;
 
                if (!user_id)
                        continue;
 
-               e_soap_message_start_element (msg, "UserId", NULL, NULL);
-               e_ews_message_write_string_parameter (msg, "PrimarySmtpAddress", NULL, user_id->primary_smtp);
-               e_soap_message_end_element (msg); /* UserId */
+               e_soap_request_start_element (request, "UserId", NULL, NULL);
+               e_ews_request_write_string_parameter (request, "PrimarySmtpAddress", NULL, 
user_id->primary_smtp);
+               e_soap_request_end_element (request);
        }
 
-       e_soap_message_end_element (msg); /* UserIds */
-
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_remove_delegate);
+       e_soap_request_end_element (request); /* UserIds */
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       e_ews_request_write_footer (request);
 
-       e_ews_connection_queue_request (
-               cnc, msg, update_delegate_response_cb,
-               pri, cancellable, simple);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       g_object_unref (simple);
-}
-
-gboolean
-e_ews_connection_remove_delegate_finish (EEwsConnection *cnc,
-                                         GAsyncResult *result,
-                                         GError **error)
-{
-       GSimpleAsyncResult *simple;
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_remove_delegate),
-               FALSE);
+       success = e_ews_process_update_delegate_response (cnc, response, error);
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       return !g_simple_async_result_propagate_error (simple, error);
+       return success;
 }
 
 gboolean
-e_ews_connection_remove_delegate_sync (EEwsConnection *cnc,
+e_ews_connection_update_delegate_sync (EEwsConnection *cnc,
                                        gint pri,
                                        const gchar *mail_id,
-                                       const GSList *delegate_ids, /* EwsUserId * */
+                                       EwsDelegateDeliver deliver_to,
+                                       const GSList *delegates, /* EwsDelegateInfo * */
                                        GCancellable *cancellable,
                                        GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       const GSList *link;
        gboolean success;
 
        g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
-       g_return_val_if_fail (delegate_ids != NULL, FALSE);
-
-       closure = e_async_closure_new ();
 
-       e_ews_connection_remove_delegate (
-               cnc, pri, mail_id, delegate_ids, cancellable,
-               e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "UpdateDelegate",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       success = e_ews_connection_remove_delegate_finish (cnc, result, error);
+       if (!request)
+               return FALSE;
 
-       e_async_closure_free (closure);
+       e_soap_request_start_element (request, "Mailbox", "messages", NULL);
+       e_ews_request_write_string_parameter (request, "EmailAddress", NULL, mail_id ? mail_id : 
cnc->priv->email);
+       e_soap_request_end_element (request);
 
-       return success;
-}
+       if (delegates) {
+               e_soap_request_start_element (request, "DelegateUsers", "messages", NULL);
 
-void
-e_ews_connection_update_delegate (EEwsConnection *cnc,
-                                  gint pri,
-                                  const gchar *mail_id,
-                                  EwsDelegateDeliver deliver_to,
-                                  const GSList *delegates, /* EwsDelegateInfo * */
-                                  GCancellable *cancellable,
-                                  GAsyncReadyCallback callback,
-                                  gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       const GSList *iter;
+               for (link = delegates; link; link = g_slist_next (link)) {
+                       const EwsDelegateInfo *di = link->data;
 
-       g_return_if_fail (cnc != NULL);
+                       if (!di)
+                               continue;
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "UpdateDelegate",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
+                       e_soap_request_start_element (request, "DelegateUser", NULL, NULL);
 
-       e_soap_message_start_element (msg, "Mailbox", "messages", NULL);
-       e_ews_message_write_string_parameter (msg, "EmailAddress", NULL, mail_id ? mail_id : 
cnc->priv->email);
-       e_soap_message_end_element (msg);
+                       e_soap_request_start_element (request, "UserId", NULL, NULL);
+                       e_ews_request_write_string_parameter (request, "PrimarySmtpAddress", NULL, 
di->user_id->primary_smtp);
+                       e_soap_request_end_element (request); /* UserId */
 
-       if (delegates) {
-               e_soap_message_start_element (msg, "DelegateUsers", "messages", NULL);
-               for (iter = delegates; iter; iter = iter->next) {
-                       const EwsDelegateInfo *di = iter->data;
+                       e_soap_request_start_element (request, "DelegatePermissions", NULL, NULL);
+                       set_delegate_permission (request, "CalendarFolderPermissionLevel", di->calendar);
+                       set_delegate_permission (request, "TasksFolderPermissionLevel", di->tasks);
+                       set_delegate_permission (request, "InboxFolderPermissionLevel", di->inbox);
+                       set_delegate_permission (request, "ContactsFolderPermissionLevel", di->contacts);
+                       set_delegate_permission (request, "NotesFolderPermissionLevel", di->notes);
+                       set_delegate_permission (request, "JournalFolderPermissionLevel", di->journal);
+                       e_soap_request_end_element (request); /* DelegatePermissions */
 
-                       if (!di)
-                               continue;
+                       e_ews_request_write_string_parameter (request, "ReceiveCopiesOfMeetingMessages", 
NULL, di->meetingcopies ? "true" : "false");
+                       e_ews_request_write_string_parameter (request, "ViewPrivateItems", NULL, 
di->view_priv_items ? "true" : "false");
 
-                       e_soap_message_start_element (msg, "DelegateUser", NULL, NULL);
-
-                       e_soap_message_start_element (msg, "UserId", NULL, NULL);
-                       e_ews_message_write_string_parameter (msg, "PrimarySmtpAddress", NULL, 
di->user_id->primary_smtp);
-                       e_soap_message_end_element (msg); /* UserId */
-
-                       e_soap_message_start_element (msg, "DelegatePermissions", NULL, NULL);
-                       set_delegate_permission (msg, "CalendarFolderPermissionLevel", di->calendar);
-                       set_delegate_permission (msg, "TasksFolderPermissionLevel", di->tasks);
-                       set_delegate_permission (msg, "InboxFolderPermissionLevel", di->inbox);
-                       set_delegate_permission (msg, "ContactsFolderPermissionLevel", di->contacts);
-                       set_delegate_permission (msg, "NotesFolderPermissionLevel", di->notes);
-                       set_delegate_permission (msg, "JournalFolderPermissionLevel", di->journal);
-                       e_soap_message_end_element (msg); /* DelegatePermissions */
-
-                       e_ews_message_write_string_parameter (
-                               msg, "ReceiveCopiesOfMeetingMessages", NULL,
-                               di->meetingcopies ? "true" : "false");
-                       e_ews_message_write_string_parameter (
-                               msg, "ViewPrivateItems", NULL,
-                               di->view_priv_items ? "true" : "false");
-
-                       e_soap_message_end_element (msg); /* DelegateUser */
+                       e_soap_request_end_element (request); /* DelegateUser */
                }
 
-               e_soap_message_end_element (msg); /* DelegateUsers */
+               e_soap_request_end_element (request); /* DelegateUsers */
        }
 
-       e_ews_message_write_string_parameter (
-               msg, "DeliverMeetingRequests", "messages",
+       e_ews_request_write_string_parameter (request, "DeliverMeetingRequests", "messages",
                deliver_to == EwsDelegateDeliver_DelegatesOnly ? "DelegatesOnly" :
                deliver_to == EwsDelegateDeliver_DelegatesAndMe ? "DelegatesAndMe" :
                "DelegatesAndSendInformationToMe");
 
-       e_ews_message_write_footer (msg);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_update_delegate);
-
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
-
-       e_ews_connection_queue_request (
-               cnc, msg, update_delegate_response_cb,
-               pri, cancellable, simple);
-
-       g_object_unref (simple);
-}
-
-gboolean
-e_ews_connection_update_delegate_finish (EEwsConnection *cnc,
-                                         GAsyncResult *result,
-                                         GError **error)
-{
-       GSimpleAsyncResult *simple;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_update_delegate),
-               FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-
-       return !g_simple_async_result_propagate_error (simple, error);
-}
-
-gboolean
-e_ews_connection_update_delegate_sync (EEwsConnection *cnc,
-                                       gint pri,
-                                       const gchar *mail_id,
-                                       EwsDelegateDeliver deliver_to,
-                                       const GSList *delegates, /* EwsDelegateInfo * */
-                                       GCancellable *cancellable,
-                                       GError **error)
-{
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
-
-       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
-
-       closure = e_async_closure_new ();
+       e_ews_request_write_footer (request);
 
-       e_ews_connection_update_delegate (
-               cnc, pri, mail_id, deliver_to, delegates, cancellable,
-               e_async_closure_callback, closure);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       result = e_async_closure_wait (closure);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       success = e_ews_connection_update_delegate_finish (cnc, result, error);
+       success = e_ews_process_update_delegate_response (cnc, response, error);
 
-       e_async_closure_free (closure);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
        return success;
 }
 
-static void
-get_folder_permissions_response_cb (ESoapResponse *response,
-                                    GSimpleAsyncResult *simple)
+static gboolean
+e_ews_process_get_folder_permissions_response (EEwsConnection *cnc,
+                                              ESoapResponse *response,
+                                              GSList **out_permissions,
+                                              GError **error)
 {
-       EwsAsyncData *async_data;
        ESoapParameter *param;
        ESoapParameter *subparam;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       GError *local_error = NULL;
 
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
        /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
        subparam = e_soap_parameter_get_first_child (param);
@@ -9502,10 +7133,8 @@ get_folder_permissions_response_cb (ESoapResponse *response,
        while (subparam != NULL) {
                const gchar *name = (const gchar *) subparam->name;
 
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
+               if (ews_get_response_status (subparam, error))
+                       return FALSE;
 
                if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "GetFolderResponseMessage")) {
                        ESoapParameter *node;
@@ -9518,7 +7147,7 @@ get_folder_permissions_response_cb (ESoapResponse *response,
                                if (node && node->name && g_str_has_suffix ((const gchar *) node->name, 
"Folder")) {
                                        node = e_soap_parameter_get_first_child_by_name (node, 
"PermissionSet");
                                        if (node) {
-                                               async_data->items = e_ews_permissions_from_soap_param (node);
+                                               *out_permissions = e_ews_permissions_from_soap_param (node);
                                        }
                                }
                        }
@@ -9528,2450 +7157,2507 @@ get_folder_permissions_response_cb (ESoapResponse *response,
 
                subparam = e_soap_parameter_get_next_child (subparam);
        }
+
+       return TRUE;
 }
 
-void
-e_ews_connection_get_folder_permissions (EEwsConnection *cnc,
-                                         gint pri,
-                                         EwsFolderId *folder_id,
-                                         GCancellable *cancellable,
-                                         GAsyncReadyCallback callback,
-                                         gpointer user_data)
+/* free permissions with e_ews_permissions_free() */
+gboolean
+e_ews_connection_get_folder_permissions_sync (EEwsConnection *cnc,
+                                              gint pri,
+                                              EwsFolderId *folder_id,
+                                              GSList **out_permissions,
+                                              GCancellable *cancellable,
+                                              GError **error)
 {
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (folder_id != NULL);
-
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "GetFolder",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
+       ESoapRequest *request;
+       ESoapResponse *response;
+       gboolean success;
 
-       e_soap_message_start_element (msg, "FolderShape", "messages", NULL);
-       e_ews_message_write_string_parameter (msg, "BaseShape", NULL, "IdOnly");
-       e_soap_message_start_element (msg, "AdditionalProperties", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (msg, "FieldURI", NULL, NULL, "FieldURI", 
"folder:PermissionSet");
-       e_soap_message_end_element (msg); /* AdditionalProperties */
-       e_soap_message_end_element (msg); /* FolderShape */
+       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
+       g_return_val_if_fail (folder_id != NULL, FALSE);
+       g_return_val_if_fail (out_permissions != NULL, FALSE);
 
-       e_soap_message_start_element (msg, "FolderIds", "messages", NULL);
-       e_ews_folder_id_append_to_msg (msg, cnc->priv->email, folder_id);
-       e_soap_message_end_element (msg);
+       *out_permissions = NULL;
 
-       e_ews_message_write_footer (msg);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetFolder",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_get_folder_permissions);
+       if (!request)
+               return FALSE;
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       e_soap_request_start_element (request, "FolderShape", "messages", NULL);
+       e_ews_request_write_string_parameter (request, "BaseShape", NULL, "IdOnly");
+       e_soap_request_start_element (request, "AdditionalProperties", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (request, "FieldURI", NULL, NULL, "FieldURI", 
"folder:PermissionSet");
+       e_soap_request_end_element (request); /* AdditionalProperties */
+       e_soap_request_end_element (request); /* FolderShape */
 
-       e_ews_connection_queue_request (
-               cnc, msg, get_folder_permissions_response_cb,
-               pri, cancellable, simple);
+       e_soap_request_start_element (request, "FolderIds", "messages", NULL);
+       e_ews_folder_id_append_to_request (request, cnc->priv->email, folder_id);
+       e_soap_request_end_element (request);
 
-       g_object_unref (simple);
-}
+       e_ews_request_write_footer (request);
 
-/* free permissions with e_ews_permissions_free() */
-gboolean
-e_ews_connection_get_folder_permissions_finish (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **permissions,
-                                                GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (permissions != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_get_folder_permissions),
-               FALSE);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       success = e_ews_process_get_folder_permissions_response (cnc, response, out_permissions, error);
 
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       *permissions = async_data->items;
+       if (!success) {
+               e_ews_permissions_free (*out_permissions);
+               *out_permissions = NULL;
+       }
 
-       return TRUE;
+       return success;
 }
 
-/* free permissions with e_ews_permissions_free() */
 gboolean
-e_ews_connection_get_folder_permissions_sync (EEwsConnection *cnc,
+e_ews_connection_set_folder_permissions_sync (EEwsConnection *cnc,
                                               gint pri,
                                               EwsFolderId *folder_id,
-                                              GSList **permissions,
+                                              EEwsFolderType folder_type,
+                                              const GSList *permissions,
                                               GCancellable *cancellable,
                                               GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       const GSList *link;
        gboolean success;
 
        g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
        g_return_val_if_fail (folder_id != NULL, FALSE);
        g_return_val_if_fail (permissions != NULL, FALSE);
 
-       closure = e_async_closure_new ();
-
-       e_ews_connection_get_folder_permissions (
-               cnc, pri, folder_id, cancellable,
-               e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_connection_get_folder_permissions_finish (
-               cnc, result, permissions, error);
-
-       e_async_closure_free (closure);
-
-       return success;
-}
-
-void
-e_ews_connection_set_folder_permissions (EEwsConnection *cnc,
-                                         gint pri,
-                                         EwsFolderId *folder_id,
-                                         EEwsFolderType folder_type,
-                                         const GSList *permissions,
-                                         GCancellable *cancellable,
-                                         GAsyncReadyCallback callback,
-                                         gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       const GSList *iter;
-
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (folder_id != NULL);
-       g_return_if_fail (permissions != NULL);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "UpdateFolder",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "UpdateFolder",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
+       if (!request)
+               return FALSE;
 
-       e_soap_message_start_element (msg, "FolderChanges", "messages", NULL);
-       e_ews_message_start_folder_change (msg, cnc->priv->email, folder_id);
+       e_soap_request_start_element (request, "FolderChanges", "messages", NULL);
+       e_ews_request_start_folder_change (request, cnc->priv->email, folder_id);
 
-       e_soap_message_start_element (msg, "SetFolderField", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (msg, "FieldURI", NULL, NULL, "FieldURI", 
"folder:PermissionSet");
+       e_soap_request_start_element (request, "SetFolderField", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (request, "FieldURI", NULL, NULL, "FieldURI", 
"folder:PermissionSet");
 
        switch (folder_type) {
        default:
        case E_EWS_FOLDER_TYPE_MAILBOX:
-               e_soap_message_start_element (msg, "Folder", NULL, NULL);
+               e_soap_request_start_element (request, "Folder", NULL, NULL);
                break;
        case E_EWS_FOLDER_TYPE_CALENDAR:
-               e_soap_message_start_element (msg, "CalendarFolder", NULL, NULL);
+               e_soap_request_start_element (request, "CalendarFolder", NULL, NULL);
                break;
        case E_EWS_FOLDER_TYPE_CONTACTS:
-               e_soap_message_start_element (msg, "ContactsFolder", NULL, NULL);
+               e_soap_request_start_element (request, "ContactsFolder", NULL, NULL);
                break;
        case E_EWS_FOLDER_TYPE_SEARCH:
-               e_soap_message_start_element (msg, "SearchFolder", NULL, NULL);
+               e_soap_request_start_element (request, "SearchFolder", NULL, NULL);
                break;
        case E_EWS_FOLDER_TYPE_TASKS:
-               e_soap_message_start_element (msg, "TasksFolder", NULL, NULL);
+               e_soap_request_start_element (request, "TasksFolder", NULL, NULL);
                break;
        }
 
-       e_soap_message_start_element (msg, "PermissionSet", NULL, NULL);
+       e_soap_request_start_element (request, "PermissionSet", NULL, NULL);
        if (folder_type == E_EWS_FOLDER_TYPE_CALENDAR)
-               e_soap_message_start_element (msg, "CalendarPermissions", NULL, NULL);
+               e_soap_request_start_element (request, "CalendarPermissions", NULL, NULL);
        else
-               e_soap_message_start_element (msg, "Permissions", NULL, NULL);
+               e_soap_request_start_element (request, "Permissions", NULL, NULL);
 
-       for (iter = permissions; iter; iter = iter->next) {
-               EEwsPermission *perm = iter->data;
+       for (link = permissions; link; link = g_slist_next (link)) {
+               EEwsPermission *perm = link->data;
                const gchar *perm_level_name;
 
                if (!perm)
                        continue;
 
                if (folder_type == E_EWS_FOLDER_TYPE_CALENDAR)
-                       e_soap_message_start_element (msg, "CalendarPermission", NULL, NULL);
+                       e_soap_request_start_element (request, "CalendarPermission", NULL, NULL);
                else
-                       e_soap_message_start_element (msg, "Permission", NULL, NULL);
+                       e_soap_request_start_element (request, "Permission", NULL, NULL);
 
-               e_soap_message_start_element (msg, "UserId", NULL, NULL);
+               e_soap_request_start_element (request, "UserId", NULL, NULL);
 
                switch (perm->user_type) {
                case E_EWS_PERMISSION_USER_TYPE_NONE:
-                       g_return_if_reached ();
+                       g_warn_if_reached ();
                        break;
                case E_EWS_PERMISSION_USER_TYPE_ANONYMOUS:
-                       e_ews_message_write_string_parameter (msg, "DistinguishedUser", NULL, "Anonymous");
+                       e_ews_request_write_string_parameter (request, "DistinguishedUser", NULL, 
"Anonymous");
                        break;
                case E_EWS_PERMISSION_USER_TYPE_DEFAULT:
-                       e_ews_message_write_string_parameter (msg, "DistinguishedUser", NULL, "Default");
+                       e_ews_request_write_string_parameter (request, "DistinguishedUser", NULL, "Default");
                        break;
                case E_EWS_PERMISSION_USER_TYPE_REGULAR:
-                       e_ews_message_write_string_parameter (msg, "PrimarySmtpAddress", NULL, 
perm->primary_smtp);
+                       e_ews_request_write_string_parameter (request, "PrimarySmtpAddress", NULL, 
perm->primary_smtp);
                        break;
                }
 
-               e_soap_message_end_element (msg); /* UserId */
+               e_soap_request_end_element (request); /* UserId */
 
                e_ews_permission_rights_to_level_name (perm->rights);
 
                perm_level_name = e_ews_permission_rights_to_level_name (perm->rights);
 
                if (g_strcmp0 (perm_level_name, "Custom") == 0) {
-                       e_ews_message_write_string_parameter (
-                               msg, "CanCreateItems", NULL,
+                       e_ews_request_write_string_parameter (request, "CanCreateItems", NULL,
                                (perm->rights & E_EWS_PERMISSION_BIT_CREATE) != 0 ? "true" : "false");
-                       e_ews_message_write_string_parameter (
-                               msg, "CanCreateSubFolders", NULL,
+                       e_ews_request_write_string_parameter (request, "CanCreateSubFolders", NULL,
                                (perm->rights & E_EWS_PERMISSION_BIT_CREATE_SUBFOLDER) != 0 ? "true" : 
"false");
-                       e_ews_message_write_string_parameter (
-                               msg, "IsFolderOwner", NULL,
+                       e_ews_request_write_string_parameter (request, "IsFolderOwner", NULL,
                                (perm->rights & E_EWS_PERMISSION_BIT_FOLDER_OWNER) != 0 ? "true" : "false");
-                       e_ews_message_write_string_parameter (
-                               msg, "IsFolderVisible", NULL,
+                       e_ews_request_write_string_parameter (request, "IsFolderVisible", NULL,
                                (perm->rights & E_EWS_PERMISSION_BIT_FOLDER_VISIBLE) != 0 ? "true" : "false");
-                       e_ews_message_write_string_parameter (
-                               msg, "IsFolderContact", NULL,
+                       e_ews_request_write_string_parameter (request, "IsFolderContact", NULL,
                                (perm->rights & E_EWS_PERMISSION_BIT_FOLDER_CONTACT) != 0 ? "true" : "false");
-                       e_ews_message_write_string_parameter (
-                               msg, "EditItems", NULL,
+                       e_ews_request_write_string_parameter (request, "EditItems", NULL,
                                (perm->rights & E_EWS_PERMISSION_BIT_EDIT_ANY) != 0 ? "All" :
                                (perm->rights & E_EWS_PERMISSION_BIT_EDIT_OWNED) != 0 ? "Owned" : "None");
-                       e_ews_message_write_string_parameter (
-                               msg, "DeleteItems", NULL,
+                       e_ews_request_write_string_parameter (request, "DeleteItems", NULL,
                                (perm->rights & E_EWS_PERMISSION_BIT_DELETE_ANY) != 0 ? "All" :
                                (perm->rights & E_EWS_PERMISSION_BIT_DELETE_OWNED) != 0 ? "Owned" : "None");
                        if (folder_type == E_EWS_FOLDER_TYPE_CALENDAR)
-                               e_ews_message_write_string_parameter (
-                                       msg, "ReadItems", NULL,
+                               e_ews_request_write_string_parameter (request, "ReadItems", NULL,
                                        (perm->rights & E_EWS_PERMISSION_BIT_READ_ANY) != 0 ? "FullDetails" :
                                        (perm->rights & E_EWS_PERMISSION_BIT_FREE_BUSY_DETAILED) != 0 ? 
"TimeAndSubjectAndLocation" :
                                        (perm->rights & E_EWS_PERMISSION_BIT_FREE_BUSY_SIMPLE) != 0 ? 
"TimeOnly" : "None");
                        else
-                               e_ews_message_write_string_parameter (
-                                       msg, "ReadItems", NULL,
+                               e_ews_request_write_string_parameter (request, "ReadItems", NULL,
                                        (perm->rights & E_EWS_PERMISSION_BIT_READ_ANY) != 0 ? "FullDetails" : 
"None");
                }
 
-               e_ews_message_write_string_parameter (
-                       msg,
+               e_ews_request_write_string_parameter (request,
                        folder_type == E_EWS_FOLDER_TYPE_CALENDAR ? "CalendarPermissionLevel" : 
"PermissionLevel", NULL,
                        perm_level_name);
 
-               e_soap_message_end_element (msg); /* Permission/CalendarPermission */
+               e_soap_request_end_element (request); /* Permission/CalendarPermission */
+       }
+
+       e_soap_request_end_element (request); /* Permissions */
+       e_soap_request_end_element (request); /* PermissionSet */
+       e_soap_request_end_element (request); /* Folder/CalendarFolder/... */
+       e_soap_request_end_element (request); /* SetFolderField */
+
+       e_ews_request_end_item_change (request);
+
+       e_ews_request_write_footer (request);
+
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
+
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
+
+       success = e_ews_process_generic_response (cnc, response, error);
+
+       g_clear_object (&request);
+       g_clear_object (&response);
+
+       return success;
+}
+
+static gboolean
+e_ews_process_get_password_expiration_response (EEwsConnection *cnc,
+                                               ESoapResponse *response,
+                                               gchar **out_exp_date,
+                                               GError **error)
+{
+       ESoapParameter *param;
+       GError *local_error = NULL;
+
+       param = e_soap_response_get_first_parameter_by_name (response, "PasswordExpirationDate", 
&local_error);
+
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
+
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
+       }
+
+       if (out_exp_date)
+               *out_exp_date = e_soap_parameter_get_string_value (param);
+
+       return TRUE;
+}
+
+gboolean
+e_ews_connection_get_password_expiration_sync (EEwsConnection *cnc,
+                                               gint pri,
+                                               const gchar *mail_id,
+                                               gchar **out_exp_date,
+                                               GCancellable *cancellable,
+                                               GError **error)
+{
+       ESoapRequest *request;
+       ESoapResponse *response;
+       gboolean success;
+
+       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
+       g_return_val_if_fail (out_exp_date != NULL, FALSE);
+
+       *out_exp_date = NULL;
+
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetPasswordExpirationDate",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2010_SP2,
+               FALSE,
+               error);
+
+       if (!request)
+               return FALSE;
+
+       e_ews_request_write_string_parameter (request, "MailboxSmtpAddress", NULL, mail_id ? mail_id : 
cnc->priv->email);
+
+       e_ews_request_write_footer (request);
+
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
+
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
        }
 
-       e_soap_message_end_element (msg); /* Permissions */
-       e_soap_message_end_element (msg); /* PermissionSet */
-       e_soap_message_end_element (msg); /* Folder/CalendarFolder/... */
-       e_soap_message_end_element (msg); /* SetFolderField */
+       success = e_ews_process_get_password_expiration_response (cnc, response, out_exp_date, error);
+
+       g_clear_object (&request);
+       g_clear_object (&response);
+
+       if (!success)
+               g_clear_pointer (out_exp_date, g_free);
+
+       return success;
+}
+
+static gboolean
+e_ews_process_get_folder_info_response (EEwsConnection *cnc,
+                                       ESoapResponse *response,
+                                       EEwsFolder **out_folder,
+                                       GError **error)
+{
+       ESoapParameter *param;
+       ESoapParameter *subparam;
+       GError *local_error = NULL;
+
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
-       e_ews_message_end_item_change (msg);
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       e_ews_message_write_footer (msg);
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
+       }
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_set_folder_permissions);
+       subparam = e_soap_parameter_get_first_child (param);
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       while (subparam != NULL) {
+               const gchar *name = (const gchar *) subparam->name;
 
-       e_ews_connection_queue_request (
-               cnc, msg, update_folder_response_cb,
-               pri, cancellable, simple);
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
 
-       g_object_unref (simple);
-}
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "GetFolderResponseMessage")) {
+                       ESoapParameter *node;
 
-gboolean
-e_ews_connection_set_folder_permissions_finish (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GError **error)
-{
-       GSimpleAsyncResult *simple;
+                       node = e_soap_parameter_get_first_child_by_name (subparam, "Folders");
+                       if (node && out_folder)
+                               *out_folder = e_ews_folder_new_from_soap_parameter (node);
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_set_folder_permissions),
-               FALSE);
+                       break;
+               }
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
+               subparam = e_soap_parameter_get_next_child (subparam);
+       }
 
-       return !g_simple_async_result_propagate_error (simple, error);
+       return TRUE;
 }
 
 gboolean
-e_ews_connection_set_folder_permissions_sync (EEwsConnection *cnc,
-                                              gint pri,
-                                              EwsFolderId *folder_id,
-                                              EEwsFolderType folder_type,
-                                              const GSList *permissions,
-                                              GCancellable *cancellable,
-                                              GError **error)
+e_ews_connection_get_folder_info_sync (EEwsConnection *cnc,
+                                       gint pri,
+                                       const gchar *mail_id,
+                                       const EwsFolderId *folder_id,
+                                       EEwsFolder **out_folder,
+                                       GCancellable *cancellable,
+                                       GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
        gboolean success;
 
        g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
        g_return_val_if_fail (folder_id != NULL, FALSE);
-       g_return_val_if_fail (permissions != NULL, FALSE);
+       g_return_val_if_fail (out_folder != NULL, FALSE);
+
+       *out_folder = NULL;
+
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetFolder",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
+
+       if (!request)
+               return FALSE;
+
+       e_soap_request_start_element (request, "FolderShape", "messages", NULL);
+       e_ews_request_write_string_parameter (request, "BaseShape", NULL, "Default");
+       e_soap_request_start_element (request, "AdditionalProperties", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (request, "FieldURI", NULL, NULL, "FieldURI", 
"folder:FolderClass");
+       e_ews_request_write_string_parameter_with_attribute (request, "FieldURI", NULL, NULL, "FieldURI", 
"folder:ParentFolderId");
+       e_soap_request_end_element (request); /* AdditionalProperties */
+       e_soap_request_end_element (request); /* FolderShape */
+
+       e_soap_request_start_element (request, "FolderIds", "messages", NULL);
+       e_ews_folder_id_append_to_request (request, mail_id, folder_id);
+       e_soap_request_end_element (request);
+
+       e_ews_request_write_footer (request);
+
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       closure = e_async_closure_new ();
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       e_ews_connection_set_folder_permissions (
-               cnc, pri, folder_id, folder_type, permissions, cancellable,
-               e_async_closure_callback, closure);
+       success = e_ews_process_get_folder_info_response (cnc, response, out_folder, error);
 
-       result = e_async_closure_wait (closure);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       success = e_ews_connection_set_folder_permissions_finish (
-               cnc, result, error);
+       if (success && !*out_folder)
+               success = FALSE;
 
-       e_async_closure_free (closure);
+       if (!success && *out_folder)
+               g_clear_object (out_folder);
 
        return success;
 }
 
-static void
-get_password_expiration_response_cb (ESoapResponse *response,
-                                     GSimpleAsyncResult *simple)
+static gboolean
+e_ews_process_find_folder_response (EEwsConnection *cnc,
+                                   ESoapResponse *response,
+                                   gboolean *out_includes_last_item,
+                                   GSList **out_folders,
+                                   GError **error)
 {
-       EwsAsyncData *async_data;
        ESoapParameter *param;
-       gchar *exp_date;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       ESoapParameter *subparam;
+       GError *local_error = NULL;
 
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "PasswordExpirationDate", &error);
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
        /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
-       exp_date = e_soap_parameter_get_string_value (param);
-
-       async_data->items = g_slist_append (async_data->items, exp_date);
-}
+       subparam = e_soap_parameter_get_first_child (param);
 
-/**
- * e_ews_connection_get_password_expiration
- * @cnc:
- * @pri:
- * @mail_id: mail is for which password expiration is requested
- * @cb:
- * @cancellable:
- * @user_data:
- **/
-void
-e_ews_connection_get_password_expiration (EEwsConnection *cnc,
-                                          gint pri,
-                                          const gchar *mail_id,
-                                          GCancellable *cancellable,
-                                          GAsyncReadyCallback callback,
-                                          gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       while (subparam != NULL) {
+               const gchar *name = (const gchar *) subparam->name;
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "GetPasswordExpirationDate",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2010_SP2,
-                       FALSE,
-                       TRUE);
-       e_ews_message_write_string_parameter (msg, "MailboxSmtpAddress", NULL, mail_id ? mail_id : 
cnc->priv->email);
-       e_ews_message_write_footer (msg);
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_get_password_expiration);
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "FindFolderResponseMessage")) {
+                       ESoapParameter *node, *subparam1;
+                       gchar *last;
+                       EEwsFolder *folder;
+                       gboolean includes_last_item;
+
+                       node = e_soap_parameter_get_first_child_by_name (subparam, "RootFolder");
+                       last = e_soap_parameter_get_property (node, "IncludesLastItemInRange");
+                       /*
+                        * Set the includes_last_item to TRUE as default.
+                        * It can avoid an infinite loop in caller, when, for some reason,
+                        * we don't receive the last_tag property from the server.
+                        */
+                       includes_last_item = g_strcmp0 (last, "false") != 0;
+                       g_free (last);
+
+                       node = e_soap_parameter_get_first_child_by_name (node, "Folders");
+                       for (subparam1 = e_soap_parameter_get_first_child (node);
+                            subparam1 && out_folders;
+                            subparam1 = e_soap_parameter_get_next_child (subparam1)) {
+                               folder = e_ews_folder_new_from_soap_parameter (subparam1);
+                               if (folder)
+                                       continue;
+                               *out_folders = g_slist_prepend (*out_folders, folder);
+                       }
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+                       if (out_includes_last_item)
+                               *out_includes_last_item = includes_last_item;
+               }
 
-       e_ews_connection_queue_request (
-               cnc, msg, get_password_expiration_response_cb,
-               pri, cancellable, simple);
+               subparam = e_soap_parameter_get_next_child (subparam);
+       }
 
-       g_object_unref (simple);
+       return TRUE;
 }
 
 gboolean
-e_ews_connection_get_password_expiration_finish (EEwsConnection *cnc,
-                                                 GAsyncResult *result,
-                                                 gchar **exp_date,
-                                                 GError **error)
+e_ews_connection_find_folder_sync (EEwsConnection *cnc,
+                                  gint pri,
+                                  const EwsFolderId *fid,
+                                  gboolean *out_includes_last_item,
+                                  GSList **out_folders,
+                                  GCancellable *cancellable,
+                                  GError **error)
 {
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       gboolean success;
 
-       g_return_val_if_fail (exp_date != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_get_password_expiration),
-               FALSE);
+       g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (out_folders != NULL, FALSE);
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       *out_folders = NULL;
 
-       if (g_simple_async_result_propagate_error (simple, error))
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "FindFolder",
+               "Traversal",
+               "Shallow",
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
+
+       if (!request)
                return FALSE;
 
-       g_return_val_if_fail (async_data->items != NULL, FALSE);
+       e_soap_request_start_element (request, "FolderShape", "messages", NULL);
+       e_ews_request_write_string_parameter (request, "BaseShape", NULL, "Default");
+       e_soap_request_start_element (request, "AdditionalProperties", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (request, "FieldURI", NULL, NULL, "FieldURI", 
"folder:FolderClass");
+       e_ews_request_write_string_parameter_with_attribute (request, "FieldURI", NULL, NULL, "FieldURI", 
"folder:ChildFolderCount");
+       e_soap_request_end_element (request); /* AdditionalProperties */
+       e_soap_request_end_element (request);
 
-       *exp_date = async_data->items->data;
-       g_slist_free (async_data->items);
+       e_soap_request_start_element (request, "ParentFolderIds", "messages", NULL);
 
-       return TRUE;
-}
+       if (fid->is_distinguished_id)
+               e_ews_request_write_string_parameter_with_attribute (request, "DistinguishedFolderId", NULL, 
NULL, "Id", fid->id);
+       else
+               e_ews_request_write_string_parameter_with_attribute (request, "FolderId", NULL, NULL, "Id", 
fid->id);
 
-/**
- * e_ews_connection_get_password_expiration_sync
- * @cnc:
- * @pri:
- * @mail_id: mail id for which password expiration is requested
- * @cancellable:
- * @error:
- **/
-gboolean
-e_ews_connection_get_password_expiration_sync (EEwsConnection *cnc,
-                                               gint pri,
-                                               const gchar *mail_id,
-                                               gchar **exp_date,
-                                               GCancellable *cancellable,
-                                               GError **error)
-{
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
+       e_soap_request_end_element (request);
 
-       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
-       g_return_val_if_fail (exp_date != NULL, FALSE);
+       e_ews_request_write_footer (request);
 
-       closure = e_async_closure_new ();
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       e_ews_connection_get_password_expiration (
-               cnc, pri, mail_id, cancellable,
-               e_async_closure_callback, closure);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       result = e_async_closure_wait (closure);
+       success = e_ews_process_find_folder_response (cnc, response, out_includes_last_item, out_folders, 
error);
 
-       success = e_ews_connection_get_password_expiration_finish (
-               cnc, result, exp_date, error);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       e_async_closure_free (closure);
+       if (success) {
+               *out_folders = g_slist_reverse (*out_folders);
+       } else {
+               g_slist_free_full (*out_folders, g_object_unref);
+               *out_folders = NULL;
+       }
 
        return success;
 }
 
+typedef struct _AuthMethodsData {
+       GCancellable *cancellable;
+       GSList **out_auth_methods;
+} AuthMethodsData;
+
 static void
-get_folder_info_response_cb (ESoapResponse *response,
-                             GSimpleAsyncResult *simple)
+e_ews_auth_methods_got_headers_cb (SoupMessage *message,
+                                  gpointer user_data)
 {
-       EwsAsyncData *async_data;
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
+       AuthMethodsData *amd = user_data;
+       const gchar *auths_lst;
+       gboolean has_bearer = FALSE;
+       gchar **auths;
+       gint ii;
 
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       g_return_if_fail (amd != NULL);
 
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
+       auths_lst = soup_message_headers_get_list (soup_message_get_response_headers (message), 
"WWW-Authenticate");
 
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       if (auths_lst) {
+               auths = g_strsplit (auths_lst, ",", -1);
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
+               for (ii = 0; auths && auths[ii]; ii++) {
+                       gchar *auth, *space;
 
-       subparam = e_soap_parameter_get_first_child (param);
+                       auth = g_strstrip (g_strdup (auths[ii]));
 
-       while (subparam != NULL) {
-               const gchar *name = (const gchar *) subparam->name;
+                       if (auth && *auth) {
+                               space = strchr (auth, ' ');
+                               if (space)
+                                       *space = '\0';
 
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
+                               has_bearer = has_bearer || g_ascii_strcasecmp (auth, "Bearer") == 0;
+                               *(amd->out_auth_methods) = g_slist_prepend (*(amd->out_auth_methods), auth);
+                       } else {
+                               g_free (auth);
+                       }
                }
 
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "GetFolderResponseMessage")) {
-                       ESoapParameter *node;
+               g_strfreev (auths);
 
-                       node = e_soap_parameter_get_first_child_by_name (subparam, "Folders");
-                       if (node) {
-                               EEwsFolder *folder = e_ews_folder_new_from_soap_parameter (node);
+               if (!has_bearer) {
+                       /* Special-case Office365 OAuth2, because outlook.office365.com doesn't advertise 
Bearer */
+                       *(amd->out_auth_methods) = g_slist_prepend (*(amd->out_auth_methods), g_strdup 
("Bearer"));
+               }
+       }
 
-                               if (folder)
-                                       async_data->items = g_slist_prepend (NULL, folder);
-                       }
+       g_cancellable_cancel (amd->cancellable);
+}
 
-                       break;
-               }
+gboolean
+e_ews_connection_query_auth_methods_sync (EEwsConnection *cnc,
+                                         gint pri,
+                                         GSList **out_auth_methods,
+                                         GCancellable *cancellable,
+                                         GError **error)
+{
+       AuthMethodsData amd;
+       CamelEwsSettings *settings;
+       ESoapRequest *request;
+       ESoupSession *session;
+       SoupMessage *message;
+       GInputStream *stream;
+       gulong cancelled_id = 0;
+       gboolean success;
+       GError *local_error = NULL;
 
-               subparam = e_soap_parameter_get_next_child (subparam);
+       g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (out_auth_methods != NULL, FALSE);
+
+       *out_auth_methods = NULL;
+
+       /* use some simple operation to get WWW-Authenticate headers from the server */
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetFolder",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               TRUE,
+               error);
+
+       if (!request)
+               return FALSE;
+
+       e_soap_request_start_element (request, "FolderShape", "messages", NULL);
+       e_ews_request_write_string_parameter (request, "BaseShape", NULL, "IdOnly");
+       e_soap_request_end_element (request);
+
+       e_soap_request_start_element (request, "FolderIds", "messages", NULL);
+       e_ews_request_write_string_parameter_with_attribute (request, "DistinguishedFolderId", NULL, NULL, 
"Id", "inbox");
+       e_soap_request_end_element (request);
+
+       e_ews_request_write_footer (request);
+
+       session = e_ews_connection_create_soup_session (cnc);
+
+       settings = e_ews_connection_ref_settings (cnc);
+       message = e_soap_request_persist (request, session, settings, error);
+       g_clear_object (&settings);
+
+       if (!message) {
+               g_clear_object (&session);
+               g_clear_object (&request);
+               return FALSE;
+       }
+
+       amd.cancellable = g_cancellable_new ();
+       amd.out_auth_methods = out_auth_methods;
+
+       g_signal_connect (message, "got-headers",
+               G_CALLBACK (e_ews_auth_methods_got_headers_cb), &amd);
+
+       if (cancellable)
+               cancelled_id = g_cancellable_connect (cancellable, G_CALLBACK (e_ews_cancel_cancellable_cb), 
amd.cancellable, NULL);
+
+       stream = e_soup_session_send_message_sync (session, message, amd.cancellable, &local_error);
+
+       /* The request should be cancelled in the got-headers handler */
+       g_clear_object (&stream);
+
+       if (local_error && !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+               success = FALSE;
+               g_propagate_error (error, local_error);
+               g_slist_free_full (*out_auth_methods, g_free);
+               *out_auth_methods = NULL;
+       } else {
+               success = TRUE;
+               *out_auth_methods = g_slist_reverse (*out_auth_methods);
+       }
+
+       if (cancelled_id)
+               g_cancellable_disconnect (cancellable, cancelled_id);
+
+       g_clear_object (&amd.cancellable);
+       g_clear_object (&message);
+       g_clear_object (&session);
+       g_clear_object (&request);
+
+       if (success && g_cancellable_set_error_if_cancelled (cancellable, error)) {
+               g_slist_free_full (*out_auth_methods, g_free);
+               *out_auth_methods = NULL;
+               success = FALSE;
        }
+
+       return success;
 }
 
-void
-e_ews_connection_get_folder_info (EEwsConnection *cnc,
-                                  gint pri,
-                                  const gchar *mail_id,
-                                  const EwsFolderId *folder_id,
-                                  GCancellable *cancellable,
-                                  GAsyncReadyCallback callback,
-                                  gpointer user_data)
+static void
+ews_connection_build_subscribed_folders_list (gpointer key,
+                                             gpointer value,
+                                             gpointer user_data)
 {
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       GSList *folders = value, *l;
+       EEwsConnection *cnc = user_data;
 
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (folder_id != NULL);
+       for (l = folders; l != NULL; l = l->next) {
+               if (g_slist_find_custom (cnc->priv->subscribed_folders, l->data, (GCompareFunc) g_strcmp0) == 
NULL) {
+                       cnc->priv->subscribed_folders =
+                               g_slist_prepend (cnc->priv->subscribed_folders, g_strdup (l->data));
+               }
+       }
+}
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "GetFolder",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
+static void
+ews_connection_subscription_id_changed_cb (EEwsNotification *notification,
+                                          const gchar *subscription_id,
+                                          gpointer user_data)
+{
+       EEwsConnection *cnc = user_data;
+
+       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
+
+       NOTIFICATION_LOCK (cnc);
+
+       if (cnc->priv->notification == notification)
+               g_signal_emit (cnc, signals[SUBSCRIPTION_ID_CHANGED], 0, subscription_id, NULL);
 
-       e_soap_message_start_element (msg, "FolderShape", "messages", NULL);
-       e_ews_message_write_string_parameter (msg, "BaseShape", NULL, "Default");
-       e_soap_message_start_element (msg, "AdditionalProperties", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (msg, "FieldURI", NULL, NULL, "FieldURI", 
"folder:FolderClass");
-       e_ews_message_write_string_parameter_with_attribute (msg, "FieldURI", NULL, NULL, "FieldURI", 
"folder:ParentFolderId");
-       e_soap_message_end_element (msg); /* AdditionalProperties */
-       e_soap_message_end_element (msg); /* FolderShape */
+       NOTIFICATION_UNLOCK (cnc);
+}
 
-       e_soap_message_start_element (msg, "FolderIds", "messages", NULL);
-       e_ews_folder_id_append_to_msg (msg, mail_id, folder_id);
-       e_soap_message_end_element (msg);
+static gpointer
+ews_connection_notification_start_thread (gpointer user_data)
+{
+       GWeakRef *weakref = user_data;
+       EEwsConnection *cnc;
 
-       e_ews_message_write_footer (msg);
+       g_return_val_if_fail (weakref != NULL, NULL);
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_get_folder_info);
+       cnc = g_weak_ref_get (weakref);
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       if (cnc && !e_ews_connection_get_disconnected_flag (cnc)) {
+               gchar *last_subscription_id = e_ews_connection_dup_last_subscription_id (cnc);
 
-       e_ews_connection_queue_request (
-               cnc, msg, get_folder_info_response_cb,
-               pri, cancellable, simple);
+               NOTIFICATION_LOCK (cnc);
 
-       g_object_unref (simple);
-}
+               if (cnc->priv->subscribed_folders) {
+                       g_warn_if_fail (cnc->priv->notification == NULL);
+                       g_clear_object (&cnc->priv->notification);
 
-gboolean
-e_ews_connection_get_folder_info_finish (EEwsConnection *cnc,
-                                         GAsyncResult *result,
-                                         EEwsFolder **folder,
-                                         GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+                       cnc->priv->notification = e_ews_notification_new (cnc, last_subscription_id);
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (folder != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_get_folder_info),
-               FALSE);
+                       /* The 'notification' assumes ownership of the 'last_subscription_id' */
+                       last_subscription_id = NULL;
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+                       g_signal_connect_object (cnc->priv->notification, "subscription-id-changed",
+                               G_CALLBACK (ews_connection_subscription_id_changed_cb), cnc, 0);
 
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+                       e_ews_notification_start_listening_sync (cnc->priv->notification, 
cnc->priv->subscribed_folders);
+               }
 
-       if (!async_data->items)
-               return FALSE;
+               NOTIFICATION_UNLOCK (cnc);
 
-       *folder = async_data->items ? async_data->items->data : NULL;
+               g_free (last_subscription_id);
+       }
 
-       g_slist_free (async_data->items);
-       async_data->items = NULL;
+       g_clear_object (&cnc);
+       e_weak_ref_free (weakref);
 
-       return TRUE;
+       return NULL;
 }
 
-gboolean
-e_ews_connection_get_folder_info_sync (EEwsConnection *cnc,
-                                       gint pri,
-                                       const gchar *mail_id,
-                                       const EwsFolderId *folder_id,
-                                       EEwsFolder **folder,
-                                       GCancellable *cancellable,
-                                       GError **error)
+static gboolean
+ews_connection_notification_delay_cb (gpointer user_data)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
-
-       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), FALSE);
-       g_return_val_if_fail (folder_id != NULL, FALSE);
-       g_return_val_if_fail (folder != NULL, FALSE);
-
-       closure = e_async_closure_new ();
+       GWeakRef *weakref = user_data;
+       EEwsConnection *cnc;
 
-       e_ews_connection_get_folder_info (
-               cnc, pri, mail_id, folder_id, cancellable,
-               e_async_closure_callback, closure);
+       if (g_source_is_destroyed (g_main_current_source ()))
+               return FALSE;
 
-       result = e_async_closure_wait (closure);
+       g_return_val_if_fail (weakref != NULL, FALSE);
 
-       success = e_ews_connection_get_folder_info_finish (
-               cnc, result, folder, error);
+       cnc = g_weak_ref_get (weakref);
 
-       e_async_closure_free (closure);
+       if (cnc) {
+               NOTIFICATION_LOCK (cnc);
 
-       return success;
-}
+               if (cnc->priv->notification_delay_id == g_source_get_id (g_main_current_source ())) {
+                       cnc->priv->notification_delay_id = 0;
 
-static void
-ews_handle_root_folder_param_folders (ESoapParameter *subparam,
-                                     EwsAsyncData *async_data)
-{
-       ESoapParameter *node, *subparam1;
-       gchar *last, *total;
-       gint total_items;
-       EEwsFolder *folder;
-       gboolean includes_last_item;
+                       if (cnc->priv->subscribed_folders) {
+                               g_thread_unref (g_thread_new (NULL, ews_connection_notification_start_thread,
+                                       e_weak_ref_new (cnc)));
+                       }
+               }
 
-       node = e_soap_parameter_get_first_child_by_name (subparam, "RootFolder");
-       total = e_soap_parameter_get_property (node, "TotalItemsInView");
-       total_items = atoi (total);
-       g_free (total);
-       last = e_soap_parameter_get_property (node, "IncludesLastItemInRange");
-       /*
-        * Set the includes_last_item to TRUE as default.
-        * It can avoid an infinite loop in caller, when, for some reason,
-        * we don't receive the last_tag property from the server.
-        */
-       includes_last_item = g_strcmp0 (last, "false") != 0;
-       g_free (last);
+               NOTIFICATION_UNLOCK (cnc);
 
-       node = e_soap_parameter_get_first_child_by_name (node, "Folders");
-       for (subparam1 = e_soap_parameter_get_first_child (node);
-            subparam1; subparam1 = e_soap_parameter_get_next_child (subparam1)) {
-               folder = e_ews_folder_new_from_soap_parameter (subparam1);
-               if (!folder) continue;
-               async_data->items = g_slist_append (async_data->items, folder);
+               g_object_unref (cnc);
        }
-       async_data->total_items = total_items;
-       async_data->includes_last_item = includes_last_item;
+
+       return FALSE;
 }
 
-static void
-find_folder_response_cb (ESoapResponse *response,
-                        GSimpleAsyncResult *simple)
+/*
+ * Enables server notification on a folder (or a set of folders).
+ * The events we are listen for notifications are: Copied, Created, Deleted, Modified and Moved.
+ *
+ * As we have only one subscription per connection, for every enable_notifications_sync() call,
+ * we do:
+ * - Check if we already are subscribed
+ * - If we are already subscribed:
+ *  - Stop to send events regards to the already subscribed folders' list
+ *  - Unsubscribe the already subscribed folders' list
+ * - Add the user folders' lst to the hash table if subscribed folders
+ * - Create a new list of the folders to subscribe for, based in the hash table of subscribed folders
+ * - Subscribed to listen notifications for the folders
+ * - Start to send events regards to the newly subscribed folders' list
+ *
+ * Pair function for this one is e_ews_connection_disable_notifications_sync() and we do
+ * something really similar for every disable_notifications_sync() call.
+ *
+ * The notification is received to the caller with the "server-notification" signal.
+ * Note that the signal is used for each notification, without distinction on the
+ * enabled object.
+ */
+void
+e_ews_connection_enable_notifications_sync (EEwsConnection *cnc,
+                                           GSList *folders,
+                                           guint *subscription_key)
 {
-       EwsAsyncData *async_data;
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
+       GSList *new_folders = NULL, *l, *flink;
+       gint subscriptions_size;
 
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       g_return_if_fail (cnc != NULL);
+       g_return_if_fail (cnc->priv != NULL);
+       g_return_if_fail (cnc->priv->version >= E_EWS_EXCHANGE_2010_SP1);
+       g_return_if_fail (folders != NULL);
 
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
+       NOTIFICATION_LOCK (cnc);
+       subscriptions_size = g_hash_table_size (cnc->priv->subscriptions);
 
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       if (subscriptions_size == G_MAXUINT - 1)
+               goto exit;
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
+       for (flink = folders; flink; flink = g_slist_next (flink)) {
+               for (l = cnc->priv->subscribed_folders; l; l = g_slist_next (l)) {
+                       if (g_strcmp0 (l->data, flink->data) == 0)
+                               break;
+               }
 
-       subparam = e_soap_parameter_get_first_child (param);
+               if (!l)
+                       break;
+       }
 
-       while (subparam != NULL) {
-               const gchar *name = (const gchar *) subparam->name;
+       /* All requested folders are already subscribed */
+       if (!flink && cnc->priv->notification)
+               goto exit;
 
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
+       if (subscriptions_size > 0) {
+               if (cnc->priv->notification) {
+                       e_ews_notification_stop_listening_sync (cnc->priv->notification);
+                       g_clear_object (&cnc->priv->notification);
                }
 
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "FindFolderResponseMessage"))
-                       ews_handle_root_folder_param_folders (subparam, async_data);
+               g_slist_free_full (cnc->priv->subscribed_folders, g_free);
+               cnc->priv->subscribed_folders = NULL;
+       }
 
-               subparam = e_soap_parameter_get_next_child (subparam);
+       while (g_hash_table_contains (cnc->priv->subscriptions, GINT_TO_POINTER (notification_key))) {
+               notification_key++;
+               if (notification_key == 0)
+                       notification_key++;
        }
-}
 
-void
-e_ews_connection_find_folder (EEwsConnection *cnc,
-                             gint pri,
-                             const EwsFolderId *fid,
-                             GCancellable *cancellable,
-                             GAsyncReadyCallback callback,
-                             gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       for (l = folders; l != NULL; l = l->next)
+               new_folders = g_slist_prepend (new_folders, g_strdup (l->data));
 
-       g_return_if_fail (cnc != NULL);
+       g_hash_table_insert (cnc->priv->subscriptions, GINT_TO_POINTER (notification_key), new_folders);
+       new_folders = NULL;
 
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "FindFolder",
-                       "Traversal",
-                       "Shallow",
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       FALSE,
-                       TRUE);
-       e_soap_message_start_element (msg, "FolderShape", "messages", NULL);
-       e_ews_message_write_string_parameter (msg, "BaseShape", NULL, "Default");
-       e_soap_message_start_element (msg, "AdditionalProperties", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (msg, "FieldURI", NULL, NULL, "FieldURI", 
"folder:FolderClass");
-       e_ews_message_write_string_parameter_with_attribute (msg, "FieldURI", NULL, NULL, "FieldURI", 
"folder:ChildFolderCount");
-       e_soap_message_end_element (msg); /* AdditionalProperties */
-       e_soap_message_end_element (msg);
+       g_hash_table_foreach (cnc->priv->subscriptions, ews_connection_build_subscribed_folders_list, cnc);
+
+       if (cnc->priv->notification_delay_id)
+               g_source_remove (cnc->priv->notification_delay_id);
 
-       e_soap_message_start_element (msg, "ParentFolderIds", "messages", NULL);
+       cnc->priv->notification_delay_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, 5,
+               ews_connection_notification_delay_cb, e_weak_ref_new (cnc), (GDestroyNotify) e_weak_ref_free);
 
-       if (fid->is_distinguished_id)
-               e_ews_message_write_string_parameter_with_attribute (msg, "DistinguishedFolderId", NULL, 
NULL, "Id", fid->id);
-       else
-               e_ews_message_write_string_parameter_with_attribute (msg, "FolderId", NULL, NULL, "Id", 
fid->id);
+exit:
+       *subscription_key = notification_key;
+       notification_key++;
+       if (notification_key == 0)
+               notification_key++;
+
+       NOTIFICATION_UNLOCK (cnc);
+}
+
+void
+e_ews_connection_disable_notifications_sync (EEwsConnection *cnc,
+                                            guint subscription_key)
+{
+       g_return_if_fail (cnc != NULL);
+       g_return_if_fail (cnc->priv != NULL);
 
-       e_soap_message_end_element (msg);
+       NOTIFICATION_LOCK (cnc);
+       if (cnc->priv->notification == NULL)
+               goto exit;
 
-       /* Complete the footer and print the request */
-       e_ews_message_write_footer (msg);
+       if (!g_hash_table_remove (cnc->priv->subscriptions, GINT_TO_POINTER (subscription_key)))
+               goto exit;
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_find_folder);
+       e_ews_notification_stop_listening_sync (cnc->priv->notification);
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       g_slist_free_full (cnc->priv->subscribed_folders, g_free);
+       cnc->priv->subscribed_folders = NULL;
 
-       e_ews_connection_queue_request (
-               cnc, msg, find_folder_response_cb,
-               pri, cancellable, simple);
+       g_hash_table_foreach (cnc->priv->subscriptions, ews_connection_build_subscribed_folders_list, cnc);
+       if (cnc->priv->subscribed_folders != NULL && !e_ews_connection_get_disconnected_flag (cnc)) {
+               e_ews_notification_start_listening_sync (cnc->priv->notification, 
cnc->priv->subscribed_folders);
+       } else {
+               g_clear_object (&cnc->priv->notification);
+       }
 
-       g_object_unref (simple);
+exit:
+       NOTIFICATION_UNLOCK (cnc);
 }
 
-gboolean
-e_ews_connection_find_folder_finish (EEwsConnection *cnc,
-                                    GAsyncResult *result,
-                                    gboolean *includes_last_item,
-                                    GSList **folders,
-                                    GError **error)
+static EEwsCalendarTo *
+ews_get_to (ESoapParameter *node)
 {
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       EEwsCalendarTo *to = NULL;
+       ESoapParameter *param;
+       gchar *kind = NULL;
+       gchar *value = NULL;
+       gboolean success = FALSE;
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_find_folder),
-               FALSE);
+       param = e_soap_parameter_get_first_child_by_name (node, "To");
+       if (param == NULL)
+               goto exit;
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       kind = e_soap_parameter_get_property (param, "Kind");
+       if (kind == NULL)
+               goto exit;
 
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+       value = e_soap_parameter_get_string_value (param);
+       if (value == NULL)
+               goto exit;
 
-       *includes_last_item = async_data->includes_last_item;
-       *folders = async_data->items;
+       success = TRUE;
 
-       return TRUE;
+ exit:
+       if (success) {
+               to = e_ews_calendar_to_new ();
+               to->kind = kind;
+               to->value = value;
+       } else {
+               g_free (kind);
+               g_free (value);
+       }
+
+       return to;
 }
 
-gboolean
-e_ews_connection_find_folder_sync (EEwsConnection *cnc,
-                                  gint pri,
-                                  const EwsFolderId *fid,
-                                  gboolean *includes_last_item,
-                                  GSList **folders,
-                                  GCancellable *cancellable,
-                                  GError **error)
+static EEwsCalendarPeriod *
+ews_get_period (ESoapParameter *node)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-
-       closure = e_async_closure_new ();
+       EEwsCalendarPeriod *period = NULL;
+       gchar *bias = NULL;
+       gchar *name = NULL;
+       gchar *id = NULL;
 
-       e_ews_connection_find_folder (cnc, pri, fid, cancellable, e_async_closure_callback, closure);
+       bias = e_soap_parameter_get_property (node, "Bias");
+       name = e_soap_parameter_get_property (node, "Name");
+       id = e_soap_parameter_get_property (node, "Id");
 
-       result = e_async_closure_wait (closure);
+       if (bias == NULL || name == NULL || id == NULL) {
+               g_free (bias);
+               g_free (name);
+               g_free (id);
 
-       success = e_ews_connection_find_folder_finish (
-               cnc, result, includes_last_item, folders, error);
+               return NULL;
+       }
 
-       e_async_closure_free (closure);
+       period = e_ews_calendar_period_new ();
+       period->bias = bias;
+       period->name = name;
+       period->id = id;
 
-       return success;
+       return period;
 }
 
-#define EWS_OBJECT_KEY_AUTHS_GATHERED "ews-auths-gathered"
-
-static void
-query_auth_methods_response_cb (ESoapResponse *response,
-                               GSimpleAsyncResult *simple)
+static GSList * /* EEwsCalendarPeriod * */
+ews_get_periods_list (ESoapParameter *node)
 {
        ESoapParameter *param;
-       GError *error = NULL;
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
+       GSList *periods = NULL;
 
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       for (param = e_soap_parameter_get_first_child_by_name (node, "Period");
+            param != NULL;
+            param = e_soap_parameter_get_next_child_by_name (param, "Period")) {
+               EEwsCalendarPeriod *period;
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+               period = ews_get_period (param);
+               if (period != NULL) {
+                       periods = g_slist_prepend (periods, period);
+               } else {
+                       g_slist_free_full (periods, (GDestroyNotify) e_ews_calendar_period_free);
+                       return NULL;
+               }
        }
 
-       /* nothing to read, it should not get this far anyway */
+       periods = g_slist_reverse (periods);
+       return periods;
 }
 
-static void
-ews_connection_gather_auth_methods_cb (SoupMessage *message,
-                                      GSimpleAsyncResult *simple)
+static EEwsCalendarAbsoluteDateTransition *
+ews_get_absolute_date_transition (ESoapParameter *node)
 {
-       EwsAsyncData *async_data;
-       const gchar *auths_lst;
-       gboolean has_bearer = FALSE;
-       gchar **auths;
-       gint ii;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       g_return_if_fail (async_data != NULL);
+       ESoapParameter *param;
+       EEwsCalendarAbsoluteDateTransition *absolute_date_transition = NULL;
+       EEwsCalendarTo *to = NULL;
+       gchar *date_time = NULL;
+       gboolean success = FALSE;
 
-       auths_lst = soup_message_headers_get_list (message->response_headers, "WWW-Authenticate");
-       if (!auths_lst)
-               return;
+       param = e_soap_parameter_get_first_child_by_name (node, "To");
+       if (param != NULL)
+               to = ews_get_to (param);
 
-       auths = g_strsplit (auths_lst, ",", -1);
-       for (ii = 0; auths && auths[ii]; ii++) {
-               gchar *auth, *space;
+       if (to == NULL)
+               goto exit;
 
-               auth = g_strstrip (g_strdup (auths[ii]));
-               if (auth && *auth) {
-                       space = strchr (auth, ' ');
-                       if (space)
-                               *space = '\0';
+       param = e_soap_parameter_get_first_child_by_name (node, "DateTime");
+       if (param != NULL)
+               date_time = e_soap_parameter_get_string_value (param);
 
-                       has_bearer = has_bearer || g_ascii_strcasecmp (auth, "Bearer") == 0;
-                       async_data->items = g_slist_prepend (async_data->items, auth);
-               } else {
-                       g_free (auth);
-               }
-       }
+       if (date_time == NULL)
+               goto exit;
 
-       g_strfreev (auths);
+       success = TRUE;
 
-       if (!has_bearer) {
-               /* Special-case Office365 OAuth2, because outlook.office365.com doesn't advertise Bearer */
-               async_data->items = g_slist_prepend (async_data->items, g_strdup ("Bearer"));
+ exit:
+       if (success) {
+               absolute_date_transition = e_ews_calendar_absolute_date_transition_new ();
+               absolute_date_transition->to = to;
+               absolute_date_transition->date_time = date_time;
+       } else {
+               e_ews_calendar_to_free (to);
+               g_free (date_time);
        }
 
-       g_object_set_data (G_OBJECT (simple), EWS_OBJECT_KEY_AUTHS_GATHERED, GINT_TO_POINTER (1));
-
-       soup_message_set_status_full (message, SOUP_STATUS_CANCELLED, "EWS auths gathered");
+       return absolute_date_transition;
 }
 
-/* Note: This only works if the connection is not connected yet */
-void
-e_ews_connection_query_auth_methods (EEwsConnection *cnc,
-                                    gint pri,
-                                    GCancellable *cancellable,
-                                    GAsyncReadyCallback callback,
-                                    gpointer user_data)
+static EEwsCalendarRecurringDateTransition *
+ews_get_recurring_date_transition (ESoapParameter *node)
 {
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       ESoapParameter *param;
+       EEwsCalendarRecurringDateTransition *recurring_date_transition = NULL;
+       EEwsCalendarTo *to = NULL;
+       gchar *time_offset = NULL;
+       gchar *month = NULL;
+       gchar *day = NULL;
+       gboolean success = FALSE;
 
-       g_return_if_fail (cnc != NULL);
+       to = ews_get_to (node);
+       if (to == NULL)
+               goto exit;
 
-       /* use some simple operation to get WWW-Authenticate headers from the server */
-       msg = e_ews_message_new_with_header (
-                       cnc->priv->settings,
-                       cnc->priv->uri,
-                       cnc->priv->impersonate_user,
-                       "GetFolder",
-                       NULL,
-                       NULL,
-                       cnc->priv->version,
-                       E_EWS_EXCHANGE_2007_SP1,
-                       TRUE,
-                       TRUE);
+       param = e_soap_parameter_get_first_child_by_name (node, "TimeOffset");
+       if (param != NULL)
+               time_offset = e_soap_parameter_get_string_value (param);
 
-       e_soap_message_start_element (msg, "FolderShape", "messages", NULL);
-       e_ews_message_write_string_parameter (msg, "BaseShape", NULL, "IdOnly");
-       e_soap_message_end_element (msg);
+       if (time_offset == NULL)
+               goto exit;
 
-       e_soap_message_start_element (msg, "FolderIds", "messages", NULL);
-       e_ews_message_write_string_parameter_with_attribute (msg, "DistinguishedFolderId", NULL, NULL, "Id", 
"inbox");
-       e_soap_message_end_element (msg);
+       param = e_soap_parameter_get_first_child_by_name (node, "Month");
+       if (param != NULL)
+               month = e_soap_parameter_get_string_value (param);
 
-       e_ews_message_write_footer (msg);
+       if (month == NULL)
+               goto exit;
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data,
-               e_ews_connection_query_auth_methods);
+       param = e_soap_parameter_get_first_child_by_name (node, "Day");
+       if (param != NULL)
+               day = e_soap_parameter_get_string_value (param);
 
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (
-               simple, async_data, (GDestroyNotify) async_data_free);
+       if (day == NULL)
+               goto exit;
 
-       soup_message_add_header_handler (SOUP_MESSAGE (msg), "got-headers", "WWW-Authenticate",
-               G_CALLBACK (ews_connection_gather_auth_methods_cb), simple);
+       success = TRUE;
 
-       e_ews_connection_queue_request (
-               cnc, msg, query_auth_methods_response_cb,
-               pri, cancellable, simple);
+ exit:
+       if (success) {
+               recurring_date_transition = e_ews_calendar_recurring_date_transition_new ();
+               recurring_date_transition->to = to;
+               recurring_date_transition->time_offset = time_offset;
+               recurring_date_transition->month = month;
+               recurring_date_transition->day = day;
+       } else {
+               e_ews_calendar_to_free (to);
+               g_free (time_offset);
+               g_free (month);
+               g_free (day);
+       }
 
-       g_object_unref (simple);
+       return recurring_date_transition;
 }
 
-gboolean
-e_ews_connection_query_auth_methods_finish (EEwsConnection *cnc,
-                                           GAsyncResult *result,
-                                           GSList **auth_methods,
-                                           GError **error)
+static EEwsCalendarRecurringDayTransition *
+ews_get_recurring_day_transition (ESoapParameter *node)
 {
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (auth_methods != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (cnc), e_ews_connection_query_auth_methods),
-               FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (simple), EWS_OBJECT_KEY_AUTHS_GATHERED)) != 1 &&
-           g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
-
-       *auth_methods = g_slist_reverse (async_data->items);
+       ESoapParameter *param;
+       EEwsCalendarRecurringDayTransition *recurring_day_transition = NULL;
+       EEwsCalendarTo *to = NULL;
+       gchar *time_offset = NULL;
+       gchar *month = NULL;
+       gchar *day_of_week = NULL;
+       gchar *occurrence = NULL;
+       gboolean success = FALSE;
 
-       return TRUE;
-}
+       to = ews_get_to (node);
+       if (to == NULL)
+               goto exit;
 
-/* Note: This only works if the connection is not connected yet */
-gboolean
-e_ews_connection_query_auth_methods_sync (EEwsConnection *cnc,
-                                         gint pri,
-                                         GSList **auth_methods,
-                                         GCancellable *cancellable,
-                                         GError **error)
-{
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
+       param = e_soap_parameter_get_first_child_by_name (node, "TimeOffset");
+       if (param != NULL)
+               time_offset = e_soap_parameter_get_string_value (param);
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
+       if (time_offset == NULL)
+               goto exit;
 
-       closure = e_async_closure_new ();
+       param = e_soap_parameter_get_first_child_by_name (node, "Month");
+       if (param != NULL)
+               month = e_soap_parameter_get_string_value (param);
 
-       e_ews_connection_query_auth_methods (cnc, pri, cancellable, e_async_closure_callback, closure);
+       if (month == NULL)
+               goto exit;
 
-       result = e_async_closure_wait (closure);
+       param = e_soap_parameter_get_first_child_by_name (node, "DayOfWeek");
+       if (param != NULL)
+               day_of_week = e_soap_parameter_get_string_value (param);
 
-       success = e_ews_connection_query_auth_methods_finish (
-               cnc, result, auth_methods, error);
+       if (day_of_week == NULL)
+               goto exit;
 
-       e_async_closure_free (closure);
+       param = e_soap_parameter_get_first_child_by_name (node, "Occurrence");
+       if (param != NULL)
+               occurrence = e_soap_parameter_get_string_value (param);
 
-       return success;
-}
+       if (occurrence == NULL)
+               goto exit;
 
-static void
-ews_connection_build_subscribed_folders_list (gpointer key,
-                                             gpointer value,
-                                             gpointer user_data)
-{
-       GSList *folders = value, *l;
-       EEwsConnection *cnc = user_data;
+       success = TRUE;
 
-       for (l = folders; l != NULL; l = l->next) {
-               if (g_slist_find_custom (cnc->priv->subscribed_folders, l->data, (GCompareFunc) g_strcmp0) == 
NULL) {
-                       cnc->priv->subscribed_folders =
-                               g_slist_prepend (cnc->priv->subscribed_folders, g_strdup (l->data));
-               }
+ exit:
+       if (success) {
+               recurring_day_transition = e_ews_calendar_recurring_day_transition_new ();
+               recurring_day_transition->to = to;
+               recurring_day_transition->time_offset = time_offset;
+               recurring_day_transition->month = month;
+               recurring_day_transition->day_of_week = day_of_week;
+               recurring_day_transition->occurrence = occurrence;
+       } else {
+               e_ews_calendar_to_free (to);
+               g_free (time_offset);
+               g_free (month);
+               g_free (day_of_week);
+               g_free (occurrence);
        }
-}
-
-static void
-ews_connection_subscription_id_changed_cb (EEwsNotification *notification,
-                                          const gchar *subscription_id,
-                                          gpointer user_data)
-{
-       EEwsConnection *cnc = user_data;
-
-       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
-
-       NOTIFICATION_LOCK (cnc);
-
-       if (cnc->priv->notification == notification)
-               g_signal_emit (cnc, signals[SUBSCRIPTION_ID_CHANGED], 0, subscription_id, NULL);
 
-       NOTIFICATION_UNLOCK (cnc);
+       return recurring_day_transition;
 }
 
-static gpointer
-ews_connection_notification_start_thread (gpointer user_data)
+static GSList * /* EEwsCalendarAbsoluteDateTransition * */
+ews_get_absolute_date_transitions_list (ESoapParameter *node)
 {
-       GWeakRef *weakref = user_data;
-       EEwsConnection *cnc;
-
-       g_return_val_if_fail (weakref != NULL, NULL);
-
-       cnc = g_weak_ref_get (weakref);
-
-       if (cnc && !e_ews_connection_get_disconnected_flag (cnc)) {
-               gchar *last_subscription_id = e_ews_connection_dup_last_subscription_id (cnc);
-
-               NOTIFICATION_LOCK (cnc);
-
-               if (cnc->priv->subscribed_folders) {
-                       g_warn_if_fail (cnc->priv->notification == NULL);
-                       g_clear_object (&cnc->priv->notification);
-
-                       cnc->priv->notification = e_ews_notification_new (cnc, last_subscription_id);
-
-                       /* The 'notification' assumes ownership of the 'last_subscription_id' */
-                       last_subscription_id = NULL;
+       ESoapParameter *param;
+       GSList *absolute_date_transitions = NULL;
 
-                       g_signal_connect_object (cnc->priv->notification, "subscription-id-changed",
-                               G_CALLBACK (ews_connection_subscription_id_changed_cb), cnc, 0);
+       for (param = e_soap_parameter_get_first_child_by_name (node, "AbsoluteDateTransition");
+            param != NULL;
+            param = e_soap_parameter_get_next_child_by_name (param, "AbsoluteDateTransition")) {
+               EEwsCalendarAbsoluteDateTransition *absolute_date_transition;
 
-                       e_ews_notification_start_listening_sync (cnc->priv->notification, 
cnc->priv->subscribed_folders);
+               absolute_date_transition = ews_get_absolute_date_transition (param);
+               if (absolute_date_transition != NULL) {
+                       absolute_date_transitions =
+                               g_slist_prepend (absolute_date_transitions, absolute_date_transition);
+               } else {
+                       g_slist_free_full (
+                               absolute_date_transitions,
+                               (GDestroyNotify) e_ews_calendar_absolute_date_transition_free);
+                       return NULL;
                }
-
-               NOTIFICATION_UNLOCK (cnc);
-
-               g_free (last_subscription_id);
        }
 
-       g_clear_object (&cnc);
-       e_weak_ref_free (weakref);
-
-       return NULL;
+       absolute_date_transitions = g_slist_reverse (absolute_date_transitions);
+       return absolute_date_transitions;
 }
 
-static gboolean
-ews_connection_notification_delay_cb (gpointer user_data)
+static GSList * /* EEwsCalendarRecurringDayTransition * */
+ews_get_recurring_day_transitions_list (ESoapParameter *node)
 {
-       GWeakRef *weakref = user_data;
-       EEwsConnection *cnc;
-
-       if (g_source_is_destroyed (g_main_current_source ()))
-               return FALSE;
-
-       g_return_val_if_fail (weakref != NULL, FALSE);
-
-       cnc = g_weak_ref_get (weakref);
-
-       if (cnc) {
-               NOTIFICATION_LOCK (cnc);
+       ESoapParameter *param;
+       GSList *recurring_day_transitions = NULL;
 
-               if (cnc->priv->notification_delay_id == g_source_get_id (g_main_current_source ())) {
-                       cnc->priv->notification_delay_id = 0;
+       for (param = e_soap_parameter_get_first_child_by_name (node, "RecurringDayTransition");
+            param != NULL;
+            param = e_soap_parameter_get_next_child_by_name (param, "RecurringDayTransition")) {
+               EEwsCalendarRecurringDayTransition *recurring_day_transition;
 
-                       if (cnc->priv->subscribed_folders) {
-                               g_thread_unref (g_thread_new (NULL, ews_connection_notification_start_thread,
-                                       e_weak_ref_new (cnc)));
-                       }
+               recurring_day_transition = ews_get_recurring_day_transition (param);
+               if (recurring_day_transition != NULL) {
+                       recurring_day_transitions =
+                               g_slist_prepend (recurring_day_transitions, recurring_day_transition);
+               } else {
+                       g_slist_free_full (
+                               recurring_day_transitions,
+                               (GDestroyNotify) e_ews_calendar_recurring_day_transition_free);
+                       return NULL;
                }
-
-               NOTIFICATION_UNLOCK (cnc);
-
-               g_object_unref (cnc);
        }
 
-       return FALSE;
+       recurring_day_transitions = g_slist_reverse (recurring_day_transitions);
+       return recurring_day_transitions;
 }
 
-/*
- * Enables server notification on a folder (or a set of folders).
- * The events we are listen for notifications are: Copied, Created, Deleted, Modified and Moved.
- *
- * As we have only one subscription per connection, for every enable_notifications_sync() call,
- * we do:
- * - Check if we already are subscribed
- * - If we are already subscribed:
- *  - Stop to send events regards to the already subscribed folders' list
- *  - Unsubscribe the already subscribed folders' list
- * - Add the user folders' lst to the hash table if subscribed folders
- * - Create a new list of the folders to subscribe for, based in the hash table of subscribed folders
- * - Subscribed to listen notifications for the folders
- * - Start to send events regards to the newly subscribed folders' list
- *
- * Pair function for this one is e_ews_connection_disable_notifications_sync() and we do
- * something really similar for every disable_notifications_sync() call.
- *
- * The notification is received to the caller with the "server-notification" signal.
- * Note that the signal is used for each notification, without distinction on the
- * enabled object.
- */
-void
-e_ews_connection_enable_notifications_sync (EEwsConnection *cnc,
-                                           GSList *folders,
-                                           guint *subscription_key)
+static GSList * /* EEwsCalendarRecurringDateTransition * */
+ews_get_recurring_date_transitions_list (ESoapParameter *node)
 {
-       GSList *new_folders = NULL, *l, *flink;
-       gint subscriptions_size;
-
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (cnc->priv != NULL);
-       g_return_if_fail (cnc->priv->version >= E_EWS_EXCHANGE_2010_SP1);
-       g_return_if_fail (folders != NULL);
-
-       NOTIFICATION_LOCK (cnc);
-       subscriptions_size = g_hash_table_size (cnc->priv->subscriptions);
+       ESoapParameter *param;
+       GSList *recurring_date_transitions = NULL;
 
-       if (subscriptions_size == G_MAXUINT - 1)
-               goto exit;
+       for (param = e_soap_parameter_get_first_child_by_name (node, "RecurringDateTransition");
+            param != NULL;
+            param = e_soap_parameter_get_next_child_by_name (param, "RecurringDateTransition")) {
+               EEwsCalendarRecurringDateTransition *recurring_date_transition;
 
-       for (flink = folders; flink; flink = g_slist_next (flink)) {
-               for (l = cnc->priv->subscribed_folders; l; l = g_slist_next (l)) {
-                       if (g_strcmp0 (l->data, flink->data) == 0)
-                               break;
+               recurring_date_transition = ews_get_recurring_date_transition (param);
+               if (recurring_date_transition != NULL) {
+                       recurring_date_transitions =
+                               g_slist_prepend (recurring_date_transitions, recurring_date_transition);
+               } else {
+                       g_slist_free_full (
+                               recurring_date_transitions,
+                               (GDestroyNotify) e_ews_calendar_recurring_date_transition_free);
+                       return NULL;
                }
-
-               if (!l)
-                       break;
        }
 
-       /* All requested folders are already subscribed */
-       if (!flink && cnc->priv->notification)
-               goto exit;
+       recurring_date_transitions = g_slist_reverse (recurring_date_transitions);
+       return recurring_date_transitions;
+}
 
-       if (subscriptions_size > 0) {
-               if (cnc->priv->notification) {
-                       e_ews_notification_stop_listening_sync (cnc->priv->notification);
-                       g_clear_object (&cnc->priv->notification);
-               }
+static EEwsCalendarTransitionsGroup *
+ews_get_transitions_group (ESoapParameter *node)
+{
+       EEwsCalendarTransitionsGroup *tg = NULL;
+       EEwsCalendarTo *transition = NULL;
+       ESoapParameter *param = NULL;
+       gchar *id = NULL;
+       GSList *absolute_date_transitions = NULL;
+       GSList *recurring_date_transitions = NULL;
+       GSList *recurring_day_transitions = NULL;
 
-               g_slist_free_full (cnc->priv->subscribed_folders, g_free);
-               cnc->priv->subscribed_folders = NULL;
-       }
+       id = e_soap_parameter_get_property (node, "Id");
+       if (id == NULL)
+               return NULL;
 
-       while (g_hash_table_contains (cnc->priv->subscriptions, GINT_TO_POINTER (notification_key))) {
-               notification_key++;
-               if (notification_key == 0)
-                       notification_key++;
-       }
+       param = e_soap_parameter_get_first_child_by_name (node, "Transition");
+       if (param != NULL)
+               transition = ews_get_to (param);
 
-       for (l = folders; l != NULL; l = l->next)
-               new_folders = g_slist_prepend (new_folders, g_strdup (l->data));
+       absolute_date_transitions = ews_get_absolute_date_transitions_list (node);
+       recurring_date_transitions = ews_get_recurring_date_transitions_list (node);
+       recurring_day_transitions = ews_get_recurring_day_transitions_list (node);
 
-       g_hash_table_insert (cnc->priv->subscriptions, GINT_TO_POINTER (notification_key), new_folders);
-       new_folders = NULL;
+       tg = e_ews_calendar_transitions_group_new ();
+       tg->id = id;
+       tg->transition = transition;
+       tg->absolute_date_transitions = absolute_date_transitions;
+       tg->recurring_date_transitions = recurring_date_transitions;
+       tg->recurring_day_transitions = recurring_day_transitions;
 
-       g_hash_table_foreach (cnc->priv->subscriptions, ews_connection_build_subscribed_folders_list, cnc);
+       return tg;
+}
 
-       if (cnc->priv->notification_delay_id)
-               g_source_remove (cnc->priv->notification_delay_id);
+static GSList * /* EEwsCalendarTransitionsGroup * */
+ews_get_transitions_groups_list (ESoapParameter *node)
+{
+       ESoapParameter *param;
+       GSList *transitions_groups = NULL;
 
-       cnc->priv->notification_delay_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, 5,
-               ews_connection_notification_delay_cb, e_weak_ref_new (cnc), (GDestroyNotify) e_weak_ref_free);
+       for (param = e_soap_parameter_get_first_child_by_name (node, "TransitionsGroup");
+            param != NULL;
+            param = e_soap_parameter_get_next_child_by_name (param, "TransitionsGroup")) {
+               EEwsCalendarTransitionsGroup *tg;
 
-exit:
-       *subscription_key = notification_key;
-       notification_key++;
-       if (notification_key == 0)
-               notification_key++;
+               tg = ews_get_transitions_group (param);
+               if (tg != NULL) {
+                       transitions_groups = g_slist_prepend (transitions_groups, tg);
+               } else {
+                       g_slist_free_full (transitions_groups, (GDestroyNotify) 
e_ews_calendar_transitions_group_free);
+                       return NULL;
+               }
+       }
 
-       NOTIFICATION_UNLOCK (cnc);
+       transitions_groups = g_slist_reverse (transitions_groups);
+       return transitions_groups;
 }
 
-void
-e_ews_connection_disable_notifications_sync (EEwsConnection *cnc,
-                                            guint subscription_key)
+static EEwsCalendarTransitions *
+ews_get_transitions (ESoapParameter *node)
 {
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (cnc->priv != NULL);
-
-       NOTIFICATION_LOCK (cnc);
-       if (cnc->priv->notification == NULL)
-               goto exit;
+       ESoapParameter *param;
+       EEwsCalendarTransitions *transitions = NULL;
+       EEwsCalendarTo *transition = NULL;
+       GSList *absolute_date_transitions = NULL;
+       GSList *recurring_date_transitions = NULL;
+       GSList *recurring_day_transitions = NULL;
 
-       if (!g_hash_table_remove (cnc->priv->subscriptions, GINT_TO_POINTER (subscription_key)))
-               goto exit;
+       param = e_soap_parameter_get_first_child_by_name (node, "Transition");
+       if (param != NULL)
+               transition = ews_get_to (param);
 
-       e_ews_notification_stop_listening_sync (cnc->priv->notification);
+       if (transition == NULL)
+               return NULL;
 
-       g_slist_free_full (cnc->priv->subscribed_folders, g_free);
-       cnc->priv->subscribed_folders = NULL;
+       absolute_date_transitions = ews_get_absolute_date_transitions_list (node);
+       recurring_day_transitions = ews_get_recurring_day_transitions_list (node);
+       recurring_date_transitions = ews_get_recurring_date_transitions_list (node);
 
-       g_hash_table_foreach (cnc->priv->subscriptions, ews_connection_build_subscribed_folders_list, cnc);
-       if (cnc->priv->subscribed_folders != NULL && !e_ews_connection_get_disconnected_flag (cnc)) {
-               e_ews_notification_start_listening_sync (cnc->priv->notification, 
cnc->priv->subscribed_folders);
-       } else {
-               g_clear_object (&cnc->priv->notification);
-       }
+       transitions = e_ews_calendar_transitions_new ();
+       transitions->transition = transition;
+       transitions->absolute_date_transitions = absolute_date_transitions;
+       transitions->recurring_day_transitions = recurring_day_transitions;
+       transitions->recurring_date_transitions = recurring_date_transitions;
 
-exit:
-       NOTIFICATION_UNLOCK (cnc);
+       return transitions;
 }
 
-static EEwsCalendarTo *
-ews_get_to (ESoapParameter *node)
+static EEwsCalendarTimeZoneDefinition *
+ews_get_time_zone_definition (ESoapParameter *node)
 {
-       EEwsCalendarTo *to = NULL;
        ESoapParameter *param;
-       gchar *kind = NULL;
-       gchar *value = NULL;
+       gchar *name = NULL;
+       gchar *id = NULL;
+       GSList *periods = NULL;
+       GSList *transitions_groups = NULL;
+       EEwsCalendarTransitions *transitions = NULL;
+       EEwsCalendarTimeZoneDefinition *tzd = NULL;
        gboolean success = FALSE;
 
-       param = e_soap_parameter_get_first_child_by_name (node, "To");
-       if (param == NULL)
+       name = e_soap_parameter_get_property (node, "Name");
+       if (name == NULL)
+               goto exit;
+
+       id = e_soap_parameter_get_property (node, "Id");
+       if (id == NULL)
+               goto exit;
+
+       param = e_soap_parameter_get_first_child_by_name (node, "Periods");
+       if (param != NULL)
+               periods = ews_get_periods_list (param);
+       if (periods == NULL)
                goto exit;
 
-       kind = e_soap_parameter_get_property (param, "Kind");
-       if (kind == NULL)
+       param = e_soap_parameter_get_first_child_by_name (node, "TransitionsGroups");
+       if (param != NULL)
+               transitions_groups = ews_get_transitions_groups_list (param);
+       if (transitions_groups == NULL)
                goto exit;
 
-       value = e_soap_parameter_get_string_value (param);
-       if (value == NULL)
+       param = e_soap_parameter_get_first_child_by_name (node, "Transitions");
+       if (param != NULL)
+               transitions = ews_get_transitions (param);
+       if (transitions == NULL)
                goto exit;
 
        success = TRUE;
 
-exit:
+ exit:
        if (success) {
-               to = e_ews_calendar_to_new ();
-               to->kind = kind;
-               to->value = value;
+               tzd = e_ews_calendar_time_zone_definition_new ();
+               tzd->name = name;
+               tzd->id = id;
+               tzd->periods = periods;
+               tzd->transitions_groups = transitions_groups;
+               tzd->transitions = transitions;
        } else {
-               g_free (kind);
-               g_free (value);
+               g_free (name);
+               g_free (id);
+               g_slist_free_full (periods, (GDestroyNotify) e_ews_calendar_period_free);
+               g_slist_free_full (transitions_groups, (GDestroyNotify) 
e_ews_calendar_transitions_group_free);
+               e_ews_calendar_transitions_free (transitions);
        }
 
-       return to;
+       return tzd;
 }
 
-static EEwsCalendarPeriod *
-ews_get_period (ESoapParameter *node)
+static gboolean
+e_ews_process_get_server_time_zones_response (EEwsConnection *cnc,
+                                             ESoapResponse *response,
+                                             GSList **out_tzds,
+                                             GError **error)
 {
-       EEwsCalendarPeriod *period = NULL;
-       gchar *bias = NULL;
-       gchar *name = NULL;
-       gchar *id = NULL;
+       ESoapParameter *param;
+       ESoapParameter *subparam;
+       GError *local_error = NULL;
 
-       bias = e_soap_parameter_get_property (node, "Bias");
-       name = e_soap_parameter_get_property (node, "Name");
-       id = e_soap_parameter_get_property (node, "Id");
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
-       if (bias == NULL || name == NULL || id == NULL) {
-               g_free (bias);
-               g_free (name);
-               g_free (id);
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-               return NULL;
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
-       period = e_ews_calendar_period_new ();
-       period->bias = bias;
-       period->name = name;
-       period->id = id;
+       subparam = e_soap_parameter_get_first_child (param);
 
-       return period;
-}
+       while (subparam != NULL) {
+               const gchar *name = (const gchar *) subparam->name;
 
-static GSList *
-ews_get_periods_list (ESoapParameter *node)
-{
-       ESoapParameter *param;
-       GSList *periods = NULL;
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
 
-       for (param = e_soap_parameter_get_first_child_by_name (node, "Period");
-            param != NULL;
-            param = e_soap_parameter_get_next_child_by_name (param, "Period")) {
-               EEwsCalendarPeriod *period;
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "GetServerTimeZonesResponseMessage") && 
out_tzds) {
+                       ESoapParameter *node, *node2;
 
-               period = ews_get_period (param);
-               if (period != NULL) {
-                       periods = g_slist_prepend (periods, period);
-               } else {
-                       g_slist_free_full (periods, (GDestroyNotify) e_ews_calendar_period_free);
-                       return NULL;
+                       node = e_soap_parameter_get_first_child_by_name (subparam, "TimeZoneDefinitions");
+                       if (node != NULL) {
+                               node2 = e_soap_parameter_get_first_child_by_name (node, "TimeZoneDefinition");
+                               if (node2 != NULL) {
+                                       EEwsCalendarTimeZoneDefinition *tzd;
+
+                                       tzd = ews_get_time_zone_definition (node2);
+                                       if (tzd != NULL)
+                                               *out_tzds = g_slist_prepend (*out_tzds, tzd);
+                               }
+                       }
                }
+
+               subparam = e_soap_parameter_get_next_child (subparam);
        }
 
-       periods = g_slist_reverse (periods);
-       return periods;
+       if (out_tzds)
+               *out_tzds = g_slist_reverse (*out_tzds);
+
+       return TRUE;
 }
 
-static EEwsCalendarAbsoluteDateTransition *
-ews_get_absolute_date_transition (ESoapParameter *node)
+gboolean
+e_ews_connection_get_server_time_zones_sync (EEwsConnection *cnc,
+                                            gint pri,
+                                            const GSList *msdn_locations,
+                                            GSList **out_tzds, /* EEwsCalendarTimeZoneDefinition */
+                                            GCancellable *cancellable,
+                                            GError **error)
 {
-       ESoapParameter *param;
-       EEwsCalendarAbsoluteDateTransition *absolute_date_transition = NULL;
-       EEwsCalendarTo *to = NULL;
-       gchar *date_time = NULL;
-       gboolean success = FALSE;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       const GSList *link;
+       gboolean success;
 
-       param = e_soap_parameter_get_first_child_by_name (node, "To");
-       if (param != NULL)
-               to = ews_get_to (param);
+       g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (out_tzds != NULL, FALSE);
 
-       if (to == NULL)
-               goto exit;
+       *out_tzds = NULL;
 
-       param = e_soap_parameter_get_first_child_by_name (node, "DateTime");
-       if (param != NULL)
-               date_time = e_soap_parameter_get_string_value (param);
+       /*
+        * EWS server version earlier than 2010 doesn't have support to "GetServerTimeZones".
+        * So, if the API is called with an older Exchange's version, let's just "fail" silently.
+        */
+       if (!e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2010_SP1)) {
+               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("Requires at least 
Microsoft Exchange 2010 SP1 server"));
+               return FALSE;
+       }
 
-       if (date_time == NULL)
-               goto exit;
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetServerTimeZones",
+               "ReturnFullTimeZoneData",
+               "true",
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2010,
+               FALSE,
+               error);
 
-       success = TRUE;
+       if (!request)
+               return FALSE;
 
-exit:
-       if (success) {
-               absolute_date_transition = e_ews_calendar_absolute_date_transition_new ();
-               absolute_date_transition->to = to;
-               absolute_date_transition->date_time = date_time;
-       } else {
-               e_ews_calendar_to_free (to);
-               g_free (date_time);
+       e_soap_request_start_element (request, "Ids", "messages", NULL);
+       for (link = msdn_locations; link; link = g_slist_next (link)) {
+               e_ews_request_write_string_parameter_with_attribute (request, "Id", NULL, link->data, NULL, 
NULL);
        }
+       e_soap_request_end_element (request); /* Ids */
 
-       return absolute_date_transition;
-}
+       e_ews_request_write_footer (request);
 
-static EEwsCalendarRecurringDateTransition *
-ews_get_recurring_date_transition (ESoapParameter *node)
-{
-       ESoapParameter *param;
-       EEwsCalendarRecurringDateTransition *recurring_date_transition = NULL;
-       EEwsCalendarTo *to = NULL;
-       gchar *time_offset = NULL;
-       gchar *month = NULL;
-       gchar *day = NULL;
-       gboolean success = FALSE;
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       to = ews_get_to (node);
-       if (to == NULL)
-               goto exit;
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       param = e_soap_parameter_get_first_child_by_name (node, "TimeOffset");
-       if (param != NULL)
-               time_offset = e_soap_parameter_get_string_value (param);
+       success = e_ews_process_get_server_time_zones_response (cnc, response, out_tzds, error);
 
-       if (time_offset == NULL)
-               goto exit;
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       param = e_soap_parameter_get_first_child_by_name (node, "Month");
-       if (param != NULL)
-               month = e_soap_parameter_get_string_value (param);
+       if (!success) {
+               g_slist_free_full (*out_tzds, (GDestroyNotify) e_ews_calendar_time_zone_definition_free);
+               *out_tzds = NULL;
+       }
 
-       if (month == NULL)
-               goto exit;
+       if (!*out_tzds)
+               success = FALSE;
 
-       param = e_soap_parameter_get_first_child_by_name (node, "Day");
-       if (param != NULL)
-               day = e_soap_parameter_get_string_value (param);
+       return success;
+}
 
-       if (day == NULL)
-               goto exit;
+static gboolean
+e_ews_process_get_user_photo_response (EEwsConnection *cnc,
+                                      ESoapResponse *response,
+                                      gchar **out_picture_data,
+                                      GError **error)
+{
+       ESoapParameter *param;
+       GError *local_error = NULL;
 
-       success = TRUE;
+       param = e_soap_response_get_first_parameter_by_name (response, "PictureData", &local_error);
 
-exit:
-       if (success) {
-               recurring_date_transition = e_ews_calendar_recurring_date_transition_new ();
-               recurring_date_transition->to = to;
-               recurring_date_transition->time_offset = time_offset;
-               recurring_date_transition->month = month;
-               recurring_date_transition->day = day;
-       } else {
-               e_ews_calendar_to_free (to);
-               g_free (time_offset);
-               g_free (month);
-               g_free (day);
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
+
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
-       return recurring_date_transition;
+       *out_picture_data = e_soap_parameter_get_string_value (param);
+
+       if (*out_picture_data && !**out_picture_data)
+               g_clear_pointer (out_picture_data, g_free);
+
+       return TRUE;
 }
 
-static EEwsCalendarRecurringDayTransition *
-ews_get_recurring_day_transition (ESoapParameter *node)
+gboolean
+e_ews_connection_get_user_photo_sync (EEwsConnection *cnc,
+                                     gint pri,
+                                     const gchar *email,
+                                     EEwsSizeRequested size_requested,
+                                     gchar **out_picture_data, /* base64-encoded */
+                                     GCancellable *cancellable,
+                                     GError **error)
 {
-       ESoapParameter *param;
-       EEwsCalendarRecurringDayTransition *recurring_day_transition = NULL;
-       EEwsCalendarTo *to = NULL;
-       gchar *time_offset = NULL;
-       gchar *month = NULL;
-       gchar *day_of_week = NULL;
-       gchar *occurrence = NULL;
-       gboolean success = FALSE;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       gchar *tmp;
+       gboolean success;
 
-       to = ews_get_to (node);
-       if (to == NULL)
-               goto exit;
+       g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (out_picture_data != NULL, FALSE);
 
-       param = e_soap_parameter_get_first_child_by_name (node, "TimeOffset");
-       if (param != NULL)
-               time_offset = e_soap_parameter_get_string_value (param);
+       *out_picture_data = NULL;
+
+       /*
+        * EWS server version earlier than 2013 doesn't have support to "GetUserPhoto".
+        */
+       if (!e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2013)) {
+               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("Requires at least 
Microsoft Exchange 2013 server"));
+               return FALSE;
+       }
 
-       if (time_offset == NULL)
-               goto exit;
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetUserPhoto",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2013,
+               FALSE,
+               error);
 
-       param = e_soap_parameter_get_first_child_by_name (node, "Month");
-       if (param != NULL)
-               month = e_soap_parameter_get_string_value (param);
+       if (!request)
+               return FALSE;
 
-       if (month == NULL)
-               goto exit;
+       e_soap_request_start_element (request, "Email", "messages", NULL);
+       e_soap_request_write_string (request, email);
+       e_soap_request_end_element (request); /* Email */
 
-       param = e_soap_parameter_get_first_child_by_name (node, "DayOfWeek");
-       if (param != NULL)
-               day_of_week = e_soap_parameter_get_string_value (param);
+       e_soap_request_start_element (request, "SizeRequested", "messages", NULL);
+       tmp = g_strdup_printf ("HR%dx%d", (gint) size_requested, size_requested);
+       e_soap_request_write_string (request, tmp);
+       g_free (tmp);
+       e_soap_request_end_element (request); /* SizeRequested */
 
-       if (day_of_week == NULL)
-               goto exit;
+       e_ews_request_write_footer (request);
 
-       param = e_soap_parameter_get_first_child_by_name (node, "Occurrence");
-       if (param != NULL)
-               occurrence = e_soap_parameter_get_string_value (param);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       if (occurrence == NULL)
-               goto exit;
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       success = TRUE;
+       success = e_ews_process_get_user_photo_response (cnc, response, out_picture_data, error);
 
-exit:
-       if (success) {
-               recurring_day_transition = e_ews_calendar_recurring_day_transition_new ();
-               recurring_day_transition->to = to;
-               recurring_day_transition->time_offset = time_offset;
-               recurring_day_transition->month = month;
-               recurring_day_transition->day_of_week = day_of_week;
-               recurring_day_transition->occurrence = occurrence;
-       } else {
-               e_ews_calendar_to_free (to);
-               g_free (time_offset);
-               g_free (month);
-               g_free (day_of_week);
-               g_free (occurrence);
-       }
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       return recurring_day_transition;
+       if (!*out_picture_data)
+               success = FALSE;
+       else if (!success)
+               g_clear_pointer (out_picture_data, g_free);
+
+       return success;
 }
 
-static GSList *
-ews_get_absolute_date_transitions_list (ESoapParameter *node)
+static gboolean
+e_ews_process_get_user_configuration_response (EEwsConnection *cnc,
+                                              ESoapResponse *response,
+                                              gchar **out_properties,
+                                              GError **error)
 {
-       ESoapParameter *param;
-       GSList *absolute_date_transitions = NULL;
+       ESoapParameter *param, *subparam;
+       GError *local_error = NULL;
 
-       for (param = e_soap_parameter_get_first_child_by_name (node, "AbsoluteDateTransition");
-            param != NULL;
-            param = e_soap_parameter_get_next_child_by_name (param, "AbsoluteDateTransition")) {
-               EEwsCalendarAbsoluteDateTransition *absolute_date_transition;
+       *out_properties = NULL;
 
-               absolute_date_transition = ews_get_absolute_date_transition (param);
-               if (absolute_date_transition != NULL) {
-                       absolute_date_transitions =
-                               g_slist_prepend (absolute_date_transitions, absolute_date_transition);
-               } else {
-                       g_slist_free_full (
-                               absolute_date_transitions,
-                               (GDestroyNotify) e_ews_calendar_absolute_date_transition_free);
-                       return NULL;
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
+
+       if (param) {
+               param = e_soap_parameter_get_first_child_by_name (param, 
"GetUserConfigurationResponseMessage");
+               if (!param) {
+                       g_set_error (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                               "Missing <%s> in SOAP response", "GetUserConfigurationResponseMessage");
                }
        }
 
-       absolute_date_transitions = g_slist_reverse (absolute_date_transitions);
-       return absolute_date_transitions;
-}
-
-static GSList *
-ews_get_recurring_day_transitions_list (ESoapParameter *node)
-{
-       ESoapParameter *param;
-       GSList *recurring_day_transitions = NULL;
+       if (param) {
+               param = e_soap_parameter_get_first_child_by_name (param, "UserConfiguration");
+               if (!param) {
+                       g_set_error (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                               "Missing <%s> in SOAP response", "UserConfiguration");
+               }
+       }
 
-       for (param = e_soap_parameter_get_first_child_by_name (node, "RecurringDayTransition");
-            param != NULL;
-            param = e_soap_parameter_get_next_child_by_name (param, "RecurringDayTransition")) {
-               EEwsCalendarRecurringDayTransition *recurring_day_transition;
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-               recurring_day_transition = ews_get_recurring_day_transition (param);
-               if (recurring_day_transition != NULL) {
-                       recurring_day_transitions =
-                               g_slist_prepend (recurring_day_transitions, recurring_day_transition);
-               } else {
-                       g_slist_free_full (
-                               recurring_day_transitions,
-                               (GDestroyNotify) e_ews_calendar_recurring_day_transition_free);
-                       return NULL;
-               }
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
-       recurring_day_transitions = g_slist_reverse (recurring_day_transitions);
-       return recurring_day_transitions;
-}
+       subparam = e_soap_parameter_get_first_child_by_name (param, "ItemId");
+       if (subparam) {
+               gchar *id, *changekey;
 
-static GSList *
-ews_get_recurring_date_transitions_list (ESoapParameter *node)
-{
-       ESoapParameter *param;
-       GSList *recurring_date_transitions = NULL;
+               id = e_soap_parameter_get_property (subparam, "Id");
+               changekey = e_soap_parameter_get_property (subparam, "ChangeKey");
 
-       for (param = e_soap_parameter_get_first_child_by_name (node, "RecurringDateTransition");
-            param != NULL;
-            param = e_soap_parameter_get_next_child_by_name (param, "RecurringDateTransition")) {
-               EEwsCalendarRecurringDateTransition *recurring_date_transition;
+               /* Encoded as: Id + "\n" + ChangeKey */
+               *out_properties = g_strconcat (id ? id : "", "\n", changekey, NULL);
 
-               recurring_date_transition = ews_get_recurring_date_transition (param);
-               if (recurring_date_transition != NULL) {
-                       recurring_date_transitions =
-                               g_slist_prepend (recurring_date_transitions, recurring_date_transition);
-               } else {
-                       g_slist_free_full (
-                               recurring_date_transitions,
-                               (GDestroyNotify) e_ews_calendar_recurring_date_transition_free);
-                       return NULL;
+               g_free (changekey);
+               g_free (id);
+       }
+
+       if (!subparam) {
+               subparam = e_soap_parameter_get_first_child_by_name (param, "Dictionary");
+               if (subparam)
+                       *out_properties = e_soap_response_dump_parameter (response, subparam);
+       }
+
+       if (!subparam) {
+               subparam = e_soap_parameter_get_first_child_by_name (param, "XmlData");
+               if (subparam) {
+                       *out_properties = e_soap_parameter_get_string_value (subparam);
                }
        }
 
-       recurring_date_transitions = g_slist_reverse (recurring_date_transitions);
-       return recurring_date_transitions;
+       if (!subparam) {
+               subparam = e_soap_parameter_get_first_child_by_name (param, "BinaryData");
+               if (subparam) {
+                       *out_properties = e_soap_parameter_get_string_value (subparam);
+               }
+       }
+
+       if (*out_properties && !**out_properties) {
+               g_free (*out_properties);
+               *out_properties = NULL;
+       }
+
+       return *out_properties != NULL;
 }
 
-static EEwsCalendarTransitionsGroup *
-ews_get_transitions_group (ESoapParameter *node)
+gboolean
+e_ews_connection_get_user_configuration_sync (EEwsConnection *cnc,
+                                             gint pri,
+                                             const EwsFolderId *fid,
+                                             const gchar *config_name,
+                                             EEwsUserConfigurationProperties props,
+                                             gchar **out_properties,
+                                             GCancellable *cancellable,
+                                             GError **error)
 {
-       EEwsCalendarTransitionsGroup *tg = NULL;
-       EEwsCalendarTo *transition = NULL;
-       ESoapParameter *param = NULL;
-       gchar *id = NULL;
-       GSList *absolute_date_transitions = NULL;
-       GSList *recurring_date_transitions = NULL;
-       GSList *recurring_day_transitions = NULL;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       EwsFolderId local_fid;
+       gboolean success;
 
-       id = e_soap_parameter_get_property (node, "Id");
-       if (id == NULL)
-               return NULL;
+       g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (out_properties != NULL, FALSE);
 
-       param = e_soap_parameter_get_first_child_by_name (node, "Transition");
-       if (param != NULL)
-               transition = ews_get_to (param);
+       *out_properties = NULL;
 
-       absolute_date_transitions = ews_get_absolute_date_transitions_list (node);
-       recurring_date_transitions = ews_get_recurring_date_transitions_list (node);
-       recurring_day_transitions = ews_get_recurring_day_transitions_list (node);
+       /* EWS server version earlier than 2010 doesn't support it. */
+       if (!e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2010)) {
+               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("Requires at least 
Microsoft Exchange 2010 server"));
+               return FALSE;
+       }
 
-       tg = e_ews_calendar_transitions_group_new ();
-       tg->id = id;
-       tg->transition = transition;
-       tg->absolute_date_transitions = absolute_date_transitions;
-       tg->recurring_date_transitions = recurring_date_transitions;
-       tg->recurring_day_transitions = recurring_day_transitions;
+       local_fid = *fid;
+       local_fid.change_key = NULL;
 
-       return tg;
-}
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetUserConfiguration",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2010,
+               FALSE,
+               error);
 
-static GSList *
-ews_get_transitions_groups_list (ESoapParameter *node)
-{
-       ESoapParameter *param;
-       GSList *transitions_groups = NULL;
+       if (!request)
+               return FALSE;
 
-       for (param = e_soap_parameter_get_first_child_by_name (node, "TransitionsGroup");
-            param != NULL;
-            param = e_soap_parameter_get_next_child_by_name (param, "TransitionsGroup")) {
-               EEwsCalendarTransitionsGroup *tg;
+       e_soap_request_start_element (request, "UserConfigurationName", "messages", NULL);
+       e_soap_request_add_attribute (request, "Name", config_name, NULL, NULL);
 
-               tg = ews_get_transitions_group (param);
-               if (tg != NULL) {
-                       transitions_groups = g_slist_prepend (transitions_groups, tg);
-               } else {
-                       g_slist_free_full (transitions_groups, (GDestroyNotify) 
e_ews_calendar_transitions_group_free);
-                       return NULL;
-               }
-       }
+       e_ews_folder_id_append_to_request (request, cnc->priv->email, &local_fid);
 
-       transitions_groups = g_slist_reverse (transitions_groups);
-       return transitions_groups;
-}
+       e_soap_request_end_element (request); /* UserConfigurationName */
 
-static EEwsCalendarTransitions *
-ews_get_transitions (ESoapParameter *node)
-{
-       ESoapParameter *param;
-       EEwsCalendarTransitions *transitions = NULL;
-       EEwsCalendarTo *transition = NULL;
-       GSList *absolute_date_transitions = NULL;
-       GSList *recurring_date_transitions = NULL;
-       GSList *recurring_day_transitions = NULL;
+       e_soap_request_start_element (request, "UserConfigurationProperties", "messages", NULL);
+
+       switch (props) {
+       case E_EWS_USER_CONFIGURATION_PROPERTIES_ID:
+               e_soap_request_write_string (request, "Id");
+               break;
+       case E_EWS_USER_CONFIGURATION_PROPERTIES_DICTIONARY:
+               e_soap_request_write_string (request, "Dictionary");
+               break;
+       case E_EWS_USER_CONFIGURATION_PROPERTIES_XMLDATA:
+               e_soap_request_write_string (request, "XmlData");
+               break;
+       case E_EWS_USER_CONFIGURATION_PROPERTIES_BINARYDATA:
+               e_soap_request_write_string (request, "BinaryData");
+               break;
+       /* case E_EWS_USER_CONFIGURATION_PROPERTIES_ALL:
+               e_soap_request_write_string (request, "All");
+               break; */
+       default:
+               e_soap_request_write_string (request, "Unknown");
+               break;
+       }
 
-       param = e_soap_parameter_get_first_child_by_name (node, "Transition");
-       if (param != NULL)
-               transition = ews_get_to (param);
+       e_soap_request_end_element (request); /* UserConfigurationProperties */
 
-       if (transition == NULL)
-               return NULL;
+       e_ews_request_write_footer (request);
 
-       absolute_date_transitions = ews_get_absolute_date_transitions_list (node);
-       recurring_day_transitions = ews_get_recurring_day_transitions_list (node);
-       recurring_date_transitions = ews_get_recurring_date_transitions_list (node);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       transitions = e_ews_calendar_transitions_new ();
-       transitions->transition = transition;
-       transitions->absolute_date_transitions = absolute_date_transitions;
-       transitions->recurring_day_transitions = recurring_day_transitions;
-       transitions->recurring_date_transitions = recurring_date_transitions;
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       return transitions;
+       success = e_ews_process_get_user_configuration_response (cnc, response, out_properties, error);
+
+       g_clear_object (&request);
+       g_clear_object (&response);
+
+       if (!success)
+               g_clear_pointer (out_properties, g_free);
+
+       return success;
 }
 
-static EEwsCalendarTimeZoneDefinition *
-ews_get_time_zone_definition (ESoapParameter *node)
+static gboolean
+e_ews_process_convert_id_response (EEwsConnection *cnc,
+                                  ESoapResponse *response,
+                                  gchar **out_converted_id,
+                                  GError **error)
 {
        ESoapParameter *param;
-       gchar *name = NULL;
-       gchar *id = NULL;
-       GSList *periods = NULL;
-       GSList *transitions_groups = NULL;
-       EEwsCalendarTransitions *transitions = NULL;
-       EEwsCalendarTimeZoneDefinition *tzd = NULL;
-       gboolean success = FALSE;
-
-       name = e_soap_parameter_get_property (node, "Name");
-       if (name == NULL)
-               goto exit;
-
-       id = e_soap_parameter_get_property (node, "Id");
-       if (id == NULL)
-               goto exit;
+       GError *local_error = NULL;
 
-       param = e_soap_parameter_get_first_child_by_name (node, "Periods");
-       if (param != NULL)
-               periods = ews_get_periods_list (param);
-       if (periods == NULL)
-               goto exit;
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
-       param = e_soap_parameter_get_first_child_by_name (node, "TransitionsGroups");
-       if (param != NULL)
-               transitions_groups = ews_get_transitions_groups_list (param);
-       if (transitions_groups == NULL)
-               goto exit;
+       if (param) {
+               param = e_soap_parameter_get_first_child_by_name (param, "ConvertIdResponseMessage");
+               if (!param) {
+                       g_set_error (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                               "Missing <%s> in SOAP response", "ConvertIdResponseMessage");
+               }
+       }
 
-       param = e_soap_parameter_get_first_child_by_name (node, "Transitions");
-       if (param != NULL)
-               transitions = ews_get_transitions (param);
-       if (transitions == NULL)
-               goto exit;
+       if (param) {
+               param = e_soap_parameter_get_first_child_by_name (param, "AlternateId");
+               if (!param) {
+                       g_set_error (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                               "Missing <%s> in SOAP response", "AlternateId");
+               }
+       }
 
-       success = TRUE;
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-exit:
-       if (success) {
-               tzd = e_ews_calendar_time_zone_definition_new ();
-               tzd->name = name;
-               tzd->id = id;
-               tzd->periods = periods;
-               tzd->transitions_groups = transitions_groups;
-               tzd->transitions = transitions;
-       } else {
-               g_free (name);
-               g_free (id);
-               g_slist_free_full (periods, (GDestroyNotify) e_ews_calendar_period_free);
-               g_slist_free_full (transitions_groups, (GDestroyNotify) 
e_ews_calendar_transitions_group_free);
-               e_ews_calendar_transitions_free (transitions);
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
-       return tzd;
+       *out_converted_id = e_soap_parameter_get_property (param, "Id");
+
+       return TRUE;
 }
 
-static void
-get_server_time_zones_response_cb (ESoapResponse *response,
-                                  GSimpleAsyncResult *simple)
+gboolean
+e_ews_connection_convert_id_sync (EEwsConnection *cnc,
+                                 gint pri,
+                                 const gchar *email,
+                                 const gchar *folder_id,
+                                 const gchar *from_format,
+                                 const gchar *to_format,
+                                 gchar **out_converted_id,
+                                 GCancellable *cancellable,
+                                 GError **error)
 {
-       EwsAsyncData *async_data;
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       ESoapRequest *request;
+       ESoapResponse *response;
+       gboolean success;
 
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessages", &error);
+       g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (folder_id != NULL, FALSE);
+       g_return_val_if_fail (from_format != NULL, FALSE);
+       g_return_val_if_fail (to_format != NULL, FALSE);
+       g_return_val_if_fail (out_converted_id != NULL, FALSE);
 
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       *out_converted_id = NULL;
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+       /* EWS server version earlier than 2007 SP1 doesn't support it. */
+       if (!e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2007_SP1)) {
+               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("Requires at least 
Microsoft Exchange 2007 SP1 server"));
+               return FALSE;
        }
 
-       subparam = e_soap_parameter_get_first_child (param);
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "ConvertId",
+               "DestinationFormat",
+               to_format,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       while (subparam != NULL) {
-               const gchar *name = (const gchar *) subparam->name;
+       if (!request)
+               return FALSE;
 
-               if (!ews_get_response_status (subparam, &error)) {
-                       g_simple_async_result_take_error (simple, error);
-                       return;
-               }
+       e_soap_request_start_element (request, "SourceIds", "messages", NULL);
+       e_soap_request_start_element (request, "AlternateId", NULL, NULL);
 
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "GetServerTimeZonesResponseMessage")) {
-                       ESoapParameter *node, *node2;
+       e_soap_request_add_attribute (request, "Id", folder_id, NULL, NULL);
+       e_soap_request_add_attribute (request, "Format", from_format, NULL, NULL);
+       e_soap_request_add_attribute (request, "Mailbox", email, NULL, NULL);
 
-                       node = e_soap_parameter_get_first_child_by_name (subparam, "TimeZoneDefinitions");
-                       if (node != NULL) {
-                               node2 = e_soap_parameter_get_first_child_by_name (node, "TimeZoneDefinition");
-                               if (node2 != NULL) {
-                                       EEwsCalendarTimeZoneDefinition *tzd;
+       e_soap_request_end_element (request); /* AlternateId */
+       e_soap_request_end_element (request); /* SourceIds */
 
-                                       tzd = ews_get_time_zone_definition (node2);
-                                       if (tzd != NULL)
-                                               async_data->tzds = g_slist_prepend (async_data->tzds, tzd);
-                               }
-                       }
-               }
+       e_ews_request_write_footer (request);
 
-               subparam = e_soap_parameter_get_next_child (subparam);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
+
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
        }
 
-       async_data->tzds = g_slist_reverse (async_data->tzds);
+       success = e_ews_process_convert_id_response (cnc, response, out_converted_id, error);
+
+       g_clear_object (&request);
+       g_clear_object (&response);
+
+       if (!success)
+               g_clear_pointer (out_converted_id, g_free);
+
+       return success;
 }
 
-void
-e_ews_connection_get_server_time_zones (EEwsConnection *cnc,
-                                       gint pri,
-                                       GSList *msdn_locations,
-                                       GCancellable *cancellable,
-                                       GAsyncReadyCallback callback,
-                                       gpointer user_data)
+static GDateTime *
+ews_oof_settings_string_to_date_time (const gchar *string)
 {
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       GSList *l;
+       GDateTime *date_time = NULL;
 
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (cnc->priv != NULL);
+       if (string) {
+               GTimeZone *utc = g_time_zone_new_utc ();
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (cnc), callback, user_data, e_ews_connection_get_server_time_zones);
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (simple, async_data, (GDestroyNotify) async_data_free);
+               date_time = g_date_time_new_from_iso8601 (string, utc);
 
-       /*
-        * EWS server version earlier than 2010 doesn't have support to "GetServerTimeZones".
-        * So, if the API is called with an older Exchange's version, let's just fail silently.
-        */
-       if (!e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2010_SP1)) {
-               g_simple_async_result_complete_in_idle (simple);
-               g_object_unref (simple);
-               return;
+               g_time_zone_unref (utc);
        }
 
-       msg = e_ews_message_new_with_header (
-               cnc->priv->settings,
-               cnc->priv->uri,
-               cnc->priv->impersonate_user,
-               "GetServerTimeZones",
-               "ReturnFullTimeZoneData",
-               "true",
-               cnc->priv->version,
-               E_EWS_EXCHANGE_2010,
-               FALSE,
-               TRUE);
+       return date_time;
+}
+
+static gchar *
+ews_oof_settings_text_from_html (gchar *html_text)
+{
+       gsize haystack_len;
+       gchar *plain_text;
+       gchar *start, *end;
+       gchar *ii, *jj;
 
-       e_soap_message_start_element (msg, "Ids", "messages", NULL);
-       for (l = msdn_locations; l != NULL; l = l->next)
-               e_ews_message_write_string_parameter_with_attribute (msg, "Id", NULL, l->data, NULL, NULL);
-       e_soap_message_end_element (msg); /* Ids */
+       g_return_val_if_fail (html_text != NULL, NULL);
 
-       e_ews_message_write_footer (msg); /* Complete the footer and print the request */
+       haystack_len = strlen (html_text);
+       start = g_strstr_len (html_text, haystack_len, "<body");
+       end = g_strstr_len (html_text, haystack_len, "</body>");
 
-       e_ews_connection_queue_request (cnc, msg, get_server_time_zones_response_cb, pri, cancellable, 
simple);
+       /* Parse the status set by Outlook Web Access. */
+       if (g_strrstr (html_text, "BodyFragment") != NULL && start == NULL) {
+               start = html_text;
+               end = html_text + haystack_len;
+       }
+
+       /* Strip HTML tags. */
+       plain_text = jj = g_malloc (end - start);
+       for (ii = start; ii < end; ii++) {
+               if (*ii == '<') {
+                       while (*ii != '>')
+                               ii++;
+               } else {
+                       *jj++ = *ii;
+               }
+       }
+       *jj = '\0';
 
-       g_object_unref (simple);
+       return plain_text;
 }
 
-gboolean
-e_ews_connection_get_server_time_zones_finish (EEwsConnection *cnc,
-                                              GAsyncResult *result,
-                                              GSList **tzds, /*EEwsCalendarTimeZoneDefinition */
-                                              GError **error)
+static gboolean
+e_ews_process_get_user_oof_settings_response (EEwsConnection *cnc,
+                                             ESoapResponse *response,
+                                             EEwsOofSettings *oof_settings,
+                                             GError **error)
 {
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       ESoapParameter *param;
+       ESoapParameter *subparam;
+       ESoapParameter *subsubparam;
+       GDateTime *date_time;
+       gchar *string;
+       gchar *text;
+       GError *local_error = NULL;
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessage", &local_error);
+
+       /* Sanity check */
        g_return_val_if_fail (
-               g_simple_async_result_is_valid (result, G_OBJECT (cnc), 
e_ews_connection_get_server_time_zones),
-               FALSE);
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
+       }
 
-       if (g_simple_async_result_propagate_error (simple, error))
+       if (!ews_get_response_status (param, error))
                return FALSE;
 
-       if (async_data->tzds == NULL)
+       param = e_soap_response_get_first_parameter_by_name (response, "OofSettings", &local_error);
+
+       /* Sanity check */
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
+
+       if (local_error) {
+               g_propagate_error (error, local_error);
                return FALSE;
+       }
 
-       if (tzds != NULL)
-               *tzds = async_data->tzds;
+       subparam = e_soap_parameter_get_first_child_by_name (param, "OofState");
+       string = e_soap_parameter_get_string_value (subparam);
+       if (g_strcmp0 (string, "Disabled") == 0)
+               e_ews_oof_settings_set_state (oof_settings, E_EWS_OOF_STATE_DISABLED);
+       else if (g_strcmp0 (string, "Enabled") == 0)
+               e_ews_oof_settings_set_state (oof_settings, E_EWS_OOF_STATE_ENABLED);
+       else if (g_strcmp0 (string, "Scheduled") == 0)
+               e_ews_oof_settings_set_state (oof_settings, E_EWS_OOF_STATE_SCHEDULED);
+       g_free (string);
+
+       subparam = e_soap_parameter_get_first_child_by_name (param, "ExternalAudience");
+       string = e_soap_parameter_get_string_value (subparam);
+       if (g_strcmp0 (string, "None") == 0)
+               e_ews_oof_settings_set_external_audience (oof_settings, E_EWS_EXTERNAL_AUDIENCE_NONE);
+       else if (g_strcmp0 (string, "Known") == 0)
+               e_ews_oof_settings_set_external_audience (oof_settings, E_EWS_EXTERNAL_AUDIENCE_KNOWN);
+       else if (g_strcmp0 (string, "All") == 0)
+               e_ews_oof_settings_set_external_audience (oof_settings, E_EWS_EXTERNAL_AUDIENCE_ALL);
+       g_free (string);
+
+       subparam = e_soap_parameter_get_first_child_by_name (param, "Duration");
+       subsubparam = e_soap_parameter_get_first_child_by_name (subparam, "StartTime");
+       string = e_soap_parameter_get_string_value (subsubparam);
+       date_time = ews_oof_settings_string_to_date_time (string);
+       if (date_time != NULL) {
+               e_ews_oof_settings_set_start_time (oof_settings, date_time);
+               g_date_time_unref (date_time);
+       }
+       g_free (string);
+
+       subsubparam = e_soap_parameter_get_first_child_by_name (subparam, "EndTime");
+       string = e_soap_parameter_get_string_value (subsubparam);
+       date_time = ews_oof_settings_string_to_date_time (string);
+       if (date_time != NULL) {
+               e_ews_oof_settings_set_end_time (oof_settings, date_time);
+               g_date_time_unref (date_time);
+       }
+       g_free (string);
+
+       subparam = e_soap_parameter_get_first_child_by_name (param, "InternalReply");
+       subsubparam = e_soap_parameter_get_first_child_by_name (subparam, "Message");
+       string = e_soap_parameter_get_string_value (subsubparam);
+       if (string == NULL)
+               text = NULL;
+       else if (g_strrstr (string, "</body>") != NULL)
+               text = ews_oof_settings_text_from_html (string);
+       else if (g_strrstr (string, "BodyFragment") != NULL)
+               text = ews_oof_settings_text_from_html (string);
        else
-               g_slist_free_full (
-                       async_data->tzds,
-                       (GDestroyNotify) e_ews_calendar_time_zone_definition_free);
+               text = g_strdup (string);
+       e_ews_oof_settings_set_internal_reply (oof_settings, text ? text : "");
+       g_free (string);
+       g_free (text);
+
+       subparam = e_soap_parameter_get_first_child_by_name (param, "ExternalReply");
+       subsubparam = e_soap_parameter_get_first_child_by_name (subparam, "Message");
+       string = e_soap_parameter_get_string_value (subsubparam);
+       if (string == NULL)
+               text = NULL;
+       else if (g_strrstr (string, "</body>") != NULL)
+               text = ews_oof_settings_text_from_html (string);
+       else if (g_strrstr (string, "BodyFragment") != NULL)
+               text = ews_oof_settings_text_from_html (string);
+       else
+               text = g_strdup (string);
+       e_ews_oof_settings_set_external_reply (oof_settings, text ? text : "");
+       g_free (string);
+       g_free (text);
 
        return TRUE;
 }
 
 gboolean
-e_ews_connection_get_server_time_zones_sync (EEwsConnection *cnc,
+e_ews_connection_get_user_oof_settings_sync (EEwsConnection *cnc,
                                             gint pri,
-                                            GSList *msdn_locations,
-                                            GSList **tzds, /* EEwsCalendarTimeZoneDefinition */
+                                            EEwsOofSettings *inout_oof_settings,
                                             GCancellable *cancellable,
                                             GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (inout_oof_settings != NULL, FALSE);
 
-       closure = e_async_closure_new ();
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetUserOofSettingsRequest",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2007_SP1,
+               FALSE,
+               error);
 
-       e_ews_connection_get_server_time_zones (
-               cnc, pri, msdn_locations, cancellable, e_async_closure_callback, closure);
+       if (!request)
+               return FALSE;
 
-       result = e_async_closure_wait (closure);
+       e_soap_request_start_element (request, "Mailbox", NULL, NULL);
+       e_ews_request_write_string_parameter (request, "Address", NULL, e_ews_connection_get_mailbox (cnc));
+       e_soap_request_end_element (request);
 
-       success = e_ews_connection_get_server_time_zones_finish (cnc, result, tzds, error);
+       e_ews_request_write_footer (request);
 
-       e_async_closure_free (closure);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       return success;
-}
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-static void
-get_user_photo_response_cb (ESoapResponse *response,
-                           GSimpleAsyncResult *simple)
-{
-       EwsAsyncData *async_data;
-       ESoapParameter *param;
-       GError *error = NULL;
+       success = e_ews_process_get_user_oof_settings_response (cnc, response, inout_oof_settings, error);
 
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "PictureData", &error);
+       return success;
+}
 
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+static gchar *
+ews_oof_settings_date_time_to_string (const GDateTime *date_time)
+{
+       gchar *string = NULL;
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
+       if (date_time)
+               string = g_date_time_format_iso8601 ((GDateTime *) date_time);
 
-       async_data->custom_data = e_soap_parameter_get_string_value (param);
-       if (async_data->custom_data && !*async_data->custom_data) {
-               g_free (async_data->custom_data);
-               async_data->custom_data = NULL;
-       }
+       return string;
 }
 
-void
-e_ews_connection_get_user_photo (EEwsConnection *cnc,
-                                gint pri,
-                                const gchar *email,
-                                EEwsSizeRequested size_requested,
-                                GCancellable *cancellable,
-                                GAsyncReadyCallback callback,
-                                gpointer user_data)
+gboolean
+e_ews_connection_set_user_oof_settings_sync (EEwsConnection *cnc,
+                                            gint pri,
+                                            EEwsOofState state,
+                                            EEwsExternalAudience external_audience,
+                                            const GDateTime *start_date,
+                                            const GDateTime *end_date,
+                                            const gchar *internal_reply,
+                                            const gchar *external_reply,
+                                            GCancellable *cancellable,
+                                            GError **error)
 {
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       gchar *tmp;
-
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (cnc->priv != NULL);
-       g_return_if_fail (email != NULL);
-
-       simple = g_simple_async_result_new (G_OBJECT (cnc), callback, user_data, 
e_ews_connection_get_user_photo);
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (simple, async_data, (GDestroyNotify) async_data_free);
+       ESoapRequest *request;
+       ESoapResponse *response;
+       gchar *start_time;
+       gchar *end_time;
+       const gchar *string;
+       gboolean success;
 
-       /*
-        * EWS server version earlier than 2013 doesn't have support to "GetUserPhoto".
-        */
-       if (!e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2013)) {
-               g_simple_async_result_complete_in_idle (simple);
-               g_object_unref (simple);
-               return;
-       }
+       g_return_val_if_fail (cnc != NULL, FALSE);
 
-       msg = e_ews_message_new_with_header (
-               cnc->priv->settings,
+       request = e_ews_request_new_with_header (
                cnc->priv->uri,
                cnc->priv->impersonate_user,
-               "GetUserPhoto",
+               "SetUserOofSettingsRequest",
                NULL,
                NULL,
                cnc->priv->version,
-               E_EWS_EXCHANGE_2013,
+               E_EWS_EXCHANGE_2007_SP1,
                FALSE,
-               TRUE);
-
-       e_soap_message_start_element (msg, "Email", "messages", NULL);
-       e_soap_message_write_string (msg, email);
-       e_soap_message_end_element (msg); /* Email */
+               error);
 
-       e_soap_message_start_element (msg, "SizeRequested", "messages", NULL);
-       tmp = g_strdup_printf ("HR%dx%d", (gint) size_requested, size_requested);
-       e_soap_message_write_string (msg, tmp);
-       g_free (tmp);
-       e_soap_message_end_element (msg); /* SizeRequested */
+       if (!request)
+               return FALSE;
 
-       e_ews_message_write_footer (msg); /* Complete the footer and print the request */
+       e_soap_request_start_element (request, "Mailbox", NULL, NULL);
+       e_ews_request_write_string_parameter (request, "Address", NULL, e_ews_connection_get_mailbox (cnc));
+       e_soap_request_end_element (request);
 
-       e_ews_connection_queue_request (cnc, msg, get_user_photo_response_cb, pri, cancellable, simple);
+       e_soap_request_start_element (request, "UserOofSettings", NULL, NULL);
 
-       g_object_unref (simple);
-}
+       switch (state) {
+               default:
+                       g_warn_if_reached ();
+                       /* fall through */
+               case E_EWS_OOF_STATE_DISABLED:
+                       string = "Disabled";
+                       break;
+               case E_EWS_OOF_STATE_ENABLED:
+                       string = "Enabled";
+                       break;
+               case E_EWS_OOF_STATE_SCHEDULED:
+                       string = "Scheduled";
+                       break;
+       }
 
-gboolean
-e_ews_connection_get_user_photo_finish (EEwsConnection *cnc,
-                                       GAsyncResult *result,
-                                       gchar **out_picture_data, /* base64-encoded */
-                                       GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       e_ews_request_write_string_parameter (request, "OofState", NULL, string);
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (result, G_OBJECT (cnc), e_ews_connection_get_user_photo),
-               FALSE);
-       g_return_val_if_fail (out_picture_data != NULL, FALSE);
+       switch (external_audience) {
+               default:
+                       g_warn_if_reached ();
+                       /* fall through */
+               case E_EWS_EXTERNAL_AUDIENCE_NONE:
+                       string = "None";
+                       break;
+               case E_EWS_EXTERNAL_AUDIENCE_KNOWN:
+                       string = "Known";
+                       break;
+               case E_EWS_EXTERNAL_AUDIENCE_ALL:
+                       string = "All";
+                       break;
+       }
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       e_ews_request_write_string_parameter (request, "ExternalAudience", NULL, string);
 
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+       start_time = ews_oof_settings_date_time_to_string (start_date);
+       end_time = ews_oof_settings_date_time_to_string (end_date);
 
-       if (!async_data->custom_data)
-               return FALSE;
+       e_soap_request_start_element (request, "Duration", NULL, NULL);
+       e_ews_request_write_string_parameter (request, "StartTime", NULL, start_time);
+       e_ews_request_write_string_parameter (request, "EndTime", NULL, end_time);
+       e_soap_request_end_element (request);
 
-       *out_picture_data = async_data->custom_data;
-       async_data->custom_data = NULL;
+       g_free (start_time);
+       g_free (end_time);
 
-       return TRUE;
-}
+       e_soap_request_start_element (request, "InternalReply", NULL, NULL);
+       e_ews_request_write_string_parameter (request, "Message", NULL, internal_reply);
+       e_soap_request_end_element (request);
 
-gboolean
-e_ews_connection_get_user_photo_sync (EEwsConnection *cnc,
-                                     gint pri,
-                                     const gchar *email,
-                                     EEwsSizeRequested size_requested,
-                                     gchar **out_picture_data, /* base64-encoded */
-                                     GCancellable *cancellable,
-                                     GError **error)
-{
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
+       e_soap_request_start_element (request, "ExternalReply", NULL, NULL);
+       e_ews_request_write_string_parameter (request, "Message", NULL, external_reply);
+       e_soap_request_end_element (request);
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
+       e_soap_request_end_element (request); /* UserOofSettings */
 
-       closure = e_async_closure_new ();
+       e_ews_request_write_footer (request);
 
-       e_ews_connection_get_user_photo (
-               cnc, pri, email, size_requested, cancellable, e_async_closure_callback, closure);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       result = e_async_closure_wait (closure);
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
+       }
 
-       success = e_ews_connection_get_user_photo_finish (cnc, result, out_picture_data, error);
+       success = e_ews_process_generic_response (cnc, response, error);
 
-       e_async_closure_free (closure);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
        return success;
 }
 
-static void
-get_user_configuration_response_cb (ESoapResponse *response,
-                                   GSimpleAsyncResult *simple)
+static gboolean
+e_ews_process_subscribe_response (EEwsConnection *cnc,
+                                 ESoapResponse *response,
+                                 gchar **out_subscription_id,
+                                 GError **error)
 {
-       EwsAsyncData *async_data;
        ESoapParameter *param, *subparam;
-       GError *error = NULL;
-
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
-
-       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &error);
-
-       if (param) {
-               param = e_soap_parameter_get_first_child_by_name (param, 
"GetUserConfigurationResponseMessage");
-               if (!param) {
-                       g_set_error (&error,
-                               SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED,
-                               "Missing <%s> in SOAP response", "GetUserConfigurationResponseMessage");
-               }
-       }
+       GError *local_error = NULL;
 
-       if (param) {
-               param = e_soap_parameter_get_first_child_by_name (param, "UserConfiguration");
-               if (!param) {
-                       g_set_error (&error,
-                               SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED,
-                               "Missing <%s> in SOAP response", "UserConfiguration");
-               }
-       }
+       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &local_error);
 
        /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       g_return_val_if_fail (
+               (param != NULL && local_error == NULL) ||
+               (param == NULL && local_error != NULL), FALSE);
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
+       if (local_error) {
+               g_propagate_error (error, local_error);
+               return FALSE;
        }
 
-       subparam = e_soap_parameter_get_first_child_by_name (param, "ItemId");
-       if (subparam) {
-               gchar *id, *changekey;
+       subparam = e_soap_parameter_get_first_child (param);
 
-               id = e_soap_parameter_get_property (subparam, "Id");
-               changekey = e_soap_parameter_get_property (subparam, "ChangeKey");
+       while (subparam != NULL) {
+               const gchar *name = (const gchar *) subparam->name;
 
-               /* Encoded as: Id + "\n" + ChangeKey */
-               async_data->custom_data = g_strconcat (id ? id : "", "\n", changekey, NULL);
+               if (!ews_get_response_status (subparam, error))
+                       return FALSE;
 
-               g_free (changekey);
-               g_free (id);
-       }
+               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "SubscribeResponseMessage")) {
+                       ESoapParameter *node;
 
-       if (!subparam) {
-               subparam = e_soap_parameter_get_first_child_by_name (param, "Dictionary");
-               if (subparam)
-                       async_data->custom_data = e_soap_response_dump_parameter (response, subparam);
-       }
+                       node = e_soap_parameter_get_first_child_by_name (subparam, "SubscriptionId");
+                       *out_subscription_id = e_soap_parameter_get_string_value (node);
 
-       if (!subparam) {
-               subparam = e_soap_parameter_get_first_child_by_name (param, "XmlData");
-               if (subparam) {
-                       async_data->custom_data = e_soap_parameter_get_string_value (subparam);
+                       break;
                }
-       }
 
-       if (!subparam) {
-               subparam = e_soap_parameter_get_first_child_by_name (param, "BinaryData");
-               if (subparam) {
-                       async_data->custom_data = e_soap_parameter_get_string_value (subparam);
-               }
+               subparam = e_soap_parameter_get_next_child (subparam);
        }
 
-       if (async_data->custom_data && !*async_data->custom_data) {
-               g_free (async_data->custom_data);
-               async_data->custom_data = NULL;
-       }
+       return *out_subscription_id != NULL;
 }
 
-void
-e_ews_connection_get_user_configuration (EEwsConnection *cnc,
-                                        gint pri,
-                                        const EwsFolderId *fid,
-                                        const gchar *config_name,
-                                        EEwsUserConfigurationProperties props,
-                                        GCancellable *cancellable,
-                                        GAsyncReadyCallback callback,
-                                        gpointer user_data)
-{
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-       EwsFolderId local_fid;
-
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (cnc->priv != NULL);
-       g_return_if_fail (fid != NULL);
-       g_return_if_fail (config_name != NULL);
-
-       simple = g_simple_async_result_new (G_OBJECT (cnc), callback, user_data, 
e_ews_connection_get_user_configuration);
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (simple, async_data, (GDestroyNotify) async_data_free);
+gboolean
+e_ews_connection_subscribe_sync (EEwsConnection *cnc,
+                                gint pri,
+                                const GSList *folder_ids, /* gchar * */
+                                gchar **out_subscription_id,
+                                GCancellable *cancellable,
+                                GError **error)
+{
+       ESoapRequest *request;
+       ESoapResponse *response;
+       const GSList *link;
+       const gchar * const *event_names;
+       gint event_type;
+       gboolean success;
 
-       /* EWS server version earlier than 2010 doesn't support it. */
-       if (!e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2010)) {
-               g_simple_async_result_complete_in_idle (simple);
-               g_object_unref (simple);
-               return;
-       }
+       g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (out_subscription_id != NULL, FALSE);
 
-       local_fid = *fid;
-       local_fid.change_key = NULL;
+       *out_subscription_id = NULL;
 
-       msg = e_ews_message_new_with_header (
-               cnc->priv->settings,
+       request = e_ews_request_new_with_header (
                cnc->priv->uri,
                cnc->priv->impersonate_user,
-               "GetUserConfiguration",
+               "Subscribe",
                NULL,
                NULL,
                cnc->priv->version,
-               E_EWS_EXCHANGE_2010,
+               E_EWS_EXCHANGE_2010_SP1,
                FALSE,
-               TRUE);
-
-       e_soap_message_start_element (msg, "UserConfigurationName", "messages", NULL);
-       e_soap_message_add_attribute (msg, "Name", config_name, NULL, NULL);
-
-       e_ews_folder_id_append_to_msg (msg, cnc->priv->email, &local_fid);
+               error);
 
-       e_soap_message_end_element (msg); /* UserConfigurationName */
+       if (!request)
+               return FALSE;
 
-       e_soap_message_start_element (msg, "UserConfigurationProperties", "messages", NULL);
+       e_soap_request_start_element (request, "StreamingSubscriptionRequest", "messages", NULL);
 
-       switch (props) {
-       case E_EWS_USER_CONFIGURATION_PROPERTIES_ID:
-               e_soap_message_write_string (msg, "Id");
-               break;
-       case E_EWS_USER_CONFIGURATION_PROPERTIES_DICTIONARY:
-               e_soap_message_write_string (msg, "Dictionary");
-               break;
-       case E_EWS_USER_CONFIGURATION_PROPERTIES_XMLDATA:
-               e_soap_message_write_string (msg, "XmlData");
-               break;
-       case E_EWS_USER_CONFIGURATION_PROPERTIES_BINARYDATA:
-               e_soap_message_write_string (msg, "BinaryData");
-               break;
-       /* case E_EWS_USER_CONFIGURATION_PROPERTIES_ALL:
-               e_soap_message_write_string (msg, "All");
-               break; */
-       default:
-               e_soap_message_write_string (msg, "Unknown");
-               break;
+       e_soap_request_start_element (request, "FolderIds", NULL, NULL);
+       for (link = folder_ids; link; link = g_slist_next (link)) {
+               e_ews_request_write_string_parameter_with_attribute (request, "FolderId", NULL, NULL, "Id", 
link->data);
        }
+       e_soap_request_end_element (request); /* FolderIds */
 
-       e_soap_message_end_element (msg); /* UserConfigurationProperties */
-
-       e_ews_message_write_footer (msg);
+       event_names = e_ews_notification_get_event_names ();
 
-       e_ews_connection_queue_request (cnc, msg, get_user_configuration_response_cb, pri, cancellable, 
simple);
+       e_soap_request_start_element (request, "EventTypes", NULL, NULL);
+       for (event_type = 0; event_names[event_type] != NULL; event_type++) {
+               if (g_strcmp0 (event_names[event_type], "StatusEvent") == 0)
+                       continue;
 
-       g_object_unref (simple);
-}
+               e_ews_request_write_string_parameter_with_attribute (request, "EventType", NULL, 
event_names[event_type], NULL, NULL);
+       }
+       e_soap_request_end_element (request); /* EventTypes */
 
-gboolean
-e_ews_connection_get_user_configuration_finish (EEwsConnection *cnc,
-                                               GAsyncResult *result,
-                                               gchar **out_properties,
-                                               GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       e_soap_request_end_element (request); /* StreamingSubscriptionRequest */
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (result, G_OBJECT (cnc), 
e_ews_connection_get_user_configuration),
-               FALSE);
-       g_return_val_if_fail (out_properties != NULL, FALSE);
+       e_ews_request_write_footer (request);
 
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       if (g_simple_async_result_propagate_error (simple, error))
+       if (!response) {
+               g_clear_object (&request);
                return FALSE;
+       }
 
-       if (!async_data->custom_data)
-               return FALSE;
+       success = e_ews_process_subscribe_response (cnc, response, out_subscription_id, error);
 
-       *out_properties = async_data->custom_data;
-       async_data->custom_data = NULL;
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       return TRUE;
+       return success;
 }
 
 gboolean
-e_ews_connection_get_user_configuration_sync (EEwsConnection *cnc,
-                                             gint pri,
-                                             const EwsFolderId *fid,
-                                             const gchar *config_name,
-                                             EEwsUserConfigurationProperties props,
-                                             gchar **out_properties,
-                                             GCancellable *cancellable,
-                                             GError **error)
+e_ews_connection_unsubscribe_sync (EEwsConnection *cnc,
+                                  gint pri,
+                                  const gchar *subscription_id,
+                                  GCancellable *cancellable,
+                                  GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       ESoapRequest *request;
+       ESoapResponse *response;
        gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
+       g_return_val_if_fail (subscription_id != NULL, FALSE);
 
-       closure = e_async_closure_new ();
-
-       e_ews_connection_get_user_configuration (
-               cnc, pri, fid, config_name, props, cancellable, e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_connection_get_user_configuration_finish (cnc, result, out_properties, error);
-
-       e_async_closure_free (closure);
-
-       return success;
-}
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "Unsubscribe",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2010_SP1,
+               FALSE,
+               error);
 
-static void
-convert_id_response_cb (ESoapResponse *response,
-                       GSimpleAsyncResult *simple)
-{
-       EwsAsyncData *async_data;
-       ESoapParameter *param;
-       GError *error = NULL;
+       if (!request)
+               return FALSE;
 
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       e_ews_request_write_string_parameter_with_attribute (request, "SubscriptionId", "messages", 
subscription_id, NULL, NULL);
 
-       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &error);
+       e_ews_request_write_footer (request);
 
-       if (param) {
-               param = e_soap_parameter_get_first_child_by_name (param, "ConvertIdResponseMessage");
-               if (!param) {
-                       g_set_error (&error,
-                               SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED,
-                               "Missing <%s> in SOAP response", "ConvertIdResponseMessage");
-               }
-       }
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
-       if (param) {
-               param = e_soap_parameter_get_first_child_by_name (param, "AlternateId");
-               if (!param) {
-                       g_set_error (&error,
-                               SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED,
-                               "Missing <%s> in SOAP response", "AlternateId");
-               }
+       if (!response) {
+               g_clear_object (&request);
+               return FALSE;
        }
 
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
+       success = e_ews_process_generic_response (cnc, response, error);
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       async_data->custom_data = e_soap_parameter_get_property (param, "Id");
+       return success;
 }
 
-void
-e_ews_connection_convert_id (EEwsConnection *cnc,
-                            gint pri,
-                            const gchar *email,
-                            const gchar *folder_id,
-                            const gchar *from_format,
-                            const gchar *to_format,
-                            GCancellable *cancellable,
-                            GAsyncReadyCallback callback,
-                            gpointer user_data)
+static void
+e_ews_get_streaming_events_custom_process (ESoapRequest *request,
+                                          SoupMessage *message,
+                                          GInputStream *input_stream,
+                                          gpointer user_data,
+                                          gboolean *out_repeat,
+                                          GCancellable *cancellable,
+                                          GError **error)
 {
-       ESoapMessage *msg;
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
-
-       g_return_if_fail (cnc != NULL);
-       g_return_if_fail (cnc->priv != NULL);
-       g_return_if_fail (email != NULL);
-       g_return_if_fail (folder_id != NULL);
-       g_return_if_fail (from_format != NULL);
-       g_return_if_fail (to_format != NULL);
-
-       simple = g_simple_async_result_new (G_OBJECT (cnc), callback, user_data, e_ews_connection_convert_id);
-       async_data = g_slice_new0 (EwsAsyncData);
-       g_simple_async_result_set_op_res_gpointer (simple, async_data, (GDestroyNotify) async_data_free);
-
-       /* EWS server version earlier than 2007 SP1 doesn't support it. */
-       if (!e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2007_SP1)) {
-               g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR, "%s", _("Requires at least 
Microsoft Exchange 2007 SP1 server"));
-               g_simple_async_result_complete_in_idle (simple);
-               g_object_unref (simple);
-               return;
-       }
-
-       msg = e_ews_message_new_with_header (
-               cnc->priv->settings,
-               cnc->priv->uri,
-               cnc->priv->impersonate_user,
-               "ConvertId",
-               "DestinationFormat",
-               to_format,
-               cnc->priv->version,
-               E_EWS_EXCHANGE_2007_SP1,
-               FALSE,
-               TRUE);
+       GInputStream **out_input_stream = user_data;
 
-       e_soap_message_start_element (msg, "SourceIds", "messages", NULL);
-       e_soap_message_start_element (msg, "AlternateId", NULL, NULL);
-
-       e_soap_message_add_attribute (msg, "Id", folder_id, NULL, NULL);
-       e_soap_message_add_attribute (msg, "Format", from_format, NULL, NULL);
-       e_soap_message_add_attribute (msg, "Mailbox", email, NULL, NULL);
-
-       e_soap_message_end_element (msg); /* AlternateId */
-       e_soap_message_end_element (msg); /* SourceIds */
-
-       e_ews_message_write_footer (msg);
-
-       e_ews_connection_queue_request (cnc, msg, convert_id_response_cb, pri, cancellable, simple);
-
-       g_object_unref (simple);
+       if (out_input_stream && input_stream)
+               *out_input_stream = g_object_ref (input_stream);
 }
 
 gboolean
-e_ews_connection_convert_id_finish (EEwsConnection *cnc,
-                                   GAsyncResult *result,
-                                   gchar **out_converted_id,
-                                   GError **error)
+e_ews_connection_get_streaming_events_sync (EEwsConnection *cnc,
+                                           gint pri,
+                                           const gchar *subscription_id,
+                                           GInputStream **out_input_stream,
+                                           GCancellable *cancellable,
+                                           GError **error)
 {
-       GSimpleAsyncResult *simple;
-       EwsAsyncData *async_data;
+       ESoapRequest *request;
+       ESoapResponse *response;
+       GInputStream *input_stream = NULL;
+       gboolean success;
 
        g_return_val_if_fail (cnc != NULL, FALSE);
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (result, G_OBJECT (cnc), e_ews_connection_convert_id),
-               FALSE);
-       g_return_val_if_fail (out_converted_id != NULL, FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       async_data = g_simple_async_result_get_op_res_gpointer (simple);
+       g_return_val_if_fail (subscription_id != NULL, FALSE);
 
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+       request = e_ews_request_new_with_header (
+               cnc->priv->uri,
+               cnc->priv->impersonate_user,
+               "GetStreamingEvents",
+               NULL,
+               NULL,
+               cnc->priv->version,
+               E_EWS_EXCHANGE_2010_SP1,
+               FALSE,
+               error);
 
-       if (!async_data->custom_data)
+       if (!request)
                return FALSE;
 
-       *out_converted_id = async_data->custom_data;
-       async_data->custom_data = NULL;
-
-       return TRUE;
-}
+       e_soap_request_start_element (request, "SubscriptionIds", "messages", NULL);
+       e_ews_request_write_string_parameter_with_attribute (request, "SubscriptionId", NULL, 
subscription_id, NULL, NULL);
+       e_soap_request_end_element (request);
 
-gboolean
-e_ews_connection_convert_id_sync (EEwsConnection *cnc,
-                                 gint pri,
-                                 const gchar *email,
-                                 const gchar *folder_id,
-                                 const gchar *from_format,
-                                 const gchar *to_format,
-                                 gchar **out_converted_id,
-                                 GCancellable *cancellable,
-                                 GError **error)
-{
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
+       e_ews_request_write_string_parameter_with_attribute (request, "ConnectionTimeout", "messages", "10", 
NULL, NULL);
 
-       g_return_val_if_fail (cnc != NULL, FALSE);
+       e_ews_request_write_footer (request);
 
-       closure = e_async_closure_new ();
+       e_soap_request_set_custom_process_fn (request, e_ews_get_streaming_events_custom_process, 
&input_stream);
 
-       e_ews_connection_convert_id (
-               cnc, pri, email, folder_id, from_format, to_format, cancellable, e_async_closure_callback, 
closure);
+       response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
+       g_warn_if_fail (response == NULL);
 
-       result = e_async_closure_wait (closure);
+       g_clear_object (&request);
+       g_clear_object (&response);
 
-       success = e_ews_connection_convert_id_finish (cnc, result, out_converted_id, error);
+       success = input_stream != NULL;
 
-       e_async_closure_free (closure);
+       if (success && out_input_stream)
+               *out_input_stream = input_stream;
+       else
+               g_clear_object (&input_stream);
 
        return success;
 }
diff --git a/src/EWS/common/e-ews-connection.h b/src/EWS/common/e-ews-connection.h
index 3e2b2785..b55fbeb1 100644
--- a/src/EWS/common/e-ews-connection.h
+++ b/src/EWS/common/e-ews-connection.h
@@ -15,10 +15,12 @@
 #include <libedataserver/libedataserver.h>
 #include <libebackend/libebackend.h>
 
-#include "e-soap-message.h"
+#include "e-soap-request.h"
+#include "e-soap-response.h"
 #include "ews-errors.h"
 #include "e-ews-folder.h"
 #include "e-ews-item.h"
+#include "e-ews-oof-settings.h"
 #include "camel-ews-settings.h"
 
 /* Standard GObject macros */
@@ -65,11 +67,9 @@ enum {
        EWS_PRIORITY_HIGH
 };
 
-typedef gboolean(*EEwsRequestCreationCallback) (ESoapMessage *msg,
+typedef gboolean(*EEwsRequestCreationCallback) (ESoapRequest *request,
                                                 gpointer user_data,
                                                 GError **error);
-typedef void   (*EwsProgressFn)                (gpointer object,
-                                                gint percent);
 typedef void   (*EEwsResponseCallback)         (ESoapResponse *response,
                                                 GSimpleAsyncResult *simple);
 
@@ -425,11 +425,6 @@ gboolean   e_ews_connection_get_ssl_error_details
                                                 gchar **out_certificate_pem,
                                                 GTlsCertificateFlags *out_certificate_errors);
 const gchar *  e_ews_connection_get_uri        (EEwsConnection *cnc);
-ESoupAuthBearer *
-               e_ews_connection_ref_bearer_auth(EEwsConnection *cnc);
-void           e_ews_connection_set_bearer_auth(EEwsConnection *cnc,
-                                                ESoupAuthBearer *bearer_auth);
-const gchar *  e_ews_connection_get_password   (EEwsConnection *cnc);
 gchar *                e_ews_connection_dup_password   (EEwsConnection *cnc);
 void           e_ews_connection_set_password   (EEwsConnection *cnc,
                                                 const gchar *password);
@@ -443,8 +438,6 @@ void                e_ews_connection_set_proxy_resolver
                                                 GProxyResolver *proxy_resolver);
 CamelEwsSettings *
                e_ews_connection_ref_settings   (EEwsConnection *cnc);
-SoupSession *  e_ews_connection_ref_soup_session
-                                               (EEwsConnection *cnc);
 gboolean       e_ews_connection_get_backoff_enabled
                                                (EEwsConnection *cnc);
 void           e_ews_connection_set_backoff_enabled
@@ -463,12 +456,6 @@ void               e_ews_connection_set_last_subscription_id
 EEwsConnection *e_ews_connection_find          (const gchar *uri,
                                                 const gchar *username);
 GSList *       e_ews_connection_list_existing  (void); /* EEwsConnection * */
-void           e_ews_connection_queue_request  (EEwsConnection *cnc,
-                                                ESoapMessage *msg,
-                                                EEwsResponseCallback cb,
-                                                gint pri,
-                                                GCancellable *cancellable,
-                                                GSimpleAsyncResult *simple);
 
 gboolean       e_ews_autodiscover_ws_url_sync  (ESource *source,
                                                 CamelEwsSettings *settings,
@@ -478,46 +465,26 @@ gboolean  e_ews_autodiscover_ws_url_sync  (ESource *source,
                                                 GTlsCertificateFlags *out_certificate_errors,
                                                 GCancellable *cancellable,
                                                 GError **error);
-void           e_ews_autodiscover_ws_url       (ESource *source,
-                                                CamelEwsSettings *settings,
-                                                const gchar *email_address,
-                                                const gchar *password,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_autodiscover_ws_url_finish
-                                               (CamelEwsSettings *settings,
-                                                GAsyncResult *result,
-                                                gchar **out_certificate_pem,
-                                                GTlsCertificateFlags *out_certificate_errors,
-                                                GError **error);
 const gchar *  e_ews_connection_get_mailbox    (EEwsConnection *cnc);
 void           e_ews_connection_set_mailbox    (EEwsConnection *cnc,
                                                 const gchar *email);
 
+EEwsServerVersion
+               e_ews_connection_get_server_version
+                                               (EEwsConnection *cnc);
+void           e_ews_connection_set_server_version
+                                               (EEwsConnection *cnc,
+                                                EEwsServerVersion version);
+void           e_ews_connection_set_server_version_from_string
+                                               (EEwsConnection *cnc,
+                                                const gchar *version);
+gboolean       e_ews_connection_satisfies_server_version
+                                               (EEwsConnection *cnc,
+                                                EEwsServerVersion versio);
+
 void           ews_user_id_free                (EwsUserId *id);
 void           ews_delegate_info_free          (EwsDelegateInfo *info);
 
-void           e_ews_connection_sync_folder_items
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *old_sync_state,
-                                                const gchar *fid,
-                                                const gchar *default_props,
-                                                const EEwsAdditionalProps *add_props,
-                                                guint max_entries,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_sync_folder_items_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                gchar **new_sync_state,
-                                                gboolean *includes_last_item,
-                                                GSList **items_created,
-                                                GSList **items_updated,
-                                                GSList **items_deleted,
-                                                GError **error);
 gboolean       e_ews_connection_sync_folder_items_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -526,38 +493,18 @@ gboolean  e_ews_connection_sync_folder_items_sync
                                                 const gchar *default_props,
                                                 const EEwsAdditionalProps *add_props,
                                                 guint max_entries,
-                                                gchar **new_sync_state,
-                                                gboolean *includes_last_item,
-                                                GSList **items_created,
-                                                GSList **items_updated,
-                                                GSList **items_deleted,
+                                                gchar **out_new_sync_state,
+                                                gboolean *out_includes_last_item,
+                                                GSList **out_items_created, /* EEwsItem * */
+                                                GSList **items_updated, /* EEwsItem * */
+                                                GSList **items_deleted, /* gchar * */
                                                 GCancellable *cancellable,
                                                 GError **error);
 
-typedef void   (*EwsConvertQueryCallback)      (ESoapMessage *msg,
+typedef void   (*EwsConvertQueryCallback)      (ESoapRequest *request,
                                                 const gchar *query,
                                                 EEwsFolderType type);
 
-void           e_ews_connection_find_folder_items
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                EwsFolderId *fid,
-                                                const gchar *props,
-                                                const EEwsAdditionalProps *add_props,
-                                                EwsSortOrder *sort_order,
-                                                const gchar *query,
-                                                GPtrArray *only_ids, /* element-type utf8 */
-                                                EEwsFolderType type,
-                                                EwsConvertQueryCallback convert_query_cb,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_find_folder_items_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                gboolean *includes_last_item,
-                                                GSList **items,
-                                                GError **error);
 gboolean       e_ews_connection_find_folder_items_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -568,74 +515,28 @@ gboolean  e_ews_connection_find_folder_items_sync
                                                 const gchar *query,
                                                 GPtrArray *only_ids, /* element-type utf8 */
                                                 EEwsFolderType type,
-                                                gboolean *includes_last_item,
-                                                GSList **items,
+                                                gboolean *out_includes_last_item,
+                                                GSList **out_items, /* EEwsItem * */
                                                 EwsConvertQueryCallback convert_query_cb,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-EEwsServerVersion
-               e_ews_connection_get_server_version
-                                               (EEwsConnection *cnc);
-void           e_ews_connection_set_server_version
-                                               (EEwsConnection *cnc,
-                                                EEwsServerVersion version);
-void           e_ews_connection_set_server_version_from_string
-                                               (EEwsConnection *cnc,
-                                                const gchar *version);
-gboolean       e_ews_connection_satisfies_server_version
-                                               (EEwsConnection *cnc,
-                                                EEwsServerVersion versio);
-
-void           e_ews_connection_get_items      (EEwsConnection *cnc,
-                                                gint pri,
-                                                const GSList *ids,
-                                                const gchar *default_props,
-                                                const EEwsAdditionalProps *add_props,
-                                                gboolean include_mime,
-                                                const gchar *mime_directory,
-                                                EEwsBodyType body_type,
-                                                ESoapProgressFn progress_fn,
-                                                gpointer progress_data,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_get_items_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **items,
-                                                GError **error);
 gboolean       e_ews_connection_get_items_sync (EEwsConnection *cnc,
                                                 gint pri,
-                                                const GSList *ids,
+                                                const GSList *ids, /* gchar * */
                                                 const gchar *default_props,
                                                 const EEwsAdditionalProps *add_props,
                                                 gboolean include_mime,
                                                 const gchar *mime_directory,
                                                 EEwsBodyType body_type,
-                                                GSList **items,
-                                                ESoapProgressFn progress_fn,
+                                                GSList **out_items, /* EEwsItem * */
+                                                ESoapResponseProgressFn progress_fn,
                                                 gpointer progress_data,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_delete_items   (EEwsConnection *cnc,
-                                                gint pri,
-                                                const GSList *ids,
-                                                EwsDeleteType delete_type,
-                                                EwsSendMeetingCancellationsType send_cancels,
-                                                EwsAffectedTaskOccurrencesType affected_tasks,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_delete_items_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GError **error);
 gboolean       e_ews_connection_delete_items_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
-                                                const GSList *ids,
+                                                const GSList *ids, /* gchar * */
                                                 EwsDeleteType delete_type,
                                                 EwsSendMeetingCancellationsType send_cancels,
                                                 EwsAffectedTaskOccurrencesType affected_tasks,
@@ -644,22 +545,12 @@ gboolean  e_ews_connection_delete_items_sync
 gboolean       e_ews_connection_delete_items_in_chunks_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
-                                                const GSList *ids,
+                                                const GSList *ids, /* gchar * */
                                                 EwsDeleteType delete_type,
                                                 EwsSendMeetingCancellationsType send_cancels,
                                                 EwsAffectedTaskOccurrencesType affected_tasks,
                                                 GCancellable *cancellable,
                                                 GError **error);
-void           e_ews_connection_delete_item    (EEwsConnection *cnc,
-                                                gint pri,
-                                                EwsId *id,
-                                                guint index,
-                                                EwsDeleteType delete_type,
-                                                EwsSendMeetingCancellationsType send_cancels,
-                                                EwsAffectedTaskOccurrencesType affected_tasks,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
 gboolean       e_ews_connection_delete_item_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -670,23 +561,6 @@ gboolean   e_ews_connection_delete_item_sync
                                                 EwsAffectedTaskOccurrencesType affected_tasks,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_update_items   (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *conflict_res,
-                                                const gchar *msg_disposition,
-                                                const gchar *send_invites,
-                                                const gchar *folder_id,
-                                                EEwsRequestCreationCallback create_cb,
-                                                gpointer create_user_data,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_update_items_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **ids,
-                                                GError **error);
 gboolean       e_ews_connection_update_items_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -696,25 +570,9 @@ gboolean   e_ews_connection_update_items_sync
                                                 const gchar *folder_id,
                                                 EEwsRequestCreationCallback create_cb,
                                                 gpointer create_user_data,
-                                                GSList **ids,
+                                                GSList **out_items, /* EEwsItem * */
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_create_items   (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *msg_disposition,
-                                                const gchar *send_invites,
-                                                const EwsFolderId *fid,
-                                                EEwsRequestCreationCallback create_cb,
-                                                gpointer create_user_data,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_create_items_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **ids,
-                                                GError **error);
 gboolean       e_ews_connection_create_items_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -723,26 +581,9 @@ gboolean   e_ews_connection_create_items_sync
                                                 const EwsFolderId *fid,
                                                 EEwsRequestCreationCallback create_cb,
                                                 gpointer create_user_data,
-                                                GSList **ids,
+                                                GSList **out_items, /* EEwsItem * */
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_sync_folder_hierarchy
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *sync_state,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_sync_folder_hierarchy_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                gchar **sync_state,
-                                                gboolean *includes_last_folder,
-                                                GSList **folders_created,
-                                                GSList **folders_updated,
-                                                GSList **folders_deleted,
-                                                GError **error);
 gboolean       e_ews_connection_sync_folder_hierarchy_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -754,23 +595,6 @@ gboolean   e_ews_connection_sync_folder_hierarchy_sync
                                                 GSList **folders_deleted,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_resolve_names  (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *resolve_name,
-                                                EwsContactsSearchScope scope,
-                                                GSList *parent_folder_ids,
-                                                gboolean fetch_contact_data,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_resolve_names_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **mailboxes,
-                                                GSList **contact_items,
-                                                gboolean *includes_last_item,
-                                                GError **error);
 gboolean       e_ews_connection_resolve_names_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -778,32 +602,18 @@ gboolean  e_ews_connection_resolve_names_sync
                                                 EwsContactsSearchScope scope,
                                                 GSList *parent_folder_ids,
                                                 gboolean fetch_contact_data,
-                                                GSList **mailboxes,
-                                                GSList **contact_items,
-                                                gboolean *includes_last_item,
-                                                GCancellable *cancellable,
-                                                GError **error);
-
-void           e_ews_connection_expand_dl      (EEwsConnection *cnc,
-                                                gint pri,
-                                                const EwsMailbox *mb,
+                                                gboolean *out_includes_last_item,
+                                                GSList **out_mailboxes, /* EwsMailbox * */
+                                                GSList **out_contact_items, /* EEwsItem * */
                                                 GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_expand_dl_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **mailboxes,
-                                                gboolean *includes_last_item,
                                                 GError **error);
 gboolean       e_ews_connection_expand_dl_sync (EEwsConnection *cnc,
                                                 gint pri,
                                                 const EwsMailbox *mb,
-                                                GSList **mailboxes,
-                                                gboolean *includes_last_item,
+                                                gboolean *out_includes_last_item,
+                                                GSList **out_mailboxes, /* EwsMailbox * */
                                                 GCancellable *cancellable,
                                                 GError **error);
-
 gboolean       e_ews_connection_ex_to_smtp_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -812,21 +622,6 @@ gboolean   e_ews_connection_ex_to_smtp_sync
                                                 gchar **smtp_address,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_create_folder  (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *parent_folder_id,
-                                                gboolean is_distinguished_id,
-                                                const gchar *folder_name,
-                                                EEwsFolderType folder_type,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_create_folder_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                EwsFolderId **folder_id,
-                                                GError **error);
 gboolean       e_ews_connection_create_folder_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -834,22 +629,9 @@ gboolean   e_ews_connection_create_folder_sync
                                                 gboolean is_distinguished_id,
                                                 const gchar *folder_name,
                                                 EEwsFolderType folder_type,
-                                                EwsFolderId **folder_id,
+                                                EwsFolderId **out_folder_id,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_delete_folder  (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *folder_id,
-                                                gboolean is_distinguished_id,
-                                                const gchar *delete_type,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_delete_folder_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GError **error);
 gboolean       e_ews_connection_delete_folder_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -858,20 +640,6 @@ gboolean   e_ews_connection_delete_folder_sync
                                                 const gchar *delete_type,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_empty_folder   (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *folder_id,
-                                                gboolean is_distinguished_id,
-                                                const gchar *delete_type,
-                                                gboolean delete_subfolders,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_empty_folder_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GError **error);
 gboolean       e_ews_connection_empty_folder_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -881,18 +649,6 @@ gboolean   e_ews_connection_empty_folder_sync
                                                 gboolean delete_subfolders,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_update_folder  (EEwsConnection *cnc,
-                                                gint pri,
-                                                EEwsRequestCreationCallback create_cb,
-                                                gpointer create_user_data,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_update_folder_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GError **error);
 gboolean       e_ews_connection_update_folder_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -900,18 +656,6 @@ gboolean   e_ews_connection_update_folder_sync
                                                 gpointer create_user_data,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_move_folder    (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *to_folder,
-                                                const gchar *folder,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_move_folder_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GError **error);
 gboolean       e_ews_connection_move_folder_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -919,50 +663,22 @@ gboolean  e_ews_connection_move_folder_sync
                                                 const gchar *folder,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_get_folder     (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *folder_shape,
-                                                const EEwsAdditionalProps *add_props,
-                                                GSList *folder_ids,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_get_folder_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **folders,
-                                                GError **error);
 gboolean       e_ews_connection_get_folder_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
                                                 const gchar *folder_shape,
                                                 const EEwsAdditionalProps *add_props,
-                                                GSList *folder_ids,
-                                                GSList **folders,
-                                                GCancellable *cancellable,
-                                                GError **error);
-
-void           e_ews_connection_move_items     (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *folder_id,
-                                                gboolean docopy,
-                                                const GSList *ids,
+                                                GSList *folder_ids, /* EwsFolderId * */
+                                                GSList **out_folders, /* EEwsFolder * */
                                                 GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_move_items_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **items,
                                                 GError **error);
 gboolean       e_ews_connection_move_items_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
                                                 const gchar *folder_id,
                                                 gboolean docopy,
-                                                const GSList *ids,
-                                                GSList **items_ret,
+                                                const GSList *ids, /* gchar * */
+                                                GSList **out_items, /* EEwsItem * */
                                                 GCancellable *cancellable,
                                                 GError **error);
 gboolean       e_ews_connection_move_items_in_chunks_sync
@@ -970,197 +686,77 @@ gboolean e_ews_connection_move_items_in_chunks_sync
                                                 gint pri,
                                                 const gchar *folder_id,
                                                 gboolean docopy,
-                                                const GSList *ids,
-                                                GSList **items,
+                                                const GSList *ids, /* gchar * */
+                                                GSList **out_items, /* EEwsItems * */
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_create_attachments
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                const EwsId *parent,
-                                                const GSList *files,
-                                                gboolean is_contact_photo,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_create_attachments_finish
-                                               (EEwsConnection *cnc,
-                                                gchar **change_key,
-                                                GSList **attachments_ids,
-                                                GAsyncResult *result,
-                                                GError **error);
 gboolean       e_ews_connection_create_attachments_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
                                                 const EwsId *parent,
-                                                const GSList *files,
+                                                const GSList *files, /* EEwsAttachmentInfo * */
                                                 gboolean is_contact_photo,
-                                                gchar **change_key,
-                                                GSList **attachments_ids,
+                                                gchar **out_change_key,
+                                                GSList **out_attachments_ids, /* gchar * */
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_delete_attachments
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                const GSList *attachments_ids,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_delete_attachments_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                gchar **new_change_key,
-                                                GError **error);
 gboolean       e_ews_connection_delete_attachments_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
-                                                const GSList *attachments_ids,
-                                                gchar **new_change_key,
+                                                const GSList *attachments_ids, /* gchar * */
+                                                gchar **out_new_change_key,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_get_attachments
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *comp_uid,
-                                                const GSList *ids,
-                                                const gchar *cache,
-                                                gboolean include_mime,
-                                                ESoapProgressFn progress_fn,
-                                                gpointer progress_data,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_get_attachments_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **items,
-                                                GError **error);
 gboolean       e_ews_connection_get_attachments_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
-                                                const gchar *comp_uid,
-                                                const GSList *ids,
-                                                const gchar *cache,
+                                                const gchar *uid,
+                                                const GSList *ids, /* const gchar * */
+                                                const gchar *cache_directory,
                                                 gboolean include_mime,
-                                                GSList **items,
-                                                ESoapProgressFn progress_fn,
+                                                GSList **out_attachments, /* EEwsAttachmentInfo * */
+                                                ESoapResponseProgressFn progress_fn,
                                                 gpointer progress_data,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
 gboolean       e_ews_connection_get_oal_list_sync
                                                (EEwsConnection *cnc,
-                                                GSList **oals,
+                                                GSList **out_oals, /* EwsOAL * */
                                                 GCancellable *cancellable,
                                                 GError **error);
-void           e_ews_connection_get_oal_list   (EEwsConnection *cnc,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_get_oal_list_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **oals,
-                                                GError **error);
 gboolean       e_ews_connection_get_oal_detail_sync
                                                (EEwsConnection *cnc,
                                                 const gchar *oal_id,
                                                 const gchar *oal_element,
                                                 const gchar *old_etag,
-                                                GSList **elements,
-                                                gchar **etag,
-                                                GCancellable *cancellable,
-                                                GError **error);
-void           e_ews_connection_get_oal_detail (EEwsConnection *cnc,
-                                                const gchar *oal_id,
-                                                const gchar *oal_element,
-                                                const gchar *etag,
+                                                GSList **out_elements, /* EwsOALDetails * */
+                                                gchar **out_etag,
                                                 GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_get_oal_detail_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **elements,
-                                                gchar **etag,
-                                                GError **error);
-
-void           e_ews_connection_get_free_busy  (EEwsConnection *cnc,
-                                                gint pri,
-                                                EEwsRequestCreationCallback free_busy_cb,
-                                                gpointer free_busy_user_data,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_get_free_busy_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **free_busy, /* ICalComponent * */
                                                 GError **error);
 gboolean       e_ews_connection_get_free_busy_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
                                                 EEwsRequestCreationCallback free_busy_cb,
                                                 gpointer create_user_data,
-                                                GSList **free_busy, /* ICalComponent * */
+                                                GSList **out_free_busy, /* ICalComponent * */
                                                 GCancellable *cancellable,
                                                 GError **error);
 gboolean       e_ews_connection_download_oal_file_sync
                                                (EEwsConnection *cnc,
                                                 const gchar *cache_filename,
-                                                EwsProgressFn progress_fn,
-                                                gpointer progress_data,
-                                                GCancellable *cancellable,
-                                                GError **error);
-void           e_ews_connection_download_oal_file
-                                               (EEwsConnection *cnc,
-                                                const gchar *cache_filename,
-                                                EwsProgressFn progress_fn,
+                                                ESoapResponseProgressFn progress_fn,
                                                 gpointer progress_data,
                                                 GCancellable *cancellable,
-                                                GAsyncReadyCallback cb,
-                                                gpointer user_data);
-gboolean       e_ews_connection_download_oal_file_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GError **error);
-
-void           e_ews_connection_get_delegate   (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *mail_id,
-                                                gboolean include_permissions,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_get_delegate_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                EwsDelegateDeliver *deliver_to,
-                                                GSList **delegates, /* EwsDelegateInfo * */
                                                 GError **error);
 gboolean       e_ews_connection_get_delegate_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
                                                 const gchar *mail_id,
                                                 gboolean include_permissions,
-                                                EwsDelegateDeliver *deliver_to,
-                                                GSList **delegates, /* EwsDelegateInfo * */
+                                                EwsDelegateDeliver *out_deliver_to,
+                                                GSList **out_delegates, /* EwsDelegateInfo * */
                                                 GCancellable *cancellable,
                                                 GError **error);
-void           e_ews_connection_add_delegate   (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *mail_id,
-                                                const GSList *delegates, /* EwsDelegateInfo * */
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_add_delegate_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GError **error);
 gboolean       e_ews_connection_add_delegate_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -1168,18 +764,6 @@ gboolean  e_ews_connection_add_delegate_sync
                                                 const GSList *delegates, /* EwsDelegateInfo * */
                                                 GCancellable *cancellable,
                                                 GError **error);
-void           e_ews_connection_remove_delegate
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *mail_id,
-                                                const GSList *delegate_ids, /* EwsUserId * */
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_remove_delegate_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GError **error);
 gboolean       e_ews_connection_remove_delegate_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -1187,19 +771,6 @@ gboolean  e_ews_connection_remove_delegate_sync
                                                 const GSList *delegate_ids, /* EwsUserId * */
                                                 GCancellable *cancellable,
                                                 GError **error);
-void           e_ews_connection_update_delegate
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *mail_id,
-                                                EwsDelegateDeliver deliver_to,
-                                                const GSList *delegates, /* EwsDelegateInfo * */
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_update_delegate_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GError **error);
 gboolean       e_ews_connection_update_delegate_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -1208,125 +779,48 @@ gboolean        e_ews_connection_update_delegate_sync
                                                 const GSList *delegates, /* EwsDelegateInfo * */
                                                 GCancellable *cancellable,
                                                 GError **error);
-void           e_ews_connection_get_folder_permissions
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                EwsFolderId *folder_id,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_get_folder_permissions_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **permissions,
-                                                GError **error);
 gboolean       e_ews_connection_get_folder_permissions_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
                                                 EwsFolderId *folder_id,
-                                                GSList **permissions,
-                                                GCancellable *cancellable,
-                                                GError **error);
-void           e_ews_connection_set_folder_permissions
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                EwsFolderId *folder_id,
-                                                EEwsFolderType folder_type,
-                                                const GSList *permissions,
+                                                GSList **out_permissions, /* EEwsPermission * */
                                                 GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_set_folder_permissions_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
                                                 GError **error);
 gboolean       e_ews_connection_set_folder_permissions_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
                                                 EwsFolderId *folder_id,
                                                 EEwsFolderType folder_type,
-                                                const GSList *permissions,
+                                                const GSList *permissions, /* EEwsPermission * */
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_get_password_expiration
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *mail_id,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-
-gboolean       e_ews_connection_get_password_expiration_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                gchar **exp_date,
-                                                GError **error);
-
 gboolean       e_ews_connection_get_password_expiration_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
                                                 const gchar *mail_id,
-                                                gchar **exp_date,
+                                                gchar **out_exp_date,
                                                 GCancellable *cancellable,
                                                 GError **error);
-
-void           e_ews_connection_get_folder_info
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *mail_id,
-                                                const EwsFolderId *folder_id,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_get_folder_info_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                EEwsFolder **folder,
-                                                GError **error);
 gboolean       e_ews_connection_get_folder_info_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
                                                 const gchar *mail_id,
                                                 const EwsFolderId *folder_id,
-                                                EEwsFolder **folder,
+                                                EEwsFolder **out_folder,
                                                 GCancellable *cancellable,
                                                 GError **error);
-void           e_ews_connection_find_folder    (EEwsConnection *cnc,
-                                                gint pri,
-                                                const EwsFolderId *fid,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_find_folder_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                gboolean *includes_last_item,
-                                                GSList **folders,
-                                                GError **error);
 gboolean       e_ews_connection_find_folder_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
                                                 const EwsFolderId *fid,
-                                                gboolean *includes_last_item,
-                                                GSList **folders,
-                                                GCancellable *cancellable,
-                                                GError **error);
-void           e_ews_connection_query_auth_methods
-                                               (EEwsConnection *cnc,
-                                                gint pri,
+                                                gboolean *out_includes_last_item,
+                                                GSList **out_folders, /* EEwsFolder * */
                                                 GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_query_auth_methods_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **auth_methods,
                                                 GError **error);
 gboolean       e_ews_connection_query_auth_methods_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
-                                                GSList **auth_methods,
+                                                GSList **out_auth_methods, /* gchar * */
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_ews_connection_enable_notifications_sync
@@ -1336,37 +830,13 @@ void             e_ews_connection_enable_notifications_sync
 void           e_ews_connection_disable_notifications_sync
                                                (EEwsConnection *cnc,
                                                 guint subscription_key);
-void           e_ews_connection_get_server_time_zones
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                GSList *msdn_locations,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_get_server_time_zones_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                GSList **tzds, /* EEwsCalendarTimeZoneDefinition */
-                                                GError **error);
 gboolean       e_ews_connection_get_server_time_zones_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
-                                                GSList *msdn_locations,
-                                                GSList **tzds, /* EEwsCalendarTimeZoneDefinition */
+                                                const GSList *msdn_locations, /* gchar * */
+                                                GSList **out_tzds, /* EEwsCalendarTimeZoneDefinition */
                                                 GCancellable *cancellable,
                                                 GError **error);
-void           e_ews_connection_get_user_photo (EEwsConnection *cnc,
-                                                gint pri,
-                                                const gchar *email,
-                                                EEwsSizeRequested size_requested,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_get_user_photo_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                gchar **out_picture_data, /* base64-encoded */
-                                                GError **error);
 gboolean       e_ews_connection_get_user_photo_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -1375,20 +845,6 @@ gboolean  e_ews_connection_get_user_photo_sync
                                                 gchar **out_picture_data, /* base64-encoded */
                                                 GCancellable *cancellable,
                                                 GError **error);
-void           e_ews_connection_get_user_configuration
-                                               (EEwsConnection *cnc,
-                                                gint pri,
-                                                const EwsFolderId *fid,
-                                                const gchar *config_name,
-                                                EEwsUserConfigurationProperties props,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_get_user_configuration_finish
-                                               (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                gchar **out_properties,
-                                                GError **error);
 gboolean       e_ews_connection_get_user_configuration_sync
                                                (EEwsConnection *cnc,
                                                 gint pri,
@@ -1398,27 +854,49 @@ gboolean e_ews_connection_get_user_configuration_sync
                                                 gchar **out_properties,
                                                 GCancellable *cancellable,
                                                 GError **error);
-void           e_ews_connection_convert_id     (EEwsConnection *cnc,
+gboolean       e_ews_connection_convert_id_sync(EEwsConnection *cnc,
                                                 gint pri,
                                                 const gchar *email,
                                                 const gchar *folder_id,
                                                 const gchar *from_format,
                                                 const gchar *to_format,
+                                                gchar **out_converted_id,
                                                 GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_ews_connection_convert_id_finish
+                                                GError **error);
+gboolean       e_ews_connection_get_user_oof_settings_sync
                                                (EEwsConnection *cnc,
-                                                GAsyncResult *result,
-                                                gchar **out_converted_id,
+                                                gint pri,
+                                                EEwsOofSettings *inout_oof_settings, /* caller-allocates */
+                                                GCancellable *cancellable,
                                                 GError **error);
-gboolean       e_ews_connection_convert_id_sync(EEwsConnection *cnc,
+gboolean       e_ews_connection_set_user_oof_settings_sync
+                                               (EEwsConnection *cnc,
                                                 gint pri,
-                                                const gchar *email,
-                                                const gchar *folder_id,
-                                                const gchar *from_format,
-                                                const gchar *to_format,
-                                                gchar **out_converted_id,
+                                                EEwsOofState state,
+                                                EEwsExternalAudience external_audience,
+                                                const GDateTime *date_start,
+                                                const GDateTime *date_end,
+                                                const gchar *internal_reply,
+                                                const gchar *external_reply,
+                                                GCancellable *cancellable,
+                                                GError **error);
+gboolean       e_ews_connection_subscribe_sync (EEwsConnection *cnc,
+                                                gint pri,
+                                                const GSList *folder_ids, /* gchar * */
+                                                gchar **out_subscription_id,
+                                                GCancellable *cancellable,
+                                                GError **error);
+gboolean       e_ews_connection_unsubscribe_sync
+                                               (EEwsConnection *cnc,
+                                                gint pri,
+                                                const gchar *subscription_id,
+                                                GCancellable *cancellable,
+                                                GError **error);
+gboolean       e_ews_connection_get_streaming_events_sync
+                                               (EEwsConnection *cnc,
+                                                gint pri,
+                                                const gchar *subscription_id,
+                                                GInputStream **out_input_stream,
                                                 GCancellable *cancellable,
                                                 GError **error);
 
diff --git a/src/EWS/common/e-ews-debug.c b/src/EWS/common/e-ews-debug.c
index 010a9662..4412ac04 100644
--- a/src/EWS/common/e-ews-debug.c
+++ b/src/EWS/common/e-ews-debug.c
@@ -7,7 +7,7 @@
 #include "evolution-ews-config.h"
 
 #include "e-ews-debug.h"
-#include "e-ews-message.h"
+#include "e-ews-request.h"
 
 gint
 e_ews_debug_get_log_level (void)
@@ -87,74 +87,6 @@ e_ews_debug_get_server_version_from_string (const gchar *version)
                return E_EWS_EXCHANGE_FUTURE;
 }
 
-static void
-print_header (const gchar *name,
-             const gchar *value,
-             gpointer user_data)
-{
-       gchar *header = g_strconcat (name, ": ", value, NULL);
-
-       fprintf (user_data, "%s\n", e_ews_debug_redact_headers ('<', header));
-
-       g_free (header);
-}
-
-static void
-e_ews_debug_dump_raw_soup_message (FILE *out,
-                                  SoupMessageHeaders *hdrs,
-                                  SoupMessageBody *body)
-{
-       if (body && soup_message_body_get_accumulate (body)) {
-               SoupBuffer *buffer;
-
-               buffer = soup_message_body_flatten (body);
-               soup_buffer_free (buffer);
-       }
-
-       /* print body */
-       fprintf (out, " =====================\n");
-       if (hdrs)
-               soup_message_headers_foreach (hdrs, print_header, out);
-       else
-               fprintf (out, " null headers\n");
-       fputc ('\n', out);
-       if (body && body->data) {
-               fputs (body->data, out);
-               fputc ('\n', out);
-       }
-       fflush (out);
-}
-
-void
-e_ews_debug_dump_raw_soup_request (SoupMessage *msg)
-{
-       gint log_level;
-
-       log_level = e_ews_debug_get_log_level ();
-       if (log_level == 1) {
-               /* print request body */
-               printf ("\n URI: %s\n", soup_uri_to_string (soup_message_get_uri (msg),
-                                                         TRUE));
-               printf (" The request headers for message %p\n", msg);
-               e_ews_debug_dump_raw_soup_message (stdout, msg->request_headers,
-                                                  msg->request_body);
-       }
-}
-
-void
-e_ews_debug_dump_raw_soup_response (SoupMessage *msg)
-{
-       gint log_level;
-
-       log_level = e_ews_debug_get_log_level ();
-       if (log_level >= 1) {
-               printf ("\n The response code: %d\n", msg->status_code);
-               printf (" The response headers for message %p\n", msg);
-               e_ews_debug_dump_raw_soup_message (stdout, msg->response_headers,
-                                                  msg->response_body);
-       }
-}
-
 const gchar *
 e_ews_debug_redact_headers (gchar direction,
                            const gchar *data)
diff --git a/src/EWS/common/e-ews-debug.h b/src/EWS/common/e-ews-debug.h
index aa6ab95c..b14ed4cd 100644
--- a/src/EWS/common/e-ews-debug.h
+++ b/src/EWS/common/e-ews-debug.h
@@ -20,10 +20,6 @@ const gchar *        e_ews_connection_get_server_version_string
 EEwsServerVersion
                e_ews_debug_get_server_version_from_string
                                                        (const gchar *version);
-void           e_ews_debug_dump_raw_soup_request
-                                                       (SoupMessage *msg);
-void           e_ews_debug_dump_raw_soup_response
-                                                       (SoupMessage *msg);
 const gchar *  e_ews_debug_redact_headers              (gchar direction,
                                                         const gchar *data);
 void           e_ews_debug_soup_log_printer_stdout     (SoupLogger *logger,
diff --git a/src/EWS/common/e-ews-folder.c b/src/EWS/common/e-ews-folder.c
index 04e6a1a3..e08c302d 100644
--- a/src/EWS/common/e-ews-folder.c
+++ b/src/EWS/common/e-ews-folder.c
@@ -10,7 +10,7 @@
 #include <glib/gi18n-lib.h>
 
 #include "e-ews-folder.h"
-#include "e-ews-message.h"
+#include "e-ews-request.h"
 #include "e-ews-enumtypes.h"
 #include "ews-errors.h"
 #include "e-source-ews-folder.h"
@@ -363,29 +363,29 @@ e_ews_folder_id_is_equal (const EwsFolderId *a,
 }
 
 void
-e_ews_folder_id_append_to_msg (ESoapMessage *msg,
-                              const gchar *email,
-                              const EwsFolderId *fid)
+e_ews_folder_id_append_to_request (ESoapRequest *request,
+                                  const gchar *email,
+                                  const EwsFolderId *fid)
 {
-       g_return_if_fail (msg != NULL);
+       g_return_if_fail (request != NULL);
        g_return_if_fail (fid != NULL);
 
        if (fid->is_distinguished_id)
-               e_soap_message_start_element (msg, "DistinguishedFolderId", NULL, NULL);
+               e_soap_request_start_element (request, "DistinguishedFolderId", NULL, NULL);
        else
-               e_soap_message_start_element (msg, "FolderId", NULL, NULL);
+               e_soap_request_start_element (request, "FolderId", NULL, NULL);
 
-       e_soap_message_add_attribute (msg, "Id", fid->id, NULL, NULL);
+       e_soap_request_add_attribute (request, "Id", fid->id, NULL, NULL);
        if (fid->change_key)
-               e_soap_message_add_attribute (msg, "ChangeKey", fid->change_key, NULL, NULL);
+               e_soap_request_add_attribute (request, "ChangeKey", fid->change_key, NULL, NULL);
 
        if (fid->is_distinguished_id && email) {
-               e_soap_message_start_element (msg, "Mailbox", NULL, NULL);
-               e_ews_message_write_string_parameter (msg, "EmailAddress", NULL, email);
-               e_soap_message_end_element (msg);
+               e_soap_request_start_element (request, "Mailbox", NULL, NULL);
+               e_ews_request_write_string_parameter (request, "EmailAddress", NULL, email);
+               e_soap_request_end_element (request);
        }
 
-       e_soap_message_end_element (msg);
+       e_soap_request_end_element (request);
 }
 
 const gchar *
diff --git a/src/EWS/common/e-ews-folder.h b/src/EWS/common/e-ews-folder.h
index dbde4d26..0a771e28 100644
--- a/src/EWS/common/e-ews-folder.h
+++ b/src/EWS/common/e-ews-folder.h
@@ -10,7 +10,7 @@
 #include <libedataserver/libedataserver.h>
 
 #include "e-ews-enums.h"
-#include "e-soap-message.h"
+#include "e-soap-request.h"
 
 G_BEGIN_DECLS
 
@@ -76,9 +76,9 @@ void          e_ews_folder_id_free (EwsFolderId *fid);
 gboolean       e_ews_folder_id_is_equal (const EwsFolderId *a,
                                          const EwsFolderId *b,
                                          gboolean check_change_key);
-void           e_ews_folder_id_append_to_msg (ESoapMessage *msg,
-                                              const gchar *email,
-                                              const EwsFolderId *fid);
+void           e_ews_folder_id_append_to_request               (ESoapRequest *request,
+                                                                const gchar *email,
+                                                                const EwsFolderId *fid);
 gchar *                e_ews_folder_utils_escape_name                  (const gchar *folder_name);
 gchar *                e_ews_folder_utils_unescape_name                (const gchar *escaped_folder_name);
 
diff --git a/src/EWS/common/e-ews-item-change.c b/src/EWS/common/e-ews-item-change.c
index 1e647f5c..5389228f 100644
--- a/src/EWS/common/e-ews-item-change.c
+++ b/src/EWS/common/e-ews-item-change.c
@@ -7,26 +7,26 @@
 
 #include "evolution-ews-config.h"
 
-#include "e-soap-message.h"
+#include "e-soap-request.h"
 #include "e-soap-response.h"
-#include "e-ews-message.h"
+#include "e-ews-request.h"
 #include "e-ews-item-change.h"
 
 void
-e_ews_message_start_folder_change (ESoapMessage *msg,
+e_ews_request_start_folder_change (ESoapRequest *request,
                                   const gchar *email,
                                   const EwsFolderId *folder_id)
 {
-       g_return_if_fail (msg != NULL);
+       g_return_if_fail (request != NULL);
        g_return_if_fail (folder_id != NULL);
 
-       e_soap_message_start_element (msg, "FolderChange", NULL, NULL);
-       e_ews_folder_id_append_to_msg (msg, email, folder_id);
-       e_soap_message_start_element (msg, "Updates", NULL, NULL);
+       e_soap_request_start_element (request, "FolderChange", NULL, NULL);
+       e_ews_folder_id_append_to_request (request, email, folder_id);
+       e_soap_request_start_element (request, "Updates", NULL, NULL);
 }
 
 void
-e_ews_message_start_item_change (ESoapMessage *msg,
+e_ews_request_start_item_change (ESoapRequest *request,
                                  EEwsItemChangeType type,
                                  const gchar *itemid,
                                  const gchar *changekey,
@@ -36,68 +36,48 @@ e_ews_message_start_item_change (ESoapMessage *msg,
 
        switch (type) {
        case E_EWS_ITEMCHANGE_TYPE_FOLDER:
-               e_soap_message_start_element (msg, "FolderChange", NULL, NULL);
-               e_soap_message_start_element (
-                       msg, "FolderId",
-                       NULL, NULL);
-               e_soap_message_add_attribute (
-                       msg, "Id",
-                       itemid, NULL, NULL);
+               e_soap_request_start_element (request, "FolderChange", NULL, NULL);
+               e_soap_request_start_element (request, "FolderId", NULL, NULL);
+               e_soap_request_add_attribute (request, "Id", itemid, NULL, NULL);
                break;
 
        case E_EWS_ITEMCHANGE_TYPE_ITEM:
-               e_soap_message_start_element (msg, "ItemChange", NULL, NULL);
-               e_soap_message_start_element (
-                       msg, "ItemId",
-                       NULL, NULL);
-               e_soap_message_add_attribute (
-                       msg, "Id",
-                       itemid, NULL, NULL);
+               e_soap_request_start_element (request, "ItemChange", NULL, NULL);
+               e_soap_request_start_element (request, "ItemId", NULL, NULL);
+               e_soap_request_add_attribute (request, "Id", itemid, NULL, NULL);
                break;
 
        case E_EWS_ITEMCHANGE_TYPE_OCCURRENCEITEM:
-               e_soap_message_start_element (msg, "ItemChange", NULL, NULL);
-               e_soap_message_start_element (
-                       msg, "OccurrenceItemId",
-                       NULL, NULL);
-               e_soap_message_add_attribute (
-                       msg, "RecurringMasterId",
-                       itemid, NULL, NULL);
+               e_soap_request_start_element (request, "ItemChange", NULL, NULL);
+               e_soap_request_start_element (request, "OccurrenceItemId", NULL, NULL);
+               e_soap_request_add_attribute (request, "RecurringMasterId", itemid, NULL, NULL);
                instance = g_strdup_printf ("%d", instance_index);
-               e_soap_message_add_attribute (
-                       msg, "InstanceIndex", instance,
-                       NULL, NULL);
+               e_soap_request_add_attribute (request, "InstanceIndex", instance, NULL, NULL);
                g_free (instance);
                break;
 
        case E_EWS_ITEMCHANGE_TYPE_RECURRINGMASTER:
-               e_soap_message_start_element (msg, "ItemChange", NULL, NULL);
-               e_soap_message_start_element (
-                       msg, "RecurringMasterItemId",
-                       NULL, NULL);
-               e_soap_message_add_attribute (
-                       msg, "OccurrenceId",
-                       itemid, NULL, NULL);
+               e_soap_request_start_element (request, "ItemChange", NULL, NULL);
+               e_soap_request_start_element (request, "RecurringMasterItemId", NULL, NULL);
+               e_soap_request_add_attribute (request, "OccurrenceId", itemid, NULL, NULL);
                break;
        }
        if (changekey)
-               e_soap_message_add_attribute (
-                       msg, "ChangeKey",
-                       changekey, NULL, NULL);
-       e_soap_message_end_element (msg);
+               e_soap_request_add_attribute (request, "ChangeKey", changekey, NULL, NULL);
+       e_soap_request_end_element (request);
 
-       e_soap_message_start_element (msg, "Updates", NULL, NULL);
+       e_soap_request_start_element (request, "Updates", NULL, NULL);
 }
 
 void
-e_ews_message_end_item_change (ESoapMessage *msg)
+e_ews_request_end_item_change (ESoapRequest *request)
 {
-       e_soap_message_end_element (msg); /* Updates */
-       e_soap_message_end_element (msg); /* ItemChange */
+       e_soap_request_end_element (request); /* Updates */
+       e_soap_request_end_element (request); /* ItemChange */
 }
 
 void
-e_ews_message_start_set_item_field (ESoapMessage *msg,
+e_ews_request_start_set_item_field (ESoapRequest *request,
                                     const gchar *name,
                                     const gchar *fielduri_prefix,
                                     const gchar *field_kind)
@@ -105,16 +85,15 @@ e_ews_message_start_set_item_field (ESoapMessage *msg,
        gchar * fielduri = NULL;
        fielduri = g_strconcat (fielduri_prefix, ":", name, NULL);
 
-       e_soap_message_start_element (msg, "SetItemField", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (
-               msg, "FieldURI", NULL, NULL, "FieldURI", fielduri);
-       e_soap_message_start_element (msg, field_kind, NULL, NULL);
+       e_soap_request_start_element (request, "SetItemField", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (request, "FieldURI", NULL, NULL, "FieldURI", 
fielduri);
+       e_soap_request_start_element (request, field_kind, NULL, NULL);
 
        g_free (fielduri);
 }
 
 void
-e_ews_message_start_set_indexed_item_field (ESoapMessage *msg,
+e_ews_request_start_set_indexed_item_field (ESoapRequest *request,
                                             const gchar *name,
                                             const gchar *fielduri_prefix,
                                             const gchar *field_kind,
@@ -125,39 +104,39 @@ e_ews_message_start_set_indexed_item_field (ESoapMessage *msg,
        fielduri = g_strconcat (fielduri_prefix, ":", name, NULL);
 
        if (delete_field)
-               e_soap_message_start_element (msg, "DeleteItemField", NULL, NULL);
+               e_soap_request_start_element (request, "DeleteItemField", NULL, NULL);
        else
-               e_soap_message_start_element (msg, "SetItemField", NULL, NULL);
+               e_soap_request_start_element (request, "SetItemField", NULL, NULL);
 
-       e_soap_message_start_element (msg, "IndexedFieldURI", NULL, NULL);
-       e_soap_message_add_attribute (msg, "FieldURI", fielduri, NULL, NULL);
-       e_soap_message_add_attribute (msg, "FieldIndex", field_index, NULL, NULL);
-       e_soap_message_end_element (msg);
+       e_soap_request_start_element (request, "IndexedFieldURI", NULL, NULL);
+       e_soap_request_add_attribute (request, "FieldURI", fielduri, NULL, NULL);
+       e_soap_request_add_attribute (request, "FieldIndex", field_index, NULL, NULL);
+       e_soap_request_end_element (request);
 
        if (!delete_field)
-               e_soap_message_start_element (msg, field_kind, NULL, NULL);
+               e_soap_request_start_element (request, field_kind, NULL, NULL);
 
        g_free (fielduri);
 }
 
 void
-e_ews_message_end_set_indexed_item_field (ESoapMessage *msg,
+e_ews_request_end_set_indexed_item_field (ESoapRequest *request,
                                           gboolean delete_field)
 {
        if (!delete_field)
-               e_soap_message_end_element (msg); /* CalendarItem */
-       e_soap_message_end_element (msg); /* SetItemField */
+               e_soap_request_end_element (request); /* CalendarItem */
+       e_soap_request_end_element (request); /* SetItemField */
 }
 
 void
-e_ews_message_end_set_item_field (ESoapMessage *msg)
+e_ews_request_end_set_item_field (ESoapRequest *request)
 {
-       e_soap_message_end_element (msg); /* CalendarItem */
-       e_soap_message_end_element (msg); /* SetItemField */
+       e_soap_request_end_element (request); /* CalendarItem */
+       e_soap_request_end_element (request); /* SetItemField */
 }
 
 void
-e_ews_message_add_delete_item_field (ESoapMessage *msg,
+e_ews_request_add_delete_item_field (ESoapRequest *request,
                                      const gchar *name,
                                      const gchar *fielduri_prefix)
 {
@@ -165,16 +144,15 @@ e_ews_message_add_delete_item_field (ESoapMessage *msg,
 
        fielduri = g_strconcat (fielduri_prefix, ":", name, NULL);
 
-       e_soap_message_start_element (msg, "DeleteItemField", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (
-               msg, "FieldURI", NULL, NULL, "FieldURI", fielduri);
-       e_soap_message_end_element (msg); /* DeleteItemField */
+       e_soap_request_start_element (request, "DeleteItemField", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (request, "FieldURI", NULL, NULL, "FieldURI", 
fielduri);
+       e_soap_request_end_element (request); /* DeleteItemField */
 
        g_free (fielduri);
 }
 
 void
-e_ews_message_add_delete_item_field_indexed (ESoapMessage *msg,
+e_ews_request_add_delete_item_field_indexed (ESoapRequest *request,
                                              const gchar *name,
                                              const gchar *fielduri_prefix,
                                              const gchar *field_index)
@@ -183,18 +161,18 @@ e_ews_message_add_delete_item_field_indexed (ESoapMessage *msg,
 
        fielduri = g_strconcat (fielduri_prefix, ":", name, NULL);
 
-       e_soap_message_start_element (msg, "DeleteItemField", NULL, NULL);
-       e_soap_message_start_element (msg, "IndexedFieldURI", NULL, NULL);
-       e_soap_message_add_attribute (msg, "FieldURI", fielduri, NULL, NULL);
-       e_soap_message_add_attribute (msg, "FieldIndex", field_index, NULL, NULL);
-       e_soap_message_end_element (msg); /* IndexedFieldURI */
-       e_soap_message_end_element (msg); /* DeleteItemField */
+       e_soap_request_start_element (request, "DeleteItemField", NULL, NULL);
+       e_soap_request_start_element (request, "IndexedFieldURI", NULL, NULL);
+       e_soap_request_add_attribute (request, "FieldURI", fielduri, NULL, NULL);
+       e_soap_request_add_attribute (request, "FieldIndex", field_index, NULL, NULL);
+       e_soap_request_end_element (request); /* IndexedFieldURI */
+       e_soap_request_end_element (request); /* DeleteItemField */
 
        g_free (fielduri);
 }
 
 const gchar *
-e_ews_message_data_type_get_xml_name (EEwsMessageDataType data_type)
+e_ews_request_data_type_get_xml_name (EEwsMessageDataType data_type)
 {
        switch (data_type) {
        case E_EWS_MESSAGE_DATA_TYPE_BOOLEAN:
@@ -215,36 +193,36 @@ e_ews_message_data_type_get_xml_name (EEwsMessageDataType data_type)
 }
 
 void
-e_ews_message_add_delete_item_field_extended_tag (ESoapMessage *msg,
+e_ews_request_add_delete_item_field_extended_tag (ESoapRequest *request,
                                                  guint32 prop_id,
                                                  EEwsMessageDataType data_type)
 {
-       const gchar *prop_type = e_ews_message_data_type_get_xml_name (data_type);
+       const gchar *prop_type = e_ews_request_data_type_get_xml_name (data_type);
 
        g_return_if_fail (prop_type != NULL);
 
-       e_soap_message_start_element (msg, "DeleteItemField", NULL, NULL);
-       e_ews_message_write_extended_tag (msg, prop_id, prop_type);
-       e_soap_message_end_element (msg); /* DeleteItemField */
+       e_soap_request_start_element (request, "DeleteItemField", NULL, NULL);
+       e_ews_request_write_extended_tag (request, prop_id, prop_type);
+       e_soap_request_end_element (request); /* DeleteItemField */
 }
 
 void
-e_ews_message_add_delete_item_field_extended_distinguished_tag (ESoapMessage *msg,
+e_ews_request_add_delete_item_field_extended_distinguished_tag (ESoapRequest *request,
                                                                const gchar *set_id,
                                                                guint32 prop_id,
                                                                EEwsMessageDataType data_type)
 {
-       const gchar *prop_type = e_ews_message_data_type_get_xml_name (data_type);
+       const gchar *prop_type = e_ews_request_data_type_get_xml_name (data_type);
 
        g_return_if_fail (prop_type != NULL);
 
-       e_soap_message_start_element (msg, "DeleteItemField", NULL, NULL);
-       e_ews_message_write_extended_distinguished_tag (msg, set_id, prop_id, prop_type);
-       e_soap_message_end_element (msg); /* DeleteItemField */
+       e_soap_request_start_element (request, "DeleteItemField", NULL, NULL);
+       e_ews_request_write_extended_distinguished_tag (request, set_id, prop_id, prop_type);
+       e_soap_request_end_element (request); /* DeleteItemField */
 }
 
 static void
-ews_message_write_data_value (ESoapMessage *msg,
+ews_request_write_data_value (ESoapRequest *request,
                              EEwsMessageDataType data_type,
                              gconstpointer value)
 {
@@ -252,19 +230,19 @@ ews_message_write_data_value (ESoapMessage *msg,
 
        switch (data_type) {
        case E_EWS_MESSAGE_DATA_TYPE_BOOLEAN:
-               e_ews_message_write_string_parameter (msg, "Value", NULL, (*((const gboolean *) value)) ? 
"true" : "false");
+               e_ews_request_write_string_parameter (request, "Value", NULL, (*((const gboolean *) value)) ? 
"true" : "false");
                return;
        case E_EWS_MESSAGE_DATA_TYPE_INT:
-               e_ews_message_write_int_parameter (msg, "Value", NULL, *((const gint *) value));
+               e_ews_request_write_int_parameter (request, "Value", NULL, *((const gint *) value));
                return;
        case E_EWS_MESSAGE_DATA_TYPE_DOUBLE:
-               e_ews_message_write_double_parameter (msg, "Value", NULL, *((const gdouble *) value));
+               e_ews_request_write_double_parameter (request, "Value", NULL, *((const gdouble *) value));
                return;
        case E_EWS_MESSAGE_DATA_TYPE_STRING:
-               e_ews_message_write_string_parameter (msg, "Value", NULL, (const gchar *) value);
+               e_ews_request_write_string_parameter (request, "Value", NULL, (const gchar *) value);
                return;
        case E_EWS_MESSAGE_DATA_TYPE_TIME:
-               e_ews_message_write_time_parameter (msg, "Value", NULL, *((const time_t *) value));
+               e_ews_request_write_time_parameter (request, "Value", NULL, *((const time_t *) value));
                return;
        }
 
@@ -272,66 +250,66 @@ ews_message_write_data_value (ESoapMessage *msg,
 }
 
 static void
-ews_message_add_extended_property_tag (ESoapMessage *msg,
+ews_request_add_extended_property_tag (ESoapRequest *request,
                                       guint32 prop_id,
                                       EEwsMessageDataType data_type,
                                       gconstpointer value)
 {
-       const gchar *prop_type = e_ews_message_data_type_get_xml_name (data_type);
+       const gchar *prop_type = e_ews_request_data_type_get_xml_name (data_type);
 
        g_return_if_fail (prop_type != NULL);
 
-       e_soap_message_start_element (msg, "ExtendedProperty", NULL, NULL);
+       e_soap_request_start_element (request, "ExtendedProperty", NULL, NULL);
 
-       e_ews_message_write_extended_tag (msg, prop_id, prop_type);
-       ews_message_write_data_value (msg, data_type, value);
+       e_ews_request_write_extended_tag (request, prop_id, prop_type);
+       ews_request_write_data_value (request, data_type, value);
 
-       e_soap_message_end_element (msg); /* ExtendedProperty */
+       e_soap_request_end_element (request); /* ExtendedProperty */
 }
 
 static void
-ews_message_add_extended_property_distinguished_tag (ESoapMessage *msg,
+ews_request_add_extended_property_distinguished_tag (ESoapRequest *request,
                                                     const gchar *set_id,
                                                     guint32 prop_id,
                                                     EEwsMessageDataType data_type,
                                                     gconstpointer value)
 {
-       const gchar *prop_type = e_ews_message_data_type_get_xml_name (data_type);
+       const gchar *prop_type = e_ews_request_data_type_get_xml_name (data_type);
 
        g_return_if_fail (prop_type != NULL);
 
-       e_soap_message_start_element (msg, "ExtendedProperty", NULL, NULL);
+       e_soap_request_start_element (request, "ExtendedProperty", NULL, NULL);
 
-       e_ews_message_write_extended_distinguished_tag (msg, set_id, prop_id, prop_type);
-       ews_message_write_data_value (msg, data_type, value);
+       e_ews_request_write_extended_distinguished_tag (request, set_id, prop_id, prop_type);
+       ews_request_write_data_value (request, data_type, value);
 
-       e_soap_message_end_element (msg); /* ExtendedProperty */
+       e_soap_request_end_element (request); /* ExtendedProperty */
 }
 
 static void
-ews_message_add_set_item_field_extended_tag (ESoapMessage *msg,
+ews_request_add_set_item_field_extended_tag (ESoapRequest *request,
                                             const gchar *elem_prefix,
                                             const gchar *elem_name,
                                             guint32 prop_id,
                                             EEwsMessageDataType data_type,
                                             gconstpointer value)
 {
-       const gchar *prop_type = e_ews_message_data_type_get_xml_name (data_type);
+       const gchar *prop_type = e_ews_request_data_type_get_xml_name (data_type);
 
        g_return_if_fail (prop_type != NULL);
 
-       e_soap_message_start_element (msg, "SetItemField", NULL, NULL);
-       e_ews_message_write_extended_tag (msg, prop_id, prop_type);
+       e_soap_request_start_element (request, "SetItemField", NULL, NULL);
+       e_ews_request_write_extended_tag (request, prop_id, prop_type);
 
-       e_soap_message_start_element (msg, elem_name, elem_prefix, NULL);
-       ews_message_add_extended_property_tag (msg, prop_id, data_type, value);
-       e_soap_message_end_element (msg); /* elem_name */
+       e_soap_request_start_element (request, elem_name, elem_prefix, NULL);
+       ews_request_add_extended_property_tag (request, prop_id, data_type, value);
+       e_soap_request_end_element (request); /* elem_name */
 
-       e_soap_message_end_element (msg); /* SetItemField */
+       e_soap_request_end_element (request); /* SetItemField */
 }
 
 static void
-ews_message_add_set_item_field_extended_distinguished_tag (ESoapMessage *msg,
+ews_request_add_set_item_field_extended_distinguished_tag (ESoapRequest *request,
                                                           const gchar *elem_prefix,
                                                           const gchar *elem_name,
                                                           const gchar *set_id,
@@ -339,321 +317,321 @@ ews_message_add_set_item_field_extended_distinguished_tag (ESoapMessage *msg,
                                                           EEwsMessageDataType data_type,
                                                           gconstpointer value)
 {
-       const gchar *prop_type = e_ews_message_data_type_get_xml_name (data_type);
+       const gchar *prop_type = e_ews_request_data_type_get_xml_name (data_type);
 
        g_return_if_fail (prop_type != NULL);
 
-       e_soap_message_start_element (msg, "SetItemField", NULL, NULL);
+       e_soap_request_start_element (request, "SetItemField", NULL, NULL);
 
-       e_ews_message_write_extended_distinguished_tag (msg, set_id, prop_id, prop_type);
+       e_ews_request_write_extended_distinguished_tag (request, set_id, prop_id, prop_type);
 
-       e_soap_message_start_element (msg, elem_name, elem_prefix, NULL);
-       ews_message_add_extended_property_distinguished_tag (msg, set_id, prop_id, data_type, value);
-       e_soap_message_end_element (msg); /* elem_name */
+       e_soap_request_start_element (request, elem_name, elem_prefix, NULL);
+       ews_request_add_extended_property_distinguished_tag (request, set_id, prop_id, data_type, value);
+       e_soap_request_end_element (request); /* elem_name */
 
-       e_soap_message_end_element (msg); /* SetItemField */
+       e_soap_request_end_element (request); /* SetItemField */
 }
 
 void
-e_ews_message_add_set_item_field_extended_tag_boolean (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_tag_boolean (ESoapRequest *request,
                                                       const gchar *elem_prefix,
                                                       const gchar *elem_name,
                                                       guint32 prop_id,
                                                       gboolean value)
 {
-       ews_message_add_set_item_field_extended_tag (msg, elem_prefix, elem_name, prop_id,
+       ews_request_add_set_item_field_extended_tag (request, elem_prefix, elem_name, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_BOOLEAN, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_tag_int (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_tag_int (ESoapRequest *request,
                                                   const gchar *elem_prefix,
                                                   const gchar *elem_name,
                                                   guint32 prop_id,
                                                   gint value)
 {
-       ews_message_add_set_item_field_extended_tag (msg, elem_prefix, elem_name, prop_id,
+       ews_request_add_set_item_field_extended_tag (request, elem_prefix, elem_name, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_INT, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_tag_double (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_tag_double (ESoapRequest *request,
                                                      const gchar *elem_prefix,
                                                      const gchar *elem_name,
                                                      guint32 prop_id,
                                                      gdouble value)
 {
-       ews_message_add_set_item_field_extended_tag (msg, elem_prefix, elem_name, prop_id,
+       ews_request_add_set_item_field_extended_tag (request, elem_prefix, elem_name, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_DOUBLE, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_tag_string (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_tag_string (ESoapRequest *request,
                                                      const gchar *elem_prefix,
                                                      const gchar *elem_name,
                                                      guint32 prop_id,
                                                      const gchar *value)
 {
-       ews_message_add_set_item_field_extended_tag (msg, elem_prefix, elem_name, prop_id,
+       ews_request_add_set_item_field_extended_tag (request, elem_prefix, elem_name, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_STRING, value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_tag_time (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_tag_time (ESoapRequest *request,
                                                    const gchar *elem_prefix,
                                                    const gchar *elem_name,
                                                    guint32 prop_id,
                                                    time_t value)
 {
-       ews_message_add_set_item_field_extended_tag (msg, elem_prefix, elem_name, prop_id,
+       ews_request_add_set_item_field_extended_tag (request, elem_prefix, elem_name, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_TIME, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_distinguished_tag_boolean (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_distinguished_tag_boolean (ESoapRequest *request,
                                                                     const gchar *elem_prefix,
                                                                     const gchar *elem_name,
                                                                     const gchar *set_id,
                                                                     guint32 prop_id,
                                                                     gboolean value)
 {
-       ews_message_add_set_item_field_extended_distinguished_tag (msg, elem_prefix, elem_name, set_id, 
prop_id,
+       ews_request_add_set_item_field_extended_distinguished_tag (request, elem_prefix, elem_name, set_id, 
prop_id,
                E_EWS_MESSAGE_DATA_TYPE_BOOLEAN, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_distinguished_tag_int (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_distinguished_tag_int (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *set_id,
                                                                 guint32 prop_id,
                                                                 gint value)
 {
-       ews_message_add_set_item_field_extended_distinguished_tag (msg, elem_prefix, elem_name, set_id, 
prop_id,
+       ews_request_add_set_item_field_extended_distinguished_tag (request, elem_prefix, elem_name, set_id, 
prop_id,
                E_EWS_MESSAGE_DATA_TYPE_INT, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_distinguished_tag_double (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_distinguished_tag_double (ESoapRequest *request,
                                                                    const gchar *elem_prefix,
                                                                    const gchar *elem_name,
                                                                    const gchar *set_id,
                                                                    guint32 prop_id,
                                                                    gdouble value)
 {
-       ews_message_add_set_item_field_extended_distinguished_tag (msg, elem_prefix, elem_name, set_id, 
prop_id,
+       ews_request_add_set_item_field_extended_distinguished_tag (request, elem_prefix, elem_name, set_id, 
prop_id,
                E_EWS_MESSAGE_DATA_TYPE_DOUBLE, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_distinguished_tag_string (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_distinguished_tag_string (ESoapRequest *request,
                                                                    const gchar *elem_prefix,
                                                                    const gchar *elem_name,
                                                                    const gchar *set_id,
                                                                    guint32 prop_id,
                                                                    const gchar *value)
 {
-       ews_message_add_set_item_field_extended_distinguished_tag (msg, elem_prefix, elem_name, set_id, 
prop_id,
+       ews_request_add_set_item_field_extended_distinguished_tag (request, elem_prefix, elem_name, set_id, 
prop_id,
                E_EWS_MESSAGE_DATA_TYPE_STRING, value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_distinguished_tag_time (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_distinguished_tag_time (ESoapRequest *request,
                                                                  const gchar *elem_prefix,
                                                                  const gchar *elem_name,
                                                                  const gchar *set_id,
                                                                  guint32 prop_id,
                                                                  time_t value)
 {
-       ews_message_add_set_item_field_extended_distinguished_tag (msg, elem_prefix, elem_name, set_id, 
prop_id,
+       ews_request_add_set_item_field_extended_distinguished_tag (request, elem_prefix, elem_name, set_id, 
prop_id,
                E_EWS_MESSAGE_DATA_TYPE_TIME, &value);
 }
 
 void
-e_ews_message_add_extended_property_tag_boolean (ESoapMessage *msg,
+e_ews_request_add_extended_property_tag_boolean (ESoapRequest *request,
                                                 guint32 prop_id,
                                                 gboolean value)
 {
-       ews_message_add_extended_property_tag (msg, prop_id,
+       ews_request_add_extended_property_tag (request, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_BOOLEAN, &value);
 }
 
 void
-e_ews_message_add_extended_property_tag_int (ESoapMessage *msg,
+e_ews_request_add_extended_property_tag_int (ESoapRequest *request,
                                             guint32 prop_id,
                                             gint value)
 {
-       ews_message_add_extended_property_tag (msg, prop_id,
+       ews_request_add_extended_property_tag (request, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_INT, &value);
 }
 
 void
-e_ews_message_add_extended_property_tag_double (ESoapMessage *msg,
+e_ews_request_add_extended_property_tag_double (ESoapRequest *request,
                                                guint32 prop_id,
                                                gdouble value)
 {
-       ews_message_add_extended_property_tag (msg, prop_id,
+       ews_request_add_extended_property_tag (request, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_DOUBLE, &value);
 }
 
 void
-e_ews_message_add_extended_property_tag_string (ESoapMessage *msg,
+e_ews_request_add_extended_property_tag_string (ESoapRequest *request,
                                                guint32 prop_id,
                                                const gchar *value)
 {
-       ews_message_add_extended_property_tag (msg, prop_id,
+       ews_request_add_extended_property_tag (request, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_STRING, value);
 }
 
 void
-e_ews_message_add_extended_property_tag_time (ESoapMessage *msg,
+e_ews_request_add_extended_property_tag_time (ESoapRequest *request,
                                              guint32 prop_id,
                                              time_t value)
 {
-       ews_message_add_extended_property_tag (msg, prop_id,
+       ews_request_add_extended_property_tag (request, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_TIME, &value);
 }
 
 void
-e_ews_message_add_extended_property_distinguished_tag_boolean (ESoapMessage *msg,
+e_ews_request_add_extended_property_distinguished_tag_boolean (ESoapRequest *request,
                                                               const gchar *set_id,
                                                               guint32 prop_id,
                                                               gboolean value)
 {
-       ews_message_add_extended_property_distinguished_tag (msg, set_id, prop_id,
+       ews_request_add_extended_property_distinguished_tag (request, set_id, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_BOOLEAN, &value);
 }
 
 void
-e_ews_message_add_extended_property_distinguished_tag_int (ESoapMessage *msg,
+e_ews_request_add_extended_property_distinguished_tag_int (ESoapRequest *request,
                                                           const gchar *set_id,
                                                           guint32 prop_id,
                                                           gint value)
 {
-       ews_message_add_extended_property_distinguished_tag (msg, set_id, prop_id,
+       ews_request_add_extended_property_distinguished_tag (request, set_id, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_INT, &value);
 }
 
 void
-e_ews_message_add_extended_property_distinguished_tag_double (ESoapMessage *msg,
+e_ews_request_add_extended_property_distinguished_tag_double (ESoapRequest *request,
                                                              const gchar *set_id,
                                                              guint32 prop_id,
                                                              gdouble value)
 {
-       ews_message_add_extended_property_distinguished_tag (msg, set_id, prop_id,
+       ews_request_add_extended_property_distinguished_tag (request, set_id, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_DOUBLE, &value);
 }
 
 void
-e_ews_message_add_extended_property_distinguished_tag_string (ESoapMessage *msg,
+e_ews_request_add_extended_property_distinguished_tag_string (ESoapRequest *request,
                                                              const gchar *set_id,
                                                              guint32 prop_id,
                                                              const gchar *value)
 {
-       ews_message_add_extended_property_distinguished_tag (msg, set_id, prop_id,
+       ews_request_add_extended_property_distinguished_tag (request, set_id, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_STRING, value);
 }
 
 void
-e_ews_message_add_extended_property_distinguished_tag_time (ESoapMessage *msg,
+e_ews_request_add_extended_property_distinguished_tag_time (ESoapRequest *request,
                                                            const gchar *set_id,
                                                            guint32 prop_id,
                                                            time_t value)
 {
-       ews_message_add_extended_property_distinguished_tag (msg, set_id, prop_id,
+       ews_request_add_extended_property_distinguished_tag (request, set_id, prop_id,
                E_EWS_MESSAGE_DATA_TYPE_TIME, &value);
 }
 
 void
-e_ews_message_add_delete_item_field_extended_name (ESoapMessage *msg,
+e_ews_request_add_delete_item_field_extended_name (ESoapRequest *request,
                                                   const gchar *name,
                                                   EEwsMessageDataType data_type)
 {
-       const gchar *prop_type = e_ews_message_data_type_get_xml_name (data_type);
+       const gchar *prop_type = e_ews_request_data_type_get_xml_name (data_type);
 
        g_return_if_fail (prop_type != NULL);
 
-       e_soap_message_start_element (msg, "DeleteItemField", NULL, NULL);
-       e_ews_message_write_extended_name (msg, name, prop_type);
-       e_soap_message_end_element (msg); /* DeleteItemField */
+       e_soap_request_start_element (request, "DeleteItemField", NULL, NULL);
+       e_ews_request_write_extended_name (request, name, prop_type);
+       e_soap_request_end_element (request); /* DeleteItemField */
 }
 
 void
-e_ews_message_add_delete_item_field_extended_distinguished_name (ESoapMessage *msg,
+e_ews_request_add_delete_item_field_extended_distinguished_name (ESoapRequest *request,
                                                                 const gchar *set_id,
                                                                 const gchar *name,
                                                                 EEwsMessageDataType data_type)
 {
-       const gchar *prop_type = e_ews_message_data_type_get_xml_name (data_type);
+       const gchar *prop_type = e_ews_request_data_type_get_xml_name (data_type);
 
        g_return_if_fail (prop_type != NULL);
 
-       e_soap_message_start_element (msg, "DeleteItemField", NULL, NULL);
-       e_ews_message_write_extended_distinguished_name (msg, set_id, name, prop_type);
-       e_soap_message_end_element (msg); /* DeleteItemField */
+       e_soap_request_start_element (request, "DeleteItemField", NULL, NULL);
+       e_ews_request_write_extended_distinguished_name (request, set_id, name, prop_type);
+       e_soap_request_end_element (request); /* DeleteItemField */
 }
 
 static void
-ews_message_add_extended_property_name (ESoapMessage *msg,
+ews_request_add_extended_property_name (ESoapRequest *request,
                                        const gchar *name,
                                        EEwsMessageDataType data_type,
                                        gconstpointer value)
 {
-       const gchar *prop_type = e_ews_message_data_type_get_xml_name (data_type);
+       const gchar *prop_type = e_ews_request_data_type_get_xml_name (data_type);
 
        g_return_if_fail (prop_type != NULL);
 
-       e_soap_message_start_element (msg, "ExtendedProperty", NULL, NULL);
+       e_soap_request_start_element (request, "ExtendedProperty", NULL, NULL);
 
-       e_ews_message_write_extended_name (msg, name, prop_type);
-       ews_message_write_data_value (msg, data_type, value);
+       e_ews_request_write_extended_name (request, name, prop_type);
+       ews_request_write_data_value (request, data_type, value);
 
-       e_soap_message_end_element (msg); /* ExtendedProperty */
+       e_soap_request_end_element (request); /* ExtendedProperty */
 }
 
 static void
-ews_message_add_extended_property_distinguished_name (ESoapMessage *msg,
+ews_request_add_extended_property_distinguished_name (ESoapRequest *request,
                                                      const gchar *set_id,
                                                      const gchar *name,
                                                      EEwsMessageDataType data_type,
                                                      gconstpointer value)
 {
-       const gchar *prop_type = e_ews_message_data_type_get_xml_name (data_type);
+       const gchar *prop_type = e_ews_request_data_type_get_xml_name (data_type);
 
        g_return_if_fail (prop_type != NULL);
 
-       e_soap_message_start_element (msg, "ExtendedProperty", NULL, NULL);
+       e_soap_request_start_element (request, "ExtendedProperty", NULL, NULL);
 
-       e_ews_message_write_extended_distinguished_name (msg, set_id, name, prop_type);
-       ews_message_write_data_value (msg, data_type, value);
+       e_ews_request_write_extended_distinguished_name (request, set_id, name, prop_type);
+       ews_request_write_data_value (request, data_type, value);
 
-       e_soap_message_end_element (msg); /* ExtendedProperty */
+       e_soap_request_end_element (request); /* ExtendedProperty */
 }
 
 static void
-ews_message_add_set_item_field_extended_name (ESoapMessage *msg,
+ews_request_add_set_item_field_extended_name (ESoapRequest *request,
                                              const gchar *elem_prefix,
                                              const gchar *elem_name,
                                              const gchar *name,
                                              EEwsMessageDataType data_type,
                                              gconstpointer value)
 {
-       const gchar *prop_type = e_ews_message_data_type_get_xml_name (data_type);
+       const gchar *prop_type = e_ews_request_data_type_get_xml_name (data_type);
 
        g_return_if_fail (prop_type != NULL);
 
-       e_soap_message_start_element (msg, "SetItemField", NULL, NULL);
-       e_ews_message_write_extended_name (msg, name, prop_type);
+       e_soap_request_start_element (request, "SetItemField", NULL, NULL);
+       e_ews_request_write_extended_name (request, name, prop_type);
 
-       e_soap_message_start_element (msg, elem_name, elem_prefix, NULL);
-       ews_message_add_extended_property_name (msg, name, data_type, value);
-       e_soap_message_end_element (msg); /* elem_name */
+       e_soap_request_start_element (request, elem_name, elem_prefix, NULL);
+       ews_request_add_extended_property_name (request, name, data_type, value);
+       e_soap_request_end_element (request); /* elem_name */
 
-       e_soap_message_end_element (msg); /* SetItemField */
+       e_soap_request_end_element (request); /* SetItemField */
 }
 
 static void
-ews_message_add_set_item_field_extended_distinguished_name (ESoapMessage *msg,
+ews_request_add_set_item_field_extended_distinguished_name (ESoapRequest *request,
                                                            const gchar *elem_prefix,
                                                            const gchar *elem_name,
                                                            const gchar *set_id,
@@ -661,227 +639,227 @@ ews_message_add_set_item_field_extended_distinguished_name (ESoapMessage *msg,
                                                            EEwsMessageDataType data_type,
                                                            gconstpointer value)
 {
-       const gchar *prop_type = e_ews_message_data_type_get_xml_name (data_type);
+       const gchar *prop_type = e_ews_request_data_type_get_xml_name (data_type);
 
        g_return_if_fail (prop_type != NULL);
 
-       e_soap_message_start_element (msg, "SetItemField", NULL, NULL);
+       e_soap_request_start_element (request, "SetItemField", NULL, NULL);
 
-       e_ews_message_write_extended_distinguished_name (msg, set_id, name, prop_type);
+       e_ews_request_write_extended_distinguished_name (request, set_id, name, prop_type);
 
-       e_soap_message_start_element (msg, elem_name, elem_prefix, NULL);
-       ews_message_add_extended_property_distinguished_name (msg, set_id, name, data_type, value);
-       e_soap_message_end_element (msg); /* elem_name */
+       e_soap_request_start_element (request, elem_name, elem_prefix, NULL);
+       ews_request_add_extended_property_distinguished_name (request, set_id, name, data_type, value);
+       e_soap_request_end_element (request); /* elem_name */
 
-       e_soap_message_end_element (msg); /* SetItemField */
+       e_soap_request_end_element (request); /* SetItemField */
 }
 
 void
-e_ews_message_add_set_item_field_extended_name_boolean (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_name_boolean (ESoapRequest *request,
                                                        const gchar *elem_prefix,
                                                        const gchar *elem_name,
                                                        const gchar *name,
                                                        gboolean value)
 {
-       ews_message_add_set_item_field_extended_name (msg, elem_prefix, elem_name, name,
+       ews_request_add_set_item_field_extended_name (request, elem_prefix, elem_name, name,
                E_EWS_MESSAGE_DATA_TYPE_BOOLEAN, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_name_int (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_name_int (ESoapRequest *request,
                                                    const gchar *elem_prefix,
                                                    const gchar *elem_name,
                                                    const gchar *name,
                                                    gint value)
 {
-       ews_message_add_set_item_field_extended_name (msg, elem_prefix, elem_name, name,
+       ews_request_add_set_item_field_extended_name (request, elem_prefix, elem_name, name,
                E_EWS_MESSAGE_DATA_TYPE_INT, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_name_double (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_name_double (ESoapRequest *request,
                                                       const gchar *elem_prefix,
                                                       const gchar *elem_name,
                                                       const gchar *name,
                                                       gdouble value)
 {
-       ews_message_add_set_item_field_extended_name (msg, elem_prefix, elem_name, name,
+       ews_request_add_set_item_field_extended_name (request, elem_prefix, elem_name, name,
                E_EWS_MESSAGE_DATA_TYPE_DOUBLE, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_name_string (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_name_string (ESoapRequest *request,
                                                       const gchar *elem_prefix,
                                                       const gchar *elem_name,
                                                       const gchar *name,
                                                       const gchar *value)
 {
-       ews_message_add_set_item_field_extended_name (msg, elem_prefix, elem_name, name,
+       ews_request_add_set_item_field_extended_name (request, elem_prefix, elem_name, name,
                E_EWS_MESSAGE_DATA_TYPE_STRING, value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_name_time (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_name_time (ESoapRequest *request,
                                                     const gchar *elem_prefix,
                                                     const gchar *elem_name,
                                                     const gchar *name,
                                                     time_t value)
 {
-       ews_message_add_set_item_field_extended_name (msg, elem_prefix, elem_name, name,
+       ews_request_add_set_item_field_extended_name (request, elem_prefix, elem_name, name,
                E_EWS_MESSAGE_DATA_TYPE_TIME, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_distinguished_name_boolean (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_distinguished_name_boolean (ESoapRequest *request,
                                                                      const gchar *elem_prefix,
                                                                      const gchar *elem_name,
                                                                      const gchar *set_id,
                                                                      const gchar *name,
                                                                      gboolean value)
 {
-       ews_message_add_set_item_field_extended_distinguished_name (msg, elem_prefix, elem_name, set_id, name,
+       ews_request_add_set_item_field_extended_distinguished_name (request, elem_prefix, elem_name, set_id, 
name,
                E_EWS_MESSAGE_DATA_TYPE_BOOLEAN, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_distinguished_name_int (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_distinguished_name_int (ESoapRequest *request,
                                                                  const gchar *elem_prefix,
                                                                  const gchar *elem_name,
                                                                  const gchar *set_id,
                                                                  const gchar *name,
                                                                  gint value)
 {
-       ews_message_add_set_item_field_extended_distinguished_name (msg, elem_prefix, elem_name, set_id, name,
+       ews_request_add_set_item_field_extended_distinguished_name (request, elem_prefix, elem_name, set_id, 
name,
                E_EWS_MESSAGE_DATA_TYPE_INT, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_distinguished_name_double (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_distinguished_name_double (ESoapRequest *request,
                                                                     const gchar *elem_prefix,
                                                                     const gchar *elem_name,
                                                                     const gchar *set_id,
                                                                     const gchar *name,
                                                                     gdouble value)
 {
-       ews_message_add_set_item_field_extended_distinguished_name (msg, elem_prefix, elem_name, set_id, name,
+       ews_request_add_set_item_field_extended_distinguished_name (request, elem_prefix, elem_name, set_id, 
name,
                E_EWS_MESSAGE_DATA_TYPE_DOUBLE, &value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_distinguished_name_string (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_distinguished_name_string (ESoapRequest *request,
                                                                     const gchar *elem_prefix,
                                                                     const gchar *elem_name,
                                                                     const gchar *set_id,
                                                                     const gchar *name,
                                                                     const gchar *value)
 {
-       ews_message_add_set_item_field_extended_distinguished_name (msg, elem_prefix, elem_name, set_id, name,
+       ews_request_add_set_item_field_extended_distinguished_name (request, elem_prefix, elem_name, set_id, 
name,
                E_EWS_MESSAGE_DATA_TYPE_STRING, value);
 }
 
 void
-e_ews_message_add_set_item_field_extended_distinguished_name_time (ESoapMessage *msg,
+e_ews_request_add_set_item_field_extended_distinguished_name_time (ESoapRequest *request,
                                                                   const gchar *elem_prefix,
                                                                   const gchar *elem_name,
                                                                   const gchar *set_id,
                                                                   const gchar *name,
                                                                   time_t value)
 {
-       ews_message_add_set_item_field_extended_distinguished_name (msg, elem_prefix, elem_name, set_id, name,
+       ews_request_add_set_item_field_extended_distinguished_name (request, elem_prefix, elem_name, set_id, 
name,
                E_EWS_MESSAGE_DATA_TYPE_TIME, &value);
 }
 
 void
-e_ews_message_add_extended_property_name_boolean (ESoapMessage *msg,
+e_ews_request_add_extended_property_name_boolean (ESoapRequest *request,
                                                  const gchar *name,
                                                  gboolean value)
 {
-       ews_message_add_extended_property_name (msg, name,
+       ews_request_add_extended_property_name (request, name,
                E_EWS_MESSAGE_DATA_TYPE_BOOLEAN, &value);
 }
 
 void
-e_ews_message_add_extended_property_name_int (ESoapMessage *msg,
+e_ews_request_add_extended_property_name_int (ESoapRequest *request,
                                              const gchar *name,
                                              gint value)
 {
-       ews_message_add_extended_property_name (msg, name,
+       ews_request_add_extended_property_name (request, name,
                E_EWS_MESSAGE_DATA_TYPE_INT, &value);
 }
 
 void
-e_ews_message_add_extended_property_name_double (ESoapMessage *msg,
+e_ews_request_add_extended_property_name_double (ESoapRequest *request,
                                                 const gchar *name,
                                                 gdouble value)
 {
-       ews_message_add_extended_property_name (msg, name,
+       ews_request_add_extended_property_name (request, name,
                E_EWS_MESSAGE_DATA_TYPE_DOUBLE, &value);
 }
 
 void
-e_ews_message_add_extended_property_name_string (ESoapMessage *msg,
+e_ews_request_add_extended_property_name_string (ESoapRequest *request,
                                                 const gchar *name,
                                                 const gchar *value)
 {
-       ews_message_add_extended_property_name (msg, name,
+       ews_request_add_extended_property_name (request, name,
                E_EWS_MESSAGE_DATA_TYPE_STRING, value);
 }
 
 void
-e_ews_message_add_extended_property_name_time (ESoapMessage *msg,
+e_ews_request_add_extended_property_name_time (ESoapRequest *request,
                                               const gchar *name,
                                               time_t value)
 {
-       ews_message_add_extended_property_name (msg, name,
+       ews_request_add_extended_property_name (request, name,
                E_EWS_MESSAGE_DATA_TYPE_TIME, &value);
 }
 
 void
-e_ews_message_add_extended_property_distinguished_name_boolean (ESoapMessage *msg,
+e_ews_request_add_extended_property_distinguished_name_boolean (ESoapRequest *request,
                                                                const gchar *set_id,
                                                                const gchar *name,
                                                                gboolean value)
 {
-       ews_message_add_extended_property_distinguished_name (msg, set_id, name,
+       ews_request_add_extended_property_distinguished_name (request, set_id, name,
                E_EWS_MESSAGE_DATA_TYPE_BOOLEAN, &value);
 }
 
 void
-e_ews_message_add_extended_property_distinguished_name_int (ESoapMessage *msg,
+e_ews_request_add_extended_property_distinguished_name_int (ESoapRequest *request,
                                                            const gchar *set_id,
                                                            const gchar *name,
                                                            gint value)
 {
-       ews_message_add_extended_property_distinguished_name (msg, set_id, name,
+       ews_request_add_extended_property_distinguished_name (request, set_id, name,
                E_EWS_MESSAGE_DATA_TYPE_INT, &value);
 }
 
 void
-e_ews_message_add_extended_property_distinguished_name_double (ESoapMessage *msg,
+e_ews_request_add_extended_property_distinguished_name_double (ESoapRequest *request,
                                                               const gchar *set_id,
                                                               const gchar *name,
                                                               gdouble value)
 {
-       ews_message_add_extended_property_distinguished_name (msg, set_id, name,
+       ews_request_add_extended_property_distinguished_name (request, set_id, name,
                E_EWS_MESSAGE_DATA_TYPE_DOUBLE, &value);
 }
 
 void
-e_ews_message_add_extended_property_distinguished_name_string (ESoapMessage *msg,
+e_ews_request_add_extended_property_distinguished_name_string (ESoapRequest *request,
                                                               const gchar *set_id,
                                                               const gchar *name,
                                                               const gchar *value)
 {
-       ews_message_add_extended_property_distinguished_name (msg, set_id, name,
+       ews_request_add_extended_property_distinguished_name (request, set_id, name,
                E_EWS_MESSAGE_DATA_TYPE_STRING, value);
 }
 
 void
-e_ews_message_add_extended_property_distinguished_name_time (ESoapMessage *msg,
+e_ews_request_add_extended_property_distinguished_name_time (ESoapRequest *request,
                                                             const gchar *set_id,
                                                             const gchar *name,
                                                             time_t value)
 {
-       ews_message_add_extended_property_distinguished_name (msg, set_id, name,
+       ews_request_add_extended_property_distinguished_name (request, set_id, name,
                E_EWS_MESSAGE_DATA_TYPE_TIME, &value);
 }
diff --git a/src/EWS/common/e-ews-item-change.h b/src/EWS/common/e-ews-item-change.h
index 52aaa09c..d81fd29f 100644
--- a/src/EWS/common/e-ews-item-change.h
+++ b/src/EWS/common/e-ews-item-change.h
@@ -9,7 +9,7 @@
 #define E_EWS_ITEM_CHANGE_H
 
 #include "e-ews-folder.h"
-#include "e-soap-message.h"
+#include "e-soap-request.h"
 #include "e-soap-response.h"
 
 G_BEGIN_DECLS
@@ -21,23 +21,35 @@ typedef enum {
        E_EWS_ITEMCHANGE_TYPE_RECURRINGMASTER,
 } EEwsItemChangeType;
 
-void e_ews_message_start_folder_change (ESoapMessage *msg, const gchar *email, const EwsFolderId *folder_id);
-void e_ews_message_start_item_change (ESoapMessage *msg, EEwsItemChangeType type,
-                                    const gchar *itemid, const gchar *changekey,
-                                    gint instance_index);
-void e_ews_message_end_item_change (ESoapMessage *msg);
-
-void e_ews_message_start_set_item_field (ESoapMessage *msg, const gchar *name, const gchar * 
fielduri_prefix, const gchar *field_kind);
-
-void e_ews_message_start_set_indexed_item_field (ESoapMessage *msg, const gchar *name, const gchar * 
fielduri_prefix, const gchar *field_kind, const gchar *field_index, gboolean delete_field);
-
-void e_ews_message_end_set_indexed_item_field (ESoapMessage *msg, gboolean delete_field);
-
-void e_ews_message_end_set_item_field (ESoapMessage *msg);
-
-void e_ews_message_add_delete_item_field (ESoapMessage *msg, const gchar *name, const gchar 
*fielduri_prefix);
-
-void e_ews_message_add_delete_item_field_indexed (ESoapMessage *msg, const gchar *name, const gchar 
*fielduri_prefix, const gchar *field_index);
+void   e_ews_request_start_folder_change                       (ESoapRequest *request,
+                                                                const gchar *email,
+                                                                const EwsFolderId *folder_id);
+void   e_ews_request_start_item_change                         (ESoapRequest *request,
+                                                                EEwsItemChangeType type,
+                                                                const gchar *itemid,
+                                                                const gchar *changekey,
+                                                                gint instance_index);
+void   e_ews_request_end_item_change                           (ESoapRequest *request);
+void   e_ews_request_start_set_item_field                      (ESoapRequest *request,
+                                                                const gchar *name,
+                                                                const gchar *fielduri_prefix,
+                                                                const gchar *field_kind);
+void   e_ews_request_start_set_indexed_item_field              (ESoapRequest *request,
+                                                                const gchar *name,
+                                                                const gchar *fielduri_prefix,
+                                                                const gchar *field_kind,
+                                                                const gchar *field_index,
+                                                                gboolean delete_field);
+void   e_ews_request_end_set_indexed_item_field                (ESoapRequest *request,
+                                                                gboolean delete_field);
+void   e_ews_request_end_set_item_field                        (ESoapRequest *request);
+void   e_ews_request_add_delete_item_field                     (ESoapRequest *request,
+                                                                const gchar *name,
+                                                                const gchar *fielduri_prefix);
+void   e_ews_request_add_delete_item_field_indexed             (ESoapRequest *request,
+                                                                const gchar *name,
+                                                                const gchar *fielduri_prefix,
+                                                                const gchar *field_index);
 
 typedef enum {
        E_EWS_MESSAGE_DATA_TYPE_BOOLEAN,
@@ -48,231 +60,230 @@ typedef enum {
 } EEwsMessageDataType;
 
 const gchar *
-       e_ews_message_data_type_get_xml_name                    (EEwsMessageDataType data_type);
+       e_ews_request_data_type_get_xml_name                    (EEwsMessageDataType data_type);
 
-void   e_ews_message_add_delete_item_field_extended_tag        (ESoapMessage *msg,
+void   e_ews_request_add_delete_item_field_extended_tag        (ESoapRequest *request,
                                                                 guint32 prop_id,
                                                                 EEwsMessageDataType data_type);
 
-void   e_ews_message_add_delete_item_field_extended_distinguished_tag
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_delete_item_field_extended_distinguished_tag
+                                                               (ESoapRequest *request,
                                                                 const gchar *set_id,
                                                                 guint32 prop_id,
                                                                 EEwsMessageDataType data_type);
 
-void   e_ews_message_add_set_item_field_extended_tag_boolean   (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_tag_boolean   (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 guint32 prop_id,
                                                                 gboolean value);
-void   e_ews_message_add_set_item_field_extended_tag_int       (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_tag_int       (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 guint32 prop_id,
                                                                 gint value);
-void   e_ews_message_add_set_item_field_extended_tag_double    (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_tag_double    (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 guint32 prop_id,
                                                                 gdouble value);
-void   e_ews_message_add_set_item_field_extended_tag_string    (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_tag_string    (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 guint32 prop_id,
                                                                 const gchar *value);
-void   e_ews_message_add_set_item_field_extended_tag_time      (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_tag_time      (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 guint32 prop_id,
                                                                 time_t value);
-void   e_ews_message_add_set_item_field_extended_distinguished_tag_boolean
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_distinguished_tag_boolean
+                                                               (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *set_id,
                                                                 guint32 prop_id,
                                                                 gboolean value);
-void   e_ews_message_add_set_item_field_extended_distinguished_tag_int
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_distinguished_tag_int
+                                                               (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *set_id,
                                                                 guint32 prop_id,
                                                                 gint value);
-void   e_ews_message_add_set_item_field_extended_distinguished_tag_double
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_distinguished_tag_double
+                                                               (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *set_id,
                                                                 guint32 prop_id,
                                                                 gdouble value);
-void   e_ews_message_add_set_item_field_extended_distinguished_tag_string
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_distinguished_tag_string
+                                                               (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *set_id,
                                                                 guint32 prop_id,
                                                                 const gchar *value);
-void   e_ews_message_add_set_item_field_extended_distinguished_tag_time
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_distinguished_tag_time
+                                                               (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *set_id,
                                                                 guint32 prop_id,
                                                                 time_t value);
-void   e_ews_message_add_extended_property_tag_boolean         (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_tag_boolean         (ESoapRequest *request,
                                                                 guint32 prop_id,
                                                                 gboolean value);
-void   e_ews_message_add_extended_property_tag_int             (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_tag_int             (ESoapRequest *request,
                                                                 guint32 prop_id,
                                                                 gint value);
-void   e_ews_message_add_extended_property_tag_double          (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_tag_double          (ESoapRequest *request,
                                                                 guint32 prop_id,
                                                                 gdouble value);
-void   e_ews_message_add_extended_property_tag_string          (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_tag_string          (ESoapRequest *request,
                                                                 guint32 prop_id,
                                                                 const gchar *value);
-void   e_ews_message_add_extended_property_tag_time            (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_tag_time            (ESoapRequest *request,
                                                                 guint32 prop_id,
                                                                 time_t value);
-void   e_ews_message_add_extended_property_distinguished_tag_boolean
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_distinguished_tag_boolean
+                                                               (ESoapRequest *request,
                                                                 const gchar *set_id,
                                                                 guint32 prop_id,
                                                                 gboolean value);
-void   e_ews_message_add_extended_property_distinguished_tag_int
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_distinguished_tag_int
+                                                               (ESoapRequest *request,
                                                                 const gchar *set_id,
                                                                 guint32 prop_id,
                                                                 gint value);
-void   e_ews_message_add_extended_property_distinguished_tag_double
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_distinguished_tag_double
+                                                               (ESoapRequest *request,
                                                                 const gchar *set_id,
                                                                 guint32 prop_id,
                                                                 gdouble value);
-void   e_ews_message_add_extended_property_distinguished_tag_string
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_distinguished_tag_string
+                                                               (ESoapRequest *request,
                                                                 const gchar *set_id,
                                                                 guint32 prop_id,
                                                                 const gchar *value);
-void   e_ews_message_add_extended_property_distinguished_tag_time
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_distinguished_tag_time
+                                                               (ESoapRequest *request,
                                                                 const gchar *set_id,
                                                                 guint32 prop_id,
                                                                 time_t value);
 
-void   e_ews_message_add_delete_item_field_extended_name       (ESoapMessage *msg,
+void   e_ews_request_add_delete_item_field_extended_name       (ESoapRequest *request,
                                                                 const gchar *name,
                                                                 EEwsMessageDataType data_type);
 
-void   e_ews_message_add_delete_item_field_extended_distinguished_name
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_delete_item_field_extended_distinguished_name
+                                                               (ESoapRequest *request,
                                                                 const gchar *set_id,
                                                                 const gchar *name,
                                                                 EEwsMessageDataType data_type);
 
-void   e_ews_message_add_set_item_field_extended_name_boolean  (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_name_boolean  (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *name,
                                                                 gboolean value);
-void   e_ews_message_add_set_item_field_extended_name_int      (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_name_int      (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *name,
                                                                 gint value);
-void   e_ews_message_add_set_item_field_extended_name_double   (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_name_double   (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *name,
                                                                 gdouble value);
-void   e_ews_message_add_set_item_field_extended_name_string   (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_name_string   (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *name,
                                                                 const gchar *value);
-void   e_ews_message_add_set_item_field_extended_name_time     (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_name_time     (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *name,
                                                                 time_t value);
-void   e_ews_message_add_set_item_field_extended_distinguished_name_boolean
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_distinguished_name_boolean
+                                                               (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *set_id,
                                                                 const gchar *name,
                                                                 gboolean value);
-void   e_ews_message_add_set_item_field_extended_distinguished_name_int
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_distinguished_name_int
+                                                               (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *set_id,
                                                                 const gchar *name,
                                                                 gint value);
-void   e_ews_message_add_set_item_field_extended_distinguished_name_double
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_distinguished_name_double
+                                                               (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *set_id,
                                                                 const gchar *name,
                                                                 gdouble value);
-void   e_ews_message_add_set_item_field_extended_distinguished_name_string
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_distinguished_name_string
+                                                               (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *set_id,
                                                                 const gchar *name,
                                                                 const gchar *value);
-void   e_ews_message_add_set_item_field_extended_distinguished_name_time
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_set_item_field_extended_distinguished_name_time
+                                                               (ESoapRequest *request,
                                                                 const gchar *elem_prefix,
                                                                 const gchar *elem_name,
                                                                 const gchar *set_id,
                                                                 const gchar *name,
                                                                 time_t value);
-void   e_ews_message_add_extended_property_name_boolean        (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_name_boolean        (ESoapRequest *request,
                                                                 const gchar *name,
                                                                 gboolean value);
-void   e_ews_message_add_extended_property_name_int            (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_name_int            (ESoapRequest *request,
                                                                 const gchar *name,
                                                                 gint value);
-void   e_ews_message_add_extended_property_name_double         (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_name_double         (ESoapRequest *request,
                                                                 const gchar *name,
                                                                 gdouble value);
-void   e_ews_message_add_extended_property_name_string         (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_name_string         (ESoapRequest *request,
                                                                 const gchar *name,
                                                                 const gchar *value);
-void   e_ews_message_add_extended_property_name_time           (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_name_time           (ESoapRequest *request,
                                                                 const gchar *name,
                                                                 time_t value);
-void   e_ews_message_add_extended_property_distinguished_name_boolean
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_distinguished_name_boolean
+                                                               (ESoapRequest *request,
                                                                 const gchar *set_id,
                                                                 const gchar *name,
                                                                 gboolean value);
-void   e_ews_message_add_extended_property_distinguished_name_int
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_distinguished_name_int
+                                                               (ESoapRequest *request,
                                                                 const gchar *set_id,
                                                                 const gchar *name,
                                                                 gint value);
-void   e_ews_message_add_extended_property_distinguished_name_double
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_distinguished_name_double
+                                                               (ESoapRequest *request,
                                                                 const gchar *set_id,
                                                                 const gchar *name,
                                                                 gdouble value);
-void   e_ews_message_add_extended_property_distinguished_name_string
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_distinguished_name_string
+                                                               (ESoapRequest *request,
                                                                 const gchar *set_id,
                                                                 const gchar *name,
                                                                 const gchar *value);
-void   e_ews_message_add_extended_property_distinguished_name_time
-                                                               (ESoapMessage *msg,
+void   e_ews_request_add_extended_property_distinguished_name_time
+                                                               (ESoapRequest *request,
                                                                 const gchar *set_id,
                                                                 const gchar *name,
                                                                 time_t value);
 
-
 G_END_DECLS
 
 #endif
diff --git a/src/EWS/common/e-ews-item.c b/src/EWS/common/e-ews-item.c
index 4bf3b2cb..d08fdf4b 100644
--- a/src/EWS/common/e-ews-item.c
+++ b/src/EWS/common/e-ews-item.c
@@ -14,7 +14,7 @@
 #include <glib.h>
 #include <glib/gstdio.h>
 #include <glib/gprintf.h>
-#include <libsoup/soup-misc.h>
+#include <libsoup/soup.h>
 #include <libedataserver/libedataserver.h>
 #include <libecal/libecal.h>
 
diff --git a/src/EWS/common/e-ews-item.h b/src/EWS/common/e-ews-item.h
index 77fbd3f1..0fa1ba58 100644
--- a/src/EWS/common/e-ews-item.h
+++ b/src/EWS/common/e-ews-item.h
@@ -7,9 +7,9 @@
 #ifndef E_EWS_ITEM_H
 #define E_EWS_ITEM_H
 
-#include "e-soap-message.h"
+#include "e-soap-request.h"
 #include "e-soap-response.h"
-#include "e-ews-message.h"
+#include "e-ews-request.h"
 
 G_BEGIN_DECLS
 
diff --git a/src/EWS/common/e-ews-notification.c b/src/EWS/common/e-ews-notification.c
index f793f9da..37860229 100644
--- a/src/EWS/common/e-ews-notification.c
+++ b/src/EWS/common/e-ews-notification.c
@@ -11,15 +11,11 @@
 #include "e-ews-connection-utils.h"
 #include "e-ews-debug.h"
 #include "e-ews-notification.h"
-#include "e-soup-auth-negotiate.h"
-
-#define EWS_NOTIFICATION_CANCEL_KEY "ews-notification-cancel-key"
 
 struct _EEwsNotificationPrivate {
        GMutex thread_lock;
        SoupSession *soup_session;
        GWeakRef connection_wk;
-       GByteArray *chunk;
        GCancellable *cancellable;
        gchar *last_subscription_id; /* guarded by the caller, because it can be set only after construct */
 };
@@ -48,6 +44,12 @@ static const gchar *default_events_names[] = {
        NULL
 };
 
+const gchar * const *
+e_ews_notification_get_event_names (void)
+{
+       return (const gchar * const *) default_events_names;
+}
+
 typedef struct _EEwsNotificationThreadData EEwsNotificationThreadData;
 
 struct _EEwsNotificationThreadData {
@@ -65,26 +67,6 @@ e_ews_notification_ref_connection (const EEwsNotification *notification)
        return g_weak_ref_get (&notification->priv->connection_wk);
 }
 
-static void
-ews_notification_authenticate (SoupSession *session,
-                              SoupMessage *message,
-                              SoupAuth *auth,
-                              gboolean retrying,
-                              gpointer data)
-{
-       EEwsNotification *notification = data;
-       EEwsConnection *cnc;
-
-       g_return_if_fail (notification != NULL);
-
-       cnc = e_ews_notification_ref_connection (notification);
-
-       if (cnc) {
-               e_ews_connection_utils_authenticate (cnc, session, message, auth, retrying);
-               g_clear_object (&cnc);
-       }
-}
-
 EEwsNotification *
 e_ews_notification_new (EEwsConnection *connection,
                        gchar *last_subscription_id)
@@ -179,11 +161,7 @@ ews_notification_dispose (GObject *object)
        if (notif->priv->cancellable != NULL)
                g_cancellable_cancel (notif->priv->cancellable);
 
-       if (notif->priv->soup_session != NULL) {
-               g_signal_handlers_disconnect_by_func (notif->priv->soup_session, 
ews_notification_authenticate, object);
-               g_clear_object (&notif->priv->soup_session);
-       }
-
+       g_clear_object (&notif->priv->soup_session);
        g_clear_object (&notif->priv->cancellable);
        g_weak_ref_set (&notif->priv->connection_wk, NULL);
 
@@ -256,36 +234,27 @@ e_ews_notification_init (EEwsNotification *notification)
                                          SOUP_TYPE_COOKIE_JAR);
 
        log_level = e_ews_debug_get_log_level ();
-       if (log_level >= 2) {
+       if (log_level > 0) {
                SoupLogger *logger;
-               logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, -1);
+               logger = soup_logger_new (SOUP_LOGGER_LOG_BODY);
 
                if (log_level == 2)
                        soup_logger_set_printer (logger, e_ews_debug_soup_log_printer_stdout, NULL, NULL);
 
                soup_session_add_feature (notification->priv->soup_session, SOUP_SESSION_FEATURE (logger));
+
                g_object_unref (logger);
        }
-
-       g_signal_connect (notification->priv->soup_session, "authenticate", G_CALLBACK 
(ews_notification_authenticate), notification);
 }
 
 static gboolean
 e_ews_notification_subscribe_folder_sync (EEwsNotification *notification,
-                                         GSList *folders,
-                                         gchar **subscription_id,
+                                         GSList *folder_ids, /* gchar * */
+                                         gchar **out_subscription_id,
                                          GCancellable *cancellable)
 {
        EEwsConnection *cnc;
-       ESoapMessage *msg;
-       ESoapResponse *response;
-       ESoapParameter *param, *subparam;
-       CamelEwsSettings *settings;
-       GError *error = NULL;
-       GSList *l;
-       guint event_type;
-       xmlDoc *doc;
-       gint log_level = e_ews_debug_get_log_level ();
+       gboolean success;
 
        g_return_val_if_fail (notification != NULL, FALSE);
        g_return_val_if_fail (notification->priv != NULL, FALSE);
@@ -299,152 +268,22 @@ e_ews_notification_subscribe_folder_sync (EEwsNotification *notification,
        if (!cnc)
                return FALSE;
 
-       settings = e_ews_connection_ref_settings (cnc);
-
-       msg = e_ews_message_new_with_header (
-               settings,
-               e_ews_connection_get_uri (cnc),
-               e_ews_connection_get_impersonate_user (cnc),
-               "Subscribe",
-               NULL,
-               NULL,
-               e_ews_connection_get_server_version (cnc),
-               E_EWS_EXCHANGE_2010_SP1,
-               FALSE,
-               FALSE);
-
-       g_clear_object (&settings);
-
-       if (!msg) {
-               e_ews_debug_print ("%s: Failed to create Soup message for URI '%s'\n", G_STRFUNC, 
e_ews_connection_get_uri (cnc));
-               g_object_unref (cnc);
-               return FALSE;
-       }
-
-       e_soap_message_start_element (msg, "StreamingSubscriptionRequest", "messages", NULL);
-
-       e_soap_message_start_element (msg, "FolderIds", NULL, NULL);
-       for (l = folders; l; l = l->next) {
-               e_ews_message_write_string_parameter_with_attribute (
-                       msg,
-                       "FolderId",
-                       NULL,
-                       NULL,
-                       "Id",
-                       l->data);
-       }
-       e_soap_message_end_element (msg); /* FolderIds */
-
-       e_soap_message_start_element (msg, "EventTypes", NULL, NULL);
-       for (event_type = 0; default_events_names[event_type] != NULL; event_type++) {
-               if (g_strcmp0 (default_events_names[event_type], "StatusEvent") == 0)
-                       continue;
-
-               e_ews_message_write_string_parameter_with_attribute (
-                       msg,
-                       "EventType",
-                       NULL,
-                       default_events_names[event_type],
-                       NULL,
-                       NULL);
-       }
-       e_soap_message_end_element (msg); /* EventTypes */
-
-       e_soap_message_end_element (msg); /* StreamingSubscriptionRequest */
-       e_ews_message_write_footer (msg); /* Complete the footer and print the request */
-
-       soup_message_body_set_accumulate (SOUP_MESSAGE (msg)->response_body, TRUE);
-
-       if (g_cancellable_is_cancelled (cancellable)) {
-               g_object_unref (msg);
-               g_object_unref (cnc);
-               return FALSE;
-       }
-
-       if (log_level >= 1 && log_level < 4) {
-               e_ews_debug_dump_raw_soup_request (SOUP_MESSAGE (msg));
-       }
-
-       if (!e_ews_connection_utils_prepare_message (cnc, notification->priv->soup_session, SOUP_MESSAGE 
(msg), cancellable)) {
-               g_object_unref (msg);
-               g_object_unref (cnc);
-               return FALSE;
-       }
-
-       soup_session_send_message (notification->priv->soup_session, SOUP_MESSAGE (msg));
-       if (!SOUP_STATUS_IS_SUCCESSFUL (SOUP_MESSAGE (msg)->status_code)) {
-               g_object_unref (msg);
-               g_object_unref (cnc);
-               return FALSE;
-       }
-
-       doc = xmlReadMemory (
-               SOUP_MESSAGE (msg)->response_body->data,
-               SOUP_MESSAGE (msg)->response_body->length,
-               "response.xml", NULL, 0);
+       success = e_ews_connection_subscribe_sync (cnc, G_PRIORITY_DEFAULT, folder_ids, out_subscription_id, 
cancellable, NULL);
 
-       response = e_soap_response_new_from_xmldoc (doc);
+       g_signal_emit (notification, signals[SUBSCRIPTION_ID_CHANGED], 0, success ? *out_subscription_id : 
NULL, NULL);
 
-       if (log_level >= 1 && log_level < 4) {
-               e_ews_debug_dump_raw_soup_response (SOUP_MESSAGE (msg));
-       }
-       g_object_unref (msg);
        g_object_unref (cnc);
 
-       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &error);
-
-       /* Sanity check */
-       g_warn_if_fail ((param != NULL && error == NULL) || (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               e_ews_debug_print (G_STRLOC ": %s\n", error->message);
-               g_error_free (error);
-
-               g_object_unref (response);
-               return FALSE;
-       }
-
-       subparam = e_soap_parameter_get_first_child (param);
-
-       while (subparam != NULL) {
-               const gchar *name = (const gchar *) subparam->name;
-
-               if (!ews_get_response_status (subparam, &error)) {
-                       e_ews_debug_print (G_STRLOC ": %s\n", error->message);
-                       g_error_free (error);
-
-                       g_object_unref (response);
-                       return FALSE;
-               }
-
-               if (E_EWS_CONNECTION_UTILS_CHECK_ELEMENT (name, "SubscribeResponseMessage")) {
-                       ESoapParameter *node;
-
-                       node = e_soap_parameter_get_first_child_by_name (subparam, "SubscriptionId");
-                       *subscription_id = e_soap_parameter_get_string_value (node);
-               }
-
-               subparam = e_soap_parameter_get_next_child (subparam);
-       }
-
-       g_object_unref (response);
-
-       g_signal_emit (notification, signals[SUBSCRIPTION_ID_CHANGED], 0, *subscription_id, NULL);
-
-       return TRUE;
+       return success;
 }
 
 static gboolean
 e_ews_notification_unsubscribe_folder_sync (EEwsNotification *notification,
-                                           const gchar *subscription_id)
+                                           const gchar *subscription_id,
+                                           GCancellable *cancellable)
 {
        EEwsConnection *cnc;
-       ESoapMessage *msg;
-       ESoapResponse *response;
-       ESoapParameter *param;
-       CamelEwsSettings *settings;
-       GError *error = NULL;
-       xmlDoc *doc;
+       gboolean success;
 
        g_return_val_if_fail (notification != NULL, FALSE);
        g_return_val_if_fail (notification->priv != NULL, FALSE);
@@ -455,76 +294,15 @@ e_ews_notification_unsubscribe_folder_sync (EEwsNotification *notification,
        if (!cnc)
                return FALSE;
 
-       settings = e_ews_connection_ref_settings (cnc);
-
-       msg = e_ews_message_new_with_header (
-               settings,
-               e_ews_connection_get_uri (cnc),
-               e_ews_connection_get_impersonate_user (cnc),
-               "Unsubscribe",
-               NULL,
-               NULL,
-               e_ews_connection_get_server_version (cnc),
-               E_EWS_EXCHANGE_2010_SP1,
-               FALSE,
-               FALSE);
-
-       g_clear_object (&settings);
-
-       if (!msg) {
-               e_ews_debug_print ("%s: Failed to create Soup message for URI '%s'\n", G_STRFUNC, 
e_ews_connection_get_uri (cnc));
-               g_object_unref (cnc);
-               return FALSE;
-       }
-
-       e_ews_message_write_string_parameter_with_attribute (
-               msg, "SubscriptionId", "messages", subscription_id, NULL, NULL);
+       success = e_ews_connection_unsubscribe_sync (cnc, G_PRIORITY_DEFAULT, subscription_id, cancellable, 
NULL);
 
-       e_ews_message_write_footer (msg); /* Complete the footer and print the request */
-
-       soup_message_body_set_accumulate (SOUP_MESSAGE (msg)->response_body, TRUE);
-
-       if (!e_ews_connection_utils_prepare_message (cnc, notification->priv->soup_session, SOUP_MESSAGE 
(msg), notification->priv->cancellable)) {
-               g_object_unref (msg);
-               g_object_unref (cnc);
-               return FALSE;
-       }
-
-       soup_session_send_message (notification->priv->soup_session, SOUP_MESSAGE (msg));
-       if (!SOUP_STATUS_IS_SUCCESSFUL (SOUP_MESSAGE (msg)->status_code)) {
-               g_object_unref (msg);
-               g_object_unref (cnc);
-               return FALSE;
-       }
-
-       doc = xmlReadMemory (
-               SOUP_MESSAGE (msg)->response_body->data,
-               SOUP_MESSAGE (msg)->response_body->length,
-               "response.xml", NULL, 0);
+       g_signal_emit (notification, signals[SUBSCRIPTION_ID_CHANGED], 0, NULL, NULL);
 
-       response = e_soap_response_new_from_xmldoc (doc);
-       g_object_unref (msg);
        g_object_unref (cnc);
 
-       param = e_soap_response_get_first_parameter_by_name (response, "ResponseMessages", &error);
-
-       /* Sanity check */
-       g_warn_if_fail ((param != NULL && error == NULL) || (param == NULL && error != NULL));
-
-       g_object_unref (response);
-
-       if (error != NULL) {
-               e_ews_debug_print (G_STRLOC ": %s\n", error->message);
-               g_error_free (error);
-               return FALSE;
-       }
-
-       g_signal_emit (notification, signals[SUBSCRIPTION_ID_CHANGED], 0, NULL, NULL);
-
-       return TRUE;
+       return success;
 }
 
-
 static EEwsNotificationEvent *
 get_folder_event_info (ESoapParameter *param,
                       EEwsNotificationEventType event_type)
@@ -672,36 +450,13 @@ ews_notification_fire_events_from_response (EEwsNotification *notification,
        return TRUE;
 }
 
-static gboolean
-ews_abort_session_idle_cb (gpointer user_data)
-{
-       SoupSession *session = user_data;
-
-       g_return_val_if_fail (SOUP_IS_SESSION (session), FALSE);
-
-       soup_session_abort (session);
-
-       return FALSE;
-}
-
 static void
-ews_notification_schedule_abort (SoupSession *session)
+ews_notification_process_chunk (EEwsNotification *notification,
+                               GByteArray *chunk_data,
+                               GCancellable *cancellable)
 {
-       g_return_if_fail (SOUP_IS_SESSION (session));
-
-       g_idle_add_full (G_PRIORITY_HIGH_IDLE, ews_abort_session_idle_cb, g_object_ref (session), 
g_object_unref);
-}
-
-static void
-ews_notification_soup_got_chunk (SoupMessage *msg,
-                                SoupBuffer *chunk,
-                                gpointer user_data)
-{
-       EEwsNotification *notification = user_data;
        const gchar *chunk_str;
        gsize chunk_len;
-       gboolean keep_parsing = TRUE;
-       gint log_level = e_ews_debug_get_log_level ();
 
        /*
         * Here we receive, in chunks, "well-formed" messages that contain:
@@ -712,27 +467,20 @@ ews_notification_soup_got_chunk (SoupMessage *msg,
         * division -- one part already read, the other just arriving)
         *
         * We are parsing those chunks in the following way:
-        * 1. Append newly arrived chunk->data to notification->priv->chunk->data
-        * 2. Search for </Envelope> in notification->priv->chunk->data
-        * 3.1 </Envelope> is not found: Do nothing. Waiting for the next chunk
-        * 3.2 </Envelope> is found: Get the pair <Envelope>...</Envelope> and handle it
-        * 4. Update the notification->priv->chunk->{data,len}, removing the pair used in 3.2
-        * 5. Repeat from 2, until that 3.1 happens
+        * 1. Search for </Envelope> in chunk_data
+        * 2.1 </Envelope> is not found: Do nothing. Waiting for the next chunk
+        * 2.2 </Envelope> is found: Get the pair <Envelope>...</Envelope> and handle it
+        * 3. Update the chunk_data, removing the pair used in 2.2
+        * 4. Repeat from 1, until the 2.1 happens
         */
-       if (notification->priv->chunk == NULL)
-               notification->priv->chunk = g_byte_array_new ();
 
-       notification->priv->chunk =
-               g_byte_array_append (notification->priv->chunk, (guint8 *) chunk->data, chunk->length);
-
-       chunk_str = (gchar *) notification->priv->chunk->data;
-       chunk_len = notification->priv->chunk->len;
+       chunk_str = (const gchar *) chunk_data->data;
+       chunk_len = chunk_data->len;
 
        do {
                ESoapResponse *response;
                const gchar *end;
                gsize len;
-               gboolean cancelled = FALSE;
 
                end = g_strstr_len (chunk_str, chunk_len, "</Envelope>");
 
@@ -745,80 +493,20 @@ ews_notification_soup_got_chunk (SoupMessage *msg,
                if (response == NULL)
                        break;
 
-               if (log_level >= 1 && log_level < 4) {
-                       e_ews_debug_dump_raw_soup_response (msg);
-                       e_soap_response_dump_response (response, stdout);
-               }
-
                if (!ews_notification_fire_events_from_response (notification, response)) {
-                       /* Mark the cancellation as not being fatal */
-                       g_object_set_data (G_OBJECT (msg), EWS_NOTIFICATION_CANCEL_KEY, GINT_TO_POINTER (1));
-                       ews_notification_schedule_abort (notification->priv->soup_session);
-
                        g_object_unref (response);
                        break;
                }
                g_object_unref (response);
 
-               notification->priv->chunk = g_byte_array_remove_range (notification->priv->chunk, 0, len);
-
-               chunk_str = (gchar *) notification->priv->chunk->data;
-               chunk_len = notification->priv->chunk->len;
-
-               cancelled = g_cancellable_is_cancelled (notification->priv->cancellable);
-               if (chunk_len == 0 || cancelled) {
-                       g_byte_array_free (notification->priv->chunk, TRUE);
-                       notification->priv->chunk = NULL;
-                       keep_parsing = FALSE;
-
-                       if (cancelled) {
-                               /* Abort any pending operations, but not here, rather in another thread */
-                               ews_notification_schedule_abort (notification->priv->soup_session);
-                       }
-               }
-       } while (keep_parsing);
-}
-
-typedef struct _NotifcationCancelData {
-       SoupSession *session;
-       SoupMessage *msg;
-} NotifcationCancelData;
-
-static NotifcationCancelData *
-notifcation_cancel_data_new (SoupSession *session,
-                            SoupMessage *msg)
-{
-       NotifcationCancelData *ncd;
-
-       ncd = g_slice_new (NotifcationCancelData);
-       ncd->session = g_object_ref (session);
-       ncd->msg = g_object_ref (msg);
-
-       return ncd;
-}
-
-static void
-notifcation_cancel_data_free (gpointer ptr)
-{
-       NotifcationCancelData *ncd = ptr;
+               g_byte_array_remove_range (chunk_data, 0, len);
 
-       if (ncd) {
-               g_clear_object (&ncd->session);
-               g_clear_object (&ncd->msg);
-               g_slice_free (NotifcationCancelData, ncd);
-       }
+               chunk_str = (gchar *) chunk_data->data;
+               chunk_len = chunk_data->len;
+       } while (chunk_len > 0 && !g_cancellable_is_cancelled (cancellable));
 }
 
-static void
-ews_notification_cancelled_cb (GCancellable *cancellable,
-                              gpointer user_data)
-{
-       NotifcationCancelData *ncd = user_data;
-
-       g_return_if_fail (ncd != NULL);
-
-       soup_session_cancel_message (ncd->session, ncd->msg, SOUP_STATUS_CANCELLED);
-}
+#define BUFFER_SIZE 16384
 
 static gboolean
 e_ews_notification_get_events_sync (EEwsNotification *notification,
@@ -827,11 +515,12 @@ e_ews_notification_get_events_sync (EEwsNotification *notification,
                                    GCancellable *cancellable)
 {
        EEwsConnection *cnc;
-       ESoapMessage *msg;
-       CamelEwsSettings *settings;
-       gboolean ret;
-       gulong handler_id, cancel_handler_id;
-       guint status_code;
+       GInputStream *input_stream = NULL;
+       GByteArray *chunk_data;
+       gpointer buffer;
+       gssize nread = 0;
+       gboolean success;
+       GError *local_error = NULL;
 
        g_return_val_if_fail (out_fatal_error != NULL, FALSE);
 
@@ -848,71 +537,37 @@ e_ews_notification_get_events_sync (EEwsNotification *notification,
        if (!cnc)
                return FALSE;
 
-       settings = e_ews_connection_ref_settings (cnc);
-
-       msg = e_ews_message_new_with_header (
-               settings,
-               e_ews_connection_get_uri (cnc),
-               e_ews_connection_get_impersonate_user (cnc),
-               "GetStreamingEvents",
-               NULL,
-               NULL,
-               e_ews_connection_get_server_version (cnc),
-               E_EWS_EXCHANGE_2010_SP1,
-               FALSE,
-               FALSE);
-
-       g_clear_object (&settings);
-
-       if (!msg) {
-               e_ews_debug_print ("%s: Failed to create Soup message for URI '%s'\n", G_STRFUNC, 
e_ews_connection_get_uri (cnc));
-               g_object_unref (cnc);
+       if (!e_ews_connection_get_streaming_events_sync (cnc, G_PRIORITY_DEFAULT, subscription_id, 
&input_stream, cancellable, &local_error) || !input_stream) {
+               *out_fatal_error = !local_error || local_error->domain == E_SOUP_SESSION_ERROR || 
local_error->domain == G_TLS_ERROR;
+               g_clear_object (&cnc);
+               g_clear_error (&local_error);
                return FALSE;
        }
 
-       e_soap_message_start_element (msg, "SubscriptionIds", "messages", NULL);
-       e_ews_message_write_string_parameter_with_attribute (msg, "SubscriptionId", NULL, subscription_id, 
NULL, NULL);
-       e_soap_message_end_element (msg); /* SubscriptionIds */
+       /* Unref early, thus it can be freed and will cancel this thread. */
+       g_clear_object (&cnc);
 
-       e_ews_message_write_string_parameter_with_attribute (msg, "ConnectionTimeout", "messages", "10", 
NULL, NULL);
+       chunk_data = g_byte_array_new ();
+       buffer = g_malloc (BUFFER_SIZE);
 
-       e_ews_message_write_footer (msg); /* Complete the footer and print the request */
-
-       if (e_ews_debug_get_log_level () <= 3)
-               soup_message_body_set_accumulate (SOUP_MESSAGE (msg)->response_body, FALSE);
-
-       if (!e_ews_connection_utils_prepare_message (cnc, notification->priv->soup_session, SOUP_MESSAGE 
(msg), notification->priv->cancellable)) {
-               g_object_unref (msg);
-               g_object_unref (cnc);
-               return FALSE;
+       while (nread = g_input_stream_read (input_stream, buffer, BUFFER_SIZE, cancellable, &local_error),
+              nread > 0) {
+               g_byte_array_append (chunk_data, buffer, nread);
+               ews_notification_process_chunk (notification, chunk_data, cancellable);
        }
 
-       handler_id = g_signal_connect (
-               SOUP_MESSAGE (msg), "got-chunk",
-               G_CALLBACK (ews_notification_soup_got_chunk), notification);
+       g_free (buffer);
+       g_byte_array_unref (chunk_data);
+       g_clear_object (&input_stream);
 
-       /* Unref it early, thus it doesn't keep the connection alive after all backends are freed */
-       g_object_unref (cnc);
+       /* It's okay when read failed on EOF */
+       *out_fatal_error = (local_error != NULL && !g_error_matches (local_error, G_IO_ERROR, 
G_IO_ERROR_PARTIAL_INPUT)) ||
+               g_cancellable_is_cancelled (cancellable);
+       success = !local_error && !*out_fatal_error;
 
-       cancel_handler_id = g_cancellable_connect (cancellable, G_CALLBACK (ews_notification_cancelled_cb),
-               notifcation_cancel_data_new (notification->priv->soup_session, SOUP_MESSAGE (msg)), 
notifcation_cancel_data_free);
+       g_clear_error (&local_error);
 
-       if (g_cancellable_is_cancelled (cancellable))
-               status_code = SOUP_STATUS_CANCELLED;
-       else
-               status_code = soup_session_send_message (notification->priv->soup_session, SOUP_MESSAGE 
(msg));
-
-       if (cancel_handler_id > 0)
-               g_cancellable_disconnect (cancellable, cancel_handler_id);
-
-       ret = SOUP_STATUS_IS_SUCCESSFUL (status_code);
-       *out_fatal_error = SOUP_STATUS_IS_CLIENT_ERROR (status_code) || SOUP_STATUS_IS_SERVER_ERROR 
(status_code) ||
-               (status_code == SOUP_STATUS_CANCELLED && !g_object_get_data (G_OBJECT (msg), 
EWS_NOTIFICATION_CANCEL_KEY));
-
-       g_signal_handler_disconnect (msg, handler_id);
-       g_object_unref (msg);
-
-       return ret;
+       return success;
 }
 
 static gpointer
@@ -944,7 +599,7 @@ e_ews_notification_get_events_thread (gpointer user_data)
        }
 
        if (td->notification->priv->last_subscription_id) {
-               e_ews_notification_unsubscribe_folder_sync (td->notification, 
td->notification->priv->last_subscription_id);
+               e_ews_notification_unsubscribe_folder_sync (td->notification, 
td->notification->priv->last_subscription_id, td->cancellable);
                g_clear_pointer (&td->notification->priv->last_subscription_id, g_free);
        }
 
@@ -960,14 +615,11 @@ e_ews_notification_get_events_thread (gpointer user_data)
                if (!ret && !g_cancellable_is_cancelled (td->cancellable)) {
                        e_ews_debug_print ("%s: Failed to get notification events (SubscriptionId: '%s')\n", 
G_STRFUNC, subscription_id);
 
-                       e_ews_notification_unsubscribe_folder_sync (td->notification, subscription_id);
+                       e_ews_notification_unsubscribe_folder_sync (td->notification, subscription_id, 
td->cancellable);
                        g_free (subscription_id);
                        subscription_id = NULL;
 
                        if (!fatal_error) {
-                               /* This will cause reconnect */
-                               soup_session_abort (td->notification->priv->soup_session);
-
                                ret = e_ews_notification_subscribe_folder_sync (td->notification, 
td->folders, &subscription_id, td->cancellable);
                                if (ret) {
                                        e_ews_debug_print ("%s: Re-subscribed to get notifications events 
(SubscriptionId: '%s')\n", G_STRFUNC, subscription_id);
@@ -980,7 +632,7 @@ e_ews_notification_get_events_thread (gpointer user_data)
 
 exit:
        if (subscription_id != NULL) {
-               e_ews_notification_unsubscribe_folder_sync (td->notification, subscription_id);
+               e_ews_notification_unsubscribe_folder_sync (td->notification, subscription_id, 
td->cancellable);
                g_free (subscription_id);
        }
 
diff --git a/src/EWS/common/e-ews-notification.h b/src/EWS/common/e-ews-notification.h
index 4e85e541..2567d48e 100644
--- a/src/EWS/common/e-ews-notification.h
+++ b/src/EWS/common/e-ews-notification.h
@@ -41,6 +41,9 @@ struct _EEwsNotificationClass {
 };
 
 GType          e_ews_notification_get_type     (void);
+const gchar * const *
+               e_ews_notification_get_event_names
+                                               (void);
 EEwsNotification *
                e_ews_notification_new          (EEwsConnection *connection,
                                                 gchar *last_subscription_id); /* assumes ownership of it */
diff --git a/src/EWS/common/e-ews-oof-settings.c b/src/EWS/common/e-ews-oof-settings.c
index 634a7d9c..a08c4f93 100644
--- a/src/EWS/common/e-ews-oof-settings.c
+++ b/src/EWS/common/e-ews-oof-settings.c
@@ -6,21 +6,20 @@
 
 #include "evolution-ews-config.h"
 
-#include "e-ews-oof-settings.h"
-
 #include <glib/gi18n-lib.h>
 
 #include <libedataserver/libedataserver.h>
 
 #include "ews-errors.h"
+#include "e-ews-connection.h"
 #include "e-ews-enumtypes.h"
-#include "e-ews-message.h"
+#include "e-ews-request.h"
+
+#include "e-ews-oof-settings.h"
 
 /* Forward Declarations */
 static void    e_ews_oof_settings_initable_init
                                        (GInitableIface *iface);
-static void    e_ews_oof_settings_async_initable_init
-                                       (GAsyncInitableIface *iface);
 
 struct _EEwsOofSettingsPrivate {
        GMutex property_lock;
@@ -46,203 +45,7 @@ enum {
 
 G_DEFINE_TYPE_WITH_CODE (EEwsOofSettings, e_ews_oof_settings, G_TYPE_OBJECT,
        G_ADD_PRIVATE (EEwsOofSettings)
-       G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, e_ews_oof_settings_initable_init)
-       G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, e_ews_oof_settings_async_initable_init))
-
-static GDateTime *
-ews_oof_settings_string_to_date_time (const gchar *string)
-{
-       GTimeVal tv = { 0, 0 };
-       GDateTime *date_time = NULL;
-
-       if (g_time_val_from_iso8601 (string, &tv))
-               date_time = g_date_time_new_from_timeval_utc (&tv);
-
-       return date_time;
-}
-
-static gchar *
-ews_oof_settings_date_time_to_string (GDateTime *date_time)
-{
-       GTimeVal tv = { 0, 0 };
-       gchar *string = NULL;
-
-       if (g_date_time_to_timeval (date_time, &tv))
-               string = g_time_val_to_iso8601 (&tv);
-
-       return string;
-}
-
-static gchar *
-ews_oof_settings_text_from_html (gchar *html_text)
-{
-       gsize haystack_len;
-       gchar *plain_text;
-       gchar *start, *end;
-       gchar *ii, *jj;
-
-       g_return_val_if_fail (html_text != NULL, NULL);
-
-       haystack_len = strlen (html_text);
-       start = g_strstr_len (html_text, haystack_len, "<body");
-       end = g_strstr_len (html_text, haystack_len, "</body>");
-
-       /* Parse the status set by Outlook Web Access. */
-       if (g_strrstr (html_text, "BodyFragment") != NULL && start == NULL) {
-               start = html_text;
-               end = html_text + haystack_len;
-       }
-
-       /* Strip HTML tags. */
-       plain_text = jj = g_malloc (end - start);
-       for (ii = start; ii < end; ii++) {
-               if (*ii == '<') {
-                       while (*ii != '>')
-                               ii++;
-               } else {
-                       *jj++ = *ii;
-               }
-       }
-       *jj = '\0';
-
-       return plain_text;
-}
-
-static void
-ews_oof_settings_get_response_cb (ESoapResponse *response,
-                                  GSimpleAsyncResult *simple)
-{
-       GAsyncResult *result;
-       GObject *source_object;
-       EEwsOofSettings *settings;
-       ESoapParameter *param;
-       ESoapParameter *subparam;
-       ESoapParameter *subsubparam;
-       GDateTime *date_time;
-       gchar *string;
-       gchar *text;
-       GError *error = NULL;
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessage", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
-
-       if (!ews_get_response_status (param, &error)) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
-
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "OofSettings", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               return;
-       }
-
-       result = G_ASYNC_RESULT (simple);
-       source_object = g_async_result_get_source_object (result);
-       settings = E_EWS_OOF_SETTINGS (source_object);
-
-       subparam = e_soap_parameter_get_first_child_by_name (
-               param, "OofState");
-       string = e_soap_parameter_get_string_value (subparam);
-       if (g_strcmp0 (string, "Disabled") == 0)
-               e_ews_oof_settings_set_state (
-                       settings, E_EWS_OOF_STATE_DISABLED);
-       else if (g_strcmp0 (string, "Enabled") == 0)
-               e_ews_oof_settings_set_state (
-                       settings, E_EWS_OOF_STATE_ENABLED);
-       else if (g_strcmp0 (string, "Scheduled") == 0)
-               e_ews_oof_settings_set_state (
-                       settings, E_EWS_OOF_STATE_SCHEDULED);
-       g_free (string);
-
-       subparam = e_soap_parameter_get_first_child_by_name (
-               param, "ExternalAudience");
-       string = e_soap_parameter_get_string_value (subparam);
-       if (g_strcmp0 (string, "None") == 0)
-               e_ews_oof_settings_set_external_audience (
-                       settings, E_EWS_EXTERNAL_AUDIENCE_NONE);
-       else if (g_strcmp0 (string, "Known") == 0)
-               e_ews_oof_settings_set_external_audience (
-                       settings, E_EWS_EXTERNAL_AUDIENCE_KNOWN);
-       else if (g_strcmp0 (string, "All") == 0)
-               e_ews_oof_settings_set_external_audience (
-                       settings, E_EWS_EXTERNAL_AUDIENCE_ALL);
-       g_free (string);
-
-       subparam = e_soap_parameter_get_first_child_by_name (
-               param, "Duration");
-       subsubparam = e_soap_parameter_get_first_child_by_name (
-               subparam, "StartTime");
-       string = e_soap_parameter_get_string_value (subsubparam);
-       date_time = ews_oof_settings_string_to_date_time (string);
-       if (date_time != NULL) {
-               e_ews_oof_settings_set_start_time (settings, date_time);
-               g_date_time_unref (date_time);
-       }
-       g_free (string);
-       subsubparam = e_soap_parameter_get_first_child_by_name (
-               subparam, "EndTime");
-       string = e_soap_parameter_get_string_value (subsubparam);
-       date_time = ews_oof_settings_string_to_date_time (string);
-       if (date_time != NULL) {
-               e_ews_oof_settings_set_end_time (settings, date_time);
-               g_date_time_unref (date_time);
-       }
-       g_free (string);
-
-       subparam = e_soap_parameter_get_first_child_by_name (
-               param, "InternalReply");
-       subsubparam = e_soap_parameter_get_first_child_by_name (
-               subparam, "Message");
-       string = e_soap_parameter_get_string_value (subsubparam);
-       if (string == NULL)
-               text = NULL;
-       else if (g_strrstr (string, "</body>") != NULL)
-               text = ews_oof_settings_text_from_html (string);
-       else if (g_strrstr (string, "BodyFragment") != NULL)
-               text = ews_oof_settings_text_from_html (string);
-       else
-               text = g_strdup (string);
-       e_ews_oof_settings_set_internal_reply (settings, text ? text : "");
-       g_free (string);
-       g_free (text);
-
-       subparam = e_soap_parameter_get_first_child_by_name (
-               param, "ExternalReply");
-       subsubparam = e_soap_parameter_get_first_child_by_name (
-               subparam, "Message");
-       string = e_soap_parameter_get_string_value (subsubparam);
-       if (string == NULL)
-               text = NULL;
-       else if (g_strrstr (string, "</body>") != NULL)
-               text = ews_oof_settings_text_from_html (string);
-       else if (g_strrstr (string, "BodyFragment") != NULL)
-               text = ews_oof_settings_text_from_html (string);
-       else
-               text = g_strdup (string);
-       e_ews_oof_settings_set_external_reply (settings, text ? text : "");
-       g_free (string);
-       g_free (text);
-
-       g_object_unref (source_object);
-}
+       G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, e_ews_oof_settings_initable_init))
 
 static void
 ews_oof_settings_set_connection (EEwsOofSettings *settings,
@@ -400,103 +203,12 @@ ews_oof_settings_initable_init (GInitable *initable,
                                 GCancellable *cancellable,
                                 GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
-       gboolean success;
-
-       closure = e_async_closure_new ();
+       EEwsOofSettings *settings = E_EWS_OOF_SETTINGS (initable);
 
-       g_async_initable_init_async (
-               G_ASYNC_INITABLE (initable),
-               G_PRIORITY_DEFAULT, cancellable,
-               e_async_closure_callback, closure);
+       g_return_val_if_fail (settings->priv->connection != NULL, FALSE);
 
-       result = e_async_closure_wait (closure);
-
-       success = g_async_initable_init_finish (
-               G_ASYNC_INITABLE (initable), result, error);
-
-       e_async_closure_free (closure);
-
-       return success;
-}
-
-static void
-ews_oof_settings_initable_init_async (GAsyncInitable *initable,
-                                      gint io_priority,
-                                      GCancellable *cancellable,
-                                      GAsyncReadyCallback callback,
-                                      gpointer user_data)
-{
-       GSimpleAsyncResult *simple;
-       EEwsOofSettings *settings;
-       EEwsConnection *connection;
-       ESoapMessage *message;
-       CamelEwsSettings *ews_settings;
-       const gchar *uri, *impersonate_user;
-       const gchar *mailbox;
-       EEwsServerVersion version;
-
-       settings = E_EWS_OOF_SETTINGS (initable);
-       connection = e_ews_oof_settings_get_connection (settings);
-
-       uri = e_ews_connection_get_uri (connection);
-       impersonate_user = e_ews_connection_get_impersonate_user (connection);
-       mailbox = e_ews_connection_get_mailbox (connection);
-       version = e_ews_connection_get_server_version (connection);
-       ews_settings = e_ews_connection_ref_settings (connection);
-
-       message = e_ews_message_new_with_header (
-               ews_settings,
-               uri,
-               impersonate_user,
-               "GetUserOofSettingsRequest",
-               NULL,
-               NULL,
-               version,
-               E_EWS_EXCHANGE_2007_SP1,
-               FALSE,
-               TRUE);
-
-       g_clear_object (&ews_settings);
-
-       e_soap_message_start_element (message, "Mailbox", NULL, NULL);
-       e_ews_message_write_string_parameter (
-               message, "Address", NULL, mailbox);
-       e_soap_message_end_element (message);
-
-       e_ews_message_write_footer (message);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (initable), callback, user_data,
-               ews_oof_settings_initable_init_async);
-
-       g_simple_async_result_set_check_cancellable (simple, cancellable);
-
-       e_ews_connection_queue_request (
-               connection, message,
-               ews_oof_settings_get_response_cb,
-               EWS_PRIORITY_MEDIUM, cancellable, simple);
-
-       g_object_unref (simple);
-}
-
-static gboolean
-ews_oof_settings_initable_init_finish (GAsyncInitable *initable,
-                                       GAsyncResult *result,
-                                       GError **error)
-{
-       GSimpleAsyncResult *simple;
-
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (initable),
-               ews_oof_settings_initable_init_async), FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-
-       /* Assume success unless a GError is set. */
-       return !g_simple_async_result_propagate_error (simple, error);
+       return e_ews_connection_get_user_oof_settings_sync (settings->priv->connection,
+               G_PRIORITY_DEFAULT, settings, cancellable, error);
 }
 
 static void
@@ -611,13 +323,6 @@ e_ews_oof_settings_initable_init (GInitableIface *iface)
        iface->init = ews_oof_settings_initable_init;
 }
 
-static void
-e_ews_oof_settings_async_initable_init (GAsyncInitableIface *iface)
-{
-       iface->init_async = ews_oof_settings_initable_init_async;
-       iface->init_finish = ews_oof_settings_initable_init_finish;
-}
-
 EEwsOofSettings *
 e_ews_oof_settings_new_sync (EEwsConnection *connection,
                              GCancellable *cancellable,
@@ -630,41 +335,6 @@ e_ews_oof_settings_new_sync (EEwsConnection *connection,
                "connection", connection, NULL);
 }
 
-void
-e_ews_oof_settings_new (EEwsConnection *connection,
-                        gint io_priority,
-                        GCancellable *cancellable,
-                        GAsyncReadyCallback callback,
-                        gpointer user_data)
-{
-       g_return_if_fail (E_IS_EWS_CONNECTION (connection));
-
-       g_async_initable_new_async (
-               E_TYPE_EWS_OOF_SETTINGS, io_priority,
-               cancellable, callback, user_data,
-               "connection", connection, NULL);
-}
-
-EEwsOofSettings *
-e_ews_oof_settings_new_finish (GAsyncResult *result,
-                               GError **error)
-{
-       GObject *source_object;
-       GObject *object;
-
-       g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
-
-       source_object = g_async_result_get_source_object (result);
-       g_return_val_if_fail (source_object != NULL, NULL);
-
-       object = g_async_initable_new_finish (
-               G_ASYNC_INITABLE (source_object), result, error);
-
-       g_object_unref (source_object);
-
-       return (object != NULL) ? E_EWS_OOF_SETTINGS (object) : NULL;
-}
-
 EEwsConnection *
 e_ews_oof_settings_get_connection (EEwsOofSettings *settings)
 {
@@ -879,51 +549,92 @@ e_ews_oof_settings_set_external_reply (EEwsOofSettings *settings,
        g_object_notify (G_OBJECT (settings), "external-reply");
 }
 
+typedef struct _SubmitData {
+       EEwsOofState state;
+       EEwsExternalAudience external_audience;
+       GDateTime *date_start;
+       GDateTime *date_end;
+       gchar *internal_reply;
+       gchar *external_reply;
+} SubmitData;
+
+static SubmitData *
+submit_data_new (EEwsOofSettings *settings)
+{
+       SubmitData *sd;
+
+       sd = g_slice_new0 (SubmitData);
+       sd->state = e_ews_oof_settings_get_state (settings);
+       sd->external_audience = e_ews_oof_settings_get_external_audience (settings);
+       sd->date_start = e_ews_oof_settings_ref_start_time (settings);
+       sd->date_end = e_ews_oof_settings_ref_end_time (settings);
+       sd->internal_reply = e_ews_oof_settings_dup_internal_reply (settings);
+       sd->external_reply = e_ews_oof_settings_dup_external_reply (settings);
+
+       return sd;
+}
+
+static void
+submit_data_free (gpointer ptr)
+{
+       SubmitData *sd = ptr;
+
+       if (sd) {
+               g_clear_pointer (&sd->date_start, g_date_time_unref);
+               g_clear_pointer (&sd->date_end, g_date_time_unref);
+               g_clear_pointer (&sd->internal_reply, g_free);
+               g_clear_pointer (&sd->external_reply, g_free);
+               g_slice_free (SubmitData, sd);
+       }
+}
+
+static gboolean
+ews_oof_settings_call_submit_sync (EEwsOofSettings *settings,
+                                  SubmitData *sd,
+                                  GCancellable *cancellable,
+                                  GError **error)
+{
+       EEwsConnection *cnc = e_ews_oof_settings_get_connection (settings);
+
+       g_return_val_if_fail (sd != NULL, FALSE);
+       g_return_val_if_fail (cnc != NULL, FALSE);
+
+       return e_ews_connection_set_user_oof_settings_sync (cnc,
+               G_PRIORITY_DEFAULT, sd->state, sd->external_audience, sd->date_start,
+               sd->date_end, sd->internal_reply, sd->external_reply,
+               cancellable, error);
+}
+
 gboolean
 e_ews_oof_settings_submit_sync (EEwsOofSettings *settings,
                                 GCancellable *cancellable,
                                 GError **error)
 {
-       EAsyncClosure *closure;
-       GAsyncResult *result;
+       SubmitData *sd;
        gboolean success;
 
        g_return_val_if_fail (E_IS_EWS_OOF_SETTINGS (settings), FALSE);
 
-       closure = e_async_closure_new ();
-
-       e_ews_oof_settings_submit (
-               settings, cancellable, e_async_closure_callback, closure);
-
-       result = e_async_closure_wait (closure);
-
-       success = e_ews_oof_settings_submit_finish (settings, result, error);
-
-       e_async_closure_free (closure);
+       sd = submit_data_new (settings);
+       success = ews_oof_settings_call_submit_sync (settings, sd, cancellable, error);
+       submit_data_free (sd);
 
        return success;
 }
 
 static void
-ews_oof_settings_submit_response_cb (ESoapResponse *response,
-                                     GSimpleAsyncResult *simple)
+ews_oof_settings_submit_thread (GTask *task,
+                               gpointer source_object,
+                               gpointer task_data,
+                               GCancellable *cancellable)
 {
-       ESoapParameter *param;
+       SubmitData *sd = task_data;
        GError *error = NULL;
 
-       param = e_soap_response_get_first_parameter_by_name (
-               response, "ResponseMessage", &error);
-
-       /* Sanity check */
-       g_return_if_fail (
-               (param != NULL && error == NULL) ||
-               (param == NULL && error != NULL));
-
-       if (error != NULL)
-               g_simple_async_result_take_error (simple, error);
-
-       else if (!ews_get_response_status (param, &error))
-               g_simple_async_result_take_error (simple, error);
+       if (ews_oof_settings_call_submit_sync (E_EWS_OOF_SETTINGS (source_object), sd, cancellable, &error))
+               g_task_return_boolean (task, TRUE);
+       else
+               g_task_return_error (task, error);
 }
 
 void
@@ -932,158 +643,20 @@ e_ews_oof_settings_submit (EEwsOofSettings *settings,
                            GAsyncReadyCallback callback,
                            gpointer user_data)
 {
-       ESoapMessage *message;
-       EEwsConnection *connection;
-       GSimpleAsyncResult *simple;
-       GDateTime *date_time;
-       const gchar *mailbox;
-       const gchar *string;
-       const gchar *uri, *impersonate_user;
-       gchar *internal_reply;
-       gchar *external_reply;
-       gchar *start_time;
-       gchar *end_time;
-       EEwsServerVersion version;
-       CamelEwsSettings *ews_settings;
+       GTask *task;
+       SubmitData *sd;
 
        g_return_if_fail (E_IS_EWS_OOF_SETTINGS (settings));
 
-       connection = e_ews_oof_settings_get_connection (settings);
-       mailbox = e_ews_connection_get_mailbox (connection);
-       uri = e_ews_connection_get_uri (connection);
-       impersonate_user = e_ews_connection_get_impersonate_user (connection);
-       version = e_ews_connection_get_server_version (connection);
-       ews_settings = e_ews_connection_ref_settings (connection);
-
-       internal_reply = e_ews_oof_settings_dup_internal_reply (settings);
-       external_reply = e_ews_oof_settings_dup_external_reply (settings);
-
-       date_time = e_ews_oof_settings_ref_start_time (settings);
-       start_time = ews_oof_settings_date_time_to_string (date_time);
-       g_date_time_unref (date_time);
-
-       date_time = e_ews_oof_settings_ref_end_time (settings);
-       end_time = ews_oof_settings_date_time_to_string (date_time);
-       g_date_time_unref (date_time);
-
-       message = e_ews_message_new_with_header (
-               ews_settings,
-               uri,
-               impersonate_user,
-               "SetUserOofSettingsRequest",
-               NULL,
-               NULL,
-               version,
-               E_EWS_EXCHANGE_2007_SP1,
-               FALSE,
-               TRUE);
-
-       g_clear_object (&ews_settings);
-
-       /* <Mailbox> */
-
-       e_soap_message_start_element (
-               message, "Mailbox", NULL, NULL);
-       e_ews_message_write_string_parameter (
-               message, "Address", NULL, mailbox);
-       e_soap_message_end_element (message);
-
-       /* </Mailbox> */
-
-       /* <UserOofSettings> */
-
-       e_soap_message_start_element (
-               message, "UserOofSettings", NULL, NULL);
-
-       switch (e_ews_oof_settings_get_state (settings)) {
-               default:
-                       g_warn_if_reached ();
-                       /* fall through */
-               case E_EWS_OOF_STATE_DISABLED:
-                       string = "Disabled";
-                       break;
-               case E_EWS_OOF_STATE_ENABLED:
-                       string = "Enabled";
-                       break;
-               case E_EWS_OOF_STATE_SCHEDULED:
-                       string = "Scheduled";
-                       break;
-       }
-
-       e_ews_message_write_string_parameter (
-               message, "OofState", NULL, string);
-
-       switch (e_ews_oof_settings_get_external_audience (settings)) {
-               default:
-                       g_warn_if_reached ();
-                       /* fall through */
-               case E_EWS_EXTERNAL_AUDIENCE_NONE:
-                       string = "None";
-                       break;
-               case E_EWS_EXTERNAL_AUDIENCE_KNOWN:
-                       string = "Known";
-                       break;
-               case E_EWS_EXTERNAL_AUDIENCE_ALL:
-                       string = "All";
-                       break;
-       }
-
-       e_ews_message_write_string_parameter (
-               message, "ExternalAudience", NULL, string);
+       task = g_task_new (settings, cancellable, callback, user_data);
+       g_task_set_source_tag (task, e_ews_oof_settings_submit);
 
-       /* <Duration> */
+       sd = submit_data_new (settings);
+       g_task_set_task_data (task, sd, submit_data_free);
 
-       e_soap_message_start_element (
-               message, "Duration", NULL, NULL);
-       e_ews_message_write_string_parameter (
-               message, "StartTime", NULL, start_time);
-       e_ews_message_write_string_parameter (
-               message, "EndTime", NULL, end_time);
-       e_soap_message_end_element (message);
+       g_task_run_in_thread (task, ews_oof_settings_submit_thread);
 
-       /* </Duration> */
-
-       /* <InternalReply> */
-
-       e_soap_message_start_element (
-               message, "InternalReply", NULL, NULL);
-       e_ews_message_write_string_parameter (
-               message, "Message", NULL, internal_reply);
-       e_soap_message_end_element (message);
-
-       /* </InternalReply> */
-
-       /* <ExternalReply> */
-
-       e_soap_message_start_element (
-               message, "ExternalReply", NULL, NULL);
-       e_ews_message_write_string_parameter (
-               message, "Message", NULL, external_reply);
-       e_soap_message_end_element (message);
-
-       /* </ExternalReply> */
-
-       e_soap_message_end_element (message);
-
-       /* </UserOofSettings> */
-
-       e_ews_message_write_footer (message);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (settings), callback,
-               user_data, e_ews_oof_settings_submit);
-
-       e_ews_connection_queue_request (
-               connection, message,
-               ews_oof_settings_submit_response_cb,
-               EWS_PRIORITY_MEDIUM, cancellable, simple);
-
-       g_object_unref (simple);
-
-       g_free (internal_reply);
-       g_free (external_reply);
-       g_free (start_time);
-       g_free (end_time);
+       g_object_unref (task);
 }
 
 gboolean
@@ -1091,16 +664,7 @@ e_ews_oof_settings_submit_finish (EEwsOofSettings *settings,
                                   GAsyncResult *result,
                                   GError **error)
 {
-       GSimpleAsyncResult *simple;
+       g_return_val_if_fail (g_task_is_valid (result, settings), FALSE);
 
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (settings),
-               e_ews_oof_settings_submit), FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-
-       /* Assume success unless a GError is set. */
-       return !g_simple_async_result_propagate_error (simple, error);
+       return g_task_propagate_boolean (G_TASK (result), error);
 }
-
diff --git a/src/EWS/common/e-ews-oof-settings.h b/src/EWS/common/e-ews-oof-settings.h
index a6c2e1c8..4130c5da 100644
--- a/src/EWS/common/e-ews-oof-settings.h
+++ b/src/EWS/common/e-ews-oof-settings.h
@@ -7,7 +7,6 @@
 #ifndef E_EWS_OOF_SETTINGS_H
 #define E_EWS_OOF_SETTINGS_H
 
-#include <common/e-ews-connection.h>
 #include <common/e-ews-enums.h>
 
 /* Standard GObject macros */
@@ -31,6 +30,8 @@
 
 G_BEGIN_DECLS
 
+struct _EEwsConnection;
+
 typedef struct _EEwsOofSettings EEwsOofSettings;
 typedef struct _EEwsOofSettingsClass EEwsOofSettingsClass;
 typedef struct _EEwsOofSettingsPrivate EEwsOofSettingsPrivate;
@@ -46,18 +47,10 @@ struct _EEwsOofSettingsClass {
 
 GType          e_ews_oof_settings_get_type     (void) G_GNUC_CONST;
 EEwsOofSettings *
-               e_ews_oof_settings_new_sync     (EEwsConnection *connection,
-                                                GCancellable *cancellable,
-                                                GError **error);
-void           e_ews_oof_settings_new          (EEwsConnection *connection,
-                                                gint io_priority,
+               e_ews_oof_settings_new_sync     (struct _EEwsConnection *connection,
                                                 GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-EEwsOofSettings *
-               e_ews_oof_settings_new_finish   (GAsyncResult *result,
                                                 GError **error);
-EEwsConnection *
+struct _EEwsConnection *
                e_ews_oof_settings_get_connection
                                                (EEwsOofSettings *settings);
 EEwsOofState   e_ews_oof_settings_get_state    (EEwsOofSettings *settings);
diff --git a/src/EWS/common/e-ews-query-to-restriction.c b/src/EWS/common/e-ews-query-to-restriction.c
index cedbf9c1..7f0a93d6 100644
--- a/src/EWS/common/e-ews-query-to-restriction.c
+++ b/src/EWS/common/e-ews-query-to-restriction.c
@@ -13,7 +13,7 @@
 #include <camel/camel.h>
 #include <libedata-cal/libedata-cal.h>
 
-#include "e-ews-message.h"
+#include "e-ews-request.h"
 
 #include "e-ews-query-to-restriction.h"
 
@@ -125,7 +125,7 @@ struct EmailIndex {
 };
 
 typedef struct _EvalContext {
-       ESoapMessage *msg; /* NULL when just checking whether any applied */
+       ESoapRequest *req; /* NULL when just checking whether any applied */
        gboolean any_applicable;
 } EvalContext;
 
@@ -138,17 +138,17 @@ ews_restriction_write_contains_message (EvalContext *ctx,
 {
        g_return_if_fail (ctx != NULL);
 
-       if (!ctx->msg) {
+       if (!ctx->req) {
                ctx->any_applicable = TRUE;
                return;
        }
 
-       e_soap_message_start_element (ctx->msg, "Contains", NULL, NULL);
-       e_soap_message_add_attribute (ctx->msg, "ContainmentMode", mode, NULL, NULL);
-       e_soap_message_add_attribute (ctx->msg, "ContainmentComparison", compare, NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "FieldURI", NULL, NULL, "FieldURI", 
uri);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "Constant", NULL, NULL, "Value", val);
-       e_soap_message_end_element (ctx->msg);
+       e_soap_request_start_element (ctx->req, "Contains", NULL, NULL);
+       e_soap_request_add_attribute (ctx->req, "ContainmentMode", mode, NULL, NULL);
+       e_soap_request_add_attribute (ctx->req, "ContainmentComparison", compare, NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "FieldURI", NULL, NULL, "FieldURI", 
uri);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "Constant", NULL, NULL, "Value", val);
+       e_soap_request_end_element (ctx->req);
 }
 
 static void
@@ -161,20 +161,20 @@ ews_restriction_write_contains_message_indexed (EvalContext *ctx,
 {
        g_return_if_fail (ctx != NULL);
 
-       if (!ctx->msg) {
+       if (!ctx->req) {
                ctx->any_applicable = TRUE;
                return;
        }
 
-       e_soap_message_start_element (ctx->msg, "Contains", NULL, NULL);
-       e_soap_message_add_attribute (ctx->msg, "ContainmentMode", mode, NULL, NULL);
-       e_soap_message_add_attribute (ctx->msg, "ContainmentComparison", compare, NULL, NULL);
-       e_soap_message_start_element (ctx->msg, "IndexedFieldURI", NULL, NULL);
-       e_soap_message_add_attribute (ctx->msg, "FieldURI", uri, NULL, NULL);
-       e_soap_message_add_attribute (ctx->msg, "FieldIndex", index, NULL, NULL);
-       e_soap_message_end_element (ctx->msg);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "Constant", NULL, NULL, "Value", val);
-       e_soap_message_end_element (ctx->msg);
+       e_soap_request_start_element (ctx->req, "Contains", NULL, NULL);
+       e_soap_request_add_attribute (ctx->req, "ContainmentMode", mode, NULL, NULL);
+       e_soap_request_add_attribute (ctx->req, "ContainmentComparison", compare, NULL, NULL);
+       e_soap_request_start_element (ctx->req, "IndexedFieldURI", NULL, NULL);
+       e_soap_request_add_attribute (ctx->req, "FieldURI", uri, NULL, NULL);
+       e_soap_request_add_attribute (ctx->req, "FieldIndex", index, NULL, NULL);
+       e_soap_request_end_element (ctx->req);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "Constant", NULL, NULL, "Value", val);
+       e_soap_request_end_element (ctx->req);
 }
 
 static void
@@ -183,14 +183,14 @@ ews_restriction_write_exists_message (EvalContext *ctx,
 {
        g_return_if_fail (ctx != NULL);
 
-       if (!ctx->msg) {
+       if (!ctx->req) {
                ctx->any_applicable = TRUE;
                return;
        }
 
-       e_soap_message_start_element (ctx->msg, "Exists", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "FieldURI", NULL, NULL, "FieldURI", 
uri);
-       e_soap_message_end_element (ctx->msg);
+       e_soap_request_start_element (ctx->req, "Exists", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "FieldURI", NULL, NULL, "FieldURI", 
uri);
+       e_soap_request_end_element (ctx->req);
 }
 
 static void
@@ -200,17 +200,17 @@ ews_restriction_write_greater_than_or_equal_to_message (EvalContext *ctx,
 {
        g_return_if_fail (ctx != NULL);
 
-       if (!ctx->msg) {
+       if (!ctx->req) {
                ctx->any_applicable = TRUE;
                return;
        }
 
-       e_soap_message_start_element (ctx->msg, "IsGreaterThanOrEqualTo", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "FieldURI", NULL, NULL, "FieldURI", 
uri);
-       e_soap_message_start_element (ctx->msg, "FieldURIOrConstant", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "Constant", NULL, NULL, "Value", val);
-       e_soap_message_end_element (ctx->msg);
-       e_soap_message_end_element (ctx->msg);
+       e_soap_request_start_element (ctx->req, "IsGreaterThanOrEqualTo", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "FieldURI", NULL, NULL, "FieldURI", 
uri);
+       e_soap_request_start_element (ctx->req, "FieldURIOrConstant", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "Constant", NULL, NULL, "Value", val);
+       e_soap_request_end_element (ctx->req);
+       e_soap_request_end_element (ctx->req);
 }
 
 static void
@@ -220,17 +220,17 @@ ews_restriction_write_less_than_or_equal_to_message (EvalContext *ctx,
 {
        g_return_if_fail (ctx != NULL);
 
-       if (!ctx->msg) {
+       if (!ctx->req) {
                ctx->any_applicable = TRUE;
                return;
        }
 
-       e_soap_message_start_element (ctx->msg, "IsLessThanOrEqualTo", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "FieldURI", NULL, NULL, "FieldURI", 
uri);
-       e_soap_message_start_element (ctx->msg, "FieldURIOrConstant", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "Constant", NULL, NULL, "Value", val);
-       e_soap_message_end_element (ctx->msg);
-       e_soap_message_end_element (ctx->msg);
+       e_soap_request_start_element (ctx->req, "IsLessThanOrEqualTo", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "FieldURI", NULL, NULL, "FieldURI", 
uri);
+       e_soap_request_start_element (ctx->req, "FieldURIOrConstant", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "Constant", NULL, NULL, "Value", val);
+       e_soap_request_end_element (ctx->req);
+       e_soap_request_end_element (ctx->req);
 }
 
 static void
@@ -240,17 +240,17 @@ ews_restriction_write_greater_than_message (EvalContext *ctx,
 {
        g_return_if_fail (ctx != NULL);
 
-       if (!ctx->msg) {
+       if (!ctx->req) {
                ctx->any_applicable = TRUE;
                return;
        }
 
-       e_soap_message_start_element (ctx->msg, "IsGreaterThan", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "FieldURI", NULL, NULL, "FieldURI", 
uri);
-       e_soap_message_start_element (ctx->msg, "FieldURIOrConstant", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "Constant", NULL, NULL, "Value", val);
-       e_soap_message_end_element (ctx->msg);
-       e_soap_message_end_element (ctx->msg);
+       e_soap_request_start_element (ctx->req, "IsGreaterThan", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "FieldURI", NULL, NULL, "FieldURI", 
uri);
+       e_soap_request_start_element (ctx->req, "FieldURIOrConstant", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "Constant", NULL, NULL, "Value", val);
+       e_soap_request_end_element (ctx->req);
+       e_soap_request_end_element (ctx->req);
 }
 
 static void
@@ -260,17 +260,17 @@ ews_restriction_write_less_than_message (EvalContext *ctx,
 {
        g_return_if_fail (ctx != NULL);
 
-       if (!ctx->msg) {
+       if (!ctx->req) {
                ctx->any_applicable = TRUE;
                return;
        }
 
-       e_soap_message_start_element (ctx->msg, "IsLessThan", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "FieldURI", NULL, NULL, "FieldURI", 
uri);
-       e_soap_message_start_element (ctx->msg, "FieldURIOrConstant", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "Constant", NULL, NULL, "Value", val);
-       e_soap_message_end_element (ctx->msg);
-       e_soap_message_end_element (ctx->msg);
+       e_soap_request_start_element (ctx->req, "IsLessThan", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "FieldURI", NULL, NULL, "FieldURI", 
uri);
+       e_soap_request_start_element (ctx->req, "FieldURIOrConstant", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "Constant", NULL, NULL, "Value", val);
+       e_soap_request_end_element (ctx->req);
+       e_soap_request_end_element (ctx->req);
 }
 
 static void
@@ -280,17 +280,17 @@ ews_restriction_write_is_equal_to_message (EvalContext *ctx,
 {
        g_return_if_fail (ctx != NULL);
 
-       if (!ctx->msg) {
+       if (!ctx->req) {
                ctx->any_applicable = TRUE;
                return;
        }
 
-       e_soap_message_start_element (ctx->msg, "IsEqualTo", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "FieldURI", NULL, NULL, "FieldURI", 
uri);
-       e_soap_message_start_element (ctx->msg, "FieldURIOrConstant", NULL, NULL);
-       e_ews_message_write_string_parameter_with_attribute (ctx->msg, "Constant", NULL, NULL, "Value", val);
-       e_soap_message_end_element (ctx->msg);
-       e_soap_message_end_element (ctx->msg);
+       e_soap_request_start_element (ctx->req, "IsEqualTo", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "FieldURI", NULL, NULL, "FieldURI", 
uri);
+       e_soap_request_start_element (ctx->req, "FieldURIOrConstant", NULL, NULL);
+       e_ews_request_write_string_parameter_with_attribute (ctx->req, "Constant", NULL, NULL, "Value", val);
+       e_soap_request_end_element (ctx->req);
+       e_soap_request_end_element (ctx->req);
 }
 
 static ESExpResult *
@@ -324,27 +324,27 @@ e_ews_implement_contact_contains (ESExp *f,
                                const gchar *value;
                                value = argv[1]->value.string;
 
-                               if (!ctx->msg) {
+                               if (!ctx->req) {
                                        ctx->any_applicable = TRUE;
                                } else {
-                                       e_soap_message_start_element (ctx->msg, "Or", NULL, NULL);
+                                       e_soap_request_start_element (ctx->req, "Or", NULL, NULL);
                                        while (n < G_N_ELEMENTS (contact_field)) {
                                                if ((contact_field[n].flag == CONTACT_NAME) && 
(!contact_field[n].indexed)) {
                                                        ews_restriction_write_contains_message (ctx, mode, 
"IgnoreCase", contact_field[n].field_uri, value);
                                                }
                                                n++;
                                        }
-                                       e_soap_message_end_element (ctx->msg); /* Or */
+                                       e_soap_request_end_element (ctx->req); /* Or */
                                }
                        } else if (!strcmp (field, "x-evolution-any-field")) {
                                gint n = 0;
                                const gchar *value;
                                value = argv[1]->value.string;
 
-                               if (!ctx->msg) {
+                               if (!ctx->req) {
                                        ctx->any_applicable = TRUE;
                                } else {
-                                       e_soap_message_start_element (ctx->msg, "Or", NULL, NULL);
+                                       e_soap_request_start_element (ctx->req, "Or", NULL, NULL);
                                        while (n < G_N_ELEMENTS (contact_field)) {
                                                if (!contact_field[n].indexed) {
                                                        ews_restriction_write_contains_message (ctx, 
"Substring", "IgnoreCase", contact_field[n].field_uri, value);
@@ -357,22 +357,22 @@ e_ews_implement_contact_contains (ESExp *f,
                                                }
                                                n++;
                                        }
-                                       e_soap_message_end_element (ctx->msg); /* Or */
+                                       e_soap_request_end_element (ctx->req); /* Or */
                                }
                        } else if (!strcmp (field, "email")) {
                                const gchar *value;
                                gint n = 0;
                                value = argv[1]->value.string;
 
-                               if (!ctx->msg) {
+                               if (!ctx->req) {
                                        ctx->any_applicable = TRUE;
                                } else {
-                                       e_soap_message_start_element (ctx->msg, "Or", NULL, NULL);
+                                       e_soap_request_start_element (ctx->req, "Or", NULL, NULL);
                                        while (n < G_N_ELEMENTS (email_index)) {
                                                ews_restriction_write_contains_message_indexed (ctx, mode, 
"IgnoreCase", "contacts:EmailAddress", email_index[n].field_index, value);
                                                n++;
                                        }
-                                       e_soap_message_end_element (ctx->msg); /* Or */
+                                       e_soap_request_end_element (ctx->req); /* Or */
                                }
                        } else if (!strcmp (field, "category_list")) {
                                const gchar *value;
@@ -397,7 +397,7 @@ e_ews_func_and_or_not (ESExp *f,
 {
        ESExpResult *r, *r1;
        EvalContext *ctx = data;
-       ESoapMessage *used_msg;
+       ESoapRequest *used_req;
        gboolean was_any_applicable;
        gint ii, n_applicable = 0;
        const gchar *elem_name = NULL;
@@ -408,8 +408,8 @@ e_ews_func_and_or_not (ESExp *f,
                goto result;
 
        was_any_applicable = ctx->any_applicable;
-       used_msg = ctx->msg;
-       ctx->msg = NULL;
+       used_req = ctx->req;
+       ctx->req = NULL;
 
        for (ii = 0; ii < argc; ii++) {
                ctx->any_applicable = FALSE;
@@ -421,9 +421,9 @@ e_ews_func_and_or_not (ESExp *f,
                        n_applicable++;
        }
 
-       ctx->msg = used_msg;
+       ctx->req = used_req;
 
-       if (!ctx->msg || !n_applicable) {
+       if (!ctx->req || !n_applicable) {
                ctx->any_applicable = n_applicable > 0 || was_any_applicable;
                goto result;
        }
@@ -440,7 +440,7 @@ e_ews_func_and_or_not (ESExp *f,
                elem_name = "Not";
 
        if (elem_name)
-               e_soap_message_start_element (ctx->msg, elem_name, NULL, NULL);
+               e_soap_request_start_element (ctx->req, elem_name, NULL, NULL);
 
        for (ii = 0; ii < argc; ii++) {
                r1 = e_sexp_term_eval (f, argv[ii]);
@@ -448,7 +448,7 @@ e_ews_func_and_or_not (ESExp *f,
        }
 
        if (elem_name)
-               e_soap_message_end_element (ctx->msg);
+               e_soap_request_end_element (ctx->req);
 
  result:
        r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);
@@ -489,13 +489,13 @@ calendar_func_contains (ESExp *f,
                                const gchar *value;
                                value = argv[1]->value.string;
 
-                               if (!ctx->msg) {
+                               if (!ctx->req) {
                                        ctx->any_applicable = TRUE;
                                } else {
-                                       e_soap_message_start_element (ctx->msg, "Or", NULL, NULL);
+                                       e_soap_request_start_element (ctx->req, "Or", NULL, NULL);
                                        ews_restriction_write_contains_message (ctx, "Substring", 
"IgnoreCase", "calendar:RequiredAttendees", value);
                                        ews_restriction_write_contains_message (ctx, "Substring", 
"IgnoreCase", "calendar:OptionalAttendees", value);
-                                       e_soap_message_end_element (ctx->msg);
+                                       e_soap_request_end_element (ctx->req);
                                }
                        } else if (!g_strcmp0 (field, "organizer")) {
                                const gchar *value;
@@ -517,10 +517,10 @@ calendar_func_contains (ESExp *f,
                                gint n = 0;
                                value = argv[1]->value.string;
 
-                               if (!ctx->msg) {
+                               if (!ctx->req) {
                                        ctx->any_applicable = TRUE;
                                } else {
-                                       e_soap_message_start_element (ctx->msg, "Or", NULL, NULL);
+                                       e_soap_request_start_element (ctx->req, "Or", NULL, NULL);
                                        while (n < G_N_ELEMENTS (calendar_field)) {
                                                if (calendar_field[n].any_field) {
                                                        ews_restriction_write_contains_message (ctx, 
"Substring", "IgnoreCase", calendar_field[n].field_uri, value);
@@ -534,7 +534,7 @@ calendar_func_contains (ESExp *f,
                                                }
                                                n++;
                                        }
-                                       e_soap_message_end_element (ctx->msg);
+                                       e_soap_request_end_element (ctx->req);
                                }
                        }
                }
@@ -635,7 +635,7 @@ calendar_func_occur_in_time_range (ESExp *f,
                return NULL;
        }
 
-       if (!ctx->msg) {
+       if (!ctx->req) {
                ctx->any_applicable = TRUE;
        } else {
                gchar *start, *end;
@@ -643,10 +643,10 @@ calendar_func_occur_in_time_range (ESExp *f,
                start = e_ews_make_timestamp (argv[0]->value.time);
                end = e_ews_make_timestamp (argv[1]->value.time);
 
-               e_soap_message_start_element (ctx->msg, "And", NULL, NULL);
+               e_soap_request_start_element (ctx->req, "And", NULL, NULL);
                ews_restriction_write_greater_than_or_equal_to_message (ctx, "calendar:Start", start);
                ews_restriction_write_less_than_or_equal_to_message (ctx, "calendar:End", end);
-               e_soap_message_end_element (ctx->msg);
+               e_soap_request_end_element (ctx->req);
 
                g_free (start);
                g_free (end);
@@ -1302,7 +1302,7 @@ e_ews_query_check_applicable (const gchar *query,
        if (!e_ews_check_is_query (query, type))
                return FALSE;
 
-       ctx.msg = NULL;
+       ctx.req = NULL;
        ctx.any_applicable = FALSE;
 
        e_ews_convert_sexp_to_restriction (&ctx, query, type);
@@ -1311,13 +1311,13 @@ e_ews_query_check_applicable (const gchar *query,
 }
 
 void
-e_ews_query_to_restriction (ESoapMessage *msg,
+e_ews_query_to_restriction (ESoapRequest *req,
                             const gchar *query,
                             EEwsFolderType type)
 {
        EvalContext ctx;
 
-       ctx.msg = msg;
+       ctx.req = req;
        ctx.any_applicable = FALSE;
 
        e_ews_convert_sexp_to_restriction (&ctx, query, type);
diff --git a/src/EWS/common/e-ews-query-to-restriction.h b/src/EWS/common/e-ews-query-to-restriction.h
index 6cc00cec..1869bf7c 100644
--- a/src/EWS/common/e-ews-query-to-restriction.h
+++ b/src/EWS/common/e-ews-query-to-restriction.h
@@ -8,13 +8,13 @@
 #ifndef E_EWS_QUERY_TO_RESTRICTION_H
 #define E_EWS_QUERY_TO_RESTRICTION_H
 
-#include "common/e-soap-message.h"
+#include "common/e-soap-request.h"
 #include "common/e-ews-folder.h"
 
 gboolean       e_ews_query_check_applicable    (const gchar *query,
                                                 EEwsFolderType type);
 
-void           e_ews_query_to_restriction      (ESoapMessage *msg,
+void           e_ews_query_to_restriction      (ESoapRequest *req,
                                                 const gchar *query,
                                                 EEwsFolderType type);
 
diff --git a/src/EWS/common/e-ews-request.c b/src/EWS/common/e-ews-request.c
new file mode 100644
index 00000000..083e5b40
--- /dev/null
+++ b/src/EWS/common/e-ews-request.c
@@ -0,0 +1,327 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * SPDX-FileCopyrightText: (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * SPDX-FileContributor: JP Rosevear <jpr ximian com>
+ * SPDX-FileContributor: Rodrigo Moya <rodrigo ximian com>
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "evolution-ews-config.h"
+
+#include <string.h>
+#include <libsoup/soup.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/tree.h>
+
+#include "e-ews-request.h"
+
+static const gchar *
+convert_server_version_to_string (EEwsServerVersion version)
+{
+       /* server info */
+       switch (version) {
+               /*
+                * If we don't know the server version, let's use the safest possible
+                */
+               case E_EWS_EXCHANGE_UNKNOWN:
+                       return "Exchange2007_SP1";
+               case E_EWS_EXCHANGE_2007:
+                       return "Exchange2007";
+               case E_EWS_EXCHANGE_2007_SP1:
+                       return "Exchange2007_SP1";
+               case E_EWS_EXCHANGE_2010:
+                       return "Exchange2010";
+               case E_EWS_EXCHANGE_2010_SP1:
+                       return "Exchange2010_SP1";
+               case E_EWS_EXCHANGE_2010_SP2:
+                       return "Exchange2010_SP2";
+               /*
+                * If we don't have support for the latest version, let's use the latest possible
+                */
+               case E_EWS_EXCHANGE_FUTURE:
+               case E_EWS_EXCHANGE_2013:
+                       return "Exchange2013";
+       }
+
+       return "Exchange2007";
+}
+
+ESoapRequest *
+e_ews_request_new_with_header (const gchar *uri,
+                               const gchar *impersonate_user,
+                               const gchar *method_name,
+                               const gchar *attribute_name,
+                               const gchar *attribute_value,
+                              EEwsServerVersion server_version,
+                               EEwsServerVersion minimum_version,
+                              gboolean force_minimum_version,
+                              GError **error)
+{
+       ESoapRequest *req;
+       const gchar *server_ver;
+       EEwsServerVersion version;
+
+       req = e_soap_request_new (SOUP_METHOD_POST, uri, FALSE, NULL, NULL, NULL, error);
+       if (req == NULL) {
+               g_warning ("%s: Could not build SOAP message for uri '%s'", G_STRFUNC, uri);
+               return NULL;
+       }
+
+       e_soap_request_start_envelope (req);
+
+       if (force_minimum_version)
+               version = minimum_version;
+       else
+               version = server_version >= minimum_version ? server_version : minimum_version;
+
+       server_ver = convert_server_version_to_string (version);
+
+       e_soap_request_start_header (req);
+
+       e_soap_request_start_element (
+               req, "RequestServerVersion", "types",
+               "http://schemas.microsoft.com/exchange/services/2006/types";);
+       e_soap_request_add_attribute (req, "Version", server_ver, NULL, NULL);
+       e_soap_request_end_element (req);
+
+       if (impersonate_user && *impersonate_user) {
+               e_soap_request_start_element (req, "ExchangeImpersonation", "types",
+                       "http://schemas.microsoft.com/exchange/services/2006/types";);
+
+               e_soap_request_start_element (req, "ConnectingSID", "types", NULL);
+
+               if (strchr (impersonate_user, '@') != 0)
+                       e_soap_request_start_element (req, "PrimarySmtpAddress", "types", NULL);
+               else
+                       e_soap_request_start_element (req, "PrincipalName", "types", NULL);
+               e_soap_request_write_string (req, impersonate_user);
+               e_soap_request_end_element (req); /* PrimarySmtpAddress or PrincipalName */
+
+               e_soap_request_end_element (req); /* ConnectingSID */
+
+               e_soap_request_end_element (req); /* ExchangeImpersonation */
+       }
+
+       e_soap_request_end_header (req);
+
+       e_soap_request_start_body (req);
+       e_soap_request_add_namespace (
+               req, "messages",
+               "http://schemas.microsoft.com/exchange/services/2006/messages";);
+       e_soap_request_start_element (req, method_name, "messages", NULL);
+       e_soap_request_set_default_namespace (
+               req,
+               "http://schemas.microsoft.com/exchange/services/2006/types";);
+       if (attribute_name != NULL)
+               e_soap_request_add_attribute (
+                       req, attribute_name, attribute_value, NULL, NULL);
+
+       return req;
+}
+
+void
+e_ews_request_write_string_parameter (ESoapRequest *req,
+                                      const gchar *name,
+                                      const gchar *prefix,
+                                      const gchar *value)
+{
+       e_soap_request_start_element (req, name, prefix, NULL);
+       e_soap_request_write_string (req, value);
+       e_soap_request_end_element (req);
+}
+
+void
+e_ews_request_write_string_parameter_with_attribute (ESoapRequest *req,
+                                                     const gchar *name,
+                                                     const gchar *prefix,
+                                                     const gchar *value,
+                                                     const gchar *attribute_name,
+                                                     const gchar *attribute_value)
+{
+       e_soap_request_start_element (req, name, prefix, NULL);
+       e_soap_request_add_attribute (
+               req, attribute_name, attribute_value, NULL, NULL);
+       e_soap_request_write_string (req, value);
+       e_soap_request_end_element (req);
+}
+
+void
+e_ews_request_write_base64_parameter (ESoapRequest *req,
+                                      const gchar *name,
+                                      const gchar *prefix,
+                                      const gchar *value)
+{
+       e_soap_request_start_element (req, name, prefix, NULL);
+       e_soap_request_write_base64 (req, value, strlen (value));
+       e_soap_request_end_element (req);
+}
+
+void
+e_ews_request_write_int_parameter (ESoapRequest *req,
+                                   const gchar *name,
+                                   const gchar *prefix,
+                                   glong value)
+{
+       e_soap_request_start_element (req, name, prefix, NULL);
+       e_soap_request_write_int (req, value);
+       e_soap_request_end_element (req);
+}
+
+void
+e_ews_request_write_double_parameter (ESoapRequest *req,
+                                     const gchar *name,
+                                     const gchar *prefix,
+                                     gdouble value)
+{
+       e_soap_request_start_element (req, name, prefix, NULL);
+       e_soap_request_write_double (req, value);
+       e_soap_request_end_element (req);
+}
+
+void
+e_ews_request_write_time_parameter (ESoapRequest *req,
+                                   const gchar *name,
+                                   const gchar *prefix,
+                                   time_t value)
+{
+       e_soap_request_start_element (req, name, prefix, NULL);
+       e_soap_request_write_time (req, value);
+       e_soap_request_end_element (req);
+}
+
+void
+e_ews_request_write_footer (ESoapRequest *req)
+{
+       e_soap_request_end_element (req);
+       e_soap_request_end_body (req);
+       e_soap_request_end_envelope (req);
+}
+
+void
+e_ews_request_write_extended_tag (ESoapRequest *req,
+                                 guint32 prop_id,
+                                 const gchar *prop_type)
+{
+       gchar *num;
+
+       num = g_strdup_printf ("%d", prop_id);
+
+       e_soap_request_start_element (req, "ExtendedFieldURI", NULL, NULL);
+       e_soap_request_add_attribute (req, "PropertyTag", num, NULL, NULL);
+       e_soap_request_add_attribute (req, "PropertyType", prop_type, NULL, NULL);
+       e_soap_request_end_element (req); /* ExtendedFieldURI */
+
+       g_free (num);
+}
+
+void
+e_ews_request_write_extended_distinguished_tag (ESoapRequest *req,
+                                               const gchar *set_id,
+                                               guint32 prop_id,
+                                               const gchar *prop_type)
+{
+       gchar *num;
+
+       num = g_strdup_printf ("%d", prop_id);
+
+       e_soap_request_start_element (req, "ExtendedFieldURI", NULL, NULL);
+       e_soap_request_add_attribute (req, "DistinguishedPropertySetId", set_id, NULL, NULL);
+       e_soap_request_add_attribute (req, "PropertyId", num, NULL, NULL);
+       e_soap_request_add_attribute (req, "PropertyType", prop_type, NULL, NULL);
+       e_soap_request_end_element (req); /* ExtendedFieldURI */
+
+       g_free (num);
+}
+
+void
+e_ews_request_write_extended_name (ESoapRequest *req,
+                                  const gchar *name,
+                                  const gchar *prop_type)
+{
+       e_soap_request_start_element (req, "ExtendedFieldURI", NULL, NULL);
+       e_soap_request_add_attribute (req, "PropertyName", name, NULL, NULL);
+       e_soap_request_add_attribute (req, "PropertyType", prop_type, NULL, NULL);
+       e_soap_request_end_element (req); /* ExtendedFieldURI */
+}
+
+void
+e_ews_request_write_extended_distinguished_name (ESoapRequest *req,
+                                                const gchar *set_id,
+                                                const gchar *name,
+                                                const gchar *prop_type)
+{
+       e_soap_request_start_element (req, "ExtendedFieldURI", NULL, NULL);
+       e_soap_request_add_attribute (req, "DistinguishedPropertySetId", set_id, NULL, NULL);
+       e_soap_request_add_attribute (req, "PropertyName", name, NULL, NULL);
+       e_soap_request_add_attribute (req, "PropertyType", prop_type, NULL, NULL);
+       e_soap_request_end_element (req); /* ExtendedFieldURI */
+}
+
+static xmlXPathObjectPtr
+xpath_eval (xmlXPathContextPtr ctx,
+           const gchar *format,
+           ...)
+{
+       xmlXPathObjectPtr result;
+       va_list args;
+       gchar *expr;
+
+       if (ctx == NULL)
+               return NULL;
+
+       va_start (args, format);
+       expr = g_strdup_vprintf (format, args);
+       va_end (args);
+
+       result = xmlXPathEvalExpression (BAD_CAST expr, ctx);
+       g_free (expr);
+
+       if (result == NULL)
+               return NULL;
+
+       if (result->type == XPATH_NODESET && xmlXPathNodeSetIsEmpty (result->nodesetval)) {
+               xmlXPathFreeObject (result);
+               return NULL;
+       }
+
+       return result;
+}
+
+void
+e_ews_request_replace_server_version (ESoapRequest *req,
+                                     EEwsServerVersion version)
+{
+       xmlDocPtr doc;
+       xmlXPathContextPtr xpctx;
+       xmlXPathObjectPtr result;
+       xmlNodeSetPtr nodeset;
+       xmlNodePtr node;
+       const gchar *server_ver;
+
+       doc = e_soap_request_get_xml_doc (req);
+       xpctx = xmlXPathNewContext (doc);
+
+       xmlXPathRegisterNs (
+                       xpctx,
+                       BAD_CAST "s",
+                       BAD_CAST "http://schemas.xmlsoap.org/soap/envelope/";);
+
+       xmlXPathRegisterNs (
+                       xpctx,
+                       BAD_CAST "t",
+                       BAD_CAST "http://schemas.microsoft.com/exchange/services/2006/types";);
+
+       result = xpath_eval (xpctx, "/s:Envelope/s:Header/t:RequestServerVersion");
+       if (result != NULL) {
+               server_ver = convert_server_version_to_string (version);
+
+               nodeset = result->nodesetval;
+               node = nodeset->nodeTab[0];
+               xmlSetProp (node, BAD_CAST "Version", BAD_CAST server_ver);
+       }
+
+       xmlXPathFreeObject (result);
+       xmlXPathFreeContext (xpctx);
+}
diff --git a/src/EWS/common/e-ews-message.h b/src/EWS/common/e-ews-request.h
similarity index 56%
rename from src/EWS/common/e-ews-message.h
rename to src/EWS/common/e-ews-request.h
index 21494486..3a7e9973 100644
--- a/src/EWS/common/e-ews-message.h
+++ b/src/EWS/common/e-ews-request.h
@@ -6,11 +6,10 @@
  * SPDX-License-Identifier: LGPL-2.1-or-later
  */
 
-#ifndef E_EWS_MESSAGE_H
-#define E_EWS_MESSAGE_H
+#ifndef E_EWS_REQUEST_H
+#define E_EWS_REQUEST_H
 
-#include "e-soap-message.h"
-#include "camel-ews-settings.h"
+#include "e-soap-request.h"
 
 G_BEGIN_DECLS
 
@@ -25,13 +24,7 @@ typedef enum {
        E_EWS_EXCHANGE_FUTURE
 } EEwsServerVersion;
 
-void           e_ews_message_attach_chunk_allocator
-                                               (SoupMessage *message);
-void           e_ews_message_set_user_agent_header
-                                               (SoupMessage *message,
-                                                CamelEwsSettings *settings);
-ESoapMessage * e_ews_message_new_with_header   (CamelEwsSettings *settings,
-                                                const gchar *uri,
+ESoapRequest * e_ews_request_new_with_header   (const gchar *uri,
                                                 const gchar *impersonate_user,
                                                 const gchar *method_name,
                                                 const gchar *attribute_name,
@@ -39,65 +32,66 @@ ESoapMessage *      e_ews_message_new_with_header   (CamelEwsSettings *settings,
                                                 EEwsServerVersion server_version,
                                                 EEwsServerVersion minimum_version,
                                                 gboolean force_minimum_version,
-                                                gboolean standard_handlers);
-void           e_ews_message_write_string_parameter
-                                               (ESoapMessage *msg,
+                                                GError **error);
+void           e_ews_request_write_string_parameter
+                                               (ESoapRequest *req,
                                                 const gchar *name,
                                                 const gchar *prefix,
                                                 const gchar *value);
-void           e_ews_message_write_string_parameter_with_attribute
-                                               (ESoapMessage *msg,
+void           e_ews_request_write_string_parameter_with_attribute
+                                               (ESoapRequest *req,
                                                 const gchar *name,
                                                 const gchar *prefix,
                                                 const gchar *value,
                                                 const gchar *attribute_name,
                                                 const gchar *attribute_value);
-void           e_ews_message_write_base64_parameter
-                                               (ESoapMessage *msg,
+void           e_ews_request_write_base64_parameter
+                                               (ESoapRequest *req,
                                                 const gchar *name,
                                                 const gchar *prefix,
                                                 const gchar *value);
-void           e_ews_message_write_int_parameter
-                                               (ESoapMessage *msg,
+void           e_ews_request_write_int_parameter
+                                               (ESoapRequest *req,
                                                 const gchar *name,
                                                 const gchar *prefix,
                                                 glong value);
-void           e_ews_message_write_double_parameter
-                                               (ESoapMessage *msg,
+void           e_ews_request_write_double_parameter
+                                               (ESoapRequest *req,
                                                 const gchar *name,
                                                 const gchar *prefix,
                                                 gdouble value);
-void           e_ews_message_write_time_parameter
-                                               (ESoapMessage *msg,
+void           e_ews_request_write_time_parameter
+                                               (ESoapRequest *req,
                                                 const gchar *name,
                                                 const gchar *prefix,
                                                 time_t value);
-void           e_ews_message_write_footer      (ESoapMessage *msg);
+void           e_ews_request_write_footer      (ESoapRequest *req);
 
-void           e_ews_message_write_extended_tag
-                                               (ESoapMessage *msg,
+void           e_ews_request_write_extended_tag
+                                               (ESoapRequest *req,
                                                 guint32 prop_id,
                                                 const gchar *prop_type);
 
-void           e_ews_message_write_extended_distinguished_tag
-                                               (ESoapMessage *msg,
+void           e_ews_request_write_extended_distinguished_tag
+                                               (ESoapRequest *req,
                                                 const gchar *set_id,
                                                 guint32 prop_id,
                                                 const gchar *prop_type);
 
-void           e_ews_message_write_extended_name
-                                               (ESoapMessage *msg,
+void           e_ews_request_write_extended_name
+                                               (ESoapRequest *req,
                                                 const gchar *name,
                                                 const gchar *prop_type);
 
-void           e_ews_message_write_extended_distinguished_name
-                                               (ESoapMessage *msg,
+void           e_ews_request_write_extended_distinguished_name
+                                               (ESoapRequest *req,
                                                 const gchar *set_id,
                                                 const gchar *name,
                                                 const gchar *prop_type);
 
-void           e_ews_message_replace_server_version (ESoapMessage *msg,
-                                                     EEwsServerVersion version);
+void           e_ews_request_replace_server_version
+                                               (ESoapRequest *req,
+                                                EEwsServerVersion version);
 
 G_END_DECLS
 
diff --git a/src/EWS/common/e-oauth2-service-office365.c b/src/EWS/common/e-oauth2-service-office365.c
index d9a944c9..e22c60c3 100644
--- a/src/EWS/common/e-oauth2-service-office365.c
+++ b/src/EWS/common/e-oauth2-service-office365.c
@@ -376,7 +376,7 @@ eos_office365_extract_authorization_code (EOAuth2Service *service,
                                          const gchar *page_content,
                                          gchar **out_authorization_code)
 {
-       SoupURI *suri;
+       GUri *uri;
        gboolean known = FALSE;
 
        g_return_val_if_fail (out_authorization_code != NULL, FALSE);
@@ -386,12 +386,12 @@ eos_office365_extract_authorization_code (EOAuth2Service *service,
        if (!page_uri || !*page_uri)
                return FALSE;
 
-       suri = soup_uri_new (page_uri);
-       if (!suri)
+       uri = g_uri_parse (page_uri, SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
+       if (!uri)
                return FALSE;
 
-       if (suri->query) {
-               GHashTable *uri_query = soup_form_decode (suri->query);
+       if (g_uri_get_query (uri)) {
+               GHashTable *uri_query = soup_form_decode (g_uri_get_query (uri));
 
                if (uri_query) {
                        const gchar *code;
@@ -419,7 +419,7 @@ eos_office365_extract_authorization_code (EOAuth2Service *service,
                }
        }
 
-       soup_uri_free (suri);
+       g_uri_unref (uri);
 
        return known;
 }
diff --git a/src/EWS/common/e-soap-request.c b/src/EWS/common/e-soap-request.c
new file mode 100644
index 00000000..b4b744da
--- /dev/null
+++ b/src/EWS/common/e-soap-request.c
@@ -0,0 +1,1145 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * SPDX-FileCopyrightText: (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "evolution-ews-config.h"
+
+#include <libedataserver/libedataserver.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <libsoup/soup.h>
+
+#include "e-ews-connection-utils.h"
+#include "e-ews-debug.h"
+
+#include "e-soap-request.h"
+
+struct _ESoapRequestPrivate {
+       gchar *method;
+       GUri *uri;
+
+       ESoapResponseProgressFn progress_fn;
+       gpointer progress_data;
+
+       ESoapRequestCustomProcessFn custom_process_fn;
+       gpointer custom_process_data;
+
+       gchar *custom_body_content_type;
+       gpointer custom_body_data;
+       gssize custom_body_data_len;
+
+       gchar *etag;
+
+       gchar *store_node_data_nodename;
+       gchar *store_node_data_directory;
+       gboolean store_node_data_base64;
+
+       gchar *certificate_pem;
+       GTlsCertificateFlags certificate_errors;
+
+       xmlDocPtr doc;
+       xmlNodePtr last_node;
+       xmlNsPtr soap_ns;
+       xmlNsPtr xsi_ns;
+       xmlChar *env_prefix;
+       xmlChar *env_uri;
+       gboolean body_started;
+       gchar *action;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (ESoapRequest, e_soap_request, G_TYPE_OBJECT)
+
+static void
+soap_request_finalize (GObject *object)
+{
+       ESoapRequest *req = E_SOAP_REQUEST (object);
+
+       g_clear_pointer (&req->priv->method, g_free);
+       g_clear_pointer (&req->priv->uri, g_uri_unref);
+       g_clear_pointer (&req->priv->custom_body_content_type, g_free);
+       g_clear_pointer (&req->priv->custom_body_data, g_free);
+       g_clear_pointer (&req->priv->etag, g_free);
+       g_clear_pointer (&req->priv->certificate_pem, g_free);
+       g_clear_pointer (&req->priv->store_node_data_nodename, g_free);
+       g_clear_pointer (&req->priv->store_node_data_directory, g_free);
+
+       g_clear_pointer (&req->priv->doc, xmlFreeDoc);
+       g_clear_pointer (&req->priv->action, g_free);
+       g_clear_pointer (&req->priv->env_uri, xmlFree);
+       g_clear_pointer (&req->priv->env_prefix, xmlFree);
+
+       /* Chain up to parent's method. */
+       G_OBJECT_CLASS (e_soap_request_parent_class)->finalize (object);
+}
+
+static void
+e_soap_request_class_init (ESoapRequestClass *class)
+{
+       GObjectClass *object_class;
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->finalize = soap_request_finalize;
+}
+
+static void
+e_soap_request_init (ESoapRequest *req)
+{
+       req->priv = e_soap_request_get_instance_private (req);
+
+       /* initialize XML structures */
+       req->priv->doc = xmlNewDoc ((const xmlChar *) "1.0");
+       req->priv->doc->standalone = FALSE;
+       req->priv->doc->encoding = xmlCharStrdup ("UTF-8");
+}
+
+static xmlNsPtr
+fetch_ns (ESoapRequest *req,
+          const gchar *prefix,
+          const gchar *ns_uri)
+{
+       xmlNsPtr ns = NULL;
+
+       if (prefix && ns_uri)
+               ns = xmlNewNs (
+                       req->priv->last_node,
+                       (const xmlChar *) ns_uri,
+                       (const xmlChar *) prefix);
+       else if (prefix && !ns_uri) {
+               ns = xmlSearchNs (
+                       req->priv->doc, req->priv->last_node,
+                       (const xmlChar *) prefix);
+               if (!ns)
+                       ns = xmlNewNs (
+                               req->priv->last_node,
+                               (const xmlChar *) "",
+                               (const xmlChar *) prefix);
+       }
+
+       return ns;
+}
+
+/**
+ * e_soap_request_new:
+ * @method: the HTTP method for the created request.
+ * @uri_string: the destination endpoint (as a string).
+ * @standalone: ??? FIXME
+ * @xml_encoding: ??? FIXME
+ * @env_prefix: ??? FIXME
+ * @env_uri: ??? FIXME
+ * @error: a #GError, or %NULL
+ *
+ * Creates a new empty #ESoapRequest, which will connect to @uri_string.
+ *
+ * Returns: the new #ESoapRequest (or %NULL if @uri_string could not be
+ * parsed).
+ */
+ESoapRequest *
+e_soap_request_new (const gchar *method,
+                    const gchar *uri_string,
+                    gboolean standalone,
+                    const gchar *xml_encoding,
+                    const gchar *env_prefix,
+                    const gchar *env_uri,
+                   GError **error)
+{
+       ESoapRequest *req;
+       GUri *uri;
+
+       uri = g_uri_parse (uri_string, SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, error);
+       if (!uri)
+               return NULL;
+
+       req = e_soap_request_new_from_uri (
+               method, uri, standalone,
+               xml_encoding, env_prefix, env_uri);
+
+       g_uri_unref (uri);
+
+       return req;
+}
+
+/**
+ * e_soap_request_new_from_uri:
+ * @method: the HTTP method for the created request.
+ * @uri: the destination endpoint (as a #GUri).
+ * @standalone: ??? FIXME
+ * @xml_encoding: ??? FIXME
+ * @env_prefix: ??? FIXME
+ * @env_uri: ??? FIXME
+ *
+ * Creates a new empty #ESoapRequest, which will connect to @uri
+ *
+ * Returns: the new #ESoapRequest
+ */
+ESoapRequest *
+e_soap_request_new_from_uri (const gchar *method,
+                             GUri *uri,
+                             gboolean standalone,
+                             const gchar *xml_encoding,
+                             const gchar *env_prefix,
+                             const gchar *env_uri)
+{
+       ESoapRequest *req;
+
+       req = g_object_new (E_TYPE_SOAP_REQUEST, NULL);
+
+       req->priv->method = g_strdup (method);
+       req->priv->uri = g_uri_ref (uri);
+       req->priv->doc->standalone = standalone;
+
+       if (xml_encoding) {
+               xmlFree ((xmlChar *) req->priv->doc->encoding);
+               req->priv->doc->encoding = xmlCharStrdup (xml_encoding);
+       }
+
+       if (env_prefix != NULL)
+               req->priv->env_prefix = xmlCharStrdup (env_prefix);
+       if (env_uri != NULL)
+               req->priv->env_uri = xmlCharStrdup (env_uri);
+
+       return req;
+}
+
+/**
+ * e_soap_request_start_envelope:
+ * @req: the %ESoapRequest.
+ *
+ * Starts the top level SOAP Envelope element.
+ */
+void
+e_soap_request_start_envelope (ESoapRequest *req)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       req->priv->doc->xmlRootNode = xmlNewDocNode (
+               req->priv->doc, NULL,
+               (const xmlChar *) "Envelope",
+               (const xmlChar *) NULL);
+       req->priv->last_node = req->priv->doc->xmlRootNode;
+
+       req->priv->soap_ns = xmlNewNs (
+               req->priv->doc->xmlRootNode,
+               req->priv->env_uri ? req->priv->env_uri :
+               (const xmlChar *) "http://schemas.xmlsoap.org/soap/envelope/";,
+               req->priv->env_prefix ? req->priv->env_prefix :
+               (const xmlChar *) "SOAP-ENV");
+
+       if (req->priv->env_uri != NULL) {
+               xmlFree (req->priv->env_uri);
+               req->priv->env_uri = NULL;
+       }
+
+       if (req->priv->env_prefix) {
+               xmlFree (req->priv->env_prefix);
+               req->priv->env_prefix = NULL;
+       }
+
+       xmlSetNs (
+               req->priv->doc->xmlRootNode,
+               req->priv->soap_ns);
+       xmlNewNs (
+               req->priv->doc->xmlRootNode,
+               (const xmlChar *) "http://schemas.xmlsoap.org/soap/encoding/";,
+               (const xmlChar *) "SOAP-ENC");
+       xmlNewNs (
+               req->priv->doc->xmlRootNode,
+               (const xmlChar *) "http://www.w3.org/2001/XMLSchema";,
+               (const xmlChar *) "xsd");
+       xmlNewNs (
+               req->priv->doc->xmlRootNode,
+               (const xmlChar *) "http://schemas.xmlsoap.org/soap/envelope/";,
+               (const xmlChar *) "SOAP-ENV");
+       req->priv->xsi_ns = xmlNewNs (
+               req->priv->doc->xmlRootNode,
+               (const xmlChar *) "http://www.w3.org/2001/XMLSchema-instance";,
+               (const xmlChar *) "xsi");
+}
+
+/**
+ * e_soap_request_end_envelope:
+ * @req: the %ESoapRequest.
+ *
+ * Closes the top level SOAP Envelope element.
+ */
+void
+e_soap_request_end_envelope (ESoapRequest *req)
+{
+       e_soap_request_end_element (req);
+}
+
+/**
+ * e_soap_request_start_body:
+ * @req: the %ESoapRequest.
+ *
+ * Starts the SOAP Body element.
+ */
+void
+e_soap_request_start_body (ESoapRequest *req)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       if (req->priv->body_started)
+               return;
+
+       req->priv->last_node = xmlNewChild (
+               req->priv->last_node,
+               req->priv->soap_ns,
+               (const xmlChar *) "Body", NULL);
+
+       req->priv->body_started = TRUE;
+}
+
+/**
+ * e_soap_request_end_body:
+ * @req: the %ESoapRequest.
+ *
+ * Closes the SOAP Body element.
+ */
+void
+e_soap_request_end_body (ESoapRequest *req)
+{
+       e_soap_request_end_element (req);
+}
+
+/**
+ * e_soap_request_start_element:
+ * @req: the #ESoapRequest.
+ * @name: the element name.
+ * @prefix: the namespace prefix
+ * @ns_uri: the namespace URI
+ *
+ * Starts a new arbitrary request element, with @name as the element
+ * name, @prefix as the XML Namespace prefix, and @ns_uri as the XML
+ * Namespace uri for * the created element.
+ *
+ * Passing @prefix with no @ns_uri will cause a recursive search for
+ * an existing namespace with the same prefix. Failing that a new ns
+ * will be created with an empty uri.
+ *
+ * Passing both @prefix and @ns_uri always causes new namespace
+ * attribute creation.
+ *
+ * Passing NULL for both @prefix and @ns_uri causes no prefix to be
+ * used, and the element will be in the default namespace.
+ */
+void
+e_soap_request_start_element (ESoapRequest *req,
+                              const gchar *name,
+                              const gchar *prefix,
+                              const gchar *ns_uri)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       req->priv->last_node = xmlNewChild (
+               req->priv->last_node, NULL,
+               (const xmlChar *) name, NULL);
+
+       xmlSetNs (req->priv->last_node, fetch_ns (req, prefix, ns_uri));
+
+       if (ns_uri == NULL)
+               ns_uri = "";
+
+       if (req->priv->body_started && req->priv->action == NULL)
+               req->priv->action = g_strconcat (ns_uri, "#", name, NULL);
+}
+
+/**
+ * e_soap_request_end_element:
+ * @req: the #ESoapRequest.
+ *
+ * Closes the current request element.
+ */
+void
+e_soap_request_end_element (ESoapRequest *req)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       req->priv->last_node = req->priv->last_node->parent;
+}
+
+/**
+ * e_soap_request_start_fault:
+ * @req: the #ESoapRequest.
+ * @faultcode: faultcode element value
+ * @faultstring: faultstring element value
+ * @faultfactor: faultfactor element value
+ *
+ * Starts a new SOAP Fault element, creating faultcode, faultstring,
+ * and faultfactor child elements.
+ *
+ * If you wish to add the faultdetail element, use
+ * e_soap_request_start_fault_detail(), and then
+ * e_soap_request_start_element() to add arbitrary sub-elements.
+ */
+void
+e_soap_request_start_fault (ESoapRequest *req,
+                            const gchar *faultcode,
+                            const gchar *faultstring,
+                            const gchar *faultfactor)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       req->priv->last_node = xmlNewChild (
+               req->priv->last_node,
+               req->priv->soap_ns,
+               (const xmlChar *) "Fault", NULL);
+       xmlNewChild (
+               req->priv->last_node,
+               req->priv->soap_ns,
+               (const xmlChar *) "faultcode",
+               (const xmlChar *) faultcode);
+       xmlNewChild (
+               req->priv->last_node,
+               req->priv->soap_ns,
+               (const xmlChar *) "faultstring",
+               (const xmlChar *) faultstring);
+
+       req->priv->last_node = xmlNewChild (
+               req->priv->last_node,
+               req->priv->soap_ns,
+               (const xmlChar *) "faultfactor",
+               (const xmlChar *) faultfactor);
+       if (faultfactor == NULL)
+               e_soap_request_set_null (req);
+
+       e_soap_request_end_element (req);
+}
+
+/**
+ * e_soap_request_end_fault:
+ * @req: the #ESoapRequest.
+ *
+ * Closes the current SOAP Fault element.
+ */
+void
+e_soap_request_end_fault (ESoapRequest *req)
+{
+       e_soap_request_end_element (req);
+}
+
+/**
+ * e_soap_request_start_fault_detail:
+ * @req: the #ESoapRequest.
+ *
+ * Start the faultdetail child element of the current SOAP Fault
+ * element. The faultdetail element allows arbitrary data to be sent
+ * in a returned fault.
+ **/
+void
+e_soap_request_start_fault_detail (ESoapRequest *req)
+{
+
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       req->priv->last_node = xmlNewChild (
+               req->priv->last_node,
+               req->priv->soap_ns,
+               (const xmlChar *) "detail",
+               (const xmlChar *) NULL);
+}
+
+/**
+ * e_soap_request_end_fault_detail:
+ * @req: the #ESoapRequest.
+ *
+ * Closes the current SOAP faultdetail element.
+ */
+void
+e_soap_request_end_fault_detail (ESoapRequest *req)
+{
+       e_soap_request_end_element (req);
+}
+
+/**
+ * e_soap_request_start_header:
+ * @req: the #ESoapRequest.
+ *
+ * Creates a new SOAP Header element. You can call
+ * e_soap_request_start_header_element() after this to add a new
+ * header child element. SOAP Header elements allow out-of-band data
+ * to be transferred while not interfering with the request body.
+ *
+ * This should be called after e_soap_request_start_envelope() and
+ * before e_soap_request_start_body().
+ */
+void
+e_soap_request_start_header (ESoapRequest *req)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       req->priv->last_node = xmlNewChild (
+               req->priv->last_node,
+               req->priv->soap_ns,
+               (const xmlChar *) "Header",
+               (const xmlChar *) NULL);
+}
+
+/**
+ * e_soap_request_end_header:
+ * @req: the #ESoapRequest.
+ *
+ * Closes the current SOAP Header element.
+ */
+void
+e_soap_request_end_header (ESoapRequest *req)
+{
+       e_soap_request_end_element (req);
+}
+
+/**
+ * e_soap_request_start_header_element:
+ * @req: the #ESoapRequest.
+ * @name: name of the header element
+ * @must_understand: whether the recipient must understand the header in order
+ * to proceed with processing the request
+ * @actor_uri: the URI which represents the destination actor for this header.
+ * @prefix: the namespace prefix
+ * @ns_uri: the namespace URI
+ *
+ * Starts a new SOAP arbitrary header element.
+ */
+void
+e_soap_request_start_header_element (ESoapRequest *req,
+                                     const gchar *name,
+                                     gboolean must_understand,
+                                     const gchar *actor_uri,
+                                     const gchar *prefix,
+                                     const gchar *ns_uri)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       e_soap_request_start_element (req, name, prefix, ns_uri);
+       if (actor_uri != NULL)
+               xmlNewNsProp (
+                       req->priv->last_node,
+                       req->priv->soap_ns,
+                       (const xmlChar *) "actorUri",
+                       (const xmlChar *) actor_uri);
+       if (must_understand)
+               xmlNewNsProp (
+                       req->priv->last_node,
+                       req->priv->soap_ns,
+                       (const xmlChar *) "mustUnderstand",
+                       (const xmlChar *) "1");
+}
+
+/**
+ * e_soap_request_end_header_element:
+ * @req: the #ESoapRequest.
+ *
+ * Closes the current SOAP header element.
+ */
+void
+e_soap_request_end_header_element (ESoapRequest *req)
+{
+       e_soap_request_end_element (req);
+}
+
+/**
+ * e_soap_request_write_int:
+ * @req: the #ESoapRequest.
+ * @i: the integer value to write.
+ *
+ * Writes the stringified value of @i as the current element's content.
+ */
+void
+e_soap_request_write_int (ESoapRequest *req,
+                          glong i)
+{
+       gchar *string;
+
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       string = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) i);
+       e_soap_request_write_string (req, string);
+       g_free (string);
+}
+
+/**
+ * e_soap_request_write_double:
+ * @req: the #ESoapRequest.
+ * @d: the double value to write.
+ *
+ * Writes the stringified value of @d as the current element's content.
+ */
+void
+e_soap_request_write_double (ESoapRequest *req,
+                             gdouble d)
+{
+       gchar buffer[G_ASCII_DTOSTR_BUF_SIZE + 1];
+
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       g_ascii_dtostr (buffer, sizeof (buffer), d);
+       e_soap_request_write_string (req, buffer);
+}
+
+/**
+ * e_soap_request_write_base64:
+ * @req: the #ESoapRequest
+ * @string: the binary data buffer to encode
+ * @len: the length of data to encode
+ *
+ * Writes the Base-64 encoded value of @string as the current
+ * element's content.
+ **/
+void
+e_soap_request_write_base64 (ESoapRequest *req,
+                             const gchar *string,
+                             gint len)
+{
+       gchar *encoded;
+
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       encoded = g_base64_encode ((const guchar *) string, len);
+       e_soap_request_write_string (req, encoded);
+       g_free (encoded);
+}
+
+/**
+ * e_soap_request_write_time:
+ * @req: the #ESoapRequest.
+ * @timeval: the time_t to encode
+ *
+ * Writes the iso8601 value of @timeval as the current element's
+ * content.
+ **/
+void
+e_soap_request_write_time (ESoapRequest *req,
+                           time_t timeval)
+{
+       GTimeVal tv;
+       gchar *iso_time;
+
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       tv.tv_usec = 0;
+       tv.tv_sec = timeval;
+
+       iso_time = g_time_val_to_iso8601 (&tv);
+       e_soap_request_write_string (req, iso_time);
+       g_free (iso_time);
+}
+
+/**
+ * e_soap_request_write_string:
+ * @req: the #ESoapRequest.
+ * @string: string to write.
+ *
+ * Writes the @string as the current element's content.
+ */
+void
+e_soap_request_write_string (ESoapRequest *req,
+                             const gchar *string)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       xmlNodeAddContent (
+               req->priv->last_node,
+               (const xmlChar *) string);
+}
+
+/**
+ * e_soap_request_write_buffer:
+ * @req: the #ESoapRequest.
+ * @buffer: the string data buffer to write.
+ * @len: length of @buffer.
+ *
+ * Writes the string buffer pointed to by @buffer as the current
+ * element's content.
+ */
+void
+e_soap_request_write_buffer (ESoapRequest *req,
+                             const gchar *buffer,
+                             gint len)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       xmlNodeAddContentLen (
+               req->priv->last_node,
+               (const xmlChar *) buffer, len);
+}
+
+/**
+ * e_soap_request_set_element_type:
+ * @req: the #ESoapRequest.
+ * @xsi_type: the type name for the element.
+ *
+ * Sets the current element's XML schema xsi:type attribute, which
+ * specifies the element's type name.
+ */
+void
+e_soap_request_set_element_type (ESoapRequest *req,
+                                 const gchar *xsi_type)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       xmlNewNsProp (
+               req->priv->last_node,
+               req->priv->xsi_ns,
+               (const xmlChar *) "type",
+               (const xmlChar *) xsi_type);
+}
+
+/**
+ * e_soap_request_set_null:
+ * @req: the #ESoapRequest.
+ *
+ * Sets the current element's XML Schema xsi:null attribute.
+ */
+void
+e_soap_request_set_null (ESoapRequest *req)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       xmlNewNsProp (
+               req->priv->last_node,
+               req->priv->xsi_ns,
+               (const xmlChar *) "null",
+               (const xmlChar *) "1");
+}
+
+/**
+ * e_soap_request_add_attribute:
+ * @req: the #ESoapRequest.
+ * @name: name of the attribute
+ * @value: value of the attribute
+ * @prefix: the namespace prefix
+ * @ns_uri: the namespace URI
+ *
+ * Adds an XML attribute to the current element.
+ */
+void
+e_soap_request_add_attribute (ESoapRequest *req,
+                              const gchar *name,
+                              const gchar *value,
+                              const gchar *prefix,
+                              const gchar *ns_uri)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       xmlNewNsProp (
+               req->priv->last_node,
+               fetch_ns (req, prefix, ns_uri),
+               (const xmlChar *) name,
+               (const xmlChar *) value);
+}
+
+/**
+ * e_soap_request_add_namespace:
+ * @req: the #ESoapRequest.
+ * @prefix: the namespace prefix
+ * @ns_uri: the namespace URI, or NULL for empty namespace
+ *
+ * Adds a new XML namespace to the current element.
+ */
+void
+e_soap_request_add_namespace (ESoapRequest *req,
+                              const gchar *prefix,
+                              const gchar *ns_uri)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       if (ns_uri == NULL)
+               ns_uri = "";
+
+       xmlNewNs (
+               req->priv->last_node,
+               (const xmlChar *) ns_uri,
+               (const xmlChar *) prefix);
+}
+
+/**
+ * e_soap_request_set_default_namespace:
+ * @req: the #ESoapRequest.
+ * @ns_uri: the namespace URI.
+ *
+ * Sets the default namespace to the URI specified in @ns_uri. The
+ * default namespace becomes the namespace all non-explicitly
+ * namespaced child elements fall into.
+ */
+void
+e_soap_request_set_default_namespace (ESoapRequest *req,
+                                      const gchar *ns_uri)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       e_soap_request_add_namespace (req, NULL, ns_uri);
+}
+
+/**
+ * e_soap_request_set_encoding_style:
+ * @req: the #ESoapRequest.
+ * @enc_style: the new encodingStyle value
+ *
+ * Sets the encodingStyle attribute on the current element to the
+ * value of @enc_style.
+ */
+void
+e_soap_request_set_encoding_style (ESoapRequest *req,
+                                   const gchar *enc_style)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       xmlNewNsProp (
+               req->priv->last_node,
+               req->priv->soap_ns,
+               (const xmlChar *) "encodingStyle",
+               (const xmlChar *) enc_style);
+}
+
+/**
+ * e_soap_request_reset:
+ * @req: the #ESoapRequest.
+ *
+ * Resets the internal XML representation of the SOAP request.
+ */
+void
+e_soap_request_reset (ESoapRequest *req)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       xmlFreeDoc (req->priv->doc);
+       req->priv->doc = xmlNewDoc ((const xmlChar *) "1.0");
+       req->priv->last_node = NULL;
+
+       g_free (req->priv->action);
+       req->priv->action = NULL;
+       req->priv->body_started = FALSE;
+
+       if (req->priv->env_uri != NULL) {
+               xmlFree (req->priv->env_uri);
+               req->priv->env_uri = NULL;
+       }
+
+       if (req->priv->env_prefix != NULL) {
+               xmlFree (req->priv->env_prefix);
+               req->priv->env_prefix = NULL;
+       }
+}
+
+/**
+ * e_soap_request_get_namespace_prefix:
+ * @req: the #ESoapRequest.
+ * @ns_uri: the namespace URI.
+ *
+ * Returns the namespace prefix for @ns_uri (or an empty string if
+ * @ns_uri is set to the default namespace)
+ *
+ * Returns: The namespace prefix, or %NULL if no namespace exists
+ * for the URI given.
+ */
+const gchar *
+e_soap_request_get_namespace_prefix (ESoapRequest *req,
+                                     const gchar *ns_uri)
+{
+       xmlNsPtr ns = NULL;
+
+       g_return_val_if_fail (E_IS_SOAP_REQUEST (req), NULL);
+       g_return_val_if_fail (ns_uri != NULL, NULL);
+
+       ns = xmlSearchNsByHref (
+               req->priv->doc,
+               req->priv->last_node,
+               (const xmlChar *) ns_uri);
+       if (ns != NULL) {
+               if (ns->prefix != NULL)
+                       return (const gchar *) ns->prefix;
+               else
+                       return "";
+       }
+
+       return NULL;
+}
+
+/**
+ * e_soap_request_get_xml_doc:
+ * @req: the #ESoapRequest.
+ *
+ * Returns the internal XML representation tree of the
+ * #ESoapRequest pointed to by @req.
+ *
+ * Returns: the #xmlDocPtr representing the SOAP request.
+ */
+xmlDocPtr
+e_soap_request_get_xml_doc (ESoapRequest *req)
+{
+       g_return_val_if_fail (E_IS_SOAP_REQUEST (req), NULL);
+
+       return req->priv->doc;
+}
+
+void
+e_soap_request_set_progress_fn (ESoapRequest *req,
+                               ESoapResponseProgressFn fn,
+                               gpointer user_data)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       req->priv->progress_fn = fn;
+       req->priv->progress_data = user_data;
+}
+
+void
+e_soap_request_get_progress_fn (ESoapRequest *req,
+                               ESoapResponseProgressFn *out_fn,
+                               gpointer *out_user_data)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+       g_return_if_fail (out_fn != NULL);
+       g_return_if_fail (out_user_data != NULL);
+
+       *out_fn = req->priv->progress_fn;
+       *out_user_data = req->priv->progress_data;
+}
+
+/**
+ * e_soap_request_set_custom_body:
+ * @req: the #ESoapRequest.
+ * @content_type: (optional): content type of the custom body
+ * @body: (optional): the custom message body, or %NULL; ignored when @content_type is %NULL
+ * @body_len: length of the @body; ignored when @content_type is %NULL
+ *
+ * Stores custom body for the request, to be used instead of the SOAP @req content.
+ * The @content_type can be %NULL to unset the custom body, or an empty string to indicate
+ * no body should be set. The @body and @body_len parameters are ignored in these cases,
+ * otherwise they are required.
+ *
+ * This function exists only to make internal API simpler.
+ **/
+void
+e_soap_request_set_custom_body (ESoapRequest *req,
+                               const gchar *content_type,
+                               gconstpointer body,
+                               gssize body_len)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       if (content_type && *content_type)
+               g_return_if_fail (body != NULL);
+
+       g_clear_pointer (&req->priv->custom_body_content_type, g_free);
+       g_clear_pointer (&req->priv->custom_body_data, g_free);
+       req->priv->custom_body_data_len = 0;
+
+       if (content_type) {
+               req->priv->custom_body_content_type = g_strdup (req->priv->custom_body_content_type);
+
+               if (*content_type) {
+                       req->priv->custom_body_data = g_memdup2 (body, body_len);
+                       req->priv->custom_body_data_len = body_len;
+               }
+       }
+}
+
+void
+e_soap_request_set_custom_process_fn (ESoapRequest *req,
+                                     ESoapRequestCustomProcessFn fn,
+                                     gpointer user_data)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       req->priv->custom_process_fn = fn;
+       req->priv->custom_process_data = user_data;
+}
+
+void
+e_soap_request_get_custom_process_fn (ESoapRequest *req,
+                                     ESoapRequestCustomProcessFn *out_fn,
+                                     gpointer *out_user_data)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+       g_return_if_fail (out_fn != NULL);
+       g_return_if_fail (out_user_data != NULL);
+
+       *out_fn = req->priv->custom_process_fn;
+       *out_user_data = req->priv->custom_process_data;
+}
+
+/**
+ * e_soap_request_take_tls_error_details:
+ * @req: an #ESoapRequest
+ * @certificate_pem: (transfer full) (nullable): a certificate in PEM format as string, or %NULL
+ * @certificate_errors: a %GTlsCertificateFlags describing the errors
+ *
+ * Set the TLS/SSL error details for the @req. Read it back
+ * with e_soap_request_get_tls_error_details().
+ *
+ * The function assumes ownership of the @certificate_pem.
+ **/
+void
+e_soap_request_take_tls_error_details (ESoapRequest *req,
+                                      gchar *certificate_pem,
+                                      GTlsCertificateFlags certificate_errors)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       g_clear_pointer (&req->priv->certificate_pem, g_free);
+
+       req->priv->certificate_pem = certificate_pem;
+       req->priv->certificate_errors = certificate_errors;
+}
+
+/**
+ * e_soap_request_get_tls_error_details:
+ * @req: an #ESoapRequest
+ * @out_certificate_pem: (out) (transfer none) (optional) (nullable): the certificatete in PEM format as 
string, or %NULL if not set
+ * @out_certificate_errors: (out) (optional): certificate errors, or 0 when none set
+ *
+ * Retries previously set TLS error details by e_soap_request_take_tls_error_details().
+ * The @out_certificate_pem is owned by the @req and is valid until the @req is freed
+ * or another call to e_soap_request_take_tls_error_details() is made.
+ *
+ * Returns: %TRUE, when the certificate PEM was set and the requested arguments
+ *    populated; %FALSE otherwise
+ **/
+gboolean
+e_soap_request_get_tls_error_details (ESoapRequest *req,
+                                     const gchar **out_certificate_pem,
+                                     GTlsCertificateFlags *out_certificate_errors)
+{
+       g_return_val_if_fail (E_IS_SOAP_REQUEST (req), FALSE);
+
+       if (!req->priv->certificate_pem)
+               return FALSE;
+
+       if (out_certificate_pem)
+               *out_certificate_pem = req->priv->certificate_pem;
+
+       if (out_certificate_errors)
+               *out_certificate_errors = req->priv->certificate_errors;
+
+       return TRUE;
+}
+
+void
+e_soap_request_set_etag (ESoapRequest *req,
+                        const gchar *etag)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       if (g_strcmp0 (req->priv->etag, etag) != 0) {
+               g_clear_pointer (&req->priv->etag, g_free);
+               req->priv->etag = g_strdup ((etag && *etag) ? etag : NULL);
+       }
+}
+
+const gchar *
+e_soap_request_get_etag (ESoapRequest *req)
+{
+       g_return_val_if_fail (E_IS_SOAP_REQUEST (req), NULL);
+
+       return req->priv->etag;
+}
+
+void
+e_soap_request_set_store_node_data (ESoapRequest *req,
+                                   const gchar *nodename,
+                                   const gchar *directory,
+                                   gboolean base64)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       if (g_strcmp0 (req->priv->store_node_data_nodename, nodename) != 0) {
+               g_free (req->priv->store_node_data_nodename);
+               req->priv->store_node_data_nodename = g_strdup (nodename);
+       }
+
+       if (g_strcmp0 (req->priv->store_node_data_directory, directory) != 0) {
+               g_free (req->priv->store_node_data_directory);
+               req->priv->store_node_data_directory = g_strdup (directory);
+       }
+
+       req->priv->store_node_data_base64 = base64;
+}
+
+void
+e_soap_request_get_store_node_data (ESoapRequest *req,
+                                   const gchar **out_nodename,
+                                   const gchar **out_directory,
+                                   gboolean *out_base64)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+       g_return_if_fail (out_nodename != NULL);
+       g_return_if_fail (out_directory != NULL);
+       g_return_if_fail (out_base64 != NULL);
+
+       *out_nodename = req->priv->store_node_data_nodename;
+       *out_directory = req->priv->store_node_data_directory;
+       *out_base64 = req->priv->store_node_data_base64;
+}
+
+/**
+ * e_soap_request_persist:
+ * @req: the #ESoapRequest.
+ * @soup_session: an #ESoupSession to create the #SoupMessage for
+ * @settings: a #CamelEwsSettings object, to read User-Agent header information from
+ * @error: (optional) (out): return location for a #GError, or %NULL
+ *
+ * Writes the serialized XML tree to the #SoupMessage's buffer.
+ *
+ * When a custom body was set with e_soap_request_set_custom_body(), then that body
+ * is used instead.
+ *
+ * Returns: (nullable) (transfer full): a #SoupMessage containing the SOAP request
+ *    as its request body, or %NULL on error.
+ */
+SoupMessage *
+e_soap_request_persist (ESoapRequest *req,
+                       ESoupSession *soup_session,
+                       CamelEwsSettings *settings,
+                       GError **error)
+{
+       SoupMessage *message;
+
+       g_return_val_if_fail (E_IS_SOAP_REQUEST (req), NULL);
+
+       message = e_soup_session_new_message_from_uri (soup_session, req->priv->method, req->priv->uri, 
error);
+
+       if (!message)
+               return NULL;
+
+       if (req->priv->custom_body_content_type) {
+               /* Can use empty string as content_type to indicate no body to be set */
+               if (*req->priv->custom_body_content_type && req->priv->custom_body_data) {
+                       e_soup_session_util_set_message_request_body_from_data (message, TRUE,
+                               req->priv->custom_body_content_type,
+                               req->priv->custom_body_data,
+                               req->priv->custom_body_data_len, NULL);
+               }
+       } else {
+               xmlChar *body;
+               gint len;
+
+               xmlDocDumpMemory (req->priv->doc, &body, &len);
+
+               e_soup_session_util_set_message_request_body_from_data (message, FALSE,
+                       "text/xml; charset=utf-8", body, len, (GDestroyNotify) xmlFree);
+       }
+
+       e_ews_connection_utils_set_user_agent_header (message, settings);
+
+       soup_message_headers_replace (soup_message_get_request_headers (message), "Connection", "Keep-Alive");
+
+       if (req->priv->etag && *req->priv->etag)
+               soup_message_headers_replace (soup_message_get_request_headers (message), "If-None-Match", 
req->priv->etag);
+
+       return message;
+}
+
+void
+e_soap_request_setup_response (ESoapRequest *req,
+                              ESoapResponse *response)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+       g_return_if_fail (E_IS_SOAP_RESPONSE (response));
+
+       e_soap_response_set_progress_fn (response, req->priv->progress_fn, req->priv->progress_data);
+       e_soap_response_set_store_node_data (response, req->priv->store_node_data_nodename,
+               req->priv->store_node_data_directory, req->priv->store_node_data_base64);
+}
diff --git a/src/EWS/common/e-soap-request.h b/src/EWS/common/e-soap-request.h
new file mode 100644
index 00000000..fddff613
--- /dev/null
+++ b/src/EWS/common/e-soap-request.h
@@ -0,0 +1,187 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * SPDX-FileCopyrightText: (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef EWS_SOAP_REQUEST_H
+#define EWS_SOAP_REQUEST_H
+
+#include <time.h>
+#include <libxml/tree.h>
+#include <libsoup/soup-message.h>
+#include <libedataserver/libedataserver.h>
+#include "camel-ews-settings.h"
+#include "e-soap-response.h"
+
+/* Standard GObject macros */
+#define E_TYPE_SOAP_REQUEST \
+       (e_soap_request_get_type ())
+#define E_SOAP_REQUEST(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), E_TYPE_SOAP_REQUEST, ESoapRequest))
+#define E_SOAP_REQUEST_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), E_TYPE_SOAP_REQUEST, ESoapRequestClass))
+#define E_IS_SOAP_REQUEST(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), E_TYPE_SOAP_REQUEST))
+#define E_IS_SOAP_REQUEST_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), E_TYPE_SOAP_REQUEST))
+#define E_SOAP_REQUEST_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), E_TYPE_SOAP_REQUEST, ESoapRequestClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ESoapRequest ESoapRequest;
+typedef struct _ESoapRequestClass ESoapRequestClass;
+typedef struct _ESoapRequestPrivate ESoapRequestPrivate;
+
+typedef void   (* ESoapRequestCustomProcessFn) (ESoapRequest *request,
+                                                SoupMessage *message,
+                                                GInputStream *input_stream,
+                                                gpointer user_data,
+                                                gboolean *out_repeat,
+                                                GCancellable *cancellable,
+                                                GError **error);
+
+struct _ESoapRequest {
+       GObject parent;
+       ESoapRequestPrivate *priv;
+};
+
+struct _ESoapRequestClass {
+       GObjectClass parent_class;
+};
+
+GType          e_soap_request_get_type         (void) G_GNUC_CONST;
+ESoapRequest * e_soap_request_new              (const gchar *method,
+                                                const gchar *uri_string,
+                                                gboolean standalone,
+                                                const gchar *xml_encoding,
+                                                const gchar *env_prefix,
+                                                const gchar *env_uri,
+                                                GError **error);
+ESoapRequest * e_soap_request_new_from_uri     (const gchar *method,
+                                                GUri *uri,
+                                                gboolean standalone,
+                                                const gchar *xml_encoding,
+                                                const gchar *env_prefix,
+                                                const gchar *env_uri);
+void           e_soap_request_start_envelope   (ESoapRequest *req);
+void           e_soap_request_end_envelope     (ESoapRequest *req);
+void           e_soap_request_start_body       (ESoapRequest *req);
+void           e_soap_request_end_body         (ESoapRequest *req);
+void           e_soap_request_start_element    (ESoapRequest *req,
+                                                const gchar *name,
+                                                const gchar *prefix,
+                                                const gchar *ns_uri);
+void           e_soap_request_end_element      (ESoapRequest *req);
+void           e_soap_request_start_fault      (ESoapRequest *req,
+                                                const gchar *faultcode,
+                                                const gchar *faultstring,
+                                                const gchar *faultfactor);
+void           e_soap_request_end_fault        (ESoapRequest *req);
+void           e_soap_request_start_fault_detail
+                                               (ESoapRequest *req);
+void           e_soap_request_end_fault_detail (ESoapRequest *req);
+void           e_soap_request_start_header     (ESoapRequest *req);
+void           e_soap_request_replace_header   (ESoapRequest *req,
+                                                const gchar *name,
+                                                const gchar *value);
+void           e_soap_request_end_header       (ESoapRequest *req);
+void           e_soap_request_start_header_element
+                                               (ESoapRequest *req,
+                                                const gchar *name,
+                                                gboolean must_understand,
+                                                const gchar *actor_uri,
+                                                const gchar *prefix,
+                                                const gchar *ns_uri);
+void           e_soap_request_end_header_element
+                                               (ESoapRequest *req);
+void           e_soap_request_write_int        (ESoapRequest *req,
+                                                glong i);
+void           e_soap_request_write_double     (ESoapRequest *req,
+                                                gdouble d);
+void           e_soap_request_write_base64     (ESoapRequest *req,
+                                                const gchar *string,
+                                                gint len);
+void           e_soap_request_write_time       (ESoapRequest *req,
+                                                time_t timeval);
+void           e_soap_request_write_string     (ESoapRequest *req,
+                                                const gchar *string);
+void           e_soap_request_write_buffer     (ESoapRequest *req,
+                                                const gchar *buffer,
+                                                gint len);
+void           e_soap_request_set_element_type (ESoapRequest *req,
+                                                const gchar *xsi_type);
+void           e_soap_request_set_null         (ESoapRequest *req);
+void           e_soap_request_add_attribute    (ESoapRequest *req,
+                                                const gchar *name,
+                                                const gchar *value,
+                                                const gchar *prefix,
+                                                const gchar *ns_uri);
+void           e_soap_request_add_namespace    (ESoapRequest *req,
+                                                const gchar *prefix,
+                                                const gchar *ns_uri);
+void           e_soap_request_set_default_namespace
+                                               (ESoapRequest *req,
+                                                const gchar *ns_uri);
+void           e_soap_request_set_encoding_style
+                                               (ESoapRequest *req,
+                                                const gchar *enc_style);
+void           e_soap_request_reset            (ESoapRequest *req);
+const gchar *  e_soap_request_get_namespace_prefix
+                                               (ESoapRequest *req,
+                                                const gchar *ns_uri);
+xmlDocPtr      e_soap_request_get_xml_doc      (ESoapRequest *req);
+void           e_soap_request_set_progress_fn  (ESoapRequest *req,
+                                                ESoapResponseProgressFn fn,
+                                                gpointer user_data);
+void           e_soap_request_get_progress_fn  (ESoapRequest *req,
+                                                ESoapResponseProgressFn *out_fn,
+                                                gpointer *out_user_data);
+void           e_soap_request_set_store_node_data
+                                               (ESoapRequest *req,
+                                                const gchar *nodename,
+                                                const gchar *directory,
+                                                gboolean base64);
+void           e_soap_request_get_store_node_data
+                                               (ESoapRequest *req,
+                                                const gchar **out_nodename,
+                                                const gchar **out_directory,
+                                                gboolean *out_base64);
+void           e_soap_request_set_custom_body  (ESoapRequest *req,
+                                                const gchar *content_type,
+                                                gconstpointer body,
+                                                gssize body_len);
+void           e_soap_request_set_custom_process_fn
+                                               (ESoapRequest *req,
+                                                ESoapRequestCustomProcessFn fn,
+                                                gpointer user_data);
+void           e_soap_request_get_custom_process_fn
+                                               (ESoapRequest *req,
+                                                ESoapRequestCustomProcessFn *out_fn,
+                                                gpointer *out_user_data);
+void           e_soap_request_take_tls_error_details
+                                               (ESoapRequest *req,
+                                                gchar *certificate_pem,
+                                                GTlsCertificateFlags certificate_errors);
+gboolean       e_soap_request_get_tls_error_details
+                                               (ESoapRequest *req,
+                                                const gchar **out_certificate_pem,
+                                                GTlsCertificateFlags *out_certificate_errors);
+void           e_soap_request_set_etag         (ESoapRequest *req,
+                                                const gchar *etag);
+const gchar *  e_soap_request_get_etag         (ESoapRequest *req);
+SoupMessage *  e_soap_request_persist          (ESoapRequest *req,
+                                                ESoupSession *soup_session,
+                                                CamelEwsSettings *settings,
+                                                GError **error);
+void           e_soap_request_setup_response   (ESoapRequest *req,
+                                                ESoapResponse *response);
+G_END_DECLS
+
+#endif /* E_SOAP_REQUEST_H */
diff --git a/src/EWS/common/e-soap-response.c b/src/EWS/common/e-soap-response.c
index a8bddc07..149af230 100644
--- a/src/EWS/common/e-soap-response.c
+++ b/src/EWS/common/e-soap-response.c
@@ -22,6 +22,22 @@ struct _ESoapResponsePrivate {
        xmlNodePtr xml_method;
        xmlNodePtr soap_fault;
        GList *parameters;
+
+       /* Serialization fields */
+       xmlParserCtxtPtr ctxt;
+
+       /* Content stealing */
+       gchar *steal_node;
+       gchar *steal_dir;
+       gboolean steal_base64;
+
+       gint steal_b64_state;
+       guint steal_b64_save;
+       gint steal_fd;
+
+       /* Progress callbacks */
+       ESoapResponseProgressFn progress_fn;
+       gpointer progress_data;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (ESoapResponse, e_soap_response, G_TYPE_OBJECT)
@@ -43,6 +59,18 @@ soap_response_finalize (GObject *object)
        g_clear_pointer (&resp->priv->xmldoc, xmlFreeDoc);
        g_list_free (resp->priv->parameters);
 
+       if (resp->priv->ctxt) {
+               if (resp->priv->ctxt->myDoc)
+                       xmlFreeDoc (resp->priv->ctxt->myDoc);
+               xmlFreeParserCtxt (resp->priv->ctxt);
+       }
+
+       g_free (resp->priv->steal_node);
+       g_free (resp->priv->steal_dir);
+
+       if (resp->priv->steal_fd != -1)
+               close (resp->priv->steal_fd);
+
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (e_soap_response_parent_class)->finalize (object);
 }
@@ -62,6 +90,7 @@ e_soap_response_init (ESoapResponse *response)
        response->priv = e_soap_response_get_instance_private (response);
 
        response->priv->xmldoc = xmlNewDoc ((const xmlChar *)"1.0");
+       response->priv->steal_fd = -1;
 }
 
 /**
@@ -243,6 +272,279 @@ e_soap_response_from_xmldoc (ESoapResponse *response,
        return TRUE;
 }
 
+static void
+soap_sax_startElementNs (gpointer _ctxt,
+                         const xmlChar *localname,
+                         const xmlChar *prefix,
+                         const xmlChar *uri,
+                         gint nb_namespaces,
+                         const xmlChar **namespaces,
+                         gint nb_attributes,
+                         gint nb_defaulted,
+                         const xmlChar **attributes)
+{
+       xmlParserCtxt *ctxt = _ctxt;
+       ESoapResponse *response = ctxt->_private;
+       gchar *fname;
+
+       xmlSAX2StartElementNs (
+               ctxt, localname, prefix, uri, nb_namespaces,
+               namespaces, nb_attributes, nb_defaulted,
+               attributes);
+
+       /* steal_node can contain multiple node name separated by " " */
+       if (response->priv->steal_node && *response->priv->steal_node) {
+               gchar **prop = g_strsplit (response->priv->steal_node, " ", 0);
+               gint i = 0;
+               gboolean isnode = FALSE;
+
+               while (prop[i]) {
+                       if (strcmp ((const gchar *) localname, prop[i]) == 0) {
+                               isnode = TRUE;
+                               break;
+                       }
+                       i++;
+               }
+               g_strfreev (prop);
+
+               if (!isnode) return;
+       } else
+               return;
+
+       fname = g_build_filename (response->priv->steal_dir, "XXXXXX", NULL);
+       response->priv->steal_fd = g_mkstemp (fname);
+       if (response->priv->steal_fd != -1) {
+               if (response->priv->steal_base64) {
+                       gchar *enc = g_base64_encode ((guchar *) fname, strlen (fname));
+                       xmlSAX2Characters (ctxt, (xmlChar *) enc, strlen (enc));
+                       g_free (enc);
+               } else
+                       xmlSAX2Characters (ctxt, (xmlChar *) fname, strlen (fname));
+       } else {
+               gint err = errno;
+
+               g_warning ("%s: Failed to create temp file '%s': %s\n", G_STRFUNC, fname, g_strerror (err));
+       }
+       g_free (fname);
+}
+
+static void
+soap_sax_endElementNs (gpointer _ctxt,
+                       const xmlChar *localname,
+                       const xmlChar *prefix,
+                       const xmlChar *uri)
+{
+       xmlParserCtxt *ctxt = _ctxt;
+       ESoapResponse *response = ctxt->_private;
+
+       if (response->priv->steal_fd != -1) {
+               close (response->priv->steal_fd);
+               response->priv->steal_fd = -1;
+       }
+       xmlSAX2EndElementNs (ctxt, localname, prefix, uri);
+}
+
+static void
+soap_sax_characters (gpointer _ctxt,
+                     const xmlChar *ch,
+                     gint len)
+{
+       xmlParserCtxt *ctxt = _ctxt;
+       ESoapResponse *response = ctxt->_private;
+
+       if (response->priv->steal_fd == -1)
+               xmlSAX2Characters (ctxt, ch, len);
+       else if (!response->priv->steal_base64) {
+               if (write (response->priv->steal_fd, (const gchar *) ch, len) != len) {
+               write_err:
+                       /* Handle error better */
+                       g_warning ("Failed to write streaming data to file");
+               }
+       } else {
+               guchar *bdata = g_malloc ((len * 3 / 4) + 3);
+               gsize blen;
+
+               blen = g_base64_decode_step (
+                       (const gchar *) ch, len,
+                       bdata, &response->priv->steal_b64_state,
+                       &response->priv->steal_b64_save);
+               if (write (response->priv->steal_fd, (const gchar *) bdata, blen) != blen) {
+                       g_free (bdata);
+                       goto write_err;
+               }
+               g_free (bdata);
+       }
+}
+
+#define BUFFER_SIZE 16384
+
+xmlDoc *
+e_soap_response_xmldoc_from_message_sync (ESoapResponse *response,
+                                         SoupMessage *msg,
+                                         GInputStream *response_data,
+                                         GCancellable *cancellable,
+                                         GError **error)
+{
+       const gchar *size;
+       xmlDoc *xmldoc = NULL;
+       gboolean success;
+       gpointer buffer;
+       gsize response_size = 0;
+       gsize response_received = 0;
+       gsize progress_percent = 0;
+       gsize nread = 0;
+
+       g_return_val_if_fail (E_IS_SOAP_RESPONSE (response), FALSE);
+       g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
+       g_return_val_if_fail (G_IS_INPUT_STREAM (response_data), FALSE);
+
+       /* Discard the existing context, if there is one, and start again */
+       if (response->priv->ctxt) {
+               if (response->priv->ctxt->myDoc)
+                       xmlFreeDoc (response->priv->ctxt->myDoc);
+               xmlFreeParserCtxt (response->priv->ctxt);
+               response->priv->ctxt = NULL;
+       }
+
+       if (response->priv->steal_fd != -1) {
+               close (response->priv->steal_fd);
+               response->priv->steal_fd = -1;
+       }
+
+       size = soup_message_headers_get_one (soup_message_get_response_headers (msg), "Content-Length");
+
+       if (size)
+               response_size = g_ascii_strtoll (size, NULL, 10);
+
+       buffer = g_malloc (BUFFER_SIZE);
+
+       while (success = g_input_stream_read_all (response_data, buffer, BUFFER_SIZE, &nread, cancellable, 
error),
+              success && nread > 0) {
+               response_received += nread;
+
+               if (response_size && response->priv->progress_fn) {
+                       gint pc = response_received * 100 / response_size;
+                       if (progress_percent != pc) {
+                               progress_percent = pc;
+                               response->priv->progress_fn (response->priv->progress_data, progress_percent);
+                       }
+               }
+
+               if (!response->priv->ctxt) {
+                       response->priv->ctxt = xmlCreatePushParserCtxt (NULL, response, buffer, nread, NULL);
+                       response->priv->ctxt->_private = response;
+                       response->priv->ctxt->sax->startElementNs = soap_sax_startElementNs;
+                       response->priv->ctxt->sax->endElementNs = soap_sax_endElementNs;
+                       response->priv->ctxt->sax->characters = soap_sax_characters;
+               } else {
+                       xmlParseChunk (response->priv->ctxt, buffer, nread, 0);
+               }
+       }
+
+       g_free (buffer);
+
+       if (success) {
+               if (response->priv->ctxt) {
+                       xmlParseChunk (response->priv->ctxt, 0, 0, 1);
+
+                       xmldoc = response->priv->ctxt->myDoc;
+
+                       xmlFreeParserCtxt (response->priv->ctxt);
+                       response->priv->ctxt = NULL;
+               } else {
+                       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "No data read");
+                       success = FALSE;
+               }
+       }
+
+       if (response->priv->ctxt) {
+               if (response->priv->ctxt->myDoc)
+                       xmlFreeDoc (response->priv->ctxt->myDoc);
+               xmlFreeParserCtxt (response->priv->ctxt);
+               response->priv->ctxt = NULL;
+       }
+
+       if (response->priv->steal_fd != -1) {
+               close (response->priv->steal_fd);
+               response->priv->steal_fd = -1;
+       }
+
+       return xmldoc;
+}
+
+gboolean
+e_soap_response_from_message_sync (ESoapResponse *response,
+                                  SoupMessage *msg,
+                                  GInputStream *response_data,
+                                  GCancellable *cancellable,
+                                  GError **error)
+{
+       xmlDoc *xmldoc;
+       gboolean success = FALSE;
+
+       g_return_val_if_fail (E_IS_SOAP_RESPONSE (response), FALSE);
+       g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
+       g_return_val_if_fail (G_IS_INPUT_STREAM (response_data), FALSE);
+
+       xmldoc = e_soap_response_xmldoc_from_message_sync (response, msg, response_data, cancellable, error);
+
+       if (xmldoc) {
+               success = e_soap_response_from_xmldoc (response, xmldoc);
+               if (!success)
+                       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Received invalid 
SOAP response");
+       }
+
+       return success;
+}
+
+/**
+ * e_soap_response_set_store_node_data:
+ * @response: the %ESoapResponse
+ * @nodename: the name of the XML node from which to store data
+ * @directory: cache directory in which to create data files
+ * @base64: flag to request base64 decoding of node content
+ *
+ * This requests that character data for certain XML nodes should
+ * be streamed directly to a disk file as it arrives, rather than
+ * being stored in memory.
+ *
+ * It is used only with e_soap_response_from_message_sync().
+ */
+void
+e_soap_response_set_store_node_data (ESoapResponse *response,
+                                    const gchar *nodename,
+                                    const gchar *directory,
+                                    gboolean base64)
+{
+       g_return_if_fail (E_IS_SOAP_RESPONSE (response));
+       g_return_if_fail (response->priv->steal_node == NULL);
+
+       response->priv->steal_node = g_strdup (nodename);
+       response->priv->steal_dir = g_strdup (directory);
+       response->priv->steal_base64 = base64;
+}
+
+/**
+ * e_soap_response_set_progress_fn:
+ * @response: the %ESoapResponse
+ * @fn: callback function to be given progress updates
+ * @object: first argument to callback function
+ *
+ * Starts the top level SOAP Envelope element.
+ *
+ * It is used only with e_soap_response_from_message_sync().
+ */
+void
+e_soap_response_set_progress_fn (ESoapResponse *response,
+                                ESoapResponseProgressFn fn,
+                                gpointer object)
+{
+       g_return_if_fail (E_IS_SOAP_RESPONSE (response));
+
+       response->priv->progress_fn = fn;
+       response->priv->progress_data = object;
+}
+
 /**
  * e_soap_response_get_method_name:
  * @response: the #ESoapResponse object.
@@ -586,11 +888,8 @@ e_soap_response_get_first_parameter_by_name (ESoapResponse *response,
 
                        string = e_soap_parameter_get_string_value (param);
 
-                       g_set_error (
-                               error,
-                               SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED,
-                               "%s", (string != NULL) ? string :
-                               "<faultstring> in SOAP response");
+                       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                               (string != NULL) ? string : "<faultstring> in SOAP response");
 
                        g_free (string);
 
@@ -598,9 +897,7 @@ e_soap_response_get_first_parameter_by_name (ESoapResponse *response,
                }
        }
 
-       g_set_error (
-               error,
-               SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED,
+       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                "Missing <%s> in SOAP response", name);
 
        return NULL;
diff --git a/src/EWS/common/e-soap-response.h b/src/EWS/common/e-soap-response.h
index b2c2fd93..1258c0d0 100644
--- a/src/EWS/common/e-soap-response.h
+++ b/src/EWS/common/e-soap-response.h
@@ -8,6 +8,7 @@
 #define E_SOAP_RESPONSE_H
 
 #include <glib-object.h>
+#include <libsoup/soup-message.h>
 #include <libxml/tree.h>
 
 /* Standard GObject macros */
@@ -31,6 +32,9 @@
 
 G_BEGIN_DECLS
 
+/* By an amazing coincidence, this looks a lot like camel_progress() */
+typedef void (* ESoapResponseProgressFn) (gpointer object, gint percent);
+
 typedef struct _ESoapResponse ESoapResponse;
 typedef struct _ESoapResponseClass ESoapResponseClass;
 typedef struct _ESoapResponsePrivate ESoapResponsePrivate;
@@ -54,6 +58,28 @@ gboolean     e_soap_response_from_string     (ESoapResponse *response,
                                                 gint xmlstr_length);
 gboolean       e_soap_response_from_xmldoc     (ESoapResponse *response,
                                                 xmlDoc *xmldoc);
+gboolean       e_soap_response_from_message_sync
+                                               (ESoapResponse *response,
+                                                SoupMessage *msg,
+                                                GInputStream *response_data,
+                                                GCancellable *cancellable,
+                                                GError **error);
+xmlDoc *       e_soap_response_xmldoc_from_message_sync
+                                               (ESoapResponse *response,
+                                                SoupMessage *msg,
+                                                GInputStream *response_data,
+                                                GCancellable *cancellable,
+                                                GError **error);
+/* used only with e_soap_response_from_message_sync() */
+void           e_soap_response_set_store_node_data
+                                               (ESoapResponse *response,
+                                                const gchar *nodename,
+                                                const gchar *directory,
+                                                gboolean base64);
+/* used only with e_soap_response_from_message_sync() */
+void           e_soap_response_set_progress_fn (ESoapResponse *response,
+                                                ESoapResponseProgressFn fn,
+                                                gpointer object);
 const gchar *  e_soap_response_get_method_name (ESoapResponse *response);
 void           e_soap_response_set_method_name (ESoapResponse *response,
                                                 const gchar *method_name);
diff --git a/src/EWS/evolution/e-ews-config-lookup.c b/src/EWS/evolution/e-ews-config-lookup.c
index 1b28295a..7e854af7 100644
--- a/src/EWS/evolution/e-ews-config-lookup.c
+++ b/src/EWS/evolution/e-ews-config-lookup.c
@@ -195,11 +195,11 @@ ews_config_lookup_worker_result_from_data (EConfigLookup *config_lookup,
                EConfigLookupResult *lookup_result;
                GString *description;
                const gchar *extension_name;
-               SoupURI *suri;
+               GUri *uri;
 
                extension_name = e_source_camel_get_extension_name ("ews");
 
-               suri = soup_uri_new (hosturl);
+               uri = g_uri_parse (hosturl, SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
 
                description = g_string_new ("");
 
@@ -247,23 +247,23 @@ ews_config_lookup_worker_result_from_data (EConfigLookup *config_lookup,
                                "user", email_address);
                }
 
-               if (suri && suri->host && *suri->host) {
+               if (uri && g_uri_get_host (uri) && *g_uri_get_host (uri)) {
                        e_config_lookup_result_simple_add_string (lookup_result,
                                E_SOURCE_EXTENSION_AUTHENTICATION,
-                               "host", suri->host);
+                               "host", g_uri_get_host (uri));
                }
 
-               if (suri && suri->port) {
+               if (uri && g_uri_get_port (uri)) {
                        e_config_lookup_result_simple_add_uint (lookup_result,
                                E_SOURCE_EXTENSION_AUTHENTICATION,
-                               "port", suri->port);
+                               "port", g_uri_get_port (uri));
                }
 
                e_config_lookup_add_result (config_lookup, lookup_result);
 
                g_string_free (description, TRUE);
-               if (suri)
-                       soup_uri_free (suri);
+               if (uri)
+                       g_uri_unref (uri);
        }
 }
 
@@ -370,16 +370,16 @@ ews_config_lookup_worker_run (EConfigLookupWorker *lookup_worker,
 
                if (e_ews_autodiscover_ws_url_sync (source, ews_settings, email_address, password, 
&certificate_pem, &certificate_errors, cancellable, &local_error)) {
                        ews_config_lookup_worker_result_from_settings (lookup_worker, config_lookup, 
email_address, ews_settings, params);
-               } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED)) {
+               } else if (g_error_matches (local_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE)) {
                        const gchar *hosturl;
-                       SoupURI *suri;
+                       GUri *uri;
 
                        hosturl = camel_ews_settings_get_hosturl (ews_settings);
-                       suri = soup_uri_new (hosturl);
-                       if (suri) {
-                               certificate_host = g_strdup (soup_uri_get_host (suri));
+                       uri = g_uri_parse (hosturl, SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
+                       if (uri) {
+                               certificate_host = g_strdup (g_uri_get_host (uri));
 
-                               soup_uri_free (suri);
+                               g_uri_unref (uri);
                        }
                } else {
                        g_clear_error (&local_error);
@@ -406,16 +406,16 @@ ews_config_lookup_worker_run (EConfigLookupWorker *lookup_worker,
 
                                if (e_ews_autodiscover_ws_url_sync (source, ews_settings, email_address, 
password, &certificate_pem, &certificate_errors, cancellable, &local_error)) {
                                        ews_config_lookup_worker_result_from_settings (lookup_worker, 
config_lookup, email_address, ews_settings, params);
-                               } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, 
SOUP_STATUS_SSL_FAILED)) {
+                               } else if (g_error_matches (local_error, G_TLS_ERROR, 
G_TLS_ERROR_BAD_CERTIFICATE)) {
                                        const gchar *hosturl;
-                                       SoupURI *suri;
+                                       GUri *uri;
 
                                        hosturl = camel_ews_settings_get_hosturl (ews_settings);
-                                       suri = soup_uri_new (hosturl);
-                                       if (suri) {
-                                               certificate_host = g_strdup (soup_uri_get_host (suri));
+                                       uri = g_uri_parse (hosturl, SOUP_HTTP_URI_FLAGS | 
G_URI_FLAGS_PARSE_RELAXED, NULL);
+                                       if (uri) {
+                                               certificate_host = g_strdup (g_uri_get_host (uri));
 
-                                               soup_uri_free (suri);
+                                               g_uri_unref (uri);
                                        }
                                } else {
                                        g_clear_error (&local_error);
@@ -427,7 +427,7 @@ ews_config_lookup_worker_run (EConfigLookupWorker *lookup_worker,
                        g_strfreev (servers_strv);
                }
 
-               if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED) &&
+               if (g_error_matches (local_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE) &&
                    certificate_pem && *certificate_pem && certificate_errors) {
                        gchar *description = e_trust_prompt_describe_certificate_errors (certificate_errors);
 
diff --git a/src/EWS/evolution/e-ews-photo-source.c b/src/EWS/evolution/e-ews-photo-source.c
index 732d6390..b58dc8c1 100644
--- a/src/EWS/evolution/e-ews-photo-source.c
+++ b/src/EWS/evolution/e-ews-photo-source.c
@@ -50,45 +50,39 @@ static void ews_photo_source_iface_init (EPhotoSourceInterface *iface);
 G_DEFINE_DYNAMIC_TYPE_EXTENDED (EEwsPhotoSource, e_ews_photo_source, E_TYPE_EXTENSION, 0,
        G_IMPLEMENT_INTERFACE_DYNAMIC (E_TYPE_PHOTO_SOURCE, ews_photo_source_iface_init))
 
-typedef struct _PhotoSourceData {
-       GMutex lock;
-       guint n_running;
-       ESimpleAsyncResult *simple;
-       GCancellable *cancellable;
-} PhotoSourceData;
-
 static void
-ews_photo_source_dec_running (PhotoSourceData *psd)
+ews_photo_source_thread (GTask *task,
+                        gpointer source_object,
+                        gpointer task_data,
+                        GCancellable *cancellable)
 {
-       if (!g_atomic_int_dec_and_test (&psd->n_running))
-               return;
+       const gchar *email_address = task_data;
+       GSList *connections, *link;
+       GHashTable *covered_uris;
+       GError *local_error = NULL;
 
-       if (psd->simple)
-               e_simple_async_result_complete_idle (psd->simple);
+       /* Most users connect to a single server anyway, thus no big deal doing
+          this in serial, instead of in parallel. */
+       covered_uris = g_hash_table_new_full (camel_strcase_hash, camel_strcase_equal, g_free, NULL);
+       connections = e_ews_connection_list_existing ();
 
-       g_clear_object (&psd->simple);
-       g_clear_object (&psd->cancellable);
-       g_mutex_clear (&psd->lock);
-       g_free (psd);
-}
+       for (link = connections; link; link = g_slist_next (link)) {
+               EEwsConnection *cnc = link->data;
+               gchar *picture_data = NULL;
+               const gchar *uri;
 
-static void
-ews_photo_source_get_user_photo_cb (GObject *source_object,
-                                   GAsyncResult *result,
-                                   gpointer user_data)
-{
-       PhotoSourceData *psd = user_data;
-       GCancellable *cancellable = NULL;
-       gchar *picture_data = NULL;
-       GError *error = NULL;
+               if (!E_IS_EWS_CONNECTION (cnc) ||
+                   !e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2013))
+                       continue;
 
-       g_return_if_fail (E_IS_EWS_CONNECTION (source_object));
-       g_return_if_fail (psd != NULL);
+               uri = e_ews_connection_get_uri (cnc);
+               if (!uri || !*uri || g_hash_table_contains (covered_uris, uri))
+                       continue;
 
-       g_mutex_lock (&psd->lock);
+               g_hash_table_insert (covered_uris, g_strdup (uri), NULL);
 
-       if (e_ews_connection_get_user_photo_finish (E_EWS_CONNECTION (source_object), result, &picture_data, 
&error)) {
-               if (psd->simple && picture_data && *picture_data) {
+               if (e_ews_connection_get_user_photo_sync (cnc, G_PRIORITY_LOW, email_address, 
E_EWS_SIZE_REQUESTED_48X48,
+                       &picture_data, cancellable, local_error ? NULL : &local_error) && picture_data) {
                        gsize len = 0;
                        guchar *decoded;
 
@@ -99,32 +93,29 @@ ews_photo_source_get_user_photo_cb (GObject *source_object,
                                stream = g_memory_input_stream_new_from_data (decoded, len, g_free);
                                decoded = NULL;
 
-                               e_simple_async_result_set_op_pointer (psd->simple, stream, g_object_unref);
-                               e_simple_async_result_complete_idle (psd->simple);
-                               g_clear_object (&psd->simple);
-
-                               cancellable = g_object_ref (psd->cancellable);
+                               g_task_return_pointer (task, stream, g_object_unref);
+                               task = NULL;
+                               g_free (decoded);
+                               break;
                        }
 
                        g_free (decoded);
                }
-       } else {
-               if (psd->simple && error) {
-                       e_simple_async_result_take_error (psd->simple, error);
-                       error = NULL;
-               }
        }
 
-       g_mutex_unlock (&psd->lock);
-
-       ews_photo_source_dec_running (psd);
+       g_slist_free_full (connections, g_object_unref);
+       g_hash_table_destroy (covered_uris);
 
-       if (cancellable)
-               g_cancellable_cancel (cancellable);
+       if (task) {
+               if (!local_error) {
+                       /* Do not localize the string, it won't go into the UI/be visible to users */
+                       g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Not Found");
+               }
 
-       g_clear_object (&cancellable);
-       g_clear_error (&error);
-       g_free (picture_data);
+               g_task_return_error (task, local_error);
+       } else {
+               g_clear_error (&local_error);
+       }
 }
 
 static void
@@ -134,46 +125,16 @@ ews_photo_source_get_photo (EPhotoSource *photo_source,
                            GAsyncReadyCallback callback,
                            gpointer user_data)
 {
-       GSList *connections, *link;
-       GHashTable *covered_uris;
-       PhotoSourceData *psd;
+       GTask *task;
 
        g_return_if_fail (E_IS_EWS_PHOTO_SOURCE (photo_source));
        g_return_if_fail (email_address != NULL);
 
-       psd = g_new0 (PhotoSourceData, 1);
-       psd->n_running = 1;
-       psd->simple = e_simple_async_result_new (G_OBJECT (photo_source), callback, user_data, 
ews_photo_source_get_photo);
-       psd->cancellable = camel_operation_new_proxy (cancellable);
-       g_mutex_init (&psd->lock);
-
-       covered_uris = g_hash_table_new_full (camel_strcase_hash, camel_strcase_equal, g_free, NULL);
-       connections = e_ews_connection_list_existing ();
-
-       for (link = connections; link; link = g_slist_next (link)) {
-               EEwsConnection *cnc = link->data;
-               const gchar *uri;
-
-               if (!E_IS_EWS_CONNECTION (cnc) ||
-                   !e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2013))
-                       continue;
-
-               uri = e_ews_connection_get_uri (cnc);
-               if (!uri || !*uri || g_hash_table_contains (covered_uris, uri))
-                       continue;
-
-               g_hash_table_insert (covered_uris, g_strdup (uri), NULL);
-
-               g_atomic_int_inc (&psd->n_running);
-
-               e_ews_connection_get_user_photo (cnc, G_PRIORITY_LOW, email_address, 
E_EWS_SIZE_REQUESTED_48X48,
-                       psd->cancellable, ews_photo_source_get_user_photo_cb, psd);
-       }
-
-       g_slist_free_full (connections, g_object_unref);
-       g_hash_table_destroy (covered_uris);
-
-       ews_photo_source_dec_running (psd);
+       task = g_task_new (photo_source, cancellable, callback, user_data);
+       g_task_set_source_tag (task, ews_photo_source_get_photo);
+       g_task_set_task_data (task, g_strdup (email_address), g_free);
+       g_task_run_in_thread (task, ews_photo_source_thread);
+       g_object_unref (task);
 }
 
 static gboolean
@@ -183,31 +144,25 @@ ews_photo_source_get_photo_finish (EPhotoSource *photo_source,
                                   gint *out_priority,
                                   GError **error)
 {
-       ESimpleAsyncResult *simple;
+       GInputStream *input_stream;
+       gboolean success;
 
        g_return_val_if_fail (E_IS_EWS_PHOTO_SOURCE (photo_source), FALSE);
-       g_return_val_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
-
-       g_return_val_if_fail (e_simple_async_result_is_valid (result, G_OBJECT (photo_source), 
ews_photo_source_get_photo), FALSE);
+       g_return_val_if_fail (g_task_is_valid (result, photo_source), FALSE);
 
        if (out_priority)
                *out_priority = G_PRIORITY_DEFAULT;
 
-       simple = E_SIMPLE_ASYNC_RESULT (result);
-
-       if (e_simple_async_result_propagate_error (simple, error))
-               return FALSE;
+       input_stream = g_task_propagate_pointer (G_TASK (result), error);
 
-       *out_stream = e_simple_async_result_get_op_pointer (simple);
-       if (*out_stream) {
-               g_object_ref (*out_stream);
-               return TRUE;
-       }
+       success = input_stream != NULL;
 
-       /* Do not localize the string, it won't go into the UI/be visible to users */
-       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Not Found");
+       if (out_stream)
+               *out_stream = input_stream;
+       else
+               g_clear_object (&input_stream);
 
-       return FALSE;
+       return success;
 }
 
 static void
diff --git a/src/EWS/evolution/e-ews-search-user.c b/src/EWS/evolution/e-ews-search-user.c
index 1b32d1b5..17485a3e 100644
--- a/src/EWS/evolution/e-ews-search-user.c
+++ b/src/EWS/evolution/e-ews-search-user.c
@@ -226,8 +226,8 @@ search_thread (gpointer user_data)
 
                if (e_ews_connection_resolve_names_sync (
                        sid->conn, EWS_PRIORITY_MEDIUM, sid->search_text,
-                       EWS_SEARCH_AD, NULL, FALSE, &mailboxes, NULL,
-                       &sid->includes_last_item, sid->cancellable, &error)) {
+                       EWS_SEARCH_AD, NULL, FALSE, &sid->includes_last_item, &mailboxes, NULL,
+                       sid->cancellable, &error)) {
                        GSList *iter;
 
                        sid->found_contacts = 0;
diff --git a/src/EWS/evolution/e-ews-subscribe-foreign-folder.c 
b/src/EWS/evolution/e-ews-subscribe-foreign-folder.c
index ab31c99e..7490c0a7 100644
--- a/src/EWS/evolution/e-ews-subscribe-foreign-folder.c
+++ b/src/EWS/evolution/e-ews-subscribe-foreign-folder.c
@@ -806,7 +806,7 @@ e_ews_subscribe_foreign_folder_resolve_name_sync (EEwsConnection *cnc,
 
        if (!e_ews_connection_resolve_names_sync (cnc, G_PRIORITY_DEFAULT,
                name, EWS_SEARCH_AD, NULL, FALSE,
-               &mailboxes, NULL, &includes_last_item,
+               &includes_last_item, &mailboxes, NULL,
                cancellable, &local_error)) {
                if (g_error_matches (local_error, EWS_CONNECTION_ERROR, 
EWS_CONNECTION_ERROR_NAMERESOLUTIONNORESULTS) ||
                    g_error_matches (local_error, EWS_CONNECTION_ERROR, 
EWS_CONNECTION_ERROR_NAMERESOLUTIONNOMAILBOX)) {
diff --git a/src/EWS/evolution/e-mail-config-ews-autodiscover.c 
b/src/EWS/evolution/e-mail-config-ews-autodiscover.c
index 08ee9292..78c38843 100644
--- a/src/EWS/evolution/e-mail-config-ews-autodiscover.c
+++ b/src/EWS/evolution/e-mail-config-ews-autodiscover.c
@@ -103,7 +103,7 @@ mail_config_ews_autodiscover_run_cb (GObject *source_object,
 
        if (e_activity_handle_cancellation (async_context->activity, error)) {
                /* Do nothing, just free the error below */
-       } else if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED) &&
+       } else if (g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE) &&
                   async_context->certificate_pem && *async_context->certificate_pem && 
async_context->certificate_errors) {
                ETrustPromptResponse response;
                GtkWidget *parent;
@@ -182,7 +182,7 @@ mail_config_ews_autodiscover_sync (ECredentialsPrompter *prompter,
 
        if (local_error == NULL) {
                *out_authenticated = TRUE;
-       } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+       } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
                *out_authenticated = FALSE;
                g_error_free (local_error);
        } else {
@@ -214,7 +214,7 @@ mail_config_ews_autodiscover_run_thread (GTask *task,
                                cancellable, &local_error);
                }
 
-               if (!without_password || g_error_matches (local_error, SOUP_HTTP_ERROR, 
SOUP_STATUS_UNAUTHORIZED)) {
+               if (!without_password || g_error_matches (local_error, E_SOUP_SESSION_ERROR, 
SOUP_STATUS_UNAUTHORIZED)) {
                        EShell *shell;
 
                        e_ews_connection_utils_force_off_ntlm_auth_check ();
diff --git a/src/EWS/evolution/e-mail-config-ews-backend.c b/src/EWS/evolution/e-mail-config-ews-backend.c
index be5380c9..d792f8d4 100644
--- a/src/EWS/evolution/e-mail-config-ews-backend.c
+++ b/src/EWS/evolution/e-mail-config-ews-backend.c
@@ -724,11 +724,11 @@ mail_config_ews_backend_check_complete (EMailConfigServiceBackend *backend)
        complete = complete && correct;
 
        if (correct) {
-               SoupURI *suri;
+               GUri *uri;
 
-               suri = soup_uri_new (hosturl);
-               if (suri) {
-                       soup_uri_free (suri);
+               uri = g_uri_parse (hosturl, SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
+               if (uri) {
+                       g_uri_unref (uri);
                        e_util_set_entry_issue_hint (ews_backend->priv->host_entry, NULL);
                } else {
                        e_util_set_entry_issue_hint (ews_backend->priv->host_entry, _("Host URL is not 
valid"));
@@ -739,11 +739,11 @@ mail_config_ews_backend_check_complete (EMailConfigServiceBackend *backend)
        }
 
        if (oaburl && *oaburl) {
-               SoupURI *suri;
+               GUri *uri;
 
-               suri = soup_uri_new (oaburl);
-               if (suri) {
-                       soup_uri_free (suri);
+               uri = g_uri_parse (oaburl, SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
+               if (uri) {
+                       g_uri_unref (uri);
                        e_util_set_entry_issue_hint (ews_backend->priv->oab_entry, NULL);
                } else {
                        e_util_set_entry_issue_hint (ews_backend->priv->oab_entry, _("OAB URL is not valid"));
diff --git a/src/EWS/evolution/e-mail-config-ews-delegates-page.c 
b/src/EWS/evolution/e-mail-config-ews-delegates-page.c
index 8352624c..ceff8493 100644
--- a/src/EWS/evolution/e-mail-config-ews-delegates-page.c
+++ b/src/EWS/evolution/e-mail-config-ews-delegates-page.c
@@ -1121,104 +1121,58 @@ mail_config_ews_delegates_page_constructed (GObject *object)
        e_mail_config_ews_delegates_page_refresh (page);
 }
 
-#define REMOVED_SLIST_KEY      "ews-delegate-removed-slist"
-#define ADDED_SLIST_KEY                "ews-delegate-added-slist"
-#define CANCELLABLE_KEY                "ews-delegate-cancellable"
-
-static void
-mail_config_ews_delegates_page_add_delegate_cb (GObject *source_object,
-                                                GAsyncResult *result,
-                                                gpointer user_data)
-{
-       GSimpleAsyncResult *simple;
-       GError *error = NULL;
-
-       simple = G_SIMPLE_ASYNC_RESULT (user_data);
-
-       e_ews_connection_add_delegate_finish (
-               E_EWS_CONNECTION (source_object), result, &error);
-
-       if (error != NULL)
-               g_simple_async_result_take_error (simple, error);
-
-       g_simple_async_result_complete (simple);
-
-       g_object_unref (simple);
-}
+typedef struct _SubmitData {
+       EEwsConnection *cnc;
+       gboolean deliver_to_changed;
+       EwsDelegateDeliver deliver_to;
+       GSList *added; /* const EwsDelegateInfo * */
+       GSList *updated; /* const EwsDelegateInfo * */
+       GSList *removed; /* const gchar * */
+} SubmitData;
 
 static void
-mail_config_ews_delegates_page_remove_delegate_cb (GObject *source_object,
-                                                   GAsyncResult *result,
-                                                   gpointer user_data)
+submit_data_free (gpointer ptr)
 {
-       GSimpleAsyncResult *simple;
-       GError *error = NULL;
-
-       simple = G_SIMPLE_ASYNC_RESULT (user_data);
-
-       e_ews_connection_remove_delegate_finish (
-               E_EWS_CONNECTION (source_object), result, &error);
-
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               g_simple_async_result_complete (simple);
-       } else {
-               GCancellable *cancellable;
-               GSList *list;
-
-               cancellable = g_object_get_data (G_OBJECT (simple), CANCELLABLE_KEY);
-               list = g_object_get_data (G_OBJECT (simple), ADDED_SLIST_KEY);
-               if (list) {
-                       e_ews_connection_add_delegate (
-                               E_EWS_CONNECTION (source_object), G_PRIORITY_DEFAULT, NULL, list,
-                               cancellable, mail_config_ews_delegates_page_add_delegate_cb, g_object_ref 
(simple));
-               } else {
-                       g_simple_async_result_complete (simple);
-               }
+       SubmitData *sd = ptr;
+
+       if (sd) {
+               g_clear_object (&sd->cnc);
+               g_slist_free (sd->added);
+               g_slist_free (sd->updated);
+               g_slist_free (sd->removed);
+               g_slice_free (SubmitData, sd);
        }
-
-       g_object_unref (simple);
 }
 
 static void
-mail_config_ews_delegates_page_update_delegate_cb (GObject *source_object,
-                                                   GAsyncResult *result,
-                                                   gpointer user_data)
+mail_config_ews_delegates_page_submit_thread (GTask *task,
+                                             gpointer source_object,
+                                             gpointer task_data,
+                                             GCancellable *cancellable)
 {
-       GSimpleAsyncResult *simple;
-       GError *error = NULL;
-
-       simple = G_SIMPLE_ASYNC_RESULT (user_data);
+       SubmitData *sd = task_data;
+       gboolean success = TRUE;
+       GError *local_error = NULL;
+       
+       if (sd->deliver_to_changed || sd->updated) {
+               success = e_ews_connection_update_delegate_sync (sd->cnc, G_PRIORITY_DEFAULT, NULL, 
sd->deliver_to, sd->updated,
+                       cancellable, &local_error);
+       }
 
-       e_ews_connection_update_delegate_finish (
-               E_EWS_CONNECTION (source_object), result, &error);
+       if (success && sd->removed) {
+               success = e_ews_connection_remove_delegate_sync (sd->cnc, G_PRIORITY_DEFAULT, NULL, 
sd->removed,
+                       cancellable, &local_error);
+       }
 
-       if (error != NULL) {
-               g_simple_async_result_take_error (simple, error);
-               g_simple_async_result_complete (simple);
-       } else {
-               GCancellable *cancellable;
-               GSList *list;
-
-               cancellable = g_object_get_data (G_OBJECT (simple), CANCELLABLE_KEY);
-               list = g_object_get_data (G_OBJECT (simple), REMOVED_SLIST_KEY);
-               if (list) {
-                       e_ews_connection_remove_delegate (
-                               E_EWS_CONNECTION (source_object), G_PRIORITY_DEFAULT, NULL, list,
-                               cancellable, mail_config_ews_delegates_page_remove_delegate_cb, g_object_ref 
(simple));
-               } else {
-                       list = g_object_get_data (G_OBJECT (simple), ADDED_SLIST_KEY);
-                       if (list) {
-                               e_ews_connection_add_delegate (
-                                       E_EWS_CONNECTION (source_object), G_PRIORITY_DEFAULT, NULL, list,
-                                       cancellable, mail_config_ews_delegates_page_add_delegate_cb, 
g_object_ref (simple));
-                       } else {
-                               g_simple_async_result_complete (simple);
-                       }
-               }
+       if (success && sd->added) {
+               success = e_ews_connection_add_delegate_sync (sd->cnc, G_PRIORITY_DEFAULT, NULL, sd->added,
+                       cancellable, &local_error);
        }
 
-       g_object_unref (simple);
+       if (local_error)
+               g_task_return_error (task, local_error);
+       else
+               g_task_return_boolean (task, success);
 }
 
 static gboolean
@@ -1246,25 +1200,29 @@ mail_config_ews_delegates_page_submit (EMailConfigPage *page,
                                        gpointer user_data)
 {
        EMailConfigEwsDelegatesPage *ews_page;
-       GSimpleAsyncResult *simple;
-       EwsDelegateDeliver deliver_to;
-       GSList *added = NULL, *updated = NULL, *removed = NULL, *iter;
+       GTask *task;
+       SubmitData *sd;
+       GSList *iter;
        GHashTable *oldies;
        GHashTableIter titer;
        gpointer key, value;
 
        ews_page = E_MAIL_CONFIG_EWS_DELEGATES_PAGE (page);
 
+       sd = g_slice_new0 (SubmitData);
+
+       task = g_task_new (ews_page, cancellable, callback, user_data);
+       g_task_set_source_tag (task, mail_config_ews_delegates_page_submit);
+       g_task_set_task_data (task, sd, submit_data_free);
+       g_task_set_check_cancellable (task, TRUE);
+
        g_mutex_lock (&ews_page->priv->delegates_lock);
 
        if (!ews_page->priv->connection) {
                g_mutex_unlock (&ews_page->priv->delegates_lock);
 
-               simple = g_simple_async_result_new (
-                       G_OBJECT (page), callback, user_data,
-                       mail_config_ews_delegates_page_submit);
-               g_simple_async_result_complete (simple);
-               g_object_unref (simple);
+               g_task_return_boolean (task, TRUE);
+               g_object_unref (task);
 
                return;
        }
@@ -1292,10 +1250,10 @@ mail_config_ews_delegates_page_submit (EMailConfigPage *page,
 
                orig_di = g_hash_table_lookup (oldies, di->user_id->primary_smtp);
                if (!orig_di) {
-                       added = g_slist_prepend (added, di);
+                       sd->added = g_slist_prepend (sd->added, di);
                } else {
                        if (!delegate_infos_equal (orig_di, di))
-                               updated = g_slist_prepend (updated, di);
+                               sd->updated = g_slist_prepend (sd->updated, di);
                        g_hash_table_remove (oldies, di->user_id->primary_smtp);
                }
        }
@@ -1304,61 +1262,36 @@ mail_config_ews_delegates_page_submit (EMailConfigPage *page,
        while (g_hash_table_iter_next (&titer, &key, &value)) {
                EwsDelegateInfo *di = value;
 
-               removed = g_slist_prepend (removed, di->user_id);
+               sd->removed = g_slist_prepend (sd->removed, di->user_id);
        }
 
        g_hash_table_destroy (oldies);
 
        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ews_page->priv->deliver_copy_me_radio)))
-               deliver_to = EwsDelegateDeliver_DelegatesAndSendInformationToMe;
+               sd->deliver_to = EwsDelegateDeliver_DelegatesAndSendInformationToMe;
        else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON 
(ews_page->priv->deliver_delegates_only_radio)))
-               deliver_to = EwsDelegateDeliver_DelegatesOnly;
+               sd->deliver_to = EwsDelegateDeliver_DelegatesOnly;
        else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON 
(ews_page->priv->deliver_delegates_and_me_radio)))
-               deliver_to = EwsDelegateDeliver_DelegatesAndMe;
+               sd->deliver_to = EwsDelegateDeliver_DelegatesAndMe;
        else
-               deliver_to = EwsDelegateDeliver_DelegatesAndSendInformationToMe;
+               sd->deliver_to = EwsDelegateDeliver_DelegatesAndSendInformationToMe;
 
-       if (deliver_to == ews_page->priv->deliver_to && !added && !updated && !removed) {
+       if (sd->deliver_to == ews_page->priv->deliver_to && !sd->added && !sd->updated && !sd->removed) {
                /* nothing changed, bye bye */
                g_mutex_unlock (&ews_page->priv->delegates_lock);
 
-               simple = g_simple_async_result_new (
-                       G_OBJECT (page), callback, user_data,
-                       mail_config_ews_delegates_page_submit);
-               g_simple_async_result_complete (simple);
-               g_object_unref (simple);
+               g_task_return_boolean (task, TRUE);
+               g_object_unref (task);
 
                return;
        }
 
-       simple = g_simple_async_result_new (
-               G_OBJECT (page), callback, user_data,
-               mail_config_ews_delegates_page_submit);
-
-       g_simple_async_result_set_check_cancellable (simple, cancellable);
-
-       g_object_set_data_full (G_OBJECT (simple), REMOVED_SLIST_KEY, removed, (GDestroyNotify) g_slist_free);
-       g_object_set_data_full (G_OBJECT (simple), ADDED_SLIST_KEY, added, (GDestroyNotify) g_slist_free);
-       if (cancellable)
-               g_object_set_data_full (G_OBJECT (simple), CANCELLABLE_KEY, g_object_ref (cancellable), 
g_object_unref);
-
-       if (deliver_to != ews_page->priv->deliver_to || updated) {
-               e_ews_connection_update_delegate (
-                       ews_page->priv->connection, G_PRIORITY_DEFAULT, NULL, deliver_to, updated,
-                       cancellable, mail_config_ews_delegates_page_update_delegate_cb, g_object_ref 
(simple));
-       } else if (removed) {
-               e_ews_connection_remove_delegate (
-                       ews_page->priv->connection, G_PRIORITY_DEFAULT, NULL, removed,
-                       cancellable, mail_config_ews_delegates_page_remove_delegate_cb, g_object_ref 
(simple));
-       } else {
-               g_warn_if_fail (added != NULL);
+       sd->cnc = g_object_ref (ews_page->priv->connection);
+       sd->deliver_to_changed = sd->deliver_to != ews_page->priv->deliver_to;
 
-               e_ews_connection_add_delegate (
-                       ews_page->priv->connection, G_PRIORITY_DEFAULT, NULL, added,
-                       cancellable, mail_config_ews_delegates_page_add_delegate_cb, g_object_ref (simple));
-       }
+       g_task_run_in_thread (task, mail_config_ews_delegates_page_submit_thread);
 
-       g_object_unref (simple);
+       g_object_unref (task);
 
        g_mutex_unlock (&ews_page->priv->delegates_lock);
 }
@@ -1368,17 +1301,9 @@ mail_config_ews_delegates_page_submit_finish (EMailConfigPage *page,
                                               GAsyncResult *result,
                                               GError **error)
 {
-       GSimpleAsyncResult *simple;
-
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (page),
-               mail_config_ews_delegates_page_submit), FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
+       g_return_val_if_fail (g_task_is_valid (result, page), FALSE);
 
-       /* Assume success unless a GError is set. */
-       return !g_simple_async_result_propagate_error (simple, error);
+       return g_task_propagate_boolean (G_TASK (result), error);
 }
 
 static gint
@@ -1451,7 +1376,7 @@ mail_config_ews_delegates_page_try_credentials_sync (EEwsConnection *connection,
                async_context->page->priv->orig_delegates = g_slist_sort (delegates, sort_by_display_name_cb);
                g_mutex_unlock (&async_context->page->priv->delegates_lock);
 
-       } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+       } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
                result = E_SOURCE_AUTHENTICATION_REJECTED;
                g_clear_object (&async_context->page->priv->connection);
                g_error_free (local_error);
diff --git a/src/EWS/evolution/e-mail-config-ews-oal-combo-box.c 
b/src/EWS/evolution/e-mail-config-ews-oal-combo-box.c
index f2c2f3f4..134ba31e 100644
--- a/src/EWS/evolution/e-mail-config-ews-oal-combo-box.c
+++ b/src/EWS/evolution/e-mail-config-ews-oal-combo-box.c
@@ -219,7 +219,7 @@ mail_config_ews_aol_combo_box_update_try_credentials_sync (EEwsConnection *conne
                combo_box->priv->oal_items = oal_items;
                g_mutex_unlock (&combo_box->priv->oal_items_lock);
 
-       } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+       } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
                result = E_SOURCE_AUTHENTICATION_REJECTED;
                g_error_free (local_error);
 
diff --git a/src/EWS/evolution/e-mail-config-ews-ooo-page.c b/src/EWS/evolution/e-mail-config-ews-ooo-page.c
index 44fd525f..fa853c81 100644
--- a/src/EWS/evolution/e-mail-config-ews-ooo-page.c
+++ b/src/EWS/evolution/e-mail-config-ews-ooo-page.c
@@ -767,7 +767,7 @@ mail_config_ews_ooo_page_try_credentials_sync (EEwsConnection *connection,
                page->priv->changed = FALSE;
                g_mutex_unlock (&page->priv->oof_settings_lock);
 
-       } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+       } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
                result = E_SOURCE_AUTHENTICATION_REJECTED;
                g_error_free (local_error);
 
diff --git a/src/EWS/registry/e-ews-backend.c b/src/EWS/registry/e-ews-backend.c
index 26ce2e9f..3a89e930 100644
--- a/src/EWS/registry/e-ews-backend.c
+++ b/src/EWS/registry/e-ews-backend.c
@@ -1125,7 +1125,7 @@ ews_backend_get_destination_address (EBackend *backend,
                                     guint16 *port)
 {
        CamelEwsSettings *ews_settings;
-       SoupURI *soup_uri;
+       GUri *uri;
        gchar *host_url;
        gboolean result = FALSE;
 
@@ -1138,10 +1138,10 @@ ews_backend_get_destination_address (EBackend *backend,
        host_url = camel_ews_settings_dup_hosturl (ews_settings);
        g_return_val_if_fail (host_url != NULL, FALSE);
 
-       soup_uri = soup_uri_new (host_url);
-       if (soup_uri) {
-               *host = g_strdup (soup_uri_get_host (soup_uri));
-               *port = soup_uri_get_port (soup_uri);
+       uri = g_uri_parse (host_url, SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
+       if (uri) {
+               *host = g_strdup (g_uri_get_host (uri));
+               *port = g_uri_get_port (uri);
 
                result = *host && **host;
                if (!result) {
@@ -1149,7 +1149,7 @@ ews_backend_get_destination_address (EBackend *backend,
                        *host = NULL;
                }
 
-               soup_uri_free (soup_uri);
+               g_uri_unref (uri);
        }
 
        g_free (host_url);
diff --git a/src/Microsoft365/camel/camel-m365-folder.c b/src/Microsoft365/camel/camel-m365-folder.c
index 2db2b366..14a97604 100644
--- a/src/Microsoft365/camel/camel-m365-folder.c
+++ b/src/Microsoft365/camel/camel-m365-folder.c
@@ -391,10 +391,10 @@ m365_folder_download_message_cb (EM365Connection *cnc,
        g_return_val_if_fail (CAMEL_IS_STREAM (cache_stream), FALSE);
        g_return_val_if_fail (G_IS_INPUT_STREAM (raw_data_stream), FALSE);
 
-       if (message && message->response_headers) {
+       if (message && soup_message_get_response_headers (message)) {
                const gchar *content_length_str;
 
-               content_length_str = soup_message_headers_get_one (message->response_headers, 
"Content-Length");
+               content_length_str = soup_message_headers_get_one (soup_message_get_response_headers 
(message), "Content-Length");
 
                if (content_length_str && *content_length_str)
                        expected_size = (gssize) g_ascii_strtoll (content_length_str, NULL, 10);
diff --git a/src/Microsoft365/camel/camel-m365-store.c b/src/Microsoft365/camel/camel-m365-store.c
index 35376917..ff1b8e3f 100644
--- a/src/Microsoft365/camel/camel-m365-store.c
+++ b/src/Microsoft365/camel/camel-m365-store.c
@@ -195,7 +195,7 @@ m365_store_read_default_folders (CamelM365Store *m365_store,
                message = soup_message_new (SOUP_METHOD_GET, uri);
 
                if (!message) {
-                       g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: ā€œ%sā€"), 
uri);
+                       g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, _("Malformed URI: ā€œ%sā€"), 
uri);
 
                        g_ptr_array_unref (requests);
                        g_free (uri);
@@ -219,7 +219,8 @@ m365_store_read_default_folders (CamelM365Store *m365_store,
                        SoupMessage *message = g_ptr_array_index (requests, ii);
                        JsonNode *node = NULL;
 
-                       if (message->status_code > 0 && SOUP_STATUS_IS_SUCCESSFUL (message->status_code) &&
+                       if (e_m365_connection_util_get_message_status_code (message) > 0 &&
+                           SOUP_STATUS_IS_SUCCESSFUL (e_m365_connection_util_get_message_status_code 
(message)) &&
                            e_m365_connection_json_node_from_message (message, NULL, &node, cancellable, 
NULL) &&
                            node && JSON_NODE_HOLDS_OBJECT (node)) {
                                JsonObject *object = json_node_get_object (node);
@@ -1806,7 +1807,7 @@ camel_m365_store_maybe_disconnect (CamelM365Store *m365_store,
        if (camel_service_get_connection_status (service) != CAMEL_SERVICE_CONNECTED)
                return;
 
-       if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+       if (g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
                ESourceRegistry *registry = NULL;
 
                camel_service_disconnect_sync (service, FALSE, NULL, NULL);
diff --git a/src/Microsoft365/common/e-m365-connection.c b/src/Microsoft365/common/e-m365-connection.c
index b32ca8fa..889dc670 100644
--- a/src/Microsoft365/common/e-m365-connection.c
+++ b/src/Microsoft365/common/e-m365-connection.c
@@ -34,21 +34,18 @@ struct _EM365ConnectionPrivate {
        CamelM365Settings *settings;
        SoupSession *soup_session;
        GProxyResolver *proxy_resolver;
-       ESoupAuthBearer *bearer_auth;
 
        gchar *user; /* The default user for the URL */
        gchar *impersonate_user;
 
-       gboolean ssl_info_set;
-       gchar *ssl_certificate_pem;
-       GTlsCertificateFlags ssl_certificate_errors;
-
        gchar *hash_key; /* in the opened connections hash */
 
        /* How many microseconds to wait, until can execute a new request.
           This is to cover throttling and server unavailable responses.
           https://docs.microsoft.com/en-us/graph/best-practices-concept#handling-expected-errors */
        gint64 backoff_for_usec;
+
+       guint concurrent_connections;
 };
 
 enum {
@@ -78,248 +75,6 @@ m365_log_enabled (void)
        return log_enabled == 1;
 }
 
-static SoupSession *
-m365_connection_ref_soup_session (EM365Connection *cnc)
-{
-       SoupSession *soup_session = NULL;
-
-       g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), NULL);
-
-       LOCK (cnc);
-
-       if (cnc->priv->soup_session)
-               soup_session = g_object_ref (cnc->priv->soup_session);
-
-       UNLOCK (cnc);
-
-       return soup_session;
-}
-
-static void
-m365_connection_utils_ensure_bearer_auth_usage (SoupSession *session,
-                                               SoupMessage *message,
-                                               ESoupAuthBearer *bearer)
-{
-       SoupAuthManager *auth_manager;
-       SoupSessionFeature *feature;
-       SoupURI *soup_uri;
-
-       g_return_if_fail (SOUP_IS_SESSION (session));
-
-       /* Preload the SoupAuthManager with a valid "Bearer" token
-        * when using OAuth 2.0. This avoids an extra unauthorized
-        * HTTP round-trip, which apparently Google doesn't like. */
-
-       feature = soup_session_get_feature (SOUP_SESSION (session), SOUP_TYPE_AUTH_MANAGER);
-
-       if (!soup_session_feature_has_feature (feature, E_TYPE_SOUP_AUTH_BEARER)) {
-               /* Add the "Bearer" auth type to support OAuth 2.0. */
-               soup_session_feature_add_feature (feature, E_TYPE_SOUP_AUTH_BEARER);
-       }
-
-       soup_uri = message ? soup_message_get_uri (message) : NULL;
-       if (soup_uri && soup_uri->host && *soup_uri->host) {
-               soup_uri = soup_uri_copy_host (soup_uri);
-       } else {
-               soup_uri = NULL;
-       }
-
-       g_return_if_fail (soup_uri != NULL);
-
-       auth_manager = SOUP_AUTH_MANAGER (feature);
-
-       /* This will make sure the 'bearer' is used regardless of the current 'auth_manager' state.
-          See https://gitlab.gnome.org/GNOME/libsoup/-/issues/196 for more information. */
-       soup_auth_manager_clear_cached_credentials (auth_manager);
-       soup_auth_manager_use_auth (auth_manager, soup_uri, SOUP_AUTH (bearer));
-
-       soup_uri_free (soup_uri);
-}
-
-static gboolean
-m365_connection_utils_setup_bearer_auth (EM365Connection *cnc,
-                                        SoupSession *session,
-                                        SoupMessage *message,
-                                        gboolean is_in_authenticate_handler,
-                                        ESoupAuthBearer *bearer,
-                                        GCancellable *cancellable,
-                                        GError **error)
-{
-       ESource *source;
-       gchar *access_token = NULL;
-       gint expires_in_seconds = -1;
-       gboolean success = FALSE;
-
-       g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), FALSE);
-       g_return_val_if_fail (E_IS_SOUP_AUTH_BEARER (bearer), FALSE);
-
-       source = e_m365_connection_get_source (cnc);
-
-       success = e_source_get_oauth2_access_token_sync (source, cancellable,
-               &access_token, &expires_in_seconds, error);
-
-       if (success) {
-               e_soup_auth_bearer_set_access_token (bearer, access_token, expires_in_seconds);
-
-               if (!is_in_authenticate_handler) {
-                       if (session)
-                               g_object_ref (session);
-                       else
-                               session = m365_connection_ref_soup_session (cnc);
-
-                       m365_connection_utils_ensure_bearer_auth_usage (session, message, bearer);
-
-                       g_clear_object (&session);
-               }
-       }
-
-       g_free (access_token);
-
-       return success;
-}
-
-static gboolean
-m365_connection_utils_prepare_bearer_auth (EM365Connection *cnc,
-                                          SoupSession *session,
-                                          SoupMessage *message,
-                                          GCancellable *cancellable)
-{
-       ESource *source;
-       ESoupAuthBearer *using_bearer_auth;
-       gboolean success;
-       GError *local_error = NULL;
-
-       g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), FALSE);
-
-       source = e_m365_connection_get_source (cnc);
-       if (!source)
-               return TRUE;
-
-       using_bearer_auth = e_m365_connection_ref_bearer_auth (cnc);
-       if (using_bearer_auth) {
-               success = m365_connection_utils_setup_bearer_auth (cnc, session, message, FALSE, 
using_bearer_auth, cancellable, &local_error);
-               g_clear_object (&using_bearer_auth);
-       } else {
-               SoupAuth *soup_auth;
-               SoupURI *soup_uri;
-
-               soup_uri = message ? soup_message_get_uri (message) : NULL;
-               if (soup_uri && soup_uri->host && *soup_uri->host) {
-                       soup_uri = soup_uri_copy_host (soup_uri);
-               } else {
-                       soup_uri = NULL;
-               }
-
-               g_warn_if_fail (soup_uri != NULL);
-
-               if (!soup_uri) {
-                       soup_message_set_status_full (message, SOUP_STATUS_MALFORMED, "Cannot get host from 
message");
-                       return FALSE;
-               }
-
-               soup_auth = g_object_new (E_TYPE_SOUP_AUTH_BEARER, SOUP_AUTH_HOST, soup_uri->host, NULL);
-
-               success = m365_connection_utils_setup_bearer_auth (cnc, session, message, FALSE, 
E_SOUP_AUTH_BEARER (soup_auth), cancellable, &local_error);
-               if (success)
-                       e_m365_connection_set_bearer_auth (cnc, E_SOUP_AUTH_BEARER (soup_auth));
-
-               g_object_unref (soup_auth);
-               soup_uri_free (soup_uri);
-       }
-
-       if (!success) {
-               if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-                       soup_message_set_status (message, SOUP_STATUS_CANCELLED);
-               else if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED) ||
-                        g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
-                       soup_message_set_status_full (message, SOUP_STATUS_UNAUTHORIZED, 
local_error->message);
-               else
-                       soup_message_set_status_full (message, SOUP_STATUS_MALFORMED, local_error ? 
local_error->message : _("Unknown error"));
-       }
-
-       g_clear_error (&local_error);
-
-       return success;
-}
-
-static void
-m365_connection_authenticate (SoupSession *session,
-                             SoupMessage *msg,
-                             SoupAuth *auth,
-                             gboolean retrying,
-                             gpointer user_data)
-{
-       EM365Connection *cnc = user_data;
-       ESoupAuthBearer *using_bearer_auth;
-       GError *local_error = NULL;
-
-       g_return_if_fail (E_IS_M365_CONNECTION (cnc));
-
-       using_bearer_auth = e_m365_connection_ref_bearer_auth (cnc);
-
-       if (E_IS_SOUP_AUTH_BEARER (auth)) {
-               g_object_ref (auth);
-               g_warn_if_fail ((gpointer) using_bearer_auth == (gpointer) auth);
-
-               g_clear_object (&using_bearer_auth);
-               using_bearer_auth = E_SOUP_AUTH_BEARER (auth);
-
-               e_m365_connection_set_bearer_auth (cnc, using_bearer_auth);
-       }
-
-       if (!using_bearer_auth) {
-               g_warn_if_reached ();
-               return;
-       }
-
-       m365_connection_utils_setup_bearer_auth (cnc, session, msg, TRUE, E_SOUP_AUTH_BEARER (auth), NULL, 
&local_error);
-
-       if (local_error)
-               soup_message_set_status_full (msg, SOUP_STATUS_MALFORMED, local_error->message);
-
-       g_object_unref (using_bearer_auth);
-       g_clear_error (&local_error);
-}
-
-static gboolean
-m365_connection_utils_prepare_message (EM365Connection *cnc,
-                                      SoupSession *session,
-                                      SoupMessage *message,
-                                      GCancellable *cancellable)
-{
-       ESoupAuthBearer *using_bearer_auth;
-       ESource *source;
-       GError *local_error = NULL;
-
-       source = e_m365_connection_get_source (cnc);
-       if (source)
-               e_soup_ssl_trust_connect (message, source);
-
-       if (!m365_connection_utils_prepare_bearer_auth (cnc, session, message, cancellable))
-               return FALSE;
-
-       using_bearer_auth = e_m365_connection_ref_bearer_auth (cnc);
-
-       if (using_bearer_auth &&
-           e_soup_auth_bearer_is_expired (using_bearer_auth) &&
-           !m365_connection_utils_setup_bearer_auth (cnc, session, message, FALSE, using_bearer_auth, 
cancellable, &local_error)) {
-               if (local_error) {
-                       soup_message_set_status_full (message, SOUP_STATUS_BAD_REQUEST, local_error->message);
-                       g_clear_error (&local_error);
-               } else {
-                       soup_message_set_status (message, SOUP_STATUS_BAD_REQUEST);
-               }
-
-               g_object_unref (using_bearer_auth);
-
-               return FALSE;
-       }
-
-       g_clear_object (&using_bearer_auth);
-
-       return TRUE;
-}
-
 static void
 m365_connection_set_settings (EM365Connection *cnc,
                              CamelM365Settings *settings)
@@ -347,6 +102,12 @@ m365_connection_set_settings (EM365Connection *cnc,
                cnc->priv->settings, "impersonate-user",
                cnc, "impersonate-user",
                G_BINDING_DEFAULT);
+
+       e_binding_bind_property (
+               cnc->priv->settings, "concurrent-connections",
+               cnc, "concurrent-connections",
+               G_BINDING_DEFAULT |
+               G_BINDING_SYNC_CREATE);
 }
 
 static void
@@ -516,8 +277,14 @@ m365_connection_constructed (GObject *object)
        /* Chain up to parent's method. */
        G_OBJECT_CLASS (e_m365_connection_parent_class)->constructed (object);
 
+       cnc->priv->soup_session = g_object_new (E_TYPE_SOUP_SESSION,
+               "source", cnc->priv->source,
+               "max-conns", cnc->priv->concurrent_connections,
+               "max-conns-per-host", cnc->priv->concurrent_connections,
+               NULL);
+
        if (m365_log_enabled ()) {
-               SoupLogger *logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, -1);
+               SoupLogger *logger = soup_logger_new (SOUP_LOGGER_LOG_BODY);
 
                soup_session_add_feature (cnc->priv->soup_session, SOUP_SESSION_FEATURE (logger));
 
@@ -526,20 +293,26 @@ m365_connection_constructed (GObject *object)
 
        soup_session_add_feature_by_type (cnc->priv->soup_session, SOUP_TYPE_COOKIE_JAR);
        soup_session_add_feature_by_type (cnc->priv->soup_session, E_TYPE_SOUP_AUTH_BEARER);
-       soup_session_remove_feature_by_type (cnc->priv->soup_session, SOUP_TYPE_AUTH_BASIC);
 
-       g_signal_connect (
-               cnc->priv->soup_session, "authenticate",
-               G_CALLBACK (m365_connection_authenticate), cnc);
+       /* This can use only OAuth2 authentication, which should be set on the ESource */
+       soup_session_remove_feature_by_type (cnc->priv->soup_session, SOUP_TYPE_AUTH_BASIC);
+       soup_session_remove_feature_by_type (cnc->priv->soup_session, SOUP_TYPE_AUTH_NTLM);
+       soup_session_remove_feature_by_type (cnc->priv->soup_session, SOUP_TYPE_AUTH_NEGOTIATE);
+       soup_session_add_feature_by_type (cnc->priv->soup_session, E_TYPE_SOUP_AUTH_BEARER);
 
        cnc->priv->hash_key = camel_network_settings_dup_user (CAMEL_NETWORK_SETTINGS (cnc->priv->settings));
 
        if (!cnc->priv->hash_key)
                cnc->priv->hash_key = g_strdup ("no-user");
 
+       e_binding_bind_property (
+               cnc, "proxy-resolver",
+               cnc->priv->soup_session, "proxy-resolver",
+               G_BINDING_SYNC_CREATE);
+
        e_binding_bind_property (
                cnc->priv->settings, "timeout",
-               cnc->priv->soup_session, SOUP_SESSION_TIMEOUT,
+               cnc->priv->soup_session, "timeout",
                G_BINDING_SYNC_CREATE);
 }
 
@@ -564,17 +337,10 @@ m365_connection_dispose (GObject *object)
 
        LOCK (cnc);
 
-       if (cnc->priv->soup_session) {
-               g_signal_handlers_disconnect_by_func (
-                       cnc->priv->soup_session,
-                       m365_connection_authenticate, object);
-       }
-
        g_clear_object (&cnc->priv->source);
        g_clear_object (&cnc->priv->settings);
        g_clear_object (&cnc->priv->soup_session);
        g_clear_object (&cnc->priv->proxy_resolver);
-       g_clear_object (&cnc->priv->bearer_auth);
 
        UNLOCK (cnc);
 
@@ -588,7 +354,6 @@ m365_connection_finalize (GObject *object)
        EM365Connection *cnc = E_M365_CONNECTION (object);
 
        g_rec_mutex_clear (&cnc->priv->property_lock);
-       g_clear_pointer (&cnc->priv->ssl_certificate_pem, g_free);
        g_clear_pointer (&cnc->priv->user, g_free);
        g_clear_pointer (&cnc->priv->impersonate_user, g_free);
        g_free (cnc->priv->hash_key);
@@ -701,24 +466,38 @@ e_m365_connection_init (EM365Connection *cnc)
        g_rec_mutex_init (&cnc->priv->property_lock);
 
        cnc->priv->backoff_for_usec = 0;
-       cnc->priv->soup_session = soup_session_new_with_options (
-               SOUP_SESSION_TIMEOUT, 90,
-               SOUP_SESSION_SSL_STRICT, TRUE,
-               SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE,
-               NULL);
-
-       /* Do not use G_BINDING_SYNC_CREATE, because we don't have a GProxyResolver yet anyway. */
-       e_binding_bind_property (
-               cnc, "proxy-resolver",
-               cnc->priv->soup_session, "proxy-resolver",
-               G_BINDING_DEFAULT);
 }
 
 gboolean
 e_m365_connection_util_delta_token_failed (const GError *error)
 {
-       return g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) ||
-              g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_BAD_REQUEST);
+       return g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED) ||
+              g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_BAD_REQUEST);
+}
+
+void
+e_m365_connection_util_set_message_status_code (SoupMessage *message,
+                                               gint status_code)
+{
+       g_return_if_fail (SOUP_IS_MESSAGE (message));
+
+       g_object_set_data (G_OBJECT (message), "m365-batch-status-code",
+               GINT_TO_POINTER (status_code));
+}
+
+gint
+e_m365_connection_util_get_message_status_code (SoupMessage *message)
+{
+       gint status_code;
+
+       g_return_val_if_fail (SOUP_IS_MESSAGE (message), -1);
+
+       status_code = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (message), "m365-batch-status-code"));
+
+       if (!status_code)
+               status_code = soup_message_get_status (message);
+
+       return status_code;
 }
 
 EM365Connection *
@@ -834,17 +613,9 @@ e_m365_connection_get_settings (EM365Connection *cnc)
 guint
 e_m365_connection_get_concurrent_connections (EM365Connection *cnc)
 {
-       guint current_cc = 0;
-
        g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), 1);
 
-       LOCK (cnc);
-
-       g_object_get (G_OBJECT (cnc->priv->soup_session), SOUP_SESSION_MAX_CONNS, &current_cc, NULL);
-
-       UNLOCK (cnc);
-
-       return current_cc;
+       return cnc->priv->concurrent_connections;
 }
 
 void
@@ -862,14 +633,9 @@ e_m365_connection_set_concurrent_connections (EM365Connection *cnc,
        if (current_cc == concurrent_connections)
                return;
 
-       LOCK (cnc);
-
-       g_object_set (G_OBJECT (cnc->priv->soup_session),
-               SOUP_SESSION_MAX_CONNS, concurrent_connections,
-               SOUP_SESSION_MAX_CONNS_PER_HOST, concurrent_connections,
-               NULL);
-
-       UNLOCK (cnc);
+       /* Will be updated in the priv->soup_session the next time it's created,
+          because "max-conns" is a construct-only property */
+       cnc->priv->concurrent_connections = concurrent_connections;
 
        g_object_notify (G_OBJECT (cnc), "concurrent-connections");
 }
@@ -921,43 +687,6 @@ e_m365_connection_set_proxy_resolver (EM365Connection *cnc,
                g_object_notify (G_OBJECT (cnc), "proxy-resolver");
 }
 
-ESoupAuthBearer *
-e_m365_connection_ref_bearer_auth (EM365Connection *cnc)
-{
-       ESoupAuthBearer *res = NULL;
-
-       g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), NULL);
-
-       LOCK (cnc);
-
-       if (cnc->priv->bearer_auth)
-               res = g_object_ref (cnc->priv->bearer_auth);
-
-       UNLOCK (cnc);
-
-       return res;
-}
-
-void
-e_m365_connection_set_bearer_auth (EM365Connection *cnc,
-                                  ESoupAuthBearer *bearer_auth)
-{
-       g_return_if_fail (E_IS_M365_CONNECTION (cnc));
-
-       LOCK (cnc);
-
-       if (cnc->priv->bearer_auth != bearer_auth) {
-               g_clear_object (&cnc->priv->bearer_auth);
-
-               cnc->priv->bearer_auth = bearer_auth;
-
-               if (cnc->priv->bearer_auth)
-                       g_object_ref (cnc->priv->bearer_auth);
-       }
-
-       UNLOCK (cnc);
-}
-
 static void
 m365_connection_request_cancelled_cb (GCancellable *cancellable,
                                      gpointer user_data)
@@ -969,35 +698,6 @@ m365_connection_request_cancelled_cb (GCancellable *cancellable,
        e_flag_set (flag);
 }
 
-static void
-m365_connection_extract_ssl_data (EM365Connection *cnc,
-                                 SoupMessage *message)
-{
-       GTlsCertificate *certificate = NULL;
-
-       g_return_if_fail (E_IS_M365_CONNECTION (cnc));
-       g_return_if_fail (SOUP_IS_MESSAGE (message));
-
-       LOCK (cnc);
-
-       g_clear_pointer (&cnc->priv->ssl_certificate_pem, g_free);
-       cnc->priv->ssl_info_set = FALSE;
-
-       g_object_get (G_OBJECT (message),
-               "tls-certificate", &certificate,
-               "tls-errors", &cnc->priv->ssl_certificate_errors,
-               NULL);
-
-       if (certificate) {
-               g_object_get (certificate, "certificate-pem", &cnc->priv->ssl_certificate_pem, NULL);
-               cnc->priv->ssl_info_set = TRUE;
-
-               g_object_unref (certificate);
-       }
-
-       UNLOCK (cnc);
-}
-
 /* An example error response:
 
   {
@@ -1018,6 +718,7 @@ m365_connection_extract_error (JsonNode *node,
                               GError **error)
 {
        JsonObject *object;
+       GQuark domain = E_SOUP_SESSION_ERROR;
        const gchar *code, *message;
 
        if (!node || !JSON_NODE_HOLDS_OBJECT (node))
@@ -1034,15 +735,17 @@ m365_connection_extract_error (JsonNode *node,
        if (!code && !message)
                return FALSE;
 
-       if (!status_code || SOUP_STATUS_IS_SUCCESSFUL (status_code))
-               status_code = SOUP_STATUS_MALFORMED;
-       else if (g_strcmp0 (code, "ErrorInvalidUser") == 0)
+       if (!status_code || status_code == -1 || SOUP_STATUS_IS_SUCCESSFUL (status_code)) {
+               domain = G_IO_ERROR;
+               status_code = G_IO_ERROR_INVALID_DATA;
+       } else if (g_strcmp0 (code, "ErrorInvalidUser") == 0) {
                status_code = SOUP_STATUS_UNAUTHORIZED;
+       }
 
        if (code && message)
-               g_set_error (error, SOUP_HTTP_ERROR, status_code, "%s: %s", code, message);
+               g_set_error (error, domain, status_code, "%s: %s", code, message);
        else
-               g_set_error_literal (error, SOUP_HTTP_ERROR, status_code, code ? code : message);
+               g_set_error_literal (error, domain, status_code, code ? code : message);
 
        return TRUE;
 }
@@ -1079,11 +782,12 @@ e_m365_connection_json_node_from_message (SoupMessage *message,
        if (message_json_object) {
                *out_node = json_node_init_object (json_node_new (JSON_NODE_OBJECT), message_json_object);
 
-               success = !m365_connection_extract_error (*out_node, message->status_code, &local_error);
+               success = !m365_connection_extract_error (*out_node, 
e_m365_connection_util_get_message_status_code (message), &local_error);
        } else {
                const gchar *content_type;
 
-               content_type = message->response_headers ? soup_message_headers_get_content_type 
(message->response_headers, NULL) : NULL;
+               content_type = soup_message_get_response_headers (message) ?
+                       soup_message_headers_get_content_type (soup_message_get_response_headers (message), 
NULL) : NULL;
 
                if (content_type && g_ascii_strcasecmp (content_type, "application/json") == 0) {
                        JsonParser *json_parser;
@@ -1093,24 +797,15 @@ e_m365_connection_json_node_from_message (SoupMessage *message,
                        if (input_stream) {
                                success = json_parser_load_from_stream (json_parser, input_stream, 
cancellable, error);
                        } else {
-                               SoupBuffer *sbuffer;
-
-                               sbuffer = soup_message_body_flatten (message->response_body);
-
-                               if (sbuffer) {
-                                       success = json_parser_load_from_data (json_parser, sbuffer->data, 
sbuffer->length, error);
-                                       soup_buffer_free (sbuffer);
-                               } else {
-                                       /* This should not happen, it's for safety check only, thus the 
string is not localized */
-                                       success = FALSE;
-                                       g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED, "No 
JSON data found");
-                               }
+                               /* This should not happen, it's for safety check only, thus the string is not 
localized */
+                               success = FALSE;
+                               g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED, "No JSON 
data found");
                        }
 
                        if (success) {
                                *out_node = json_parser_steal_root (json_parser);
 
-                               success = !m365_connection_extract_error (*out_node, message->status_code, 
&local_error);
+                               success = !m365_connection_extract_error (*out_node, 
e_m365_connection_util_get_message_status_code (message), &local_error);
                        }
 
                        g_object_unref (json_parser);
@@ -1139,15 +834,15 @@ m365_connection_send_request_sync (EM365Connection *cnc,
 {
        SoupSession *soup_session;
        gint need_retry_seconds = 5;
-       gboolean success = FALSE, need_retry = TRUE;
        gboolean did_io_error_retry = FALSE;
+       gboolean success = FALSE, need_retry = TRUE;
 
        g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), FALSE);
        g_return_val_if_fail (SOUP_IS_MESSAGE (message), FALSE);
        g_return_val_if_fail (response_func != NULL || raw_data_func != NULL, FALSE);
        g_return_val_if_fail (response_func == NULL || raw_data_func == NULL, FALSE);
 
-       while (need_retry && !g_cancellable_is_cancelled (cancellable) && message->status_code != 
SOUP_STATUS_CANCELLED) {
+       while (need_retry && !g_cancellable_is_cancelled (cancellable)) {
                need_retry = FALSE;
 
                LOCK (cnc);
@@ -1168,7 +863,7 @@ m365_connection_send_request_sync (EM365Connection *cnc,
                                        flag, NULL);
                        }
 
-                       while (wait_ms > 0 && !g_cancellable_is_cancelled (cancellable) && 
message->status_code != SOUP_STATUS_CANCELLED) {
+                       while (wait_ms > 0 && !g_cancellable_is_cancelled (cancellable)) {
                                gint64 now = g_get_monotonic_time ();
                                gint left_minutes, left_seconds;
 
@@ -1215,50 +910,49 @@ m365_connection_send_request_sync (EM365Connection *cnc,
                if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
                        UNLOCK (cnc);
 
-                       soup_message_set_status (message, SOUP_STATUS_CANCELLED);
+                       e_m365_connection_util_set_message_status_code (message, -1);
 
                        return FALSE;
                }
 
                soup_session = cnc->priv->soup_session ? g_object_ref (cnc->priv->soup_session) : NULL;
 
-               g_clear_pointer (&cnc->priv->ssl_certificate_pem, g_free);
-               cnc->priv->ssl_certificate_errors = 0;
-               cnc->priv->ssl_info_set = FALSE;
-
                UNLOCK (cnc);
 
-               if (soup_session &&
-                   m365_connection_utils_prepare_message (cnc, soup_session, message, cancellable)) {
+               if (soup_session) {
                        GInputStream *input_stream;
+                       GError *local_error = NULL;
+                       gboolean is_io_error;
 
-                       input_stream = soup_session_send (soup_session, message, cancellable, error);
+                       input_stream = e_soup_session_send_message_sync (E_SOUP_SESSION (soup_session), 
message, cancellable, &local_error);
 
                        success = input_stream != NULL;
+                       is_io_error = !did_io_error_retry && g_error_matches (local_error, G_IO_ERROR, 
G_IO_ERROR_PARTIAL_INPUT);
 
-                       if (success && m365_log_enabled ())
-                               input_stream = e_soup_logger_attach (message, input_stream);
+                       if (local_error) {
+                               g_propagate_error (error, local_error);
+                               local_error = NULL;
+                       }
 
-                       if ((!did_io_error_retry && message->status_code == SOUP_STATUS_IO_ERROR) ||
+                       if (is_io_error ||
                            /* Throttling - https://docs.microsoft.com/en-us/graph/throttling  */
-                           message->status_code == 429 ||
+                           e_m365_connection_util_get_message_status_code (message) == 429 ||
                            /* 
https://docs.microsoft.com/en-us/graph/best-practices-concept#handling-expected-errors */
-                           message->status_code == SOUP_STATUS_SERVICE_UNAVAILABLE) {
-                               did_io_error_retry = did_io_error_retry || message->status_code == 
SOUP_STATUS_IO_ERROR;
+                           e_m365_connection_util_get_message_status_code (message) == 
SOUP_STATUS_SERVICE_UNAVAILABLE) {
+                               did_io_error_retry = did_io_error_retry || is_io_error;
                                need_retry = TRUE;
-                       } else if (message->status_code == SOUP_STATUS_SSL_FAILED) {
-                               m365_connection_extract_ssl_data (cnc, message);
                        }
 
                        if (need_retry) {
                                const gchar *retry_after_str;
                                gint64 retry_after;
 
-                               retry_after_str = message->response_headers ? soup_message_headers_get_one 
(message->response_headers, "Retry-After") : NULL;
+                               retry_after_str = soup_message_get_response_headers (message) ?
+                                       soup_message_headers_get_one (soup_message_get_response_headers 
(message), "Retry-After") : NULL;
 
                                if (retry_after_str && *retry_after_str)
                                        retry_after = g_ascii_strtoll (retry_after_str, NULL, 10);
-                               else if (message->status_code == SOUP_STATUS_IO_ERROR)
+                               else if (is_io_error)
                                        retry_after = M365_RETRY_IO_ERROR_SECONDS;
                                else
                                        retry_after = 0;
@@ -1273,13 +967,13 @@ m365_connection_send_request_sync (EM365Connection *cnc,
                                if (cnc->priv->backoff_for_usec < need_retry_seconds * G_USEC_PER_SEC)
                                        cnc->priv->backoff_for_usec = need_retry_seconds * G_USEC_PER_SEC;
 
-                               if (message->status_code == SOUP_STATUS_SERVICE_UNAVAILABLE)
+                               if (e_m365_connection_util_get_message_status_code (message) == 
SOUP_STATUS_SERVICE_UNAVAILABLE)
                                        soup_session_abort (soup_session);
 
                                UNLOCK (cnc);
 
                                success = FALSE;
-                       } else if (success && raw_data_func && SOUP_STATUS_IS_SUCCESSFUL 
(message->status_code)) {
+                       } else if (success && raw_data_func && SOUP_STATUS_IS_SUCCESSFUL 
(e_m365_connection_util_get_message_status_code (message))) {
                                success = raw_data_func (cnc, message, input_stream, func_user_data, 
cancellable, error);
                        } else if (success) {
                                JsonNode *node = NULL;
@@ -1292,30 +986,29 @@ m365_connection_send_request_sync (EM365Connection *cnc,
                                        success = response_func && response_func (cnc, message, input_stream, 
node, func_user_data, &next_link, cancellable, error);
 
                                        if (success && next_link && *next_link) {
-                                               SoupURI *suri;
+                                               GUri *uri;
 
-                                               suri = soup_uri_new (next_link);
+                                               uri = g_uri_parse (next_link, SOUP_HTTP_URI_FLAGS | 
G_URI_FLAGS_PARSE_RELAXED, NULL);
 
                                                /* Check whether the server returned correct nextLink URI */
-                                               g_warn_if_fail (suri != NULL);
+                                               g_warn_if_fail (uri != NULL);
 
-                                               if (suri) {
+                                               if (uri) {
                                                        need_retry = TRUE;
 
-                                                       soup_message_set_uri (message, suri);
-                                                       soup_uri_free (suri);
+                                                       soup_message_set_uri (message, uri);
+                                                       g_uri_unref (uri);
                                                }
                                        }
 
                                        g_free (next_link);
-                               } else if (error && !*error && message->status_code && 
!SOUP_STATUS_IS_SUCCESSFUL (message->status_code)) {
-                                       if (message->status_code == SOUP_STATUS_CANCELLED) {
-                                               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
-                                                       message->reason_phrase ? message->reason_phrase : 
soup_status_get_phrase (message->status_code));
-                                       } else {
-                                               g_set_error_literal (error, SOUP_HTTP_ERROR, 
message->status_code,
-                                                       message->reason_phrase ? message->reason_phrase : 
soup_status_get_phrase (message->status_code));
-                                       }
+                               } else if (error && !*error && e_m365_connection_util_get_message_status_code 
(message) && !SOUP_STATUS_IS_SUCCESSFUL (e_m365_connection_util_get_message_status_code (message))) {
+                                       if (e_m365_connection_util_get_message_status_code (message) == -1)
+                                               g_set_error_literal (error, G_IO_ERROR, 
G_IO_ERROR_INVALID_DATA, _("Invalid data"));
+                                       else
+                                               g_set_error_literal (error, E_SOUP_SESSION_ERROR, 
e_m365_connection_util_get_message_status_code (message),
+                                                       soup_message_get_reason_phrase (message) ? 
soup_message_get_reason_phrase (message) :
+                                                       soup_status_get_phrase 
(e_m365_connection_util_get_message_status_code (message)));
                                }
 
                                if (node)
@@ -1324,15 +1017,14 @@ m365_connection_send_request_sync (EM365Connection *cnc,
 
                        g_clear_object (&input_stream);
                } else {
-                       if (!message->status_code)
-                               soup_message_set_status (message, SOUP_STATUS_CANCELLED);
-
-                       if (message->status_code == SOUP_STATUS_CANCELLED) {
-                               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
-                                       message->reason_phrase ? message->reason_phrase : 
soup_status_get_phrase (message->status_code));
+                       if (!e_m365_connection_util_get_message_status_code (message)) {
+                               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, _("Operation 
was cancelled"));
+                       } else if (e_m365_connection_util_get_message_status_code (message) == -1) {
+                               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, _("Invalid 
data"));
                        } else {
-                               g_set_error_literal (error, SOUP_HTTP_ERROR, message->status_code,
-                                       message->reason_phrase ? message->reason_phrase : 
soup_status_get_phrase (message->status_code));
+                               g_set_error_literal (error, E_SOUP_SESSION_ERROR, 
e_m365_connection_util_get_message_status_code (message),
+                                       soup_message_get_reason_phrase (message) ? 
soup_message_get_reason_phrase (message) :
+                                       soup_status_get_phrase 
(e_m365_connection_util_get_message_status_code (message)));
                        }
                }
 
@@ -1388,7 +1080,7 @@ e_m365_read_to_byte_array_cb (EM365Connection *cnc,
        if (!*out_byte_array) {
                goffset content_length;
 
-               content_length = soup_message_headers_get_content_length (message->response_headers);
+               content_length = soup_message_headers_get_content_length (soup_message_get_response_headers 
(message));
 
                if (!content_length || content_length > 65536)
                        content_length = 65535;
@@ -1514,46 +1206,24 @@ m365_connection_new_soup_message (const gchar *method,
        message = soup_message_new (method, uri);
 
        if (message) {
-               soup_message_headers_append (message->request_headers, "Connection", "Close");
-               soup_message_headers_append (message->request_headers, "User-Agent", "Evolution-M365/" 
VERSION);
+               SoupMessageHeaders *request_headers = soup_message_get_request_headers (message);
+
+               soup_message_headers_append (request_headers, "Connection", "Close");
+               soup_message_headers_append (request_headers, "User-Agent", "Evolution-M365/" VERSION);
 
                /* Disable caching for proxies (RFC 4918, section 10.4.5) */
-               soup_message_headers_append (message->request_headers, "Cache-Control", "no-cache");
-               soup_message_headers_append (message->request_headers, "Pragma", "no-cache");
+               soup_message_headers_append (request_headers, "Cache-Control", "no-cache");
+               soup_message_headers_append (request_headers, "Pragma", "no-cache");
 
                if ((csm_flags & CSM_DISABLE_RESPONSE) != 0)
-                       soup_message_headers_append (message->request_headers, "Prefer", "return=minimal");
+                       soup_message_headers_append (request_headers, "Prefer", "return=minimal");
        } else {
-               g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: ā€œ%sā€"), uri);
+               g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, _("Malformed URI: ā€œ%sā€"), uri);
        }
 
        return message;
 }
 
-gboolean
-e_m365_connection_get_ssl_error_details (EM365Connection *cnc,
-                                        gchar **out_certificate_pem,
-                                        GTlsCertificateFlags *out_certificate_errors)
-{
-       g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), FALSE);
-       g_return_val_if_fail (out_certificate_pem != NULL, FALSE);
-       g_return_val_if_fail (out_certificate_errors != NULL, FALSE);
-
-       LOCK (cnc);
-
-       if (!cnc->priv->ssl_info_set) {
-               UNLOCK (cnc);
-               return FALSE;
-       }
-
-       *out_certificate_pem = g_strdup (cnc->priv->ssl_certificate_pem);
-       *out_certificate_errors = cnc->priv->ssl_certificate_errors;
-
-       UNLOCK (cnc);
-
-       return TRUE;
-}
-
 ESourceAuthenticationResult
 e_m365_connection_authenticate_sync (EM365Connection *cnc,
                                     const gchar *user_override,
@@ -1606,35 +1276,22 @@ e_m365_connection_authenticate_sync (EM365Connection *cnc,
        if (success) {
                result = E_SOURCE_AUTHENTICATION_ACCEPTED;
        } else {
-               if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_CANCELLED)) {
-                       local_error->domain = G_IO_ERROR;
-                       local_error->code = G_IO_ERROR_CANCELLED;
-               } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED)) {
+               if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+                       /* Nothing to do */
+               } else if (e_soup_session_get_ssl_error_details (E_SOUP_SESSION (cnc->priv->soup_session), 
out_certificate_pem, out_certificate_errors)) {
                        result = E_SOURCE_AUTHENTICATION_ERROR_SSL_FAILED;
+               } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+                       LOCK (cnc);
 
-                       if (out_certificate_pem || out_certificate_errors)
-                               e_m365_connection_get_ssl_error_details (cnc, out_certificate_pem, 
out_certificate_errors);
-               } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
-                       ESoupAuthBearer *bearer;
-
-                       bearer = e_m365_connection_ref_bearer_auth (cnc);
-
-                       if (bearer) {
-                               LOCK (cnc);
-
-                               if (cnc->priv->impersonate_user) {
-                                       g_propagate_error (error, local_error);
-                                       local_error = NULL;
-                               } else {
-                                       result = E_SOURCE_AUTHENTICATION_REJECTED;
-                               }
-
-                               UNLOCK (cnc);
+                       if (cnc->priv->impersonate_user) {
+                               g_propagate_error (error, local_error);
+                               local_error = NULL;
                        } else {
-                               result = E_SOURCE_AUTHENTICATION_REQUIRED;
+                               result = E_SOURCE_AUTHENTICATION_REJECTED;
                        }
 
-                       g_clear_object (&bearer);
+                       UNLOCK (cnc);
+
                        g_clear_error (&local_error);
                }
 
@@ -1728,7 +1385,7 @@ e_m365_connection_construct_uri (EM365Connection *cnc,
                if (use_user) {
                        gchar *encoded;
 
-                       encoded = soup_uri_encode (use_user, NULL);
+                       encoded = g_uri_escape_string (use_user, NULL, FALSE);
 
                        g_string_append_c (uri, '/');
                        g_string_append (uri, encoded);
@@ -1772,7 +1429,7 @@ e_m365_connection_construct_uri (EM365Connection *cnc,
                        if (*value) {
                                gchar *encoded;
 
-                               encoded = soup_uri_encode (value, NULL);
+                               encoded = g_uri_escape_string (value, NULL, FALSE);
 
                                g_string_append (uri, encoded);
 
@@ -1813,10 +1470,10 @@ e_m365_connection_set_json_body (SoupMessage *message,
 
        data = json_generator_to_data (generator, &data_length);
 
-       soup_message_headers_set_content_type (message->request_headers, "application/json", NULL);
+       soup_message_headers_set_content_type (soup_message_get_request_headers (message), 
"application/json", NULL);
 
        if (data)
-               soup_message_body_append_take (message->request_body, (guchar *) data, data_length);
+               e_soup_session_util_set_message_request_body_from_data (message, FALSE, "application/json", 
data, data_length, g_free);
 
        g_object_unref (generator);
        json_node_unref (node);
@@ -1840,7 +1497,7 @@ e_m365_fill_message_headers_cb (JsonObject *object,
                value = json_node_get_string (member_node);
 
                if (value)
-                       soup_message_headers_replace (message->response_headers, member_name, value);
+                       soup_message_headers_replace (soup_message_get_response_headers (message), 
member_name, value);
        }
 }
 
@@ -1853,7 +1510,7 @@ e_m365_connection_fill_batch_response (SoupMessage *message,
        g_return_if_fail (SOUP_IS_MESSAGE (message));
        g_return_if_fail (object != NULL);
 
-       message->status_code = e_m365_json_get_int_member (object, "status", SOUP_STATUS_MALFORMED);
+       e_m365_connection_util_set_message_status_code (message, e_m365_json_get_int_member (object, 
"status", -1));
 
        subobject = e_m365_json_get_object_member (object, "headers");
 
@@ -1964,7 +1621,9 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
        for (ii = 0; success && ii < requests->len; ii++) {
                SoupMessageHeadersIter iter;
                SoupMessage *submessage;
-               SoupURI *suri;
+               GUri *guri;
+               GInputStream *request_body;
+               gssize request_body_length = 0;
                gboolean has_headers = FALSE;
                const gchar *hdr_name, *hdr_value, *use_uri;
                gboolean is_application_json = FALSE;
@@ -1974,13 +1633,13 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
                if (!submessage)
                        continue;
 
-               submessage->status_code = SOUP_STATUS_MALFORMED;
+               e_m365_connection_util_set_message_status_code (submessage, -1);
 
-               suri = soup_message_get_uri (submessage);
-               uri = suri ? soup_uri_to_string (suri, TRUE) : NULL;
+               guri = soup_message_get_uri (submessage);
+               uri = guri ? g_uri_to_string_partial (guri, G_URI_HIDE_PASSWORD) : NULL;
 
                if (!uri) {
-                       submessage->status_code = SOUP_STATUS_MALFORMED;
+                       g_warning ("%s: Batch message ignored due to no URI", G_STRFUNC);
                        continue;
                }
 
@@ -1996,12 +1655,12 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
                e_m365_json_begin_object_member (builder, NULL);
 
                e_m365_json_add_string_member (builder, "id", buff);
-               e_m365_json_add_string_member (builder, "method", submessage->method);
+               e_m365_json_add_string_member (builder, "method", soup_message_get_method (submessage));
                e_m365_json_add_string_member (builder, "url", use_uri);
 
                g_free (uri);
 
-               soup_message_headers_iter_init (&iter, submessage->request_headers);
+               soup_message_headers_iter_init (&iter, soup_message_get_request_headers (submessage));
 
                while (soup_message_headers_iter_next (&iter, &hdr_name, &hdr_value)) {
                        if (hdr_name && *hdr_name && hdr_value &&
@@ -2024,42 +1683,57 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
                if (has_headers)
                        e_m365_json_end_object_member (builder); /* headers */
 
-               if (submessage->request_body) {
-                       SoupBuffer *sbuffer;
+               request_body = e_soup_session_util_ref_message_request_body (submessage, 
&request_body_length);
 
-                       sbuffer = soup_message_body_flatten (submessage->request_body);
+               if (request_body && request_body_length > 0) {
+                       if (is_application_json) {
+                               /* The server needs it unpacked, not as a plain string */
+                               JsonParser *parser;
+                               JsonNode *node;
 
-                       if (sbuffer && sbuffer->length > 0) {
-                               if (is_application_json) {
-                                       /* The server needs it unpacked, not as a plain string */
-                                       JsonParser *parser;
-                                       JsonNode *node;
+                               parser = json_parser_new_immutable ();
 
-                                       parser = json_parser_new_immutable ();
+                               success = json_parser_load_from_stream (parser, request_body, cancellable, 
error);
 
-                                       success = json_parser_load_from_data (parser, sbuffer->data, 
sbuffer->length, error);
+                               if (!success)
+                                       g_prefix_error (error, "%s", _("Failed to parse own Json data"));
 
-                                       if (!success)
-                                               g_prefix_error (error, "%s", _("Failed to parse own Json 
data"));
+                               node = success ? json_parser_steal_root (parser) : NULL;
 
-                                       node = success ? json_parser_steal_root (parser) : NULL;
+                               if (node) {
+                                       json_builder_set_member_name (builder, "body");
+                                       json_builder_add_value (builder, node);
+                               }
 
-                                       if (node) {
-                                               json_builder_set_member_name (builder, "body");
-                                               json_builder_add_value (builder, node);
-                                       }
+                               g_clear_object (&parser);
+                       } else {
+                               GByteArray *array;
+                               guint8 *buffer;
+                               gsize n_buffer_sz = 16384;
+                               gsize n_read;
 
-                                       g_clear_object (&parser);
-                               } else {
-                                       e_m365_json_add_string_member (builder, "body", sbuffer->data);
+                               buffer = g_new0 (guint8, n_buffer_sz);
+                               array = g_byte_array_sized_new (request_body_length + 1);
+
+                               while (g_input_stream_read_all (request_body, buffer, n_buffer_sz, &n_read, 
cancellable, NULL)) {
+                                       if (n_read > 0)
+                                               g_byte_array_append (array, buffer, n_read);
                                }
-                       }
 
-                       if (sbuffer)
-                               soup_buffer_free (sbuffer);
+                               /* null-terminate the data, to use it as a string */
+                               buffer[0] = '\0';
+                               g_byte_array_append (array, buffer, 1);
+
+                               e_m365_json_add_string_member (builder, "body", (const gchar *) array->data);
+
+                               g_byte_array_unref (array);
+                               g_free (buffer);
+                       }
                }
 
                e_m365_json_end_object_member (builder); /* unnamed object */
+
+               g_clear_object (&request_body);
        }
 
        e_m365_json_end_array_member (builder);
@@ -2067,7 +1741,7 @@ e_m365_connection_batch_request_internal_sync (EM365Connection *cnc,
 
        e_m365_connection_set_json_body (message, builder);
 
-       soup_message_headers_append (message->request_headers, "Accept", "application/json");
+       soup_message_headers_append (soup_message_get_request_headers (message), "Accept", 
"application/json");
 
        g_object_unref (builder);
 
@@ -2091,8 +1765,8 @@ e_m365_connection_batch_request_sync (EM365Connection *cnc,
 {
        GPtrArray *use_requests;
        gint need_retry_seconds = 5;
-       gboolean success, need_retry = TRUE;
        gboolean did_io_error_retry = FALSE;
+       gboolean success, need_retry = TRUE;
 
        g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), FALSE);
        g_return_val_if_fail (requests != NULL, FALSE);
@@ -2102,9 +1776,30 @@ e_m365_connection_batch_request_sync (EM365Connection *cnc,
        use_requests = requests;
 
        while (need_retry) {
+               GError *local_error = NULL;
+
                need_retry = FALSE;
+               g_clear_error (error);
+
+               success = e_m365_connection_batch_request_internal_sync (cnc, api_version, use_requests, 
cancellable, &local_error);
+
+               if (!did_io_error_retry && g_error_matches (local_error, G_IO_ERROR, 
G_IO_ERROR_PARTIAL_INPUT)) {
+                       did_io_error_retry = TRUE;
+                       success = FALSE;
+                       need_retry = TRUE;
+
+                       LOCK (cnc);
 
-               success = e_m365_connection_batch_request_internal_sync (cnc, api_version, use_requests, 
cancellable, error);
+                       if (cnc->priv->backoff_for_usec < M365_RETRY_IO_ERROR_SECONDS * G_USEC_PER_SEC)
+                               cnc->priv->backoff_for_usec = M365_RETRY_IO_ERROR_SECONDS * G_USEC_PER_SEC;
+
+                       UNLOCK (cnc);
+               }
+
+               if (local_error) {
+                       g_propagate_error (error, local_error);
+                       local_error = NULL;
+               }
 
                if (success) {
                        GPtrArray *new_requests = NULL;
@@ -2117,15 +1812,13 @@ e_m365_connection_batch_request_sync (EM365Connection *cnc,
                                if (!message)
                                        continue;
 
-                               if ((!did_io_error_retry && message->status_code == SOUP_STATUS_IO_ERROR) ||
-                                   /* Throttling - https://docs.microsoft.com/en-us/graph/throttling  */
-                                   message->status_code == 429 ||
+                               /* Throttling - https://docs.microsoft.com/en-us/graph/throttling  */
+                               if (e_m365_connection_util_get_message_status_code (message) == 429 ||
                                    /* 
https://docs.microsoft.com/en-us/graph/best-practices-concept#handling-expected-errors */
-                                   message->status_code == SOUP_STATUS_SERVICE_UNAVAILABLE) {
+                                   e_m365_connection_util_get_message_status_code (message) == 
SOUP_STATUS_SERVICE_UNAVAILABLE) {
                                        const gchar *retry_after_str;
                                        gint64 retry_after;
 
-                                       did_io_error_retry = did_io_error_retry || message->status_code == 
SOUP_STATUS_IO_ERROR;
                                        need_retry = TRUE;
 
                                        if (!new_requests)
@@ -2133,12 +1826,11 @@ e_m365_connection_batch_request_sync (EM365Connection *cnc,
 
                                        g_ptr_array_add (new_requests, message);
 
-                                       retry_after_str = message->response_headers ? 
soup_message_headers_get_one (message->response_headers, "Retry-After") : NULL;
+                                       retry_after_str = soup_message_get_response_headers (message) ?
+                                               soup_message_headers_get_one 
(soup_message_get_response_headers (message), "Retry-After") : NULL;
 
                                        if (retry_after_str && *retry_after_str)
                                                retry_after = g_ascii_strtoll (retry_after_str, NULL, 10);
-                                       else if (message->status_code == SOUP_STATUS_IO_ERROR)
-                                               retry_after = M365_RETRY_IO_ERROR_SECONDS;
                                        else
                                                retry_after = 0;
 
@@ -2356,7 +2048,7 @@ e_m365_connection_get_folders_delta_sync (EM365Connection *cnc,
 
                prefer_value = g_strdup_printf ("odata.maxpagesize=%u", max_page_size);
 
-               soup_message_headers_append (message->request_headers, "Prefer", prefer_value);
+               soup_message_headers_append (soup_message_get_request_headers (message), "Prefer", 
prefer_value);
 
                g_free (prefer_value);
        }
@@ -2687,7 +2379,7 @@ e_m365_connection_get_objects_delta_sync (EM365Connection *cnc,
 
                prefer_value = g_strdup_printf ("odata.maxpagesize=%u", max_page_size);
 
-               soup_message_headers_append (message->request_headers, "Prefer", prefer_value);
+               soup_message_headers_append (soup_message_get_request_headers (message), "Prefer", 
prefer_value);
 
                g_free (prefer_value);
        }
@@ -3231,7 +2923,7 @@ e_m365_connection_send_mail_message_sync (EM365Connection *cnc,
 
        g_free (uri);
 
-       soup_message_headers_append (message->request_headers, "Content-Length", "0");
+       soup_message_headers_append (soup_message_get_request_headers (message), "Content-Length", "0");
 
        success = m365_connection_send_request_sync (cnc, message, NULL, e_m365_read_no_response_cb, NULL, 
cancellable, error);
 
@@ -3401,11 +3093,11 @@ e_m365_connection_update_contact_photo_sync (EM365Connection *cnc,
 
        g_free (uri);
 
-       soup_message_headers_set_content_type (message->request_headers, "image/jpeg", NULL);
-       soup_message_headers_set_content_length (message->request_headers, jpeg_photo ? jpeg_photo->len : 0);
+       soup_message_headers_set_content_type (soup_message_get_request_headers (message), "image/jpeg", 
NULL);
+       soup_message_headers_set_content_length (soup_message_get_request_headers (message), jpeg_photo ? 
jpeg_photo->len : 0);
 
        if (jpeg_photo)
-               soup_message_body_append (message->request_body, SOUP_MEMORY_STATIC, jpeg_photo->data, 
jpeg_photo->len);
+               e_soup_session_util_set_message_request_body_from_data (message, FALSE, "image/jpeg", 
jpeg_photo->data, jpeg_photo->len, NULL);
 
        success = m365_connection_send_request_sync (cnc, message, NULL, e_m365_read_no_response_cb, NULL, 
cancellable, error);
 
@@ -4093,7 +3785,7 @@ m365_connection_prefer_outlook_timezone (SoupMessage *message,
 
                prefer_value = g_strdup_printf ("outlook.timezone=\"%s\"", prefer_outlook_timezone);
 
-               soup_message_headers_append (message->request_headers, "Prefer", prefer_value);
+               soup_message_headers_append (soup_message_get_request_headers (message), "Prefer", 
prefer_value);
 
                g_free (prefer_value);
        }
@@ -4142,7 +3834,7 @@ e_m365_connection_list_events_sync (EM365Connection *cnc,
 
        m365_connection_prefer_outlook_timezone (message, prefer_outlook_timezone);
 
-       soup_message_headers_append (message->request_headers, "Prefer", 
"outlook.body-content-type=\"text\"");
+       soup_message_headers_append (soup_message_get_request_headers (message), "Prefer", 
"outlook.body-content-type=\"text\"");
 
        memset (&rd, 0, sizeof (EM365ResponseData));
 
@@ -4244,7 +3936,7 @@ e_m365_connection_prepare_get_event (EM365Connection *cnc,
        g_free (uri);
 
        m365_connection_prefer_outlook_timezone (message, prefer_outlook_timezone);
-       soup_message_headers_append (message->request_headers, "Prefer", 
"outlook.body-content-type=\"text\"");
+       soup_message_headers_append (soup_message_get_request_headers (message), "Prefer", 
"outlook.body-content-type=\"text\"");
 
        return message;
 }
@@ -5408,7 +5100,7 @@ e_m365_connection_list_tasks_sync (EM365Connection *cnc,
        g_free (uri);
 
        m365_connection_prefer_outlook_timezone (message, prefer_outlook_timezone);
-       soup_message_headers_append (message->request_headers, "Prefer", 
"outlook.body-content-type=\"text\"");
+       soup_message_headers_append (soup_message_get_request_headers (message), "Prefer", 
"outlook.body-content-type=\"text\"");
 
        memset (&rd, 0, sizeof (EM365ResponseData));
 
@@ -5511,7 +5203,7 @@ e_m365_connection_prepare_get_task (EM365Connection *cnc,
        g_free (uri);
 
        m365_connection_prefer_outlook_timezone (message, prefer_outlook_timezone);
-       soup_message_headers_append (message->request_headers, "Prefer", 
"outlook.body-content-type=\"text\"");
+       soup_message_headers_append (soup_message_get_request_headers (message), "Prefer", 
"outlook.body-content-type=\"text\"");
 
        return message;
 }
diff --git a/src/Microsoft365/common/e-m365-connection.h b/src/Microsoft365/common/e-m365-connection.h
index e12a18be..89cee114 100644
--- a/src/Microsoft365/common/e-m365-connection.h
+++ b/src/Microsoft365/common/e-m365-connection.h
@@ -76,6 +76,11 @@ struct _EM365ConnectionClass {
 
 gboolean       e_m365_connection_util_delta_token_failed
                                                (const GError *error);
+void           e_m365_connection_util_set_message_status_code
+                                               (SoupMessage *message,
+                                                gint status_code);
+gint           e_m365_connection_util_get_message_status_code
+                                               (SoupMessage *message);
 
 GType          e_m365_connection_get_type      (void) G_GNUC_CONST;
 
@@ -105,16 +110,6 @@ GProxyResolver *e_m365_connection_ref_proxy_resolver
 void           e_m365_connection_set_proxy_resolver
                                                (EM365Connection *cnc,
                                                 GProxyResolver *proxy_resolver);
-ESoupAuthBearer *
-               e_m365_connection_ref_bearer_auth
-                                               (EM365Connection *cnc);
-void           e_m365_connection_set_bearer_auth
-                                               (EM365Connection *cnc,
-                                                ESoupAuthBearer *bearer_auth);
-gboolean       e_m365_connection_get_ssl_error_details
-                                               (EM365Connection *cnc,
-                                                gchar **out_certificate_pem,
-                                                GTlsCertificateFlags *out_certificate_errors);
 ESourceAuthenticationResult
                e_m365_connection_authenticate_sync
                                                (EM365Connection *cnc,
diff --git a/src/Microsoft365/common/e-oauth2-service-microsoft365.c 
b/src/Microsoft365/common/e-oauth2-service-microsoft365.c
index 5440dd24..3b51384c 100644
--- a/src/Microsoft365/common/e-oauth2-service-microsoft365.c
+++ b/src/Microsoft365/common/e-oauth2-service-microsoft365.c
@@ -333,7 +333,7 @@ eos_microsoft365_extract_authorization_code (EOAuth2Service *service,
                                             const gchar *page_content,
                                             gchar **out_authorization_code)
 {
-       SoupURI *suri;
+       GUri *uri;
        gboolean known = FALSE;
 
        g_return_val_if_fail (out_authorization_code != NULL, FALSE);
@@ -343,12 +343,12 @@ eos_microsoft365_extract_authorization_code (EOAuth2Service *service,
        if (!page_uri || !*page_uri)
                return FALSE;
 
-       suri = soup_uri_new (page_uri);
-       if (!suri)
+       uri = g_uri_parse (page_uri, SOUP_HTTP_URI_FLAGS | G_URI_FLAGS_PARSE_RELAXED, NULL);
+       if (!uri)
                return FALSE;
 
-       if (suri->query) {
-               GHashTable *uri_query = soup_form_decode (suri->query);
+       if (g_uri_get_query (uri)) {
+               GHashTable *uri_query = soup_form_decode (g_uri_get_query (uri));
 
                if (uri_query) {
                        const gchar *code;
@@ -376,7 +376,7 @@ eos_microsoft365_extract_authorization_code (EOAuth2Service *service,
                }
        }
 
-       soup_uri_free (suri);
+       g_uri_unref (uri);
 
        return known;
 }
diff --git a/src/Microsoft365/registry/e-m365-backend.c b/src/Microsoft365/registry/e-m365-backend.c
index a19917b0..e8bb3580 100644
--- a/src/Microsoft365/registry/e-m365-backend.c
+++ b/src/Microsoft365/registry/e-m365-backend.c
@@ -344,8 +344,8 @@ m365_backend_sync_contact_folders_sync (EM365Backend *m365_backend,
                        id, NULL, display_name, TRUE, NULL);
 
                json_object_unref (user_contacts);
-       } else if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_NOT_FOUND) ||
-                  g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+       } else if (g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_NOT_FOUND) ||
+                  g_error_matches (error, E_SOUP_SESSION_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
                m365_backend_remove_resource (m365_backend, E_SOURCE_EXTENSION_ADDRESS_BOOK, NULL);
        }
 


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