[evolution-ews] Bug 764065 - [Camel] Port more classes to GObject



commit e4dcf633bbe4c5b8d08eb0faf176dfbac6156a70
Author: Milan Crha <mcrha redhat com>
Date:   Tue Nov 8 15:53:15 2016 +0100

    Bug 764065 - [Camel] Port more classes to GObject

 src/calendar/e-cal-backend-ews.c   |    6 +-
 src/camel/CMakeLists.txt           |    2 +
 src/camel/camel-ews-folder.c       |  259 ++++++++++++----------
 src/camel/camel-ews-message-info.c |  431 ++++++++++++++++++++++++++++++++++++
 src/camel/camel-ews-message-info.h |   81 +++++++
 src/camel/camel-ews-store.c        |   16 +-
 src/camel/camel-ews-summary.c      |  229 ++++---------------
 src/camel/camel-ews-summary.h      |   23 +--
 src/camel/camel-ews-utils.c        |  229 ++++++++++---------
 src/camel/camel-ews-utils.h        |    2 +-
 10 files changed, 838 insertions(+), 440 deletions(-)
---
diff --git a/src/calendar/e-cal-backend-ews.c b/src/calendar/e-cal-backend-ews.c
index 15fd9a4..41a36cd 100644
--- a/src/calendar/e-cal-backend-ews.c
+++ b/src/calendar/e-cal-backend-ews.c
@@ -2697,6 +2697,7 @@ ewscal_send_cancellation_email (ECalBackend *backend,
                                 const gchar *calobj)
 {
        CamelMimeMessage *message;
+       CamelContentType *mime_type;
        GError *error = NULL;
        CamelMultipart *multi;
        CamelMimePart *text_part, *vcal_part;
@@ -2726,8 +2727,9 @@ ewscal_send_cancellation_email (ECalBackend *backend,
        camel_mime_part_set_content (text_part, body, strlen (body), "text/plain");
 
        vcal_part = camel_mime_part_new ();
-       camel_content_type_set_param (CAMEL_DATA_WRAPPER (vcal_part)->mime_type, "charset", "utf-8");
-       camel_content_type_set_param (CAMEL_DATA_WRAPPER (vcal_part)->mime_type, "method", "CANCEL");
+       mime_type = camel_data_wrapper_get_mime_type_field (CAMEL_DATA_WRAPPER (vcal_part));
+       camel_content_type_set_param (mime_type, "charset", "utf-8");
+       camel_content_type_set_param (mime_type, "method", "CANCEL");
        ical_str = icalcomponent_as_ical_string_r ((icalcomponent *) vcal);
        camel_mime_part_set_content (vcal_part, ical_str, strlen (ical_str), "text/calendar; method=CANCEL");
        free (ical_str);
diff --git a/src/camel/CMakeLists.txt b/src/camel/CMakeLists.txt
index 9280522..817eef1 100644
--- a/src/camel/CMakeLists.txt
+++ b/src/camel/CMakeLists.txt
@@ -16,6 +16,8 @@ set(SOURCES
        camel-ews-enums.h
        camel-ews-folder.c
        camel-ews-folder.h
+       camel-ews-message-info.c
+       camel-ews-message-info.h
        camel-ews-private.h
        camel-ews-store-summary.c
        camel-ews-store-summary.h
diff --git a/src/camel/camel-ews-folder.c b/src/camel/camel-ews-folder.c
index 0e9be48..a45c051 100644
--- a/src/camel/camel-ews-folder.c
+++ b/src/camel/camel-ews-folder.c
@@ -761,31 +761,45 @@ ews_folder_maybe_update_mlist (CamelFolder *folder,
                               const gchar *uid,
                               CamelMimeMessage *message)
 {
-       CamelEwsMessageInfo *mi;
+       CamelMessageInfo *mi;
+       const gchar *set_mlist;
 
        g_return_if_fail (CAMEL_IS_FOLDER (folder));
        g_return_if_fail (uid != NULL);
        g_return_if_fail (message != NULL);
 
-       mi = (CamelEwsMessageInfo *) camel_folder_summary_get (folder->summary, uid);
+       mi = camel_folder_summary_get (camel_folder_get_folder_summary (folder), uid);
        if (!mi)
                return;
 
-       if (!mi->info.mlist || !*mi->info.mlist) {
+       camel_message_info_property_lock (mi);
+       set_mlist = camel_message_info_get_mlist (mi);
+
+       if (!set_mlist || !*set_mlist) {
                /* update mailing list information, if necessary */
-               gchar *mlist = camel_header_raw_check_mailing_list (&(CAMEL_MIME_PART (message)->headers));
+               gchar *mlist = camel_headers_dup_mailing_list (camel_medium_get_headers (CAMEL_MEDIUM 
(message)));
 
                if (mlist) {
-                       if (mi->info.mlist)
-                               camel_pstring_free (mi->info.mlist);
-                       mi->info.mlist = camel_pstring_add (mlist, TRUE);
-                       mi->info.dirty = TRUE;
-
-                       camel_folder_summary_touch (folder->summary);
+                       camel_message_info_set_mlist (mi, mlist);
+                       g_free (mlist);
                }
        }
 
-       camel_message_info_unref (mi);
+       camel_message_info_property_unlock (mi);
+
+       g_clear_object (&mi);
+}
+
+static guint32
+ews_folder_get_permanent_flags (CamelFolder *folder)
+{
+       return CAMEL_MESSAGE_ANSWERED |
+               CAMEL_MESSAGE_DELETED |
+               CAMEL_MESSAGE_DRAFT |
+               CAMEL_MESSAGE_FLAGGED |
+               CAMEL_MESSAGE_SEEN |
+               CAMEL_MESSAGE_FORWARDED |
+               CAMEL_MESSAGE_USER;
 }
 
 /* Get the message from cache if available otherwise get it from server */
@@ -916,23 +930,31 @@ msg_update_flags (ESoapMessage *msg,
 {
        /* the mi_list is owned by the caller */
        const GSList *mi_list = user_data, *iter;
-       CamelEwsMessageInfo *mi;
+       CamelMessageInfo *mi;
+       CamelEwsMessageInfo *emi;
 
        for (iter = mi_list; iter; iter = g_slist_next (iter)) {
-               guint32 flags_changed;
+               guint32 flags_changed, mi_flags;
                GSList *user_flags;
 
                mi = iter->data;
+               emi = CAMEL_EWS_MESSAGE_INFO (mi);
+
+               if (!mi || !emi)
+                       continue;
+
+               camel_message_info_property_lock (mi);
 
-               flags_changed = mi->server_flags ^ mi->info.flags;
+               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,
-                       mi->info.uid, mi->change_key, 0);
+                       camel_message_info_get_uid (mi), camel_ews_message_info_get_change_key (emi), 0);
                if (flags_changed & CAMEL_MESSAGE_FLAGGED) {
                        const gchar *flag;
 
-                       if (mi->info.flags & CAMEL_MESSAGE_FLAGGED)
+                       if ((mi_flags & CAMEL_MESSAGE_FLAGGED) != 0)
                                flag = "High";
                        else
                                flag = "Normal";
@@ -959,10 +981,8 @@ msg_update_flags (ESoapMessage *msg,
                        e_soap_message_end_element (msg);
 
                        e_soap_message_start_element (msg, "Message", NULL, NULL);
-                       e_ews_message_write_string_parameter (
-                               msg, "IsRead", NULL,
-                               (mi->info.flags & CAMEL_MESSAGE_SEEN) ?
-                               "true" : "false");
+                       e_ews_message_write_string_parameter (msg, "IsRead", NULL,
+                               (mi_flags & CAMEL_MESSAGE_SEEN) ? "true" : "false");
 
                        e_soap_message_end_element (msg); /* Message */
                        e_soap_message_end_element (msg); /* SetItemField */
@@ -970,11 +990,11 @@ msg_update_flags (ESoapMessage *msg,
                /* 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? */
                if (flags_changed & (CAMEL_MESSAGE_FORWARDED | CAMEL_MESSAGE_ANSWERED)) {
-                       gint icon = (mi->info.flags & CAMEL_MESSAGE_SEEN) ? 0x100 : 0x101;
+                       gint icon = (mi_flags & CAMEL_MESSAGE_SEEN) ? 0x100 : 0x101;
 
-                       if (mi->info.flags & CAMEL_MESSAGE_ANSWERED)
+                       if (mi_flags & CAMEL_MESSAGE_ANSWERED)
                                icon = 0x105;
-                       if (mi->info.flags & CAMEL_MESSAGE_FORWARDED)
+                       if (mi_flags & CAMEL_MESSAGE_FORWARDED)
                                icon = 0x106;
 
                        e_ews_message_add_set_item_field_extended_tag_int (msg, NULL, "Message", 0x1080, 
icon);
@@ -1009,14 +1029,13 @@ msg_update_flags (ESoapMessage *msg,
 
                g_slist_free_full (user_flags, g_free);
 
-               ews_utils_update_followup_flags (msg, (CamelMessageInfo *) mi);
+               ews_utils_update_followup_flags (msg, mi);
 
                e_ews_message_end_item_change (msg);
 
-               mi->info.flags = mi->info.flags & (~CAMEL_MESSAGE_FOLDER_FLAGGED);
-               mi->info.dirty = TRUE;
+               camel_message_info_set_folder_flagged (mi, FALSE);
 
-               camel_folder_summary_touch (mi->info.summary);
+               camel_message_info_property_unlock (mi);
        }
 }
 
@@ -1026,29 +1045,32 @@ ews_suppress_read_receipt (ESoapMessage *msg,
 {
        /* the mi_list is owned by the caller */
        const GSList *mi_list = user_data, *iter;
-       CamelEwsMessageInfo *mi;
+       CamelMessageInfo *mi;
 
        for (iter = mi_list; iter; iter = g_slist_next (iter)) {
                mi = iter->data;
                if (!mi || (camel_message_info_get_flags (mi) & CAMEL_EWS_MESSAGE_MSGFLAG_RN_PENDING) == 0)
                        continue;
 
+               camel_message_info_property_lock (mi);
+               camel_message_info_freeze_notifications (mi);
+
                /* 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", mi->info.uid, NULL, NULL);
-               e_soap_message_add_attribute (msg, "ChangeKey", mi->change_key, 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 */
 
-               mi->info.flags = mi->info.flags & (~CAMEL_EWS_MESSAGE_MSGFLAG_RN_PENDING);
-               mi->info.dirty = TRUE;
+               camel_message_info_set_flags (mi, CAMEL_EWS_MESSAGE_MSGFLAG_RN_PENDING, 0);
 
-               if (!camel_message_info_get_user_flag ((CamelMessageInfo *) mi, "receipt-handled"))
-                       camel_message_info_set_user_flag ((CamelMessageInfo *) mi, "receipt-handled", TRUE);
+               if (!camel_message_info_get_user_flag (mi, "receipt-handled"))
+                       camel_message_info_set_user_flag (mi, "receipt-handled", TRUE);
 
-               camel_folder_summary_touch (mi->info.summary);
+               camel_message_info_thaw_notifications (mi);
+               camel_message_info_property_unlock (mi);
        }
 }
 
@@ -1073,7 +1095,7 @@ ews_sync_mi_flags (CamelFolder *folder,
        cnc = camel_ews_store_ref_connection (ews_store);
 
        for (iter = mi_list; iter; iter = g_slist_next (iter)) {
-               CamelEwsMessageInfo *mi = iter->data;
+               CamelMessageInfo *mi = iter->data;
 
                if (mi && (camel_message_info_get_flags (mi) & CAMEL_EWS_MESSAGE_MSGFLAG_RN_PENDING) != 0)
                        break;
@@ -1107,7 +1129,7 @@ ews_sync_mi_flags (CamelFolder *folder,
                        cancellable, &local_error);
        }
 
-       camel_folder_summary_save_to_db (folder->summary, NULL);
+       camel_folder_summary_save (camel_folder_get_folder_summary (folder), NULL);
 
        if (local_error) {
                camel_ews_store_maybe_disconnect (ews_store, local_error);
@@ -1233,17 +1255,17 @@ ews_move_to_junk_folder (CamelFolder *folder,
                                if (!item || e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_ERROR)
                                        continue;
 
-                               camel_folder_summary_lock (folder->summary);
+                               camel_folder_summary_lock (camel_folder_get_folder_summary (folder));
 
                                camel_folder_change_info_remove_uid (changes, uid);
-                               camel_folder_summary_remove_uid (folder->summary, uid);
+                               camel_folder_summary_remove_uid (camel_folder_get_folder_summary (folder), 
uid);
                                ews_data_cache_remove (ews_folder->cache, "cur", uid, NULL);
 
-                               camel_folder_summary_unlock (folder->summary);
+                               camel_folder_summary_unlock (camel_folder_get_folder_summary (folder));
                        }
 
                        if (camel_folder_change_info_changed (changes)) {
-                               camel_folder_summary_touch (folder->summary);
+                               camel_folder_summary_touch (camel_folder_get_folder_summary (folder));
                                camel_folder_changed (folder, changes);
                        }
                        camel_folder_change_info_free (changes);
@@ -1270,6 +1292,7 @@ ews_synchronize_sync (CamelFolder *folder,
                       GError **error)
 {
        CamelEwsStore *ews_store;
+       CamelFolderSummary *folder_summary;
        GPtrArray *uids;
        GSList *mi_list = NULL, *deleted_uids = NULL, *junk_uids = NULL;
        gint mi_list_len = 0;
@@ -1282,12 +1305,13 @@ ews_synchronize_sync (CamelFolder *folder,
        if (!camel_ews_store_connected (ews_store, cancellable, error))
                return FALSE;
 
-       if (camel_folder_summary_get_deleted_count (folder->summary) > 0 ||
-           camel_folder_summary_get_junk_count (folder->summary) > 0) {
-               camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
-               uids = camel_folder_summary_get_array (folder->summary);
+       folder_summary = camel_folder_get_folder_summary (folder);
+       if (camel_folder_summary_get_deleted_count (folder_summary) > 0 ||
+           camel_folder_summary_get_junk_count (folder_summary) > 0) {
+               camel_folder_summary_prepare_fetch_all (folder_summary, NULL);
+               uids = camel_folder_summary_get_array (folder_summary);
        } else {
-               uids = camel_folder_summary_get_changed (folder->summary);
+               uids = camel_folder_summary_get_changed (folder_summary);
        }
        if (!uids || !uids->len) {
                camel_folder_summary_free_array (uids);
@@ -1296,12 +1320,13 @@ ews_synchronize_sync (CamelFolder *folder,
 
        for (i = 0; success && i < uids->len; i++) {
                guint32 flags_changed, flags_set;
-               CamelEwsMessageInfo *mi = (gpointer) camel_folder_summary_get (folder->summary, 
uids->pdata[i]);
+               CamelMessageInfo *mi = camel_folder_summary_get (folder_summary, uids->pdata[i]);
+
                if (!mi)
                        continue;
 
                flags_set = camel_message_info_get_flags (mi);
-               flags_changed = mi->server_flags ^ flags_set;
+               flags_changed = camel_ews_message_info_get_server_flags (CAMEL_EWS_MESSAGE_INFO (mi)) ^ 
flags_set;
 
                /* Exchange doesn't seem to have a sane representation
                 * for most flags — not even replied/forwarded. */
@@ -1316,21 +1341,21 @@ ews_synchronize_sync (CamelFolder *folder,
                                junk_uids = g_slist_prepend (junk_uids, (gpointer) camel_pstring_strdup 
(uids->pdata[i]));
                } else if (flags_set & CAMEL_MESSAGE_DELETED) {
                        deleted_uids = g_slist_prepend (deleted_uids, (gpointer) camel_pstring_strdup 
(uids->pdata[i]));
-                       camel_message_info_unref (mi);
+                       g_clear_object (&mi);
                } else if (flags_set & CAMEL_MESSAGE_JUNK) {
                        junk_uids = g_slist_prepend (junk_uids, (gpointer) camel_pstring_strdup 
(uids->pdata[i]));
-                       camel_message_info_unref (mi);
+                       g_clear_object (&mi);
                } else if ((flags_set & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0) {
                        /* OK, the change must have been the labels */
                        mi_list = g_slist_prepend (mi_list, mi);
                        mi_list_len++;
                } else {
-                       camel_message_info_unref (mi);
+                       g_clear_object (&mi);
                }
 
                if (mi_list_len == EWS_MAX_FETCH_COUNT) {
                        success = ews_save_flags (folder, mi_list, cancellable, &local_error);
-                       g_slist_free_full (mi_list, camel_message_info_unref);
+                       g_slist_free_full (mi_list, g_object_unref);
                        mi_list = NULL;
                        mi_list_len = 0;
                }
@@ -1338,7 +1363,7 @@ ews_synchronize_sync (CamelFolder *folder,
 
        if (mi_list != NULL && success)
                success = ews_save_flags (folder, mi_list, cancellable, &local_error);
-       g_slist_free_full (mi_list, camel_message_info_unref);
+       g_slist_free_full (mi_list, g_object_unref);
 
        if (deleted_uids && success)
                success = ews_delete_messages (folder, deleted_uids, ews_folder_is_of_type (folder, 
CAMEL_FOLDER_TYPE_TRASH), cancellable, &local_error);
@@ -1348,7 +1373,7 @@ ews_synchronize_sync (CamelFolder *folder,
                success = ews_move_to_junk_folder (folder, junk_uids, cancellable, &local_error);
        g_slist_free_full (junk_uids, (GDestroyNotify) camel_pstring_free);
 
-       camel_folder_summary_save_to_db (folder->summary, NULL);
+       camel_folder_summary_save (folder_summary, NULL);
        camel_folder_summary_free_array (uids);
 
        if (local_error)
@@ -1370,7 +1395,7 @@ ews_folder_count_notify_cb (CamelFolderSummary *folder_summary,
        g_return_if_fail (folder_summary != NULL);
        g_return_if_fail (param != NULL);
        g_return_if_fail (folder != NULL);
-       g_return_if_fail (folder->summary == folder_summary);
+       g_return_if_fail (camel_folder_get_folder_summary (folder) == folder_summary);
 
        ews_store = CAMEL_EWS_STORE (camel_folder_get_parent_store (folder));
        g_return_if_fail (ews_store != NULL);
@@ -1424,6 +1449,7 @@ camel_ews_folder_new (CamelStore *store,
                       GError **error)
 {
        CamelFolder *folder;
+       CamelFolderSummary *folder_summary;
        CamelEwsFolder *ews_folder;
        gchar *state_file;
        const gchar *short_name;
@@ -1441,16 +1467,18 @@ camel_ews_folder_new (CamelStore *store,
 
        ews_folder = CAMEL_EWS_FOLDER (folder);
 
-       folder->summary = camel_ews_summary_new (folder);
+       folder_summary = camel_ews_summary_new (folder);
 
-       if (!folder->summary) {
-               g_object_unref (CAMEL_OBJECT (folder));
+       if (!folder_summary) {
+               g_object_unref (folder);
                g_set_error (
                        error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
                        _("Could not load summary for %s"), folder_name);
                return NULL;
        }
 
+       camel_folder_take_folder_summary (folder, folder_summary);
+
        /* set/load persistent state */
        state_file = g_build_filename (folder_dir, "cmeta", NULL);
        camel_object_set_state_filename (CAMEL_OBJECT (folder), state_file);
@@ -1474,7 +1502,7 @@ camel_ews_folder_new (CamelStore *store,
                        CAMEL_STORE_SETTINGS (settings));
 
                if (filter_inbox)
-                       folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
+                       camel_folder_set_flags (folder, camel_folder_get_flags (folder) | 
CAMEL_FOLDER_FILTER_RECENT);
 
                g_object_unref (settings);
        }
@@ -1485,8 +1513,8 @@ camel_ews_folder_new (CamelStore *store,
                return NULL;
        }
 
-       g_signal_connect (folder->summary, "notify::saved-count", G_CALLBACK (ews_folder_count_notify_cb), 
folder);
-       g_signal_connect (folder->summary, "notify::unread-count", G_CALLBACK (ews_folder_count_notify_cb), 
folder);
+       g_signal_connect (folder_summary, "notify::saved-count", G_CALLBACK (ews_folder_count_notify_cb), 
folder);
+       g_signal_connect (folder_summary, "notify::unread-count", G_CALLBACK (ews_folder_count_notify_cb), 
folder);
 
        return folder;
 }
@@ -1528,15 +1556,15 @@ sync_updated_items (CamelEwsFolder *ews_folder,
 
                /* Compare the item_type from summary as the updated items seems to
                 * arrive as generic types while its not the case */
-               mi = camel_folder_summary_get (folder->summary, id->id);
+               mi = camel_folder_summary_get (camel_folder_get_folder_summary (folder), id->id);
                if (!mi) {
                        g_object_unref (item);
                        continue;
                }
 
                /* Check if the item has really changed */
-               if (!g_strcmp0 (((CamelEwsMessageInfo *) mi)->change_key, id->change_key)) {
-                       camel_message_info_unref (mi);
+               if (!g_strcmp0 (camel_ews_message_info_get_change_key (CAMEL_EWS_MESSAGE_INFO (mi)), 
id->change_key)) {
+                       g_clear_object (&mi);
                        g_object_unref (item);
                        continue;
                }
@@ -1554,7 +1582,7 @@ sync_updated_items (CamelEwsFolder *ews_folder,
                        item_type == E_EWS_ITEM_TYPE_UNKNOWN)
                        msg_ids = g_slist_append (msg_ids, g_strdup (id->id));
 
-               camel_message_info_unref (mi);
+               g_clear_object (&mi);
                g_object_unref (item);
        }
        g_slist_free (updated_items);
@@ -1767,6 +1795,7 @@ ews_folder_forget_all_mails (CamelEwsFolder *ews_folder)
 {
        CamelFolder *folder;
        CamelFolderChangeInfo *changes;
+       CamelFolderSummary *folder_summary;
        GPtrArray *known_uids;
        gint ii;
 
@@ -1775,25 +1804,26 @@ ews_folder_forget_all_mails (CamelEwsFolder *ews_folder)
        folder = CAMEL_FOLDER (ews_folder);
        g_return_if_fail (folder != NULL);
 
-       known_uids = camel_folder_summary_get_array (folder->summary);
+       known_uids = camel_folder_summary_get_array (camel_folder_get_folder_summary (folder));
        if (!known_uids)
                return;
 
        changes = camel_folder_change_info_new ();
+       folder_summary = camel_folder_get_folder_summary (folder);
 
-       camel_folder_summary_lock (folder->summary);
+       camel_folder_summary_lock (folder_summary);
        for (ii = 0; ii < known_uids->len; ii++) {
                const gchar *uid = g_ptr_array_index (known_uids, ii);
 
                camel_folder_change_info_remove_uid (changes, uid);
-               camel_folder_summary_remove_uid (folder->summary, uid);
+               camel_folder_summary_remove_uid (folder_summary, uid);
                ews_data_cache_remove (ews_folder->cache, "cur", uid, NULL);
        }
-       camel_folder_summary_unlock (folder->summary);
+       camel_folder_summary_unlock (folder_summary);
 
        if (camel_folder_change_info_changed (changes)) {
-               camel_folder_summary_touch (folder->summary);
-               camel_folder_summary_save_to_db (folder->summary, NULL);
+               camel_folder_summary_touch (folder_summary);
+               camel_folder_summary_save (folder_summary, NULL);
                camel_folder_changed (folder, changes);
        }
 
@@ -1807,6 +1837,7 @@ ews_refresh_info_sync (CamelFolder *folder,
                        GError **error)
 {
        CamelFolderChangeInfo *change_info;
+       CamelFolderSummary *folder_summary;
        CamelEwsFolder *ews_folder;
        CamelEwsFolderPrivate *priv;
        EEwsConnection *cnc;
@@ -1840,7 +1871,8 @@ ews_refresh_info_sync (CamelFolder *folder,
        cnc = camel_ews_store_ref_connection (ews_store);
        g_return_val_if_fail (cnc != NULL, FALSE);
 
-       camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
+       folder_summary = camel_folder_get_folder_summary (folder);
+       camel_folder_summary_prepare_fetch_all (folder_summary, NULL);
 
        change_info = camel_folder_change_info_new ();
        last_folder_update_time = g_get_monotonic_time ();
@@ -1855,7 +1887,7 @@ ews_refresh_info_sync (CamelFolder *folder,
         * Due to these reasons we just get the item ids and its type in
         * SyncFolderItem request and fetch the item using the
         * GetItem request. */
-       sync_state = camel_ews_summary_dup_sync_state ((CamelEwsSummary *) folder->summary);
+       sync_state = camel_ews_summary_dup_sync_state (CAMEL_EWS_SUMMARY (folder_summary));
        do {
                GSList *items_created = NULL, *items_updated = NULL;
                GSList *items_deleted = NULL;
@@ -1867,7 +1899,7 @@ ews_refresh_info_sync (CamelFolder *folder,
 
                if (g_error_matches (local_error, EWS_CONNECTION_ERROR, 
EWS_CONNECTION_ERROR_INVALIDSYNCSTATEDATA)) {
                        g_clear_error (&local_error);
-                       camel_ews_summary_set_sync_state ((CamelEwsSummary *) folder->summary, NULL);
+                       camel_ews_summary_set_sync_state (CAMEL_EWS_SUMMARY (folder_summary), NULL);
                        g_free (sync_state);
                        sync_state = NULL;
                        ews_folder_forget_all_mails (ews_folder);
@@ -1903,19 +1935,19 @@ ews_refresh_info_sync (CamelFolder *folder,
                if (local_error)
                        break;
 
-               total = camel_folder_summary_count (folder->summary);
-               unread = camel_folder_summary_get_unread_count (folder->summary);
+               total = camel_folder_summary_count (folder_summary);
+               unread = camel_folder_summary_get_unread_count (folder_summary);
 
                camel_ews_store_summary_set_folder_total (ews_store->summary, id, total);
                camel_ews_store_summary_set_folder_unread (ews_store->summary, id, unread);
                camel_ews_store_summary_save (ews_store->summary, NULL);
 
-               camel_ews_summary_set_sync_state ((CamelEwsSummary *) folder->summary, sync_state);
+               camel_ews_summary_set_sync_state (CAMEL_EWS_SUMMARY (folder_summary), sync_state);
 
-               camel_folder_summary_touch (folder->summary);
+               camel_folder_summary_touch (folder_summary);
 
                if (camel_folder_change_info_changed (change_info)) {
-                       camel_folder_summary_save_to_db (folder->summary, NULL);
+                       camel_folder_summary_save (folder_summary, NULL);
                        /* Notify any listeners only once per 10 seconds, as such notify can cause UI update 
*/
                        if (g_get_monotonic_time () - last_folder_update_time >= 10 * G_USEC_PER_SEC) {
                                last_folder_update_time = g_get_monotonic_time ();
@@ -1928,11 +1960,11 @@ ews_refresh_info_sync (CamelFolder *folder,
        camel_operation_pop_message (cancellable);
 
        if (camel_folder_change_info_changed (change_info)) {
-               camel_folder_summary_touch (folder->summary);
-               camel_folder_summary_save_to_db (folder->summary, NULL);
+               camel_folder_summary_touch (folder_summary);
+               camel_folder_summary_save (folder_summary, NULL);
                camel_folder_changed (folder, change_info);
        } else {
-               camel_folder_summary_save_to_db (folder->summary, NULL);
+               camel_folder_summary_save (folder_summary, NULL);
        }
 
        camel_folder_change_info_free (change_info);
@@ -2008,7 +2040,7 @@ ews_append_message_sync (CamelFolder *folder,
        e_ews_folder_id_free (fid);
        g_free (folder_id);
 
-       if (camel_ews_summary_add_message (folder->summary, itemid, changekey, info, message)) {
+       if (camel_ews_summary_add_message (camel_folder_get_folder_summary (folder), itemid, changekey, info, 
message)) {
                CamelFolderChangeInfo *changes;
 
                changes = camel_folder_change_info_new ();
@@ -2063,11 +2095,11 @@ ews_transfer_messages_to_sync (CamelFolder *source,
 
        for (i = 0; success && i < uids->len; i++) {
                guint32 flags_set;
-               CamelEwsMessageInfo *mi;
+               CamelMessageInfo *mi;
 
                ids = g_slist_prepend (ids, (gchar *) uids->pdata[i]);
 
-               mi = (gpointer) camel_folder_summary_get (source->summary, uids->pdata[i]);
+               mi = camel_folder_summary_get (camel_folder_get_folder_summary (source), uids->pdata[i]);
                if (!mi)
                        continue;
 
@@ -2079,12 +2111,12 @@ ews_transfer_messages_to_sync (CamelFolder *source,
                        mi_list = g_slist_prepend (mi_list, mi);
                        mi_list_len++;
                } else {
-                       camel_message_info_unref (mi);
+                       g_clear_object (&mi);
                }
 
                if (mi_list_len == EWS_MAX_FETCH_COUNT) {
                        success = ews_save_flags (source, mi_list, cancellable, &local_error);
-                       g_slist_free_full (mi_list, camel_message_info_unref);
+                       g_slist_free_full (mi_list, g_object_unref);
                        mi_list = NULL;
                        mi_list_len = 0;
                }
@@ -2092,7 +2124,7 @@ ews_transfer_messages_to_sync (CamelFolder *source,
 
        if (mi_list != NULL && success)
                success = ews_save_flags (source, mi_list, cancellable, &local_error);
-       g_slist_free_full (mi_list, camel_message_info_unref);
+       g_slist_free_full (mi_list, g_object_unref);
 
        ids = g_slist_reverse (ids);
 
@@ -2141,7 +2173,7 @@ ews_transfer_messages_to_sync (CamelFolder *source,
                        camel_data_wrapper_write_to_stream_sync (
                                CAMEL_DATA_WRAPPER (message), stream, cancellable, NULL);
 
-                       info = camel_folder_summary_get (source->summary, uids->pdata[i]);
+                       info = camel_folder_summary_get (camel_folder_get_folder_summary (source), 
uids->pdata[i]);
                        if (info == NULL) {
                                g_object_unref (stream);
                                g_object_unref (message);
@@ -2149,13 +2181,13 @@ ews_transfer_messages_to_sync (CamelFolder *source,
                                continue;
                        }
 
-                       clone = camel_message_info_clone (info);
+                       clone = camel_message_info_clone (info, NULL);
 
-                       if (camel_ews_summary_add_message (destination->summary, id->id, id->change_key, 
clone, message))
+                       if (camel_ews_summary_add_message (camel_folder_get_folder_summary (destination), 
id->id, id->change_key, clone, message))
                                camel_folder_change_info_add_uid (changes, id->id);
 
-                       camel_message_info_unref (clone);
-                       camel_message_info_unref (info);
+                       g_clear_object (&clone);
+                       g_clear_object (&info);
                        g_object_unref (stream);
                        g_object_unref (message);
                }
@@ -2171,12 +2203,12 @@ ews_transfer_messages_to_sync (CamelFolder *source,
                        for (l = processed_items; l; l = g_slist_next (l)) {
                                const gchar *uid = l->data;
 
-                               camel_folder_summary_remove_uid (source->summary, uid);
+                               camel_folder_summary_remove_uid (camel_folder_get_folder_summary (source), 
uid);
                                camel_folder_change_info_remove_uid (changes, uid);
                                ews_data_cache_remove (CAMEL_EWS_FOLDER (source)->cache, "cur", uid, NULL);
                        }
                        if (camel_folder_change_info_changed (changes)) {
-                               camel_folder_summary_touch (source->summary);
+                               camel_folder_summary_touch (camel_folder_get_folder_summary (source));
                                camel_folder_changed (source, changes);
                        }
 
@@ -2213,7 +2245,7 @@ ews_prepare_content_refresh (CamelFolder *folder)
 {
        g_return_if_fail (CAMEL_IS_EWS_FOLDER (folder));
 
-       camel_ews_summary_set_sync_state (CAMEL_EWS_SUMMARY (folder->summary), NULL);
+       camel_ews_summary_set_sync_state (CAMEL_EWS_SUMMARY (camel_folder_get_folder_summary (folder)), NULL);
 }
 
 static gboolean
@@ -2242,22 +2274,24 @@ ews_delete_messages_from_folder (CamelFolder *folder,
                                 const GSList *deleted_items)
 {
        CamelFolderChangeInfo *changes;
+       CamelFolderSummary *folder_summary;
        const GSList *iter;
 
        changes = camel_folder_change_info_new ();
+       folder_summary = camel_folder_get_folder_summary (folder);
 
        for (iter = deleted_items; iter != NULL; iter = iter->next) {
                const gchar *uid = iter->data;
 
-               camel_folder_summary_lock (folder->summary);
+               camel_folder_summary_lock (folder_summary);
                camel_folder_change_info_remove_uid (changes, uid);
-               camel_folder_summary_remove_uid (folder->summary, uid);
+               camel_folder_summary_remove_uid (folder_summary, uid);
                ews_data_cache_remove (CAMEL_EWS_FOLDER (folder)->cache, "cur", uid, NULL);
-               camel_folder_summary_unlock (folder->summary);
+               camel_folder_summary_unlock (folder_summary);
        }
 
        if (camel_folder_change_info_changed (changes)) {
-               camel_folder_summary_touch (folder->summary);
+               camel_folder_summary_touch (folder_summary);
                camel_folder_changed (folder, changes);
        }
 
@@ -2408,7 +2442,6 @@ ews_expunge_sync (CamelFolder *folder,
                   GCancellable *cancellable,
                   GError **error)
 {
-       CamelEwsMessageInfo *ews_info;
        CamelStore *parent_store;
        GSList *deleted_items = NULL;
        gint i;
@@ -2430,8 +2463,8 @@ ews_expunge_sync (CamelFolder *folder,
         */
        is_trash = ews_folder_is_of_type (folder, CAMEL_FOLDER_TYPE_TRASH);
 
-       camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
-       known_uids = camel_folder_summary_get_array (folder->summary);
+       camel_folder_summary_prepare_fetch_all (camel_folder_get_folder_summary (folder), NULL);
+       known_uids = camel_folder_summary_get_array (camel_folder_get_folder_summary (folder));
 
        if (known_uids == NULL)
                return TRUE;
@@ -2458,13 +2491,12 @@ ews_expunge_sync (CamelFolder *folder,
                CamelMessageInfo *info;
                const gchar *uid = g_ptr_array_index (known_uids, i);
 
-               info = camel_folder_summary_get (folder->summary, uid);
-               ews_info = (CamelEwsMessageInfo *) info;
+               info = camel_folder_summary_get (camel_folder_get_folder_summary (folder), uid);
 
-               if (ews_info && (is_trash || (ews_info->info.flags & CAMEL_MESSAGE_DELETED) != 0))
+               if (info && (is_trash || (camel_message_info_get_flags (info) & CAMEL_MESSAGE_DELETED) != 0))
                        deleted_items = g_slist_prepend (deleted_items, (gpointer) camel_pstring_strdup 
(uid));
 
-               camel_message_info_unref (info);
+               g_clear_object (&info);
        }
 
        if (is_trash && !delete_items_from_server) {
@@ -2497,12 +2529,12 @@ ews_folder_dispose (GObject *object)
        CamelEwsFolder *ews_folder = CAMEL_EWS_FOLDER (object);
        CamelFolderSummary *summary;
 
-       summary = CAMEL_FOLDER (ews_folder)->summary;
+       summary = camel_folder_get_folder_summary (CAMEL_FOLDER (ews_folder));
        if (summary) {
-               g_signal_handlers_disconnect_by_func (CAMEL_FOLDER (ews_folder)->summary, G_CALLBACK 
(ews_folder_count_notify_cb), ews_folder);
+               g_signal_handlers_disconnect_by_func (summary, G_CALLBACK (ews_folder_count_notify_cb), 
ews_folder);
 
                /* save changes, if there are any unsaved */
-               camel_folder_summary_save_to_db (summary, NULL);
+               camel_folder_summary_save (summary, NULL);
        }
 
        if (ews_folder->cache != NULL) {
@@ -2589,6 +2621,7 @@ camel_ews_folder_class_init (CamelEwsFolderClass *class)
        object_class->constructed = ews_folder_constructed;
 
        folder_class = CAMEL_FOLDER_CLASS (class);
+       folder_class->get_permanent_flags = ews_folder_get_permanent_flags;
        folder_class->get_message_sync = ews_folder_get_message_sync;
        folder_class->get_message_cached = ews_folder_get_message_cached;
        folder_class->search_by_expression = ews_folder_search_by_expression;
@@ -2612,11 +2645,7 @@ camel_ews_folder_init (CamelEwsFolder *ews_folder)
 
        ews_folder->priv = CAMEL_EWS_FOLDER_GET_PRIVATE (ews_folder);
 
-       folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_DELETED |
-               CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN |
-               CAMEL_MESSAGE_FORWARDED | CAMEL_MESSAGE_USER;
-
-       folder->folder_flags = CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY;
+       camel_folder_set_flags (folder, CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY);
 
        g_mutex_init (&ews_folder->priv->search_lock);
        g_mutex_init (&ews_folder->priv->state_lock);
diff --git a/src/camel/camel-ews-message-info.c b/src/camel/camel-ews-message-info.c
new file mode 100644
index 0000000..a4a9d00
--- /dev/null
+++ b/src/camel/camel-ews-message-info.c
@@ -0,0 +1,431 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "camel/camel.h"
+#include "camel-ews-summary.h"
+
+#include "camel-ews-message-info.h"
+
+struct _CamelEwsMessageInfoPrivate {
+       guint32 server_flags;
+       gint32 item_type;
+       gchar *change_key;
+};
+
+enum {
+       PROP_0,
+       PROP_SERVER_FLAGS,
+       PROP_ITEM_TYPE,
+       PROP_CHANGE_KEY,
+};
+
+G_DEFINE_TYPE (CamelEwsMessageInfo, camel_ews_message_info, CAMEL_TYPE_MESSAGE_INFO_BASE)
+
+static CamelMessageInfo *
+ews_message_info_clone (const CamelMessageInfo *mi,
+                       CamelFolderSummary *assign_summary)
+{
+       CamelMessageInfo *result;
+
+       g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (mi), NULL);
+
+       result = CAMEL_MESSAGE_INFO_CLASS (camel_ews_message_info_parent_class)->clone (mi, assign_summary);
+       if (!result)
+               return NULL;
+
+       if (CAMEL_IS_EWS_MESSAGE_INFO (result)) {
+               CamelEwsMessageInfo *emi, *emi_result;
+
+               emi = CAMEL_EWS_MESSAGE_INFO (mi);
+               emi_result = CAMEL_EWS_MESSAGE_INFO (result);
+
+               camel_ews_message_info_set_server_flags (emi_result, camel_ews_message_info_get_server_flags 
(emi));
+               camel_ews_message_info_set_item_type (emi_result, camel_ews_message_info_get_item_type (emi));
+               camel_ews_message_info_take_change_key (emi_result, camel_ews_message_info_dup_change_key 
(emi));
+       }
+
+       return result;
+}
+
+static gboolean
+ews_message_info_load (CamelMessageInfo *mi,
+                      const CamelMIRecord *record,
+                      /* const */ gchar **bdata_ptr)
+{
+       CamelEwsMessageInfo *emi;
+
+       g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (mi), FALSE);
+       g_return_val_if_fail (record != NULL, FALSE);
+       g_return_val_if_fail (bdata_ptr != NULL, FALSE);
+
+       if (!CAMEL_MESSAGE_INFO_CLASS (camel_ews_message_info_parent_class)->load ||
+           !CAMEL_MESSAGE_INFO_CLASS (camel_ews_message_info_parent_class)->load (mi, record, bdata_ptr))
+               return FALSE;
+
+       emi = CAMEL_EWS_MESSAGE_INFO (mi);
+
+       if (*bdata_ptr) {
+               gchar **values;
+
+               values = g_strsplit (*bdata_ptr, " ", -1);
+
+               if (values && values[0] && values[1] && values[2]) {
+                       camel_ews_message_info_set_server_flags (emi, g_ascii_strtoll (values[0], NULL, 10));
+                       camel_ews_message_info_set_item_type (emi, g_ascii_strtoll (values[1], NULL, 10));
+                       camel_ews_message_info_set_change_key (emi, values[2]);
+               }
+
+               g_strfreev (values);
+       }
+
+       return TRUE;
+}
+
+static gboolean
+ews_message_info_save (const CamelMessageInfo *mi,
+                      CamelMIRecord *record,
+                      GString *bdata_str)
+{
+       CamelEwsMessageInfo *emi;
+
+       g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (mi), FALSE);
+       g_return_val_if_fail (record != NULL, FALSE);
+       g_return_val_if_fail (bdata_str != NULL, FALSE);
+
+       if (!CAMEL_MESSAGE_INFO_CLASS (camel_ews_message_info_parent_class)->save ||
+           !CAMEL_MESSAGE_INFO_CLASS (camel_ews_message_info_parent_class)->save (mi, record, bdata_str))
+               return FALSE;
+
+       emi = CAMEL_EWS_MESSAGE_INFO (mi);
+
+       g_string_append_printf (bdata_str, "%u %d %s",
+               camel_ews_message_info_get_server_flags (emi),
+               camel_ews_message_info_get_item_type (emi),
+               camel_ews_message_info_get_change_key (emi));
+
+       return TRUE;
+}
+
+static void
+ews_message_info_set_property (GObject *object,
+                              guint property_id,
+                              const GValue *value,
+                              GParamSpec *pspec)
+{
+       CamelEwsMessageInfo *emi = CAMEL_EWS_MESSAGE_INFO (object);
+
+       switch (property_id) {
+       case PROP_SERVER_FLAGS:
+               camel_ews_message_info_set_server_flags (emi, g_value_get_uint (value));
+               return;
+
+       case PROP_ITEM_TYPE:
+               camel_ews_message_info_set_item_type (emi, g_value_get_int (value));
+               return;
+
+       case PROP_CHANGE_KEY:
+               camel_ews_message_info_set_change_key (emi, g_value_get_string (value));
+               return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+ews_message_info_get_property (GObject *object,
+                              guint property_id,
+                              GValue *value,
+                              GParamSpec *pspec)
+{
+       CamelEwsMessageInfo *emi = CAMEL_EWS_MESSAGE_INFO (object);
+
+       switch (property_id) {
+
+       case PROP_SERVER_FLAGS:
+               g_value_set_uint (value, camel_ews_message_info_get_server_flags (emi));
+               return;
+
+       case PROP_ITEM_TYPE:
+               g_value_set_int (value, camel_ews_message_info_get_item_type (emi));
+               return;
+
+       case PROP_CHANGE_KEY:
+               g_value_take_string (value, camel_ews_message_info_dup_change_key (emi));
+               return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+ews_message_info_dispose (GObject *object)
+{
+       CamelEwsMessageInfo *emi = CAMEL_EWS_MESSAGE_INFO (object);
+
+       g_free (emi->priv->change_key);
+       emi->priv->change_key = NULL;
+
+       /* Chain up to parent's method. */
+       G_OBJECT_CLASS (camel_ews_message_info_parent_class)->dispose (object);
+}
+
+static void
+camel_ews_message_info_class_init (CamelEwsMessageInfoClass *class)
+{
+       CamelMessageInfoClass *mi_class;
+       GObjectClass *object_class;
+
+       g_type_class_add_private (class, sizeof (CamelEwsMessageInfoPrivate));
+
+       mi_class = CAMEL_MESSAGE_INFO_CLASS (class);
+       mi_class->clone = ews_message_info_clone;
+       mi_class->load = ews_message_info_load;
+       mi_class->save = ews_message_info_save;
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->set_property = ews_message_info_set_property;
+       object_class->get_property = ews_message_info_get_property;
+       object_class->dispose = ews_message_info_dispose;
+
+       /**
+        * CamelEwsMessageInfo:server-flags
+        *
+        * Last known server flags of the message.
+        *
+        * Since: 3.24
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_SERVER_FLAGS,
+               g_param_spec_uint (
+                       "server-flags",
+                       "Server Flags",
+                       NULL,
+                       0, G_MAXUINT32, 0,
+                       G_PARAM_READWRITE));
+
+       /**
+        * CamelEwsMessageInfo:item-type
+        *
+        * Item type of the message.
+        *
+        * Since: 3.24
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_ITEM_TYPE,
+               g_param_spec_int (
+                       "item-type",
+                       "Item Type",
+                       NULL,
+                       0, G_MAXINT32, 0,
+                       G_PARAM_READWRITE));
+
+       /**
+        * CamelEwsMessageInfo:change-key
+        *
+        * Change key of the message on the server.
+        *
+        * Since: 3.24
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_CHANGE_KEY,
+               g_param_spec_string (
+                       "change-key",
+                       "Change Key",
+                       NULL,
+                       NULL,
+                       G_PARAM_READWRITE));
+}
+
+static void
+camel_ews_message_info_init (CamelEwsMessageInfo *emi)
+{
+       emi->priv = G_TYPE_INSTANCE_GET_PRIVATE (emi, CAMEL_TYPE_EWS_MESSAGE_INFO, 
CamelEwsMessageInfoPrivate);
+}
+
+guint32
+camel_ews_message_info_get_server_flags (const CamelEwsMessageInfo *emi)
+{
+       CamelMessageInfo *mi;
+       guint32 result;
+
+       g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), 0);
+
+       mi = CAMEL_MESSAGE_INFO (emi);
+
+       camel_message_info_property_lock (mi);
+       result = emi->priv->server_flags;
+       camel_message_info_property_unlock (mi);
+
+       return result;
+}
+
+gboolean
+camel_ews_message_info_set_server_flags (CamelEwsMessageInfo *emi,
+                                        guint32 server_flags)
+{
+       CamelMessageInfo *mi;
+       gboolean changed;
+
+       g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), FALSE);
+
+       mi = CAMEL_MESSAGE_INFO (emi);
+
+       camel_message_info_property_lock (mi);
+
+       changed = emi->priv->server_flags != server_flags;
+
+       if (changed)
+               emi->priv->server_flags = server_flags;
+
+       camel_message_info_property_unlock (mi);
+
+       if (changed && !camel_message_info_get_abort_notifications (mi)) {
+               g_object_notify (G_OBJECT (emi), "server-flags");
+               camel_message_info_set_dirty (mi, TRUE);
+       }
+
+       return changed;
+}
+
+gint32
+camel_ews_message_info_get_item_type (const CamelEwsMessageInfo *emi)
+{
+       CamelMessageInfo *mi;
+       gint32 result;
+
+       g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), 0);
+
+       mi = CAMEL_MESSAGE_INFO (emi);
+
+       camel_message_info_property_lock (mi);
+       result = emi->priv->item_type;
+       camel_message_info_property_unlock (mi);
+
+       return result;
+}
+
+gboolean
+camel_ews_message_info_set_item_type (CamelEwsMessageInfo *emi,
+                                     gint32 item_type)
+{
+       CamelMessageInfo *mi;
+       gboolean changed;
+
+       g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), FALSE);
+
+       mi = CAMEL_MESSAGE_INFO (emi);
+
+       camel_message_info_property_lock (mi);
+
+       changed = emi->priv->item_type != item_type;
+
+       if (changed)
+               emi->priv->item_type = item_type;
+
+       camel_message_info_property_unlock (mi);
+
+       if (changed && !camel_message_info_get_abort_notifications (mi)) {
+               g_object_notify (G_OBJECT (emi), "item-type");
+               camel_message_info_set_dirty (mi, TRUE);
+       }
+
+       return changed;
+}
+
+const gchar *
+camel_ews_message_info_get_change_key (const CamelEwsMessageInfo *emi)
+{
+       CamelMessageInfo *mi;
+       const gchar *result;
+
+       g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), NULL);
+
+       mi = CAMEL_MESSAGE_INFO (emi);
+
+       camel_message_info_property_lock (mi);
+       result = emi->priv->change_key;
+       camel_message_info_property_unlock (mi);
+
+       return result;
+}
+
+gchar *
+camel_ews_message_info_dup_change_key (const CamelEwsMessageInfo *emi)
+{
+       CamelMessageInfo *mi;
+       gchar *result;
+
+       g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), NULL);
+
+       mi = CAMEL_MESSAGE_INFO (emi);
+
+       camel_message_info_property_lock (mi);
+       result = g_strdup (emi->priv->change_key);
+       camel_message_info_property_unlock (mi);
+
+       return result;
+}
+
+gboolean
+camel_ews_message_info_set_change_key (CamelEwsMessageInfo *emi,
+                                      const gchar *change_key)
+{
+       g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), FALSE);
+
+       return camel_ews_message_info_take_change_key (emi, g_strdup (change_key));
+}
+
+gboolean
+camel_ews_message_info_take_change_key (CamelEwsMessageInfo *emi,
+                                       gchar *change_key)
+{
+       CamelMessageInfo *mi;
+       gboolean changed;
+
+       g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (emi), FALSE);
+
+       mi = CAMEL_MESSAGE_INFO (emi);
+
+       camel_message_info_property_lock (mi);
+
+       changed = g_strcmp0 (emi->priv->change_key, change_key) != 0;
+
+       if (changed) {
+               g_free (emi->priv->change_key);
+               emi->priv->change_key = change_key;
+       } else if (change_key != emi->priv->change_key) {
+               g_free (change_key);
+       }
+
+       camel_message_info_property_unlock (mi);
+
+       if (changed && !camel_message_info_get_abort_notifications (mi)) {
+               g_object_notify (G_OBJECT (emi), "change-key");
+               camel_message_info_set_dirty (mi, TRUE);
+       }
+
+       return changed;
+}
diff --git a/src/camel/camel-ews-message-info.h b/src/camel/camel-ews-message-info.h
new file mode 100644
index 0000000..4687d64
--- /dev/null
+++ b/src/camel/camel-ews-message-info.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CAMEL_EWS_MESSAGE_INFO_H
+#define CAMEL_EWS_MESSAGE_INFO_H
+
+#include <glib-object.h>
+
+#include <camel/camel.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_EWS_MESSAGE_INFO \
+       (camel_ews_message_info_get_type ())
+#define CAMEL_EWS_MESSAGE_INFO(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), CAMEL_TYPE_EWS_MESSAGE_INFO, CamelEwsMessageInfo))
+#define CAMEL_EWS_MESSAGE_INFO_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), CAMEL_TYPE_EWS_MESSAGE_INFO, CamelEwsMessageInfoClass))
+#define CAMEL_IS_EWS_MESSAGE_INFO(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), CAMEL_TYPE_EWS_MESSAGE_INFO))
+#define CAMEL_IS_EWS_MESSAGE_INFO_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), CAMEL_TYPE_EWS_MESSAGE_INFO))
+#define CAMEL_EWS_MESSAGE_INFO_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), CAMEL_TYPE_EWS_MESSAGE_INFO, CamelEwsMessageInfoClass))
+
+G_BEGIN_DECLS
+
+/* extra summary flags*/
+enum {
+       CAMEL_EWS_MESSAGE_MSGFLAG_RN_PENDING = CAMEL_MESSAGE_FOLDER_FLAGGED << 1
+};
+
+typedef struct _CamelEwsMessageInfo CamelEwsMessageInfo;
+typedef struct _CamelEwsMessageInfoClass CamelEwsMessageInfoClass;
+typedef struct _CamelEwsMessageInfoPrivate CamelEwsMessageInfoPrivate;
+
+struct _CamelEwsMessageInfo {
+       CamelMessageInfoBase parent;
+       CamelEwsMessageInfoPrivate *priv;
+};
+
+struct _CamelEwsMessageInfoClass {
+       CamelMessageInfoBaseClass parent_class;
+};
+
+GType          camel_ews_message_info_get_type (void);
+
+guint32                camel_ews_message_info_get_server_flags (const CamelEwsMessageInfo *emi);
+gboolean       camel_ews_message_info_set_server_flags (CamelEwsMessageInfo *emi,
+                                                        guint32 server_flags);
+gint32         camel_ews_message_info_get_item_type    (const CamelEwsMessageInfo *emi);
+gboolean       camel_ews_message_info_set_item_type    (CamelEwsMessageInfo *emi,
+                                                        gint32 item_type);
+const gchar *  camel_ews_message_info_get_change_key   (const CamelEwsMessageInfo *emi);
+gchar *                camel_ews_message_info_dup_change_key   (const CamelEwsMessageInfo *emi);
+gboolean       camel_ews_message_info_set_change_key   (CamelEwsMessageInfo *emi,
+                                                        const gchar *change_key);
+gboolean       camel_ews_message_info_take_change_key  (CamelEwsMessageInfo *emi,
+                                                        gchar *change_key);
+
+G_END_DECLS
+
+#endif /* CAMEL_EWS_MESSAGE_INFO_H */
diff --git a/src/camel/camel-ews-store.c b/src/camel/camel-ews-store.c
index ced0aa4..f4b38f5 100644
--- a/src/camel/camel-ews-store.c
+++ b/src/camel/camel-ews-store.c
@@ -277,10 +277,10 @@ ews_store_initable_init (GInitable *initable,
        store = CAMEL_STORE (initable);
        service = CAMEL_SERVICE (initable);
 
-       store->flags |= CAMEL_STORE_USE_CACHE_DIR | CAMEL_STORE_SUPPORTS_INITIAL_SETUP;
+       camel_store_set_flags (store, camel_store_get_flags (store) | CAMEL_STORE_USE_CACHE_DIR | 
CAMEL_STORE_SUPPORTS_INITIAL_SETUP);
        ews_migrate_to_user_cache_dir (service);
 
-       store->flags |= CAMEL_STORE_CAN_DELETE_FOLDERS_AT_ONCE;
+       camel_store_set_flags (store, camel_store_get_flags (store) | CAMEL_STORE_CAN_DELETE_FOLDERS_AT_ONCE);
 
        /* Chain up to parent interface's init() method. */
        if (!parent_initable_interface->init (initable, cancellable, error))
@@ -313,13 +313,17 @@ ews_store_construct (CamelService *service,
 {
        CamelEwsStore *ews_store;
        gchar *summary_file, *session_storage_path;
+       guint32 store_flags;
 
        ews_store = (CamelEwsStore *) service;
 
+       store_flags = camel_store_get_flags (CAMEL_STORE (ews_store));
+
        /* Disable virtual trash and junk folders. Exchange has real
         * folders for that */
-       ((CamelStore *) ews_store)->flags &= ~(CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK);
-       ((CamelStore *) ews_store)->flags |= CAMEL_STORE_REAL_JUNK_FOLDER;
+       store_flags &= ~(CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK);
+       store_flags |= CAMEL_STORE_REAL_JUNK_FOLDER;
+       camel_store_set_flags (CAMEL_STORE (ews_store), store_flags);
 
        /*storage path*/
        session_storage_path = g_strdup (camel_service_get_user_cache_dir (service));
@@ -3003,12 +3007,12 @@ ews_get_trash_folder_sync (CamelStore *store,
                   are moved to the Deleted Items folder first, thus in case of the trash
                   folder instance being used to expunge messages will contain all of them.
                */
-               folders = camel_object_bag_list (store->folders);
+               folders = camel_store_dup_opened_folders (store);
                for (ii = 0; ii < folders->len; ii++) {
                        CamelFolder *secfolder = folders->pdata[ii];
 
                        if (secfolder != folder && can)
-                           can = camel_folder_synchronize_sync (secfolder, FALSE, cancellable, NULL);
+                               can = camel_folder_synchronize_sync (secfolder, FALSE, cancellable, NULL);
 
                        g_object_unref (secfolder);
                }
diff --git a/src/camel/camel-ews-summary.c b/src/camel/camel-ews-summary.c
index 9df6ca8..b79487d 100644
--- a/src/camel/camel-ews-summary.c
+++ b/src/camel/camel-ews-summary.c
@@ -42,14 +42,8 @@
 #define d(x)
 
 /*Prototypes*/
-static gboolean ews_info_set_flags (CamelMessageInfo *info, guint32 flags, guint32 set);
-
-static gboolean summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
-static CamelFIRecord * summary_header_to_db (CamelFolderSummary *s, GError **error);
-static CamelMIRecord * message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info);
-static CamelMessageInfo * message_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir);
-static gboolean content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelMIRecord 
*mir);
-static CamelMessageContentInfo * content_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir);
+static gboolean summary_header_load (CamelFolderSummary *s, CamelFIRecord *mir);
+static CamelFIRecord * summary_header_save (CamelFolderSummary *s, GError **error);
 
 /*End of Prototypes*/
 
@@ -61,34 +55,6 @@ struct _CamelEwsSummaryPrivate {
 
 G_DEFINE_TYPE (CamelEwsSummary, camel_ews_summary, CAMEL_TYPE_FOLDER_SUMMARY)
 
-static CamelMessageInfo *
-ews_message_info_clone (CamelFolderSummary *s,
-                        const CamelMessageInfo *mi)
-{
-       CamelEwsMessageInfo *to;
-       const CamelEwsMessageInfo *from = (const CamelEwsMessageInfo *) mi;
-
-       to = (CamelEwsMessageInfo *) CAMEL_FOLDER_SUMMARY_CLASS 
(camel_ews_summary_parent_class)->message_info_clone (s, mi);
-       to->server_flags = from->server_flags;
-       to->item_type = from->item_type;
-       to->change_key = g_strdup (from->change_key);
-
-       /* FIXME: parent clone should do this */
-       to->info.content = camel_folder_summary_content_info_new (s);
-
-       return (CamelMessageInfo *) to;
-}
-
-static void
-ews_message_info_free (CamelFolderSummary *s,
-                       CamelMessageInfo *mi)
-{
-       CamelEwsMessageInfo *emi = (gpointer) mi;
-
-       g_free (emi->change_key);
-       CAMEL_FOLDER_SUMMARY_CLASS (camel_ews_summary_parent_class)->message_info_free (s, mi);
-}
-
 static void
 ews_summary_finalize (GObject *object)
 {
@@ -113,17 +79,9 @@ camel_ews_summary_class_init (CamelEwsSummaryClass *class)
        object_class->finalize = ews_summary_finalize;
 
        folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
-       folder_summary_class->message_info_size = sizeof (CamelEwsMessageInfo);
-       folder_summary_class->content_info_size = sizeof (CamelEwsMessageContentInfo);
-       folder_summary_class->message_info_clone = ews_message_info_clone;
-       folder_summary_class->message_info_free = ews_message_info_free;
-       folder_summary_class->info_set_flags = ews_info_set_flags;
-       folder_summary_class->summary_header_to_db = summary_header_to_db;
-       folder_summary_class->summary_header_from_db = summary_header_from_db;
-       folder_summary_class->message_info_to_db = message_info_to_db;
-       folder_summary_class->message_info_from_db = message_info_from_db;
-       folder_summary_class->content_info_to_db = content_info_to_db;
-       folder_summary_class->content_info_from_db = content_info_from_db;
+       folder_summary_class->message_info_type = CAMEL_TYPE_EWS_MESSAGE_INFO;
+       folder_summary_class->summary_header_save = summary_header_save;
+       folder_summary_class->summary_header_load = summary_header_load;
 }
 
 static void
@@ -148,21 +106,20 @@ camel_ews_summary_new (struct _CamelFolder *folder)
        CamelFolderSummary *summary;
 
        summary = g_object_new (CAMEL_TYPE_EWS_SUMMARY, "folder", folder, NULL);
-       camel_folder_summary_set_build_content (summary, TRUE);
 
-       camel_folder_summary_load_from_db (summary, NULL);
+       camel_folder_summary_load (summary, NULL);
 
        return summary;
 }
 
 static gboolean
-summary_header_from_db (CamelFolderSummary *s,
-                        CamelFIRecord *mir)
+summary_header_load (CamelFolderSummary *s,
+                    CamelFIRecord *mir)
 {
        CamelEwsSummary *ews_summary = CAMEL_EWS_SUMMARY (s);
        gchar *part;
 
-       if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_ews_summary_parent_class)->summary_header_from_db (s, mir))
+       if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_ews_summary_parent_class)->summary_header_load (s, mir))
                return FALSE;
 
        part = mir->bdata;
@@ -178,14 +135,14 @@ summary_header_from_db (CamelFolderSummary *s,
 }
 
 static CamelFIRecord *
-summary_header_to_db (CamelFolderSummary *s,
-                      GError **error)
+summary_header_save (CamelFolderSummary *s,
+                    GError **error)
 {
        CamelEwsSummary *ews_summary = CAMEL_EWS_SUMMARY (s);
        struct _CamelFIRecord *fir;
        gchar *sync_state;
 
-       fir = CAMEL_FOLDER_SUMMARY_CLASS (camel_ews_summary_parent_class)->summary_header_to_db (s, error);
+       fir = CAMEL_FOLDER_SUMMARY_CLASS (camel_ews_summary_parent_class)->summary_header_save (s, error);
        if (!fir)
                return NULL;
 
@@ -199,95 +156,6 @@ summary_header_to_db (CamelFolderSummary *s,
 
 }
 
-static CamelMessageInfo *
-message_info_from_db (CamelFolderSummary *s,
-                      CamelMIRecord *mir)
-{
-       CamelMessageInfo *info;
-       CamelEwsMessageInfo *iinfo;
-
-       info = CAMEL_FOLDER_SUMMARY_CLASS (camel_ews_summary_parent_class)->message_info_from_db (s, mir);
-       if (info) {
-               gchar *part = mir->bdata;
-               gchar **values;
-
-               iinfo = (CamelEwsMessageInfo *) info;
-               if (part) {
-                       values = g_strsplit (part, " ", -1);
-
-                       if (values && values[0] && values[1] && values[2]) {
-                               iinfo->server_flags = g_ascii_strtoll (values[0], NULL, 10);
-                               iinfo->item_type = g_ascii_strtoll (values[1], NULL, 10);
-                               iinfo->change_key = g_strdup (values[2]);
-                       }
-
-                       g_strfreev (values);
-               }
-       }
-
-       return info;
-}
-
-static CamelMIRecord *
-message_info_to_db (CamelFolderSummary *s,
-                    CamelMessageInfo *info)
-{
-       CamelEwsMessageInfo *iinfo = (CamelEwsMessageInfo *) info;
-       struct _CamelMIRecord *mir;
-
-       mir = CAMEL_FOLDER_SUMMARY_CLASS (camel_ews_summary_parent_class)->message_info_to_db (s, info);
-       if (mir)
-               mir->bdata = g_strdup_printf ("%u %d %s", iinfo->server_flags, iinfo->item_type, 
iinfo->change_key);
-
-       return mir;
-}
-
-static CamelMessageContentInfo *
-content_info_from_db (CamelFolderSummary *s,
-                      CamelMIRecord *mir)
-{
-       gchar *part = mir->cinfo;
-       guint32 type = 0;
-
-       if (part) {
-               if (*part == ' ')
-                       part++;
-               if (part) {
-                       EXTRACT_FIRST_DIGIT (type);
-               }
-       }
-       mir->cinfo = part;
-       if (type)
-               return CAMEL_FOLDER_SUMMARY_CLASS (camel_ews_summary_parent_class)->content_info_from_db (s, 
mir);
-       else
-               return camel_folder_summary_content_info_new (s);
-}
-
-static gboolean
-content_info_to_db (CamelFolderSummary *s,
-                    CamelMessageContentInfo *info,
-                    CamelMIRecord *mir)
-{
-
-       if (info->type) {
-               g_free (mir->cinfo);
-               mir->cinfo = g_strdup ("1");
-               return CAMEL_FOLDER_SUMMARY_CLASS (camel_ews_summary_parent_class)->content_info_to_db (s, 
info, mir);
-       } else {
-               g_free (mir->cinfo);
-               mir->cinfo = g_strdup ("0");
-               return TRUE;
-       }
-}
-
-static gboolean
-ews_info_set_flags (CamelMessageInfo *info,
-                    guint32 flags,
-                    guint32 set)
-{
-       return CAMEL_FOLDER_SUMMARY_CLASS (camel_ews_summary_parent_class)->info_set_flags (info, flags, set);
-}
-
 gboolean
 camel_ews_summary_add_message (CamelFolderSummary *summary,
                                const gchar *uid,
@@ -295,67 +163,55 @@ camel_ews_summary_add_message (CamelFolderSummary *summary,
                               CamelMessageInfo *info,
                                CamelMimeMessage *message)
 {
-       CamelEwsMessageInfo *mi;
-       const CamelFlag *flag;
-       const CamelTag *tag;
+       CamelMessageInfo *mi;
 
        g_return_val_if_fail (uid != NULL, FALSE);
        g_return_val_if_fail (info != NULL, FALSE);
        g_return_val_if_fail (message != NULL, FALSE);
 
        /* Create summary entry */
-       mi = (CamelEwsMessageInfo *) camel_folder_summary_info_new_from_message (summary, message, NULL);
+       mi = camel_folder_summary_info_new_from_message (summary, message);
        g_return_val_if_fail (mi != NULL, FALSE);
 
-       /* Set the change_key */
-       mi->change_key = g_strdup (change_key);
-
-       /* Copy flags 'n' tags */
-       mi->info.flags = camel_message_info_get_flags (info);
-
-       flag = camel_message_info_get_user_flags (info);
-       while (flag) {
-               camel_message_info_set_user_flag ((CamelMessageInfo *) mi, flag->name, TRUE);
-               flag = flag->next;
-       }
+       camel_message_info_set_abort_notifications (mi, TRUE);
 
-       tag = camel_message_info_get_user_tags (info);
-       while (tag) {
-               /* coverity[unchecked_value] */
-               camel_message_info_set_user_tag ((CamelMessageInfo *) mi, tag->name, tag->value);
-               tag = tag->next;
-       }
+       camel_ews_message_info_set_change_key (CAMEL_EWS_MESSAGE_INFO (mi), change_key);
+       camel_message_info_set_flags (mi, ~0, camel_message_info_get_flags (info));
+       camel_message_info_take_user_flags (mi, camel_message_info_dup_user_flags (info));
+       camel_message_info_take_user_tags (mi, camel_message_info_dup_user_tags (info));
+       camel_message_info_set_size (mi, camel_message_info_get_size (info));
+       camel_message_info_set_uid (mi, uid);
 
-       mi->info.size = camel_message_info_get_size (info);
-       mi->info.uid = camel_pstring_strdup (uid);
+       camel_message_info_set_abort_notifications (mi, FALSE);
 
-       camel_folder_summary_add (summary, (CamelMessageInfo *) mi);
+       camel_folder_summary_add (summary, mi, FALSE);
        camel_folder_summary_touch (summary);
-       camel_folder_summary_save_to_db (summary, NULL);
+       camel_folder_summary_save (summary, NULL);
+
+       g_object_unref (mi);
 
        return TRUE;
 }
 
 static gboolean
 ews_update_user_flags (CamelMessageInfo *info,
-                       CamelFlag *server_user_flags)
+                       const CamelNamedFlags *server_user_flags)
 {
        gboolean changed = FALSE;
-       CamelMessageInfoBase *binfo = (CamelMessageInfoBase *) info;
        gboolean set_cal = FALSE, set_note = FALSE;
 
-       if (camel_flag_get (&binfo->user_flags, "$has_cal"))
+       if (camel_message_info_get_user_flag (info, "$has_cal"))
                set_cal = TRUE;
-       if (camel_flag_get (&binfo->user_flags, "$has_note"))
+       if (camel_message_info_get_user_flag (info, "$has_note"))
                set_note = TRUE;
 
-       changed = camel_flag_list_copy (&binfo->user_flags, &server_user_flags);
+       changed = camel_message_info_take_user_flags (info, camel_named_flags_copy (server_user_flags));
 
        /* reset the flags as they were set in messageinfo before */
        if (set_cal)
-               camel_flag_set (&binfo->user_flags, "$has_cal", TRUE);
+               camel_message_info_set_user_flag (info, "$has_cal", TRUE);
        if (set_note)
-               camel_flag_set (&binfo->user_flags, "$has_note", TRUE);
+               camel_message_info_set_user_flag (info, "$has_note", TRUE);
 
        return changed;
 }
@@ -364,21 +220,24 @@ gboolean
 camel_ews_update_message_info_flags (CamelFolderSummary *summary,
                                      CamelMessageInfo *info,
                                      guint32 server_flags,
-                                     CamelFlag *server_user_flags)
+                                     const CamelNamedFlags *server_user_flags)
 {
-       CamelEwsMessageInfo *einfo = (CamelEwsMessageInfo *) info;
+       CamelEwsMessageInfo *emi;
        gboolean changed = FALSE;
 
-       if (server_flags != einfo->server_flags) {
+       g_return_val_if_fail (CAMEL_IS_EWS_SUMMARY (summary), FALSE);
+       g_return_val_if_fail (CAMEL_IS_EWS_MESSAGE_INFO (info), FALSE);
+
+       emi = CAMEL_EWS_MESSAGE_INFO (info);
+
+       if (server_flags != camel_ews_message_info_get_server_flags (emi)) {
                guint32 server_set, server_cleared;
 
-               server_set = server_flags & ~einfo->server_flags;
-               server_cleared = einfo->server_flags & ~server_flags;
+               server_set = server_flags & ~camel_ews_message_info_get_server_flags (emi);
+               server_cleared = camel_ews_message_info_get_server_flags (emi) & ~server_flags;
 
-               camel_message_info_set_flags (info, server_set | server_cleared, (einfo->info.flags | 
server_set) & ~server_cleared);
-               einfo->server_flags = server_flags;
-               if (info->summary)
-                       camel_folder_summary_touch (info->summary);
+               camel_message_info_set_flags (info, server_set | server_cleared, 
(camel_message_info_get_flags (info) | server_set) & ~server_cleared);
+               camel_ews_message_info_set_server_flags (emi, server_flags);
                changed = TRUE;
        }
 
diff --git a/src/camel/camel-ews-summary.h b/src/camel/camel-ews-summary.h
index b085ab3..4903a2b 100644
--- a/src/camel/camel-ews-summary.h
+++ b/src/camel/camel-ews-summary.h
@@ -24,6 +24,8 @@
 
 #include <camel/camel.h>
 
+#include "camel-ews-message-info.h"
+
 /* Standard GObject macros */
 #define CAMEL_TYPE_EWS_SUMMARY \
        (camel_ews_summary_get_type ())
@@ -48,25 +50,6 @@ G_BEGIN_DECLS
 typedef struct _CamelEwsSummary CamelEwsSummary;
 typedef struct _CamelEwsSummaryClass CamelEwsSummaryClass;
 typedef struct _CamelEwsSummaryPrivate CamelEwsSummaryPrivate;
-typedef struct _CamelEwsMessageInfo CamelEwsMessageInfo;
-typedef struct _CamelEwsMessageContentInfo CamelEwsMessageContentInfo;
-
-/* extra summary flags*/
-enum {
-       CAMEL_EWS_MESSAGE_MSGFLAG_RN_PENDING = CAMEL_MESSAGE_FOLDER_FLAGGED << 1
-};
-
-struct _CamelEwsMessageInfo {
-       CamelMessageInfoBase info;
-
-       guint32 server_flags;
-       gint32 item_type;
-       gchar *change_key;
-} ;
-
-struct _CamelEwsMessageContentInfo {
-       CamelMessageContentInfo info;
-} ;
 
 struct _CamelEwsSummary {
        CamelFolderSummary parent;
@@ -86,7 +69,7 @@ gboolean
                                        (CamelFolderSummary *summary,
                                         CamelMessageInfo *info,
                                         guint32 server_flags,
-                                        CamelFlag *server_user_flags);
+                                        const CamelNamedFlags *server_user_flags);
 gboolean
        camel_ews_summary_add_message   (CamelFolderSummary *summary,
                                         const gchar *uid,
diff --git a/src/camel/camel-ews-utils.c b/src/camel/camel-ews-utils.c
index 78d4644..e490118 100644
--- a/src/camel/camel-ews-utils.c
+++ b/src/camel/camel-ews-utils.c
@@ -364,13 +364,13 @@ camel_ews_utils_sync_deleted_items (CamelEwsFolder *ews_folder,
                items_deleted_list = g_list_prepend (
                        items_deleted_list, (gpointer) id);
 
-               camel_folder_summary_remove_uid (folder->summary, id);
+               camel_folder_summary_remove_uid (camel_folder_get_folder_summary (folder), id);
                camel_folder_change_info_remove_uid (change_info, id);
        }
 
        items_deleted_list = g_list_reverse (items_deleted_list);
        camel_db_delete_uids (
-               CAMEL_STORE (ews_store)->cdb_w,
+               camel_store_get_db (CAMEL_STORE (ews_store)),
                full_name, items_deleted_list, NULL);
        g_list_free (items_deleted_list);
 
@@ -380,7 +380,7 @@ camel_ews_utils_sync_deleted_items (CamelEwsFolder *ews_folder,
 
 static const gchar *
 ews_utils_rename_label (const gchar *cat,
-                        gint from_cat)
+                        gboolean from_cat)
 {
        gint i;
 
@@ -424,16 +424,21 @@ ews_utils_is_system_user_flag (const gchar *name)
    the lists' members are values for the String xml element. */
 GSList *
 ews_utils_gather_server_user_flags (ESoapMessage *msg,
-                                   CamelEwsMessageInfo *mi)
+                                   CamelMessageInfo *mi)
 {
-       GSList *user_flags = NULL;
-       const CamelFlag *flag;
+       GSList *out_user_flags = NULL;
+       const CamelNamedFlags *user_flags;
+       guint ii, len;
+
+       camel_message_info_property_lock (mi);
+
+       user_flags = camel_message_info_get_user_flags (mi);
+       len = camel_named_flags_get_length (user_flags);
 
        /* transfer camel flags to become the categories as an XML
         * array of strings */
-       for (flag = camel_message_info_get_user_flags (&mi->info); flag;
-            flag = flag->next) {
-               const gchar *n = ews_utils_rename_label (flag->name, 0);
+       for (ii = 0; ii < len; ii++) {
+               const gchar *n = ews_utils_rename_label (camel_named_flags_get (user_flags, ii), FALSE);
                if (*n == '\0')
                        continue;
 
@@ -442,40 +447,51 @@ ews_utils_gather_server_user_flags (ESoapMessage *msg,
                if (ews_utils_is_system_user_flag (n))
                        continue;
 
-               user_flags = g_slist_prepend (user_flags, g_strdup (n));
+               out_user_flags = g_slist_prepend (out_user_flags, g_strdup (n));
        }
 
-       return g_slist_reverse (user_flags);
+       camel_message_info_property_unlock (mi);
+
+       return g_slist_reverse (out_user_flags);
 }
 
 static void
 ews_utils_merge_server_user_flags (EEwsItem *item,
-                                   CamelEwsMessageInfo *mi)
+                                   CamelMessageInfo *mi)
 {
        GSList *list = NULL;
        const GSList *p;
-       const CamelFlag *flag;
+       const CamelNamedFlags *user_flags;
+       guint ii, len;
+
+       camel_message_info_property_lock (mi);
+       camel_message_info_freeze_notifications (mi);
+
+       user_flags = camel_message_info_get_user_flags (mi);
+       len = camel_named_flags_get_length (user_flags);
 
        /* transfer camel flags to a list */
-       for (flag = camel_message_info_get_user_flags (&mi->info); flag;
-            flag = flag->next) {
-               if (!ews_utils_is_system_user_flag (flag->name))
-                       list = g_slist_prepend (list, (gchar *) flag->name);
+       for (ii = 0; ii < len; ii++) {
+               const gchar *name = camel_named_flags_get (user_flags, ii);
+
+               if (!ews_utils_is_system_user_flag (name))
+                       list = g_slist_prepend (list, (gchar *) name);
        }
 
        for (p = list; p; p = p->next) {
                /* remove custom user flags */
-               camel_flag_set (&mi->info.user_flags, p->data, FALSE);
+               camel_message_info_set_user_flag (mi, p->data, FALSE);
        }
 
        g_slist_free (list);
 
        /* now transfer over all the categories */
        for (p = e_ews_item_get_categories (item); p; p = p->next) {
-               camel_flag_set (
-                       &mi->info.user_flags,
-                       ews_utils_rename_label (p->data, 1), 1);
+               camel_message_info_set_user_flag (mi, ews_utils_rename_label (p->data, TRUE), TRUE);
        }
+
+       camel_message_info_thaw_notifications (mi);
+       camel_message_info_property_unlock (mi);
 }
 
 static guint32
@@ -516,7 +532,7 @@ ews_utils_get_server_flags (EEwsItem *item)
        return server_flags;
 }
 
-static const gchar *
+static gchar *
 form_email_string_from_mb (EEwsConnection *cnc,
                            const EwsMailbox *mb,
                            GCancellable *cancellable)
@@ -540,26 +556,25 @@ form_email_string_from_mb (EEwsConnection *cnc,
                        g_string_append (str, ">");
                }
 
-               return camel_pstring_add (g_string_free (str, FALSE), TRUE);
+               return g_string_free (str, FALSE);
        } else
-              return camel_pstring_strdup ("");
+               return NULL;
 }
 
-static const gchar *
+static gchar *
 form_recipient_list (EEwsConnection *cnc,
                      const GSList *recipients,
                      GCancellable *cancellable)
 {
        const GSList *l;
        GString *str = NULL;
-       const gchar *ret;
 
        if (!recipients)
                return NULL;
 
        for (l = recipients; l != NULL; l = g_slist_next (l)) {
                EwsMailbox *mb = (EwsMailbox *) l->data;
-               const gchar *mb_str = form_email_string_from_mb (cnc, mb, cancellable);
+               gchar *mb_str = form_email_string_from_mb (cnc, mb, cancellable);
 
                if (!str)
                        str = g_string_new ("");
@@ -567,12 +582,11 @@ form_recipient_list (EEwsConnection *cnc,
                        str = g_string_append (str, ", ");
 
                str = g_string_append (str, mb_str);
-       }
 
-       ret = camel_pstring_add (str->str, TRUE);
-       g_string_free (str, FALSE);
+               g_free (mb_str);
+       }
 
-       return ret;
+       return g_string_free (str, FALSE);
 }
 
 static guint8 *
@@ -594,63 +608,55 @@ get_md5_digest (const guchar *str)
 }
 
 static void
-ews_set_threading_data (CamelEwsMessageInfo *mi,
+ews_set_threading_data (CamelMessageInfo *mi,
                         EEwsItem *item)
 {
-       const gchar *references, *inreplyto;
-       gint count = 0;
+       const gchar *references_str, *inreplyto_str;
        const gchar *message_id;
-       GSList *refs, *irt, *scan;
+       GSList *refs, *irt, *link;
        guint8 *digest;
        gchar *msgid;
+       CamelSummaryMessageID tmp_msgid;
+       GArray *references;
 
        /* set message id */
        message_id = e_ews_item_get_msg_id (item);
        msgid = camel_header_msgid_decode (message_id);
        if (msgid) {
                digest = get_md5_digest ((const guchar *) msgid);
-               memcpy (
-                       mi->info.message_id.id.hash,
-                       digest, sizeof (mi->info.message_id.id.hash));
+               memcpy (tmp_msgid.id.hash, digest, sizeof (tmp_msgid.id.hash));
                g_free (digest);
                g_free (msgid);
+
+               camel_message_info_set_message_id (mi, tmp_msgid.id.id);
        }
 
        /* Process References: header */
-       references = e_ews_item_get_references (item);
-       refs = camel_header_references_decode (references);
+       references_str = e_ews_item_get_references (item);
+       refs = camel_header_references_decode (references_str);
 
        /* Prepend In-Reply-To: contents to References: for summary info */
-       inreplyto = e_ews_item_get_in_replyto (item);
-       irt = camel_header_references_decode (inreplyto);
+       inreplyto_str = e_ews_item_get_in_replyto (item);
+       irt = camel_header_references_decode (inreplyto_str);
        if (irt) {
                refs = g_slist_concat (irt, refs);
        }
        if (!refs)
                return;
 
-       count = g_slist_length (refs);
-       g_free (mi->info.references);
-       mi->info.references = NULL;
-       mi->info.references = g_malloc (
-               sizeof (*mi->info.references) + ((count - 1) *
-               sizeof (mi->info.references->references[0])));
-       scan = refs;
-       count = 0;
-
-       while (scan) {
-               digest = get_md5_digest ((const guchar *) scan->data);
-               memcpy (
-                       mi->info.references->references[count].id.hash,
-                       digest, sizeof (mi->info.message_id.id.hash));
+       references = g_array_sized_new (FALSE, FALSE, sizeof (guint64), g_slist_length (refs));
+
+       for (link = refs; link; link = g_slist_next (link)) {
+               digest = get_md5_digest ((const guchar *) link->data);
+               memcpy (tmp_msgid.id.hash, digest, sizeof (tmp_msgid.id.hash));
                g_free (digest);
 
-               count++;
-               scan = g_slist_next (scan);
+               g_array_append_val (references, tmp_msgid.id.id);
        }
 
-       mi->info.references->size = count;
        g_slist_free_full (refs, g_free);
+
+       camel_message_info_take_references (mi, references);
 }
 
 static gboolean
@@ -740,14 +746,16 @@ camel_ews_utils_sync_updated_items (CamelEwsFolder *ews_folder,
                                    CamelFolderChangeInfo *change_info)
 {
        CamelFolder *folder;
+       CamelFolderSummary *folder_summary;
        GSList *l;
 
        folder = CAMEL_FOLDER (ews_folder);
+       folder_summary = camel_folder_get_folder_summary (folder);
 
        for (l = items_updated; l != NULL; l = g_slist_next (l)) {
                EEwsItem *item = (EEwsItem *) l->data;
                const EwsId *id;
-               CamelEwsMessageInfo *mi;
+               CamelMessageInfo *mi;
 
                if (e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_ERROR) {
                        g_object_unref (item);
@@ -762,33 +770,31 @@ camel_ews_utils_sync_updated_items (CamelEwsFolder *ews_folder,
                        continue;
                }
 
-               mi = (CamelEwsMessageInfo *) camel_folder_summary_get (folder->summary, id->id);
+               mi = camel_folder_summary_get (folder_summary, id->id);
                if (mi) {
                        guint32 server_flags;
                        gboolean changed, was_changed;
 
-                       was_changed = (mi->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0;
+                       camel_message_info_freeze_notifications (mi);
+                       was_changed = camel_message_info_get_folder_flagged (mi);
 
                        server_flags = ews_utils_get_server_flags (item);
                        ews_utils_merge_server_user_flags (item, mi);
-                       changed = camel_ews_update_message_info_flags (
-                               folder->summary, (CamelMessageInfo *) mi,
-                               server_flags, NULL);
-                       changed = camel_ews_utils_update_follow_up_flags (item, (CamelMessageInfo *) mi) || 
changed;
-                       changed = camel_ews_utils_update_read_receipt_flags (item, (CamelMessageInfo *) mi, 
server_flags, FALSE) || changed;
+                       changed = camel_ews_update_message_info_flags (folder_summary, mi, server_flags, 
NULL);
+                       changed = camel_ews_utils_update_follow_up_flags (item, mi) || changed;
+                       changed = camel_ews_utils_update_read_receipt_flags (item, mi, server_flags, FALSE) 
|| changed;
 
                        if (changed)
-                               camel_folder_change_info_change_uid (change_info, mi->info.uid);
+                               camel_folder_change_info_change_uid (change_info, id->id);
 
-                       g_free (mi->change_key);
-                       mi->change_key = g_strdup (id->change_key);
-                       mi->info.dirty = TRUE;
+                       camel_ews_message_info_set_change_key (CAMEL_EWS_MESSAGE_INFO (mi), id->change_key);
                        if (!was_changed) {
                                /* do not save to the server what was just read, when did not change locally 
before */
-                               mi->info.flags = mi->info.flags & (~CAMEL_MESSAGE_FOLDER_FLAGGED);
+                               camel_message_info_set_folder_flagged (mi, FALSE);
                        }
 
-                       camel_message_info_unref (mi);
+                       camel_message_info_thaw_notifications (mi);
+                       g_clear_object (&mi);
                        g_object_unref (item);
                        continue;
                }
@@ -807,20 +813,22 @@ camel_ews_utils_sync_created_items (CamelEwsFolder *ews_folder,
                                     GCancellable *cancellable)
 {
        CamelFolder *folder;
+       CamelFolderSummary *folder_summary;
        GSList *l;
 
        if (!items_created)
                return;
 
        folder = CAMEL_FOLDER (ews_folder);
+       folder_summary = camel_folder_get_folder_summary (folder);
 
        for (l = items_created; l != NULL; l = g_slist_next (l)) {
                EEwsItem *item = (EEwsItem *) l->data;
-               CamelEwsMessageInfo *mi;
+               CamelMessageInfo *mi;
                const EwsId *id;
                const EwsMailbox *from;
+               gchar *tmp;
                EEwsItemType item_type;
-               const GSList *to, *cc;
                const gchar *msg_headers;
                gboolean has_attachments, found_property, message_requests_read_receipt = FALSE;
                guint32 server_flags;
@@ -841,9 +849,9 @@ camel_ews_utils_sync_created_items (CamelEwsFolder *ews_folder,
                        continue;
                }
 
-               mi = (CamelEwsMessageInfo *) camel_folder_summary_get (folder->summary, id->id);
+               mi = camel_folder_summary_get (folder_summary, id->id);
                if (mi) {
-                       camel_message_info_unref (mi);
+                       g_clear_object (&mi);
                        g_object_unref (item);
                        continue;
                }
@@ -867,8 +875,8 @@ camel_ews_utils_sync_created_items (CamelEwsFolder *ews_folder,
                        g_object_unref (stream);
 
                        if (camel_mime_part_construct_from_parser_sync (part, parser, NULL, NULL)) {
-                               mi = (CamelEwsMessageInfo *) camel_folder_summary_info_new_from_header 
(folder->summary, part->headers);
-                               if (camel_header_raw_find (&(part->headers), "Disposition-Notification-To", 
NULL))
+                               mi = camel_folder_summary_info_new_from_headers (folder_summary, 
camel_medium_get_headers (CAMEL_MEDIUM (part)));
+                               if (camel_medium_get_header (CAMEL_MEDIUM (part), 
"Disposition-Notification-To"))
                                        message_requests_read_receipt = TRUE;
                        }
 
@@ -877,15 +885,9 @@ camel_ews_utils_sync_created_items (CamelEwsFolder *ews_folder,
                }
 
                if (!mi)
-                       mi = (CamelEwsMessageInfo *) camel_message_info_new (folder->summary);
-
-               if (mi->info.content == NULL) {
-                       mi->info.content =
-                               camel_folder_summary_content_info_new (
-                               folder->summary);
-                       mi->info.content->type =
-                               camel_content_type_new ("multipart", "mixed");
-               }
+                       mi = camel_message_info_new (folder_summary);
+
+               camel_message_info_set_abort_notifications (mi, TRUE);
 
                item_type = e_ews_item_get_item_type (item);
                if (item_type == E_EWS_ITEM_TYPE_EVENT ||
@@ -893,56 +895,61 @@ camel_ews_utils_sync_created_items (CamelEwsFolder *ews_folder,
                         item_type == E_EWS_ITEM_TYPE_MEETING_REQUEST ||
                         item_type == E_EWS_ITEM_TYPE_MEETING_RESPONSE ||
                         item_type == E_EWS_ITEM_TYPE_MEETING_RESPONSE)
-                       camel_message_info_set_user_flag (
-                               (CamelMessageInfo *) mi, "$has_cal", TRUE);
+                       camel_message_info_set_user_flag (mi, "$has_cal", TRUE);
 
-               mi->info.uid = camel_pstring_strdup (id->id);
-               mi->info.size = e_ews_item_get_size (item);
-               mi->info.subject = camel_pstring_strdup (
-                       e_ews_item_get_subject (item));
-               mi->item_type = item_type;
-               mi->change_key = g_strdup (id->change_key);
+               camel_message_info_set_uid (mi, id->id);
+               camel_message_info_set_size (mi, e_ews_item_get_size (item));
+               camel_message_info_set_subject (mi, e_ews_item_get_subject (item));
+               camel_ews_message_info_set_item_type (CAMEL_EWS_MESSAGE_INFO (mi), item_type);
+               camel_ews_message_info_set_change_key (CAMEL_EWS_MESSAGE_INFO (mi), id->change_key);
 
-               mi->info.date_sent = e_ews_item_get_date_sent (item);
-               mi->info.date_received = e_ews_item_get_date_received (item);
+               camel_message_info_set_date_sent (mi, e_ews_item_get_date_sent (item));
+               camel_message_info_set_date_received (mi, e_ews_item_get_date_received (item));
 
                from = e_ews_item_get_from (item);
                if (!from)
                        from = e_ews_item_get_sender (item);
-               mi->info.from = form_email_string_from_mb (cnc, from, cancellable);
+               tmp = form_email_string_from_mb (cnc, from, cancellable);
+               camel_message_info_set_from (mi, tmp);
+               g_free (tmp);
 
-               to = e_ews_item_get_to_recipients (item);
-               mi->info.to = form_recipient_list (cnc, to, cancellable);
+               tmp = form_recipient_list (cnc, e_ews_item_get_to_recipients (item), cancellable);
+               camel_message_info_set_to (mi, tmp);
+               g_free (tmp);
 
-               cc = e_ews_item_get_cc_recipients (item);
-               mi->info.cc = form_recipient_list (cnc, cc, cancellable);
+               tmp = form_recipient_list (cnc, e_ews_item_get_cc_recipients (item), cancellable);
+               camel_message_info_set_cc (mi, tmp);
+               g_free (tmp);
 
                e_ews_item_has_attachments (item, &has_attachments);
                if (has_attachments)
-                       mi->info.flags |= CAMEL_MESSAGE_ATTACHMENTS;
+                       camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, 
CAMEL_MESSAGE_ATTACHMENTS);
 
                ews_set_threading_data (mi, item);
                server_flags = ews_utils_get_server_flags (item);
                ews_utils_merge_server_user_flags (item, mi);
 
-               mi->info.flags |= server_flags;
-               mi->server_flags = server_flags;
+               camel_message_info_set_flags (mi, server_flags, server_flags);
+               camel_ews_message_info_set_server_flags (CAMEL_EWS_MESSAGE_INFO (mi), server_flags);
+
+               camel_ews_utils_update_follow_up_flags (item, mi);
+               camel_ews_utils_update_read_receipt_flags (item, mi, server_flags, 
message_requests_read_receipt);
 
-               camel_ews_utils_update_follow_up_flags (item, (CamelMessageInfo *) mi);
-               camel_ews_utils_update_read_receipt_flags (item, (CamelMessageInfo *) mi, server_flags, 
message_requests_read_receipt);
+               camel_message_info_set_abort_notifications (mi, FALSE);
 
-               camel_folder_summary_add (folder->summary, (CamelMessageInfo *) mi);
+               camel_folder_summary_add (folder_summary, mi, FALSE);
 
                /* camel_folder_summary_add() sets folder_flagged flag
                 * on the message info, but this is a fresh item downloaded
                 * from the server, thus unset it, to avoid resync up to the server
                 * on folder leave/store
-               */
-               mi->info.flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
+                */
+               camel_message_info_set_folder_flagged (mi, FALSE);
 
                camel_folder_change_info_add_uid (change_info, id->id);
                camel_folder_change_info_recent_uid (change_info, id->id);
 
+               g_object_unref (mi);
                g_object_unref (item);
        }
 
diff --git a/src/camel/camel-ews-utils.h b/src/camel/camel-ews-utils.h
index 93ec395..e6125c9 100644
--- a/src/camel/camel-ews-utils.h
+++ b/src/camel/camel-ews-utils.h
@@ -76,7 +76,7 @@ void          camel_ews_utils_sync_updated_items
                                                 CamelFolderChangeInfo *change_info);
 GSList *       ews_utils_gather_server_user_flags
                                                (ESoapMessage *msg,
-                                                CamelEwsMessageInfo *mi);
+                                                CamelMessageInfo *mi);
 void           ews_utils_update_followup_flags (ESoapMessage *msg,
                                                 CamelMessageInfo *mi);
 gchar *                camel_ews_utils_get_host_name   (CamelSettings *settings);


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