[evolution-mapi/wip/camel-more-gobject] Use GObject-based CamelMessageInfo



commit c7b084187e71589c14d93cba68b9efddc9b0d413
Author: Milan Crha <mcrha redhat com>
Date:   Tue Sep 13 11:28:31 2016 +0200

    Use GObject-based CamelMessageInfo
    
    The code builds. It doesn't mean it does what it should do.

 src/camel/Makefile.am                 |   90 +++++-----
 src/camel/camel-mapi-folder-summary.c |   96 +----------
 src/camel/camel-mapi-folder-summary.h |   17 +--
 src/camel/camel-mapi-folder.c         |  218 ++++++++++-------------
 src/camel/camel-mapi-message-info.c   |  306 +++++++++++++++++++++++++++++++++
 src/camel/camel-mapi-message-info.h   |   76 ++++++++
 6 files changed, 531 insertions(+), 272 deletions(-)
---
diff --git a/src/camel/Makefile.am b/src/camel/Makefile.am
index 1e01e72..54eef80 100644
--- a/src/camel/Makefile.am
+++ b/src/camel/Makefile.am
@@ -1,46 +1,48 @@
-## Process this file with automake to produce Makefile.in
-
-camel_provider_LTLIBRARIES = libcamelmapi.la
-camel_provider_DATA = libcamelmapi.urls
-
-AM_CPPFLAGS = -I..                             \
-       -I$(top_srcdir)/src/                    \
-       -I$(top_srcdir)/src/camel               \
-       -I$(top_srcdir)/src/libexchangemapi     \
-       $(EVOLUTION_MAIL_CFLAGS)                \
-       $(CAMEL_CFLAGS)                         \
-       $(LIBECAL_CFLAGS)                       \
-        $(LIBMAPI_CFLAGS)                       \
-       $(CODE_COVERAGE_CFLAGS)                 \
-       -DEXCHANGE_MAPI_LOCALEDIR=\"$(localedir)\" \
-       -DG_LOG_DOMAIN=\"camel-mapi-provider\"
-
-libcamelmapi_la_SOURCES =                      \
-       camel-mapi-provider.c                   \
-       camel-mapi-folder.c                     \
-       camel-mapi-folder-summary.c             \
-       camel-mapi-sasl-krb.c                   \
-        camel-mapi-store.c                     \
-       camel-mapi-store-summary.c              \
-       camel-mapi-transport.c                  
-
-noinst_HEADERS =                               \
-       camel-mapi-folder.h                     \
-       camel-mapi-folder-summary.h             \
-       camel-mapi-sasl-krb.h                   \
-       camel-mapi-store.h                      \
-       camel-mapi-store-summary.h              \
-       camel-mapi-transport.h
-
-libcamelmapi_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS)
-
-libcamelmapi_la_LIBADD =                       \
-       $(top_builddir)/src/libexchangemapi/libexchangemapi-1.0.la \
-       $(EVOLUTION_MAIL_LIBS)                  \
-       $(CAMEL_LIBS)                           \
-       $(LIBECAL_LIBS)                         \
-        $(LIBMAPI_LIBS)
-
-EXTRA_DIST = libcamelmapi.urls
+## Process this file with automake to produce Makefile.in
+
+camel_provider_LTLIBRARIES = libcamelmapi.la
+camel_provider_DATA = libcamelmapi.urls
+
+AM_CPPFLAGS = -I..                             \
+       -I$(top_srcdir)/src/                    \
+       -I$(top_srcdir)/src/camel               \
+       -I$(top_srcdir)/src/libexchangemapi     \
+       $(EVOLUTION_MAIL_CFLAGS)                \
+       $(CAMEL_CFLAGS)                         \
+       $(LIBECAL_CFLAGS)                       \
+        $(LIBMAPI_CFLAGS)                       \
+       $(CODE_COVERAGE_CFLAGS)                 \
+       -DEXCHANGE_MAPI_LOCALEDIR=\"$(localedir)\" \
+       -DG_LOG_DOMAIN=\"camel-mapi-provider\"
+
+libcamelmapi_la_SOURCES =                      \
+       camel-mapi-provider.c                   \
+       camel-mapi-folder.c                     \
+       camel-mapi-folder-summary.c             \
+       camel-mapi-message-info.c               \
+       camel-mapi-sasl-krb.c                   \
+        camel-mapi-store.c                     \
+       camel-mapi-store-summary.c              \
+       camel-mapi-transport.c
+
+noinst_HEADERS =                               \
+       camel-mapi-folder.h                     \
+       camel-mapi-folder-summary.h             \
+       camel-mapi-message-info.h               \
+       camel-mapi-sasl-krb.h                   \
+       camel-mapi-store.h                      \
+       camel-mapi-store-summary.h              \
+       camel-mapi-transport.h
+
+libcamelmapi_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS)
+
+libcamelmapi_la_LIBADD =                       \
+       $(top_builddir)/src/libexchangemapi/libexchangemapi-1.0.la \
+       $(EVOLUTION_MAIL_LIBS)                  \
+       $(CAMEL_LIBS)                           \
+       $(LIBECAL_LIBS)                         \
+        $(LIBMAPI_LIBS)
+
+EXTRA_DIST = libcamelmapi.urls
 
 -include $(top_srcdir)/git.mk
diff --git a/src/camel/camel-mapi-folder-summary.c b/src/camel/camel-mapi-folder-summary.c
index 9023a72..b197185 100644
--- a/src/camel/camel-mapi-folder-summary.c
+++ b/src/camel/camel-mapi-folder-summary.c
@@ -41,9 +41,6 @@
 static CamelFIRecord* mapi_summary_header_to_db (CamelFolderSummary *, GError **error);
 static gboolean mapi_summary_header_from_db (CamelFolderSummary *, CamelFIRecord *fir);
 
-static CamelMessageInfo *mapi_message_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir);
-static CamelMIRecord *mapi_message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info);
-
 static CamelMessageContentInfo * mapi_content_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir);
 static gboolean mapi_content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelMIRecord 
*mir);
 
@@ -52,49 +49,14 @@ static gboolean mapi_content_info_to_db (CamelFolderSummary *s, CamelMessageCont
 G_DEFINE_TYPE (CamelMapiFolderSummary, camel_mapi_folder_summary, CAMEL_TYPE_FOLDER_SUMMARY)
 
 static void
-mapi_summary_finalize (GObject *object)
-{
-       /* Chain up to parent's finalize() method. */
-       G_OBJECT_CLASS (camel_mapi_folder_summary_parent_class)->finalize (object);
-}
-
-static CamelMessageInfo *
-mapi_message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi)
-{
-       CamelMapiMessageInfo *to;
-       const CamelMapiMessageInfo *from = (const CamelMapiMessageInfo *)mi;
-       CamelFolderSummaryClass *folder_summary_class;
-
-       folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (
-               camel_mapi_folder_summary_parent_class);
-
-       to = (CamelMapiMessageInfo *)folder_summary_class->message_info_clone(s, mi);
-       to->server_flags = from->server_flags;
-       to->last_modified = from->last_modified;
-
-       /* FIXME: parent clone should do this */
-       to->info.content = camel_folder_summary_content_info_new(s);
-
-       return (CamelMessageInfo *)to;
-}
-
-static void
 camel_mapi_folder_summary_class_init (CamelMapiFolderSummaryClass *class)
 {
-       GObjectClass *object_class;
        CamelFolderSummaryClass *folder_summary_class;
 
-       object_class = G_OBJECT_CLASS (class);
-       object_class->finalize = mapi_summary_finalize;
-
        folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
-       folder_summary_class->message_info_size = sizeof (CamelMapiMessageInfo);
-       folder_summary_class->content_info_size = sizeof (CamelMapiMessageContentInfo);
-       folder_summary_class->message_info_clone = mapi_message_info_clone;
+       folder_summary_class->message_info_type = CAMEL_TYPE_MAPI_MESSAGE_INFO;
        folder_summary_class->summary_header_to_db = mapi_summary_header_to_db;
        folder_summary_class->summary_header_from_db = mapi_summary_header_from_db;
-       folder_summary_class->message_info_to_db = mapi_message_info_to_db;
-       folder_summary_class->message_info_from_db = mapi_message_info_from_db;
        folder_summary_class->content_info_to_db = mapi_content_info_to_db;
        folder_summary_class->content_info_from_db = mapi_content_info_from_db;
 }
@@ -151,7 +113,7 @@ mapi_summary_header_from_db (CamelFolderSummary *summary, CamelFIRecord *fir)
        part = fir->bdata;
 
        if (part)
-               mapi_summary->version = bdata_extract_digit (&part);
+               mapi_summary->version = camel_util_bdata_get_number (&part, 0);
 
        return TRUE;
 }
@@ -162,8 +124,7 @@ mapi_summary_header_to_db (CamelFolderSummary *summary, GError **error)
        CamelFolderSummaryClass *folder_summary_class;
        struct _CamelFIRecord *fir;
 
-       folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (
-               camel_mapi_folder_summary_parent_class);
+       folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (camel_mapi_folder_summary_parent_class);
 
        fir = folder_summary_class->summary_header_to_db (summary, error);
 
@@ -175,47 +136,6 @@ mapi_summary_header_to_db (CamelFolderSummary *summary, GError **error)
        return fir;
 }
 
-static CamelMessageInfo*
-mapi_message_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir)
-{
-       CamelFolderSummaryClass *folder_summary_class;
-       CamelMessageInfo *info;
-
-       folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (
-               camel_mapi_folder_summary_parent_class);
-
-       info = folder_summary_class->message_info_from_db (s, mir);
-       if (info) {
-               gchar *part = mir->bdata;
-               if (part && *part) {
-                       CamelMapiMessageInfo *m_info;
-
-                       m_info = (CamelMapiMessageInfo *) info;
-                       m_info->server_flags = bdata_extract_digit (&part);
-                       m_info->last_modified = bdata_extract_digit (&part);
-               }
-       }
-
-       return info;
-}
-
-static CamelMIRecord *
-mapi_message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info)
-{
-       CamelFolderSummaryClass *folder_summary_class;
-       CamelMapiMessageInfo *m_info = (CamelMapiMessageInfo *) info;
-       struct _CamelMIRecord *mir;
-
-       folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (
-               camel_mapi_folder_summary_parent_class);
-
-       mir = folder_summary_class->message_info_to_db (s, info);
-       if (mir)
-               mir->bdata = g_strdup_printf ("%u %u", m_info->server_flags, (guint32) m_info->last_modified);
-
-       return mir;
-}
-
 static CamelMessageContentInfo*
 mapi_content_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir)
 {
@@ -223,11 +143,10 @@ mapi_content_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir)
        gchar *part = mir->cinfo;
        guint32 type=0;
 
-       folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (
-               camel_mapi_folder_summary_parent_class);
+       folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (camel_mapi_folder_summary_parent_class);
 
        if (part)
-               type = bdata_extract_digit (&part);
+               type = camel_util_bdata_get_number (&part, 0);
 
        mir->cinfo = part;
 
@@ -242,8 +161,7 @@ mapi_content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, C
 {
        CamelFolderSummaryClass *folder_summary_class;
 
-       folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (
-               camel_mapi_folder_summary_parent_class);
+       folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (camel_mapi_folder_summary_parent_class);
 
        if (info->type) {
                mir->cinfo = g_strdup ("1");
@@ -272,7 +190,7 @@ mapi_summary_clear (CamelFolderSummary *summary, gboolean uncache)
                uid = camel_message_info_get_uid (info);
                camel_folder_change_info_remove_uid (changes, uid);
                camel_folder_summary_remove_uid (summary, uid);
-               camel_message_info_unref (info);
+               g_clear_object (&info);
        }
 
        camel_folder_summary_free_array (known_uids);
diff --git a/src/camel/camel-mapi-folder-summary.h b/src/camel/camel-mapi-folder-summary.h
index c530e8f..ed53d9d 100644
--- a/src/camel/camel-mapi-folder-summary.h
+++ b/src/camel/camel-mapi-folder-summary.h
@@ -26,6 +26,8 @@
 
 #include <camel/camel.h>
 
+#include "camel-mapi-message-info.h"
+
 /* Standard GObject macros */
 #define CAMEL_TYPE_MAPI_FOLDER_SUMMARY \
        (camel_mapi_folder_summary_get_type ())
@@ -47,23 +49,8 @@
 
 G_BEGIN_DECLS
 
-#define CAMEL_MAPI_MESSAGE_WITH_READ_RECEIPT (CAMEL_MESSAGE_FOLDER_FLAGGED << 1)
-
 typedef struct _CamelMapiFolderSummary CamelMapiFolderSummary;
 typedef struct _CamelMapiFolderSummaryClass CamelMapiFolderSummaryClass;
-typedef struct _CamelMapiMessageInfo CamelMapiMessageInfo;
-typedef struct _CamelMapiMessageContentInfo CamelMapiMessageContentInfo;
-
-struct _CamelMapiMessageInfo {
-       CamelMessageInfoBase info;
-
-       guint32 server_flags;
-       time_t last_modified; /* PidTagLastModificationTime of this message */
-};
-
-struct _CamelMapiMessageContentInfo {
-       CamelMessageContentInfo info;
-};
 
 struct _CamelMapiFolderSummary {
        CamelFolderSummary parent;
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index e03efd0..138cb33 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -145,12 +145,13 @@ mapi_folder_search_by_uids (CamelFolder *folder,
 }
 
 static void
-mapi_set_message_id (CamelMapiMessageInfo *mapi_mi, const gchar *message_id)
+mapi_set_message_id (CamelMessageInfo *mi,
+                    const gchar *message_id)
 {
        gchar *msgid;
        guint8 *digest;
        gsize length;
-       CamelMessageInfoBase *mi = &mapi_mi->info;
+       CamelSummaryMessageID tmp_msgid;
 
        msgid = camel_header_msgid_decode (message_id);
        if (msgid) {
@@ -164,24 +165,28 @@ mapi_set_message_id (CamelMapiMessageInfo *mapi_mi, const gchar *message_id)
                g_checksum_get_digest (checksum, digest, &length);
                g_checksum_free (checksum);
 
-               memcpy(mi->message_id.id.hash, digest, sizeof(mi->message_id.id.hash));
-               g_free(msgid);
-       }
+               memcpy (tmp_msgid.id.hash, digest, sizeof (tmp_msgid.id.hash));
+               g_free (msgid);
 
+               camel_message_info_set_message_id (mi, tmp_msgid.id.id);
+       }
 }
 
 static void
-mapi_set_message_references (CamelMapiMessageInfo *mapi_mi, const gchar *references, const gchar 
*in_reply_to)
+mapi_set_message_references (CamelMessageInfo *mi,
+                            const gchar *references,
+                            const gchar *in_reply_to)
 {
-       GSList *refs, *irt, *scan;
+       GSList *refs, *irt, *link;
        guint8 *digest;
-       gint count;
        gsize length;
-       CamelMessageInfoBase *mi = &mapi_mi->info;
+       CamelSummaryMessageID tmp_msgid;
 
        refs = camel_header_references_decode (references);
        irt = camel_header_references_decode (in_reply_to);
        if (refs || irt) {
+               GArray *references;
+
                if (irt) {
                        /* The References field is populated from the "References" and/or "In-Reply-To"
                           headers. If both headers exist, take the first thing in the In-Reply-To header
@@ -190,28 +195,27 @@ mapi_set_message_references (CamelMapiMessageInfo *mapi_mi, const gchar *referen
                        refs = g_slist_concat (irt, refs);
                }
 
-               count = g_slist_length (refs);
-               mi->references = g_malloc(sizeof(*mi->references) + ((count-1) * 
sizeof(mi->references->references[0])));
+               references = g_array_sized_new (FALSE, FALSE, sizeof (guint64), g_slist_length (refs));
 
                length = g_checksum_type_get_length (G_CHECKSUM_MD5);
                digest = g_alloca (length);
 
-               count = 0;
-               scan = refs;
-               while (scan) {
+               for (link = refs; link; link = g_slist_next (link)) {
                        GChecksum *checksum;
 
                        checksum = g_checksum_new (G_CHECKSUM_MD5);
-                       g_checksum_update (checksum, (guchar *) scan->data, -1);
+                       g_checksum_update (checksum, (guchar *) link->data, -1);
                        g_checksum_get_digest (checksum, digest, &length);
                        g_checksum_free (checksum);
 
-                       memcpy(mi->references->references[count].id.hash, digest, 
sizeof(mi->message_id.id.hash));
-                       count++;
-                       scan = g_slist_next (scan);
+                       memcpy (tmp_msgid.id.hash, digest, sizeof (tmp_msgid.id.hash));
+
+                       g_array_append_val (references, tmp_msgid.id.id);
                }
-               mi->references->size = count;
+
                g_slist_free_full (refs, g_free);
+
+               camel_message_info_take_references (mi, references);
        }
 }
 
@@ -309,9 +313,9 @@ gather_changed_objects_to_slist (EMapiConnection *conn,
 
                info = camel_folder_summary_get (gco->summary, uid_str);
                if (info) {
-                       CamelMapiMessageInfo *minfo = (CamelMapiMessageInfo *) info;
+                       CamelMapiMessageInfo *minfo = CAMEL_MAPI_MESSAGE_INFO (info);
 
-                       if (minfo->last_modified != object_data->last_modified
+                       if (camel_mapi_message_info_get_last_modified (minfo) != object_data->last_modified
                            && (object_data->msg_flags & MSGFLAG_UNMODIFIED) == 0) {
                                update = TRUE;
                        } else {
@@ -326,26 +330,20 @@ gather_changed_objects_to_slist (EMapiConnection *conn,
                                if ((object_data->msg_flags & MSGFLAG_HASATTACH) != 0)
                                        flags |= CAMEL_MESSAGE_ATTACHMENTS;
 
-                               if ((minfo->info.flags & CAMEL_MAPI_MESSAGE_WITH_READ_RECEIPT) != 0) {
+                               if ((camel_message_info_get_flags (info) & 
CAMEL_MAPI_MESSAGE_WITH_READ_RECEIPT) != 0) {
                                        if ((object_data->msg_flags & MSGFLAG_RN_PENDING) == 0 &&
                                            !camel_message_info_get_user_flag (info, "receipt-handled")) {
                                                camel_message_info_set_user_flag (info, "receipt-handled", 
TRUE);
-                                               minfo->info.dirty = TRUE;
-
-                                               camel_folder_summary_touch (gco->summary);
                                        }
                                }
 
-                               if ((minfo->info.flags & mask) != (flags & mask)) {
+                               if ((camel_message_info_get_flags (info) & mask) != (flags & mask)) {
                                        camel_message_info_set_flags (info, mask, flags);
-                                       minfo->server_flags = camel_message_info_get_flags (info);
-                                       minfo->info.dirty = TRUE;
-
-                                       camel_folder_summary_touch (gco->summary);
+                                       camel_mapi_message_info_set_server_flags (minfo, 
camel_message_info_get_flags (info));
                                }
                        }
 
-                       camel_message_info_unref (info);
+                       g_clear_object (&info);
                }
        } else {
                update = TRUE;
@@ -377,7 +375,6 @@ update_message_info (CamelMessageInfo *info,
                     gboolean is_public_folder,
                     gboolean user_has_read)
 {
-       CamelMapiMessageInfo *minfo = (CamelMapiMessageInfo *) info;
        guint32 flags = 0, mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_ATTACHMENTS | CAMEL_MESSAGE_ANSWERED | 
CAMEL_MESSAGE_FORWARDED | CAMEL_MAPI_MESSAGE_WITH_READ_RECEIPT;
        const uint32_t *pmsg_flags, *picon_index;
        const struct FILETIME *last_modified;
@@ -394,11 +391,11 @@ update_message_info (CamelMessageInfo *info,
        pread_receipt = e_mapi_util_find_array_propval (&object->properties, PidTagReadReceiptRequested);
        msg_class = e_mapi_util_find_array_propval (&object->properties, PidTagMessageClass);
 
-       if (!minfo->info.size) {
+       if (!camel_message_info_get_size (info)) {
                const uint32_t *msg_size;
 
                msg_size = e_mapi_util_find_array_propval (&object->properties, PidTagMessageSize);
-               minfo->info.size = msg_size ? *msg_size : 0;
+               camel_message_info_set_size (info, msg_size ? *msg_size : 0);
        }
 
        if (msg_class && g_str_has_prefix (msg_class, "REPORT.IPM.Note.IPNRN"))
@@ -412,11 +409,8 @@ update_message_info (CamelMessageInfo *info,
                        msg_flags = (msg_flags & (~MSGFLAG_READ)) | (user_has_read ? MSGFLAG_READ : 0);
        }
 
-       if (last_modified) {
-               minfo->last_modified = e_mapi_util_filetime_to_time_t (last_modified);
-       } else {
-               minfo->last_modified = 0;
-       }
+       camel_mapi_message_info_set_last_modified (CAMEL_MAPI_MESSAGE_INFO (info),
+               last_modified ? e_mapi_util_filetime_to_time_t (last_modified) : 0);
 
        if ((msg_flags & MSGFLAG_READ) != 0)
                flags |= CAMEL_MESSAGE_SEEN;
@@ -437,14 +431,11 @@ update_message_info (CamelMessageInfo *info,
 
        if ((camel_message_info_get_flags (info) & mask) != flags) {
                if (is_new)
-                       minfo->info.flags = flags;
+                       camel_message_info_set_flags (info, ~0, flags);
                else
                        camel_message_info_set_flags (info, mask, flags);
-               minfo->server_flags = camel_message_info_get_flags (info);
+               camel_mapi_message_info_set_server_flags (CAMEL_MAPI_MESSAGE_INFO (info), 
camel_message_info_get_flags (info));
        }
-
-       minfo->info.dirty = TRUE;
-       camel_folder_summary_touch (minfo->info.summary);
 }
 
 static gsize
@@ -537,7 +528,7 @@ gather_object_for_offline_cb (EMapiConnection *conn,
                                info = camel_folder_summary_get (gos->folder->summary, uid_str);
                                if (info) {
                                        user_has_read = (camel_message_info_get_flags (info) & 
CAMEL_MESSAGE_SEEN) != 0;
-                                       camel_message_info_unref (info);
+                                       g_clear_object (&info);
                                }
                        }
 
@@ -546,28 +537,29 @@ gather_object_for_offline_cb (EMapiConnection *conn,
 
                info = camel_folder_summary_info_new_from_message (gos->folder->summary, msg, NULL);
                if (info) {
-                       CamelMapiMessageInfo *minfo = (CamelMapiMessageInfo *) info;
+                       camel_message_info_set_abort_notifications (info, TRUE);
 
-                       minfo->info.uid = camel_pstring_strdup (uid_str);
+                       camel_message_info_set_uid (info, uid_str);
 
                        update_message_info (info, object, is_new, gos->is_public_folder, user_has_read);
 
-                       if (!minfo->info.size)
-                               minfo->info.size = camel_mapi_get_message_size (msg);
+                       if (!camel_message_info_get_size (info))
+                               camel_message_info_set_size (info, camel_mapi_get_message_size (msg));
 
+                       camel_message_info_set_abort_notifications (info, FALSE);
                        camel_folder_summary_add (gos->folder->summary, info);
-                       camel_message_info_ref (info);
+                       g_object_ref (info);
 
                        if (is_new) {
-                               camel_folder_change_info_add_uid (gos->changes, camel_message_info_get_uid 
(info));
-                               camel_folder_change_info_recent_uid (gos->changes, camel_message_info_get_uid 
(info));
+                               camel_folder_change_info_add_uid (gos->changes, uid_str);
+                               camel_folder_change_info_recent_uid (gos->changes, uid_str);
                        } else {
-                               camel_folder_change_info_change_uid (gos->changes, camel_message_info_get_uid 
(info));
+                               camel_folder_change_info_change_uid (gos->changes, uid_str);
                        }
 
                        add_message_to_cache (CAMEL_MAPI_FOLDER (gos->folder), uid_str, &msg, cancellable);
 
-                       camel_message_info_unref (info);
+                       g_clear_object (&info);
                } else {
                        g_debug ("%s: Failed to create message info from message", G_STRFUNC);
                }
@@ -626,8 +618,6 @@ gather_object_summary_cb (EMapiConnection *conn,
 
        info = camel_folder_summary_get (gos->folder->summary, uid_str);
        if (!info) {
-               CamelMapiMessageInfo *minfo;
-
                is_new = TRUE;
 
                if (transport_headers && *transport_headers) {
@@ -646,11 +636,11 @@ gather_object_summary_cb (EMapiConnection *conn,
                                if (info) {
                                        const uint32_t *msg_size;
 
-                                       minfo = (CamelMapiMessageInfo *) info;
-                                       minfo->info.uid = camel_pstring_strdup (uid_str);
+                                       camel_message_info_freeze_notifications (info);
+                                       camel_message_info_set_uid (info, uid_str);
 
                                        msg_size = e_mapi_util_find_array_propval (&object->properties, 
PidTagMessageSize);
-                                       minfo->info.size = msg_size ? *msg_size : 0;
+                                       camel_message_info_set_size (info, msg_size ? *msg_size : 0);
                                }
                        }
 
@@ -676,18 +666,19 @@ gather_object_summary_cb (EMapiConnection *conn,
                        display_cc = e_mapi_util_find_array_propval (&object->properties, PidTagDisplayCc);
 
                        info = camel_message_info_new (gos->folder->summary);
-                       minfo = (CamelMapiMessageInfo *) info;
 
-                       minfo->info.uid = camel_pstring_strdup (uid_str);
-                       minfo->info.subject = camel_pstring_strdup (subject);
-                       minfo->info.date_sent = e_mapi_util_filetime_to_time_t (submit_time);
-                       minfo->info.date_received = e_mapi_util_filetime_to_time_t (delivery_time);
-                       minfo->info.size = msg_size ? *msg_size : 0;
+                       camel_message_info_freeze_notifications (info);
+
+                       camel_message_info_set_uid (info, uid_str);
+                       camel_message_info_set_subject (info, subject);
+                       camel_message_info_set_date_sent (info, e_mapi_util_filetime_to_time_t (submit_time));
+                       camel_message_info_set_date_received (info, e_mapi_util_filetime_to_time_t 
(delivery_time));
+                       camel_message_info_set_size (info, msg_size ? *msg_size : 0);
 
                        /* Threading related properties */
-                       mapi_set_message_id (minfo, message_id);
+                       mapi_set_message_id (info, message_id);
                        if (references || in_reply_to)
-                               mapi_set_message_references (minfo, references, in_reply_to);
+                               mapi_set_message_references (info, references, in_reply_to);
 
                        /* Recipients */
                        to_addr = (CamelAddress *) camel_internet_address_new ();
@@ -698,18 +689,18 @@ gather_object_summary_cb (EMapiConnection *conn,
 
                        if (camel_address_length (to_addr) > 0) {
                                formatted_addr = camel_address_format (to_addr);
-                               minfo->info.to = camel_pstring_strdup (formatted_addr);
+                               camel_message_info_set_to (info, formatted_addr);
                                g_free (formatted_addr);
                        } else {
-                               minfo->info.to = camel_pstring_strdup (display_to);
+                               camel_message_info_set_to (info, display_to);
                        }
 
                        if (camel_address_length (cc_addr) > 0) {
                                formatted_addr = camel_address_format (cc_addr);
-                               minfo->info.cc = camel_pstring_strdup (formatted_addr);
+                               camel_message_info_set_cc (info, formatted_addr);
                                g_free (formatted_addr);
                        } else {
-                               minfo->info.cc = camel_pstring_strdup (display_cc);
+                               camel_message_info_set_cc (info, display_cc);
                        }
 
                        g_object_unref (to_addr);
@@ -728,7 +719,7 @@ gather_object_summary_cb (EMapiConnection *conn,
                        if (from_email && *from_email) {
                                formatted_addr = camel_internet_address_format_address (from_name, 
from_email);
 
-                               minfo->info.from = camel_pstring_strdup (formatted_addr);
+                               camel_message_info_set_from (info, formatted_addr);
 
                                g_free (formatted_addr);
                        }
@@ -737,28 +728,31 @@ gather_object_summary_cb (EMapiConnection *conn,
                        g_free (from_email);
                }
 
-               minfo = (CamelMapiMessageInfo *) info;
-               if (minfo->info.date_sent == 0)
-                       minfo->info.date_sent = minfo->info.date_received;
-               if (minfo->info.date_received == 0)
-                       minfo->info.date_received = minfo->info.date_sent;
+               if (!camel_message_info_get_date_sent (info))
+                       camel_message_info_set_date_sent (info, camel_message_info_get_date_received (info));
+               if (!camel_message_info_get_date_received (info))
+                       camel_message_info_set_date_received (info, camel_message_info_get_date_sent (info));
+       } else {
+               camel_message_info_freeze_notifications (info);
        }
 
        user_has_read = (camel_message_info_get_flags (info) & CAMEL_MESSAGE_SEEN) != 0;
 
        update_message_info (info, object, is_new, gos->is_public_folder, user_has_read);
 
+       camel_message_info_thaw_notifications (info);
+
        if (is_new) {
                camel_folder_summary_add (gos->folder->summary, info);
                camel_folder_change_info_add_uid (gos->changes, camel_message_info_get_uid (info));
                camel_folder_change_info_recent_uid (gos->changes, camel_message_info_get_uid (info));
 
-               camel_message_info_ref (info);
+               g_object_ref (info);
        } else {
                camel_folder_change_info_change_uid (gos->changes, camel_message_info_get_uid (info));
        }
 
-       camel_message_info_unref (info);
+       g_clear_object (&info);
 
        if (obj_total > 0)
                camel_operation_progress (cancellable, obj_index * 100 / obj_total);
@@ -1072,27 +1066,6 @@ mapi_cmp_uids (CamelFolder *folder, const gchar *uid1, const gchar *uid2)
        return strcmp (uid1, uid2);
 }
 
-static gboolean
-mapi_set_message_flags (CamelFolder *folder,
-                        const gchar *uid,
-                        CamelMessageFlags flags,
-                        CamelMessageFlags set)
-{
-       CamelMessageInfo *info;
-       gint res;
-
-       g_return_val_if_fail (folder->summary != NULL, FALSE);
-
-       info = camel_folder_summary_get (folder->summary, uid);
-       if (info == NULL)
-               return FALSE;
-
-       res = camel_message_info_set_flags (info, flags, set);
-
-       camel_message_info_unref (info);
-       return res;
-}
-
 static void
 mapi_folder_dispose (GObject *object)
 {
@@ -1293,7 +1266,6 @@ mapi_folder_expunge_sync (CamelFolder *folder,
 {
        CamelMapiStore *mapi_store;
        CamelMapiFolder *mapi_folder;
-       CamelMapiMessageInfo *minfo;
        CamelMessageInfo *info;
        CamelFolderChangeInfo *changes;
        CamelStore *parent_store;
@@ -1375,8 +1347,7 @@ mapi_folder_expunge_sync (CamelFolder *folder,
        /*Collect UIDs of deleted messages.*/
        for (i = 0; known_uids && i < known_uids->len; i++) {
                info = camel_folder_summary_get (folder->summary, g_ptr_array_index (known_uids, i));
-               minfo = (CamelMapiMessageInfo *) info;
-               if (minfo && (minfo->info.flags & CAMEL_MESSAGE_DELETED)) {
+               if (info && (camel_message_info_get_flags (info) & CAMEL_MESSAGE_DELETED) != 0) {
                        const gchar *uid = camel_message_info_get_uid (info);
                        mapi_id_t *mid = g_new0 (mapi_id_t, 1);
 
@@ -1392,7 +1363,7 @@ mapi_folder_expunge_sync (CamelFolder *folder,
                        }
                        deleted_items_uid = g_slist_prepend (deleted_items_uid, (gpointer) uid);
                }
-               camel_message_info_unref (info);
+               g_clear_object (&info);
        }
 
        camel_folder_summary_free_array (known_uids);
@@ -1517,7 +1488,7 @@ mapi_folder_get_message_sync (CamelFolder *folder,
        CamelMimeMessage *msg = NULL;
        CamelMapiFolder *mapi_folder;
        CamelMapiStore *mapi_store;
-       CamelMapiMessageInfo *mi = NULL;
+       CamelMessageInfo *mi;
        CamelStore *parent_store;
        mapi_id_t id_message;
        EMapiConnection *conn;
@@ -1532,7 +1503,7 @@ mapi_folder_get_message_sync (CamelFolder *folder,
 
        /* see if it is there in cache */
 
-       mi = (CamelMapiMessageInfo *) camel_folder_summary_get (folder->summary, uid);
+       mi = camel_folder_summary_get (folder->summary, uid);
        if (mi == NULL) {
                /* Translators: The first %s is replaced with a message ID,
                   the second %s is replaced with a detailed error string */
@@ -1546,7 +1517,7 @@ mapi_folder_get_message_sync (CamelFolder *folder,
 
        msg = mapi_folder_get_message_cached (folder, uid, cancellable);
        if (msg != NULL) {
-               camel_message_info_unref (&mi->info);
+               g_clear_object (&mi);
                return msg;
        }
 
@@ -1555,7 +1526,7 @@ mapi_folder_get_message_sync (CamelFolder *folder,
                        error, CAMEL_SERVICE_ERROR,
                        CAMEL_SERVICE_ERROR_UNAVAILABLE,
                        _("This message is not available in offline mode."));
-               camel_message_info_unref (&mi->info);
+               g_clear_object (&mi);
                return NULL;
        }
 
@@ -1573,13 +1544,15 @@ mapi_folder_get_message_sync (CamelFolder *folder,
                                CAMEL_SERVICE_ERROR_INVALID,
                                _("Could not get message"));
                }
-               camel_message_info_unref (&mi->info);
+               g_clear_object (&mi);
                return NULL;
        }
 
        conn = camel_mapi_store_ref_connection (mapi_store, cancellable, error);
-       if (!conn)
+       if (!conn) {
+               g_clear_object (&mi);
                return NULL;
+       }
 
        e_mapi_util_mapi_id_from_string (uid, &id_message);
 
@@ -1606,13 +1579,13 @@ mapi_folder_get_message_sync (CamelFolder *folder,
                                CAMEL_SERVICE_ERROR_INVALID,
                                _("Could not get message"));
                }
-               camel_message_info_unref (&mi->info);
+               g_clear_object (&mi);
                return NULL;
        }
 
        add_message_to_cache (mapi_folder, uid, &msg, cancellable);
 
-       camel_message_info_unref (&mi->info);
+       g_clear_object (&mi);
 
        return msg;
 }
@@ -1634,7 +1607,6 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
        CamelMapiStore *mapi_store;
        CamelMapiFolder *mapi_folder;
        CamelMessageInfo *info = NULL;
-       CamelMapiMessageInfo *mapi_info = NULL;
        CamelStore *parent_store;
        CamelFolderChangeInfo *changes = NULL;
        CamelServiceConnectionStatus status;
@@ -1680,12 +1652,11 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
        known_uids = camel_folder_summary_get_array (folder->summary);
        for (i = 0; known_uids && i < known_uids->len; i++) {
                info = camel_folder_summary_get (folder->summary, g_ptr_array_index (known_uids, i));
-               mapi_info = (CamelMapiMessageInfo *) info;
 
-               if (mapi_info && (mapi_info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
+               if (info && camel_message_info_get_folder_flagged (info)) {
                        const gchar *uid;
                        mapi_id_t *mid = g_new0 (mapi_id_t, 1); /* FIXME : */
-                       guint32 flags;
+                       guint32 flags, server_flags;
                        gboolean used = FALSE;
 
                        uid = camel_message_info_get_uid (info);
@@ -1693,17 +1664,18 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
 
                        /* Why are we getting so much noise here :-/ */
                        if (!e_mapi_util_mapi_id_from_string (uid, mid)) {
-                               camel_message_info_unref (info);
+                               g_clear_object (&info);
                                g_free (mid);
                                continue;
                        }
 
-                       mapi_utils_do_flags_diff (&diff, mapi_info->server_flags, mapi_info->info.flags);
-                       mapi_utils_do_flags_diff (&unset_flags, flags, mapi_info->server_flags);
+                       server_flags = camel_mapi_message_info_get_server_flags (CAMEL_MAPI_MESSAGE_INFO 
(info));
+                       mapi_utils_do_flags_diff (&diff, server_flags, flags);
+                       mapi_utils_do_flags_diff (&unset_flags, flags, server_flags);
 
                        diff.changed &= folder->permanent_flags;
                        if (!diff.changed) {
-                               camel_message_info_unref (info);
+                               g_clear_object (&info);
                                g_free (mid);
                                continue;
                        }
@@ -1730,11 +1702,10 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
                        else
                                g_free (mid);
 
-                       mapi_info->server_flags = mapi_info->info.flags;
+                       camel_mapi_message_info_set_server_flags (CAMEL_MAPI_MESSAGE_INFO (info), 
camel_message_info_get_flags (info));
                }
 
-               if (info)
-                       camel_message_info_unref (info);
+               g_clear_object (&info);
        }
 
        camel_folder_summary_free_array (known_uids);
@@ -2030,7 +2001,6 @@ camel_mapi_folder_class_init (CamelMapiFolderClass *class)
        folder_class->cmp_uids = mapi_cmp_uids;
        folder_class->search_by_uids = mapi_folder_search_by_uids;
        folder_class->search_free = mapi_folder_search_free;
-       folder_class->set_message_flags = mapi_set_message_flags;
        folder_class->append_message_sync = mapi_folder_append_message_sync;
        folder_class->expunge_sync = mapi_folder_expunge_sync;
        folder_class->get_message_sync = mapi_folder_get_message_sync;
diff --git a/src/camel/camel-mapi-message-info.c b/src/camel/camel-mapi-message-info.c
new file mode 100644
index 0000000..acf0a3e
--- /dev/null
+++ b/src/camel/camel-mapi-message-info.c
@@ -0,0 +1,306 @@
+/* -*- 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-mapi-folder-summary.h"
+
+#include "camel-mapi-message-info.h"
+
+struct _CamelMapiMessageInfoPrivate {
+       guint32 server_flags;
+       gint64 last_modified; /* like time_t */
+};
+
+enum {
+       PROP_0,
+       PROP_SERVER_FLAGS,
+       PROP_LAST_MODIFIED
+};
+
+G_DEFINE_TYPE (CamelMapiMessageInfo, camel_mapi_message_info, CAMEL_TYPE_MESSAGE_INFO_BASE)
+
+static CamelMessageInfo *
+mapi_message_info_clone (const CamelMessageInfo *mi,
+                        CamelFolderSummary *assign_summary)
+{
+       CamelMessageInfo *result;
+
+       g_return_val_if_fail (CAMEL_IS_MAPI_MESSAGE_INFO (mi), NULL);
+
+       result = CAMEL_MESSAGE_INFO_CLASS (camel_mapi_message_info_parent_class)->clone (mi, assign_summary);
+       if (!result)
+               return NULL;
+
+       if (CAMEL_IS_MAPI_MESSAGE_INFO (result)) {
+               CamelMapiMessageInfo *mmi, *mmi_result;
+
+               mmi = CAMEL_MAPI_MESSAGE_INFO (mi);
+               mmi_result = CAMEL_MAPI_MESSAGE_INFO (result);
+
+               /* safe-guard that the mmi's filename doesn't change before it's copied to mmi_result */
+               camel_message_info_property_lock (mi);
+
+               camel_mapi_message_info_set_server_flags (mmi_result, 
camel_mapi_message_info_get_server_flags (mmi));
+               camel_mapi_message_info_set_last_modified (mmi_result, 
camel_mapi_message_info_get_last_modified (mmi));
+
+               camel_message_info_property_unlock (mi);
+       }
+
+       return result;
+}
+
+static gboolean
+mapi_message_info_load (CamelMessageInfo *mi,
+                       const CamelMIRecord *record,
+                       /* const */ gchar **bdata_ptr)
+{
+       CamelMapiMessageInfo *mmi;
+
+       g_return_val_if_fail (CAMEL_IS_MAPI_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_mapi_message_info_parent_class)->load ||
+           !CAMEL_MESSAGE_INFO_CLASS (camel_mapi_message_info_parent_class)->load (mi, record, bdata_ptr))
+               return FALSE;
+
+       mmi = CAMEL_MAPI_MESSAGE_INFO (mi);
+
+       camel_mapi_message_info_set_server_flags (mmi, camel_util_bdata_get_number (bdata_ptr, 0));
+       camel_mapi_message_info_set_last_modified (mmi, camel_util_bdata_get_number (bdata_ptr, 0));
+
+       return TRUE;
+}
+
+static gboolean
+mapi_message_info_save (const CamelMessageInfo *mi,
+                       CamelMIRecord *record,
+                       GString *bdata_str)
+{
+       CamelMapiMessageInfo *mmi;
+
+       g_return_val_if_fail (CAMEL_IS_MAPI_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_mapi_message_info_parent_class)->save ||
+           !CAMEL_MESSAGE_INFO_CLASS (camel_mapi_message_info_parent_class)->save (mi, record, bdata_str))
+               return FALSE;
+
+       mmi = CAMEL_MAPI_MESSAGE_INFO (mi);
+
+       camel_util_bdata_put_number (bdata_str, camel_mapi_message_info_get_server_flags (mmi));
+       camel_util_bdata_put_number (bdata_str, camel_mapi_message_info_get_last_modified (mmi));
+
+       return TRUE;
+}
+
+static void
+mapi_message_info_set_property (GObject *object,
+                               guint property_id,
+                               const GValue *value,
+                               GParamSpec *pspec)
+{
+       CamelMapiMessageInfo *mmi = CAMEL_MAPI_MESSAGE_INFO (object);
+
+       switch (property_id) {
+       case PROP_SERVER_FLAGS:
+               camel_mapi_message_info_set_server_flags (mmi, g_value_get_uint (value));
+               return;
+
+       case PROP_LAST_MODIFIED:
+               camel_mapi_message_info_set_last_modified (mmi, g_value_get_int64 (value));
+               return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mapi_message_info_get_property (GObject *object,
+                                  guint property_id,
+                                  GValue *value,
+                                  GParamSpec *pspec)
+{
+       CamelMapiMessageInfo *mmi = CAMEL_MAPI_MESSAGE_INFO (object);
+
+       switch (property_id) {
+       case PROP_SERVER_FLAGS:
+               g_value_set_uint (value, camel_mapi_message_info_get_server_flags (mmi));
+               return;
+
+       case PROP_LAST_MODIFIED:
+               g_value_set_int64 (value, camel_mapi_message_info_get_last_modified (mmi));
+               return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+camel_mapi_message_info_class_init (CamelMapiMessageInfoClass *class)
+{
+       CamelMessageInfoClass *mi_class;
+       GObjectClass *object_class;
+
+       g_type_class_add_private (class, sizeof (CamelMapiMessageInfoPrivate));
+
+       mi_class = CAMEL_MESSAGE_INFO_CLASS (class);
+       mi_class->clone = mapi_message_info_clone;
+       mi_class->load = mapi_message_info_load;
+       mi_class->save = mapi_message_info_save;
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->set_property = mapi_message_info_set_property;
+       object_class->get_property = mapi_message_info_get_property;
+
+       /**
+        * CamelMapiMessageInfo:server-flags
+        *
+        * Flags of the message on the server.
+        *
+        * 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));
+
+       /**
+        * CamelMapiMessageInfo:last-modified
+        *
+        * PidTagLastModificationTime of this message.
+        *
+        * Since: 3.24
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_LAST_MODIFIED,
+               g_param_spec_int64 (
+                       "last-modified",
+                       "Last Modified",
+                       NULL,
+                       G_MININT64, G_MAXINT64, 0,
+                       G_PARAM_READWRITE));
+}
+
+static void
+camel_mapi_message_info_init (CamelMapiMessageInfo *mmi)
+{
+       mmi->priv = G_TYPE_INSTANCE_GET_PRIVATE (mmi, CAMEL_TYPE_MAPI_MESSAGE_INFO, 
CamelMapiMessageInfoPrivate);
+}
+
+guint32
+camel_mapi_message_info_get_server_flags (const CamelMapiMessageInfo *mmi)
+{
+       CamelMessageInfo *mi;
+       guint32 result;
+
+       g_return_val_if_fail (CAMEL_IS_MAPI_MESSAGE_INFO (mmi), 0);
+
+       mi = CAMEL_MESSAGE_INFO (mmi);
+
+       camel_message_info_property_lock (mi);
+       result = mmi->priv->server_flags;
+       camel_message_info_property_unlock (mi);
+
+       return result;
+}
+
+gboolean
+camel_mapi_message_info_set_server_flags (CamelMapiMessageInfo *mmi,
+                                         guint32 server_flags)
+{
+       CamelMessageInfo *mi;
+       gboolean changed;
+
+       g_return_val_if_fail (CAMEL_IS_MAPI_MESSAGE_INFO (mmi), FALSE);
+
+       mi = CAMEL_MESSAGE_INFO (mmi);
+
+       camel_message_info_property_lock (mi);
+
+       changed = mmi->priv->server_flags != server_flags;
+
+       if (changed)
+               mmi->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 (mmi), "server-flags");
+               camel_message_info_set_dirty (mi, TRUE);
+       }
+
+       return changed;
+}
+
+gint64
+camel_mapi_message_info_get_last_modified (const CamelMapiMessageInfo *mmi)
+{
+       CamelMessageInfo *mi;
+       gint64 result;
+
+       g_return_val_if_fail (CAMEL_IS_MAPI_MESSAGE_INFO (mmi), 0);
+
+       mi = CAMEL_MESSAGE_INFO (mmi);
+
+       camel_message_info_property_lock (mi);
+       result = mmi->priv->last_modified;
+       camel_message_info_property_unlock (mi);
+
+       return result;
+}
+
+gboolean
+camel_mapi_message_info_set_last_modified (CamelMapiMessageInfo *mmi,
+                                          gint64 last_modified)
+{
+       CamelMessageInfo *mi;
+       gboolean changed;
+
+       g_return_val_if_fail (CAMEL_IS_MAPI_MESSAGE_INFO (mmi), FALSE);
+
+       mi = CAMEL_MESSAGE_INFO (mmi);
+
+       camel_message_info_property_lock (mi);
+
+       changed = mmi->priv->last_modified != last_modified;
+
+       if (changed)
+               mmi->priv->last_modified = last_modified;
+
+       camel_message_info_property_unlock (mi);
+
+       if (changed && !camel_message_info_get_abort_notifications (mi)) {
+               g_object_notify (G_OBJECT (mmi), "last-modified");
+               camel_message_info_set_dirty (mi, TRUE);
+       }
+
+       return changed;
+}
diff --git a/src/camel/camel-mapi-message-info.h b/src/camel/camel-mapi-message-info.h
new file mode 100644
index 0000000..994c119
--- /dev/null
+++ b/src/camel/camel-mapi-message-info.h
@@ -0,0 +1,76 @@
+/* -*- 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_MAPI_MESSAGE_INFO_H
+#define CAMEL_MAPI_MESSAGE_INFO_H
+
+#include <glib-object.h>
+
+#include <camel/camel.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_MAPI_MESSAGE_INFO \
+       (camel_mapi_message_info_get_type ())
+#define CAMEL_MAPI_MESSAGE_INFO(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), CAMEL_TYPE_MAPI_MESSAGE_INFO, CamelMapiMessageInfo))
+#define CAMEL_MAPI_MESSAGE_INFO_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), CAMEL_TYPE_MAPI_MESSAGE_INFO, CamelMapiMessageInfoClass))
+#define CAMEL_IS_MAPI_MESSAGE_INFO(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), CAMEL_TYPE_MAPI_MESSAGE_INFO))
+#define CAMEL_IS_MAPI_MESSAGE_INFO_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), CAMEL_TYPE_MAPI_MESSAGE_INFO))
+#define CAMEL_MAPI_MESSAGE_INFO_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), CAMEL_TYPE_MAPI_MESSAGE_INFO, CamelMapiMessageInfoClass))
+
+G_BEGIN_DECLS
+
+#define CAMEL_MAPI_MESSAGE_WITH_READ_RECEIPT (CAMEL_MESSAGE_FOLDER_FLAGGED << 1)
+
+typedef struct _CamelMapiMessageInfo CamelMapiMessageInfo;
+typedef struct _CamelMapiMessageInfoClass CamelMapiMessageInfoClass;
+typedef struct _CamelMapiMessageInfoPrivate CamelMapiMessageInfoPrivate;
+
+struct _CamelMapiMessageInfo {
+       CamelMessageInfoBase parent;
+       CamelMapiMessageInfoPrivate *priv;
+};
+
+struct _CamelMapiMessageInfoClass {
+       CamelMessageInfoBaseClass parent_class;
+};
+
+GType          camel_mapi_message_info_get_type        (void);
+
+guint32                camel_mapi_message_info_get_server_flags
+                                                       (const CamelMapiMessageInfo *mmi);
+gboolean       camel_mapi_message_info_set_server_flags
+                                                       (CamelMapiMessageInfo *mmi,
+                                                        guint32 server_flags);
+gint64         camel_mapi_message_info_get_last_modified
+                                                       (const CamelMapiMessageInfo *mmi);
+gboolean       camel_mapi_message_info_set_last_modified
+                                                       (CamelMapiMessageInfo *mmi,
+                                                        gint64 last_modified);
+
+G_END_DECLS
+
+#endif /* CAMEL_MAPI_MESSAGE_INFO_H */



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