[evolution-ews/wip/camel-more-gobject: 6/6] Bug 764065 - [Camel] Port more classes to GObject



commit c27c75a660540d12ffa95bd726d2579bc7a8e73a
Author: Milan Crha <mcrha redhat com>
Date:   Tue Oct 11 22:03:20 2016 +0200

    Bug 764065 - [Camel] Port more classes to GObject

 src/camel/CMakeLists.txt           |    2 +
 src/camel/camel-ews-folder.c       |  123 ++++++-----
 src/camel/camel-ews-message-info.c |  431 ++++++++++++++++++++++++++++++++++++
 src/camel/camel-ews-message-info.h |   81 +++++++
 src/camel/camel-ews-summary.c      |  205 +++---------------
 src/camel/camel-ews-summary.h      |   23 +--
 src/camel/camel-ews-utils.c        |  213 +++++++++---------
 src/camel/camel-ews-utils.h        |    2 +-
 8 files changed, 724 insertions(+), 356 deletions(-)
---
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 7675a6a..1123cb9 100644
--- a/src/camel/camel-ews-folder.c
+++ b/src/camel/camel-ews-folder.c
@@ -761,31 +761,33 @@ 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 (folder->summary, 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));
 
                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);
 }
 
 /* Get the message from cache if available otherwise get it from server */
@@ -916,22 +918,30 @@ 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;
 
                mi = iter->data;
+               emi = CAMEL_EWS_MESSAGE_INFO (mi);
+
+               if (!mi || !emi)
+                       continue;
 
-               flags_changed = mi->server_flags ^ mi->info.flags;
+               camel_message_info_property_lock (mi);
+
+               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";
@@ -958,10 +968,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 */
@@ -969,11 +977,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);
@@ -995,14 +1003,13 @@ msg_update_flags (ESoapMessage *msg,
                e_soap_message_end_element (msg); /* Message */
                e_soap_message_end_element (msg); /* SetItemField */
 
-               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);
        }
 }
 
@@ -1012,29 +1019,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);
        }
 }
 
@@ -1059,7 +1069,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;
@@ -1282,12 +1292,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. */
@@ -1302,21 +1313,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;
                }
@@ -1324,7 +1335,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);
@@ -1521,8 +1532,8 @@ sync_updated_items (CamelEwsFolder *ews_folder,
                }
 
                /* 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;
                }
@@ -1540,7 +1551,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);
@@ -2049,11 +2060,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 (source->summary, uids->pdata[i]);
                if (!mi)
                        continue;
 
@@ -2065,12 +2076,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;
                }
@@ -2078,7 +2089,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);
 
@@ -2135,13 +2146,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))
                                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);
                }
@@ -2394,7 +2405,6 @@ ews_expunge_sync (CamelFolder *folder,
                   GCancellable *cancellable,
                   GError **error)
 {
-       CamelEwsMessageInfo *ews_info;
        CamelStore *parent_store;
        GSList *deleted_items = NULL;
        gint i;
@@ -2445,12 +2455,11 @@ ews_expunge_sync (CamelFolder *folder,
                const gchar *uid = g_ptr_array_index (known_uids, i);
 
                info = camel_folder_summary_get (folder->summary, uid);
-               ews_info = (CamelEwsMessageInfo *) info;
 
-               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) {
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-summary.c b/src/camel/camel-ews-summary.c
index 9df6ca8..0ed7d4b 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);
 
 /*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->message_info_type = CAMEL_TYPE_EWS_MESSAGE_INFO;
        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;
 }
 
 static void
@@ -148,7 +106,6 @@ 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);
 
@@ -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);
 
+       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 5f05603..c195fdb 100644
--- a/src/camel/camel-ews-utils.c
+++ b/src/camel/camel-ews-utils.c
@@ -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;
 
@@ -422,15 +422,20 @@ ews_utils_is_system_user_flag (const gchar *name)
 
 void
 ews_utils_replace_server_user_flags (ESoapMessage *msg,
-                                     CamelEwsMessageInfo *mi)
+                                     CamelMessageInfo *mi)
 {
-       const CamelFlag *flag;
+       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;
 
@@ -441,36 +446,47 @@ ews_utils_replace_server_user_flags (ESoapMessage *msg,
 
                e_ews_message_write_string_parameter (msg, "String", NULL, n);
        }
+
+       camel_message_info_property_unlock (mi);
 }
 
 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
@@ -511,7 +527,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)
@@ -535,26 +551,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 ("");
@@ -562,12 +577,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 *
@@ -589,63 +603,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
@@ -742,7 +748,7 @@ camel_ews_utils_sync_updated_items (CamelEwsFolder *ews_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);
@@ -757,33 +763,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;
                }
@@ -811,11 +815,11 @@ camel_ews_utils_sync_created_items (CamelEwsFolder *ews_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;
@@ -836,9 +840,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;
                }
@@ -862,7 +866,7 @@ 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);
+                               mi = camel_folder_summary_info_new_from_header (folder->summary, 
part->headers);
                                if (camel_header_raw_find (&(part->headers), "Disposition-Notification-To", 
NULL))
                                        message_requests_read_receipt = TRUE;
                        }
@@ -872,15 +876,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 ||
@@ -888,56 +886,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 0cf4940..90296de 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);
 void           ews_utils_replace_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]