You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2018/12/21 02:25:33 UTC

[2/4] james-project git commit: MAILBOX-359 Do not mix system and user flags in JSON

MAILBOX-359 Do not mix system and user flags in JSON


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ae28a25a
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ae28a25a
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ae28a25a

Branch: refs/heads/master
Commit: ae28a25a26c38d6ff5d533c1f7f4abd087acb51b
Parents: 110e9a2
Author: Matthieu Baechler <ma...@apache.org>
Authored: Wed Dec 19 14:51:36 2018 +0100
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Fri Dec 21 09:10:55 2018 +0700

----------------------------------------------------------------------
 .../org/apache/james/event/json/DTOs.scala      |  84 ++---
 .../james/event/json/EventSerializer.scala      |  18 +-
 .../event/json/AddedSerializationTest.java      | 358 +++++++++++++-----
 .../event/json/ExpungedSerializationTest.java   | 370 +++++++++++++-----
 .../json/FlagsUpdatedSerializationTest.java     | 371 +++++++++++++------
 5 files changed, 871 insertions(+), 330 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/ae28a25a/mailbox/event/json/src/main/scala/org/apache/james/event/json/DTOs.scala
----------------------------------------------------------------------
diff --git a/mailbox/event/json/src/main/scala/org/apache/james/event/json/DTOs.scala b/mailbox/event/json/src/main/scala/org/apache/james/event/json/DTOs.scala
index c708f92..ec8bea4 100644
--- a/mailbox/event/json/src/main/scala/org/apache/james/event/json/DTOs.scala
+++ b/mailbox/event/json/src/main/scala/org/apache/james/event/json/DTOs.scala
@@ -22,8 +22,10 @@ package org.apache.james.event.json
 import java.time.Instant
 import java.util.Date
 
+import javax.mail.Flags.Flag
 import javax.mail.{Flags => JavaMailFlags}
 import org.apache.james.core.quota.QuotaValue
+import org.apache.james.event.json.DTOs.SystemFlag.SystemFlag
 import org.apache.james.mailbox.acl.{ACLDiff => JavaACLDiff}
 import org.apache.james.mailbox.model.{MailboxACL, MessageId, MailboxPath => JavaMailboxPath, MessageMetaData => JavaMessageMetaData, Quota => JavaQuota, UpdatedFlags => JavaUpdatedFlags}
 import org.apache.james.mailbox.{FlagsBuilder, MessageUid}
@@ -74,58 +76,56 @@ object DTOs {
     def fromJava(javaMessageMetaData: JavaMessageMetaData): MessageMetaData = DTOs.MessageMetaData(
       javaMessageMetaData.getUid,
       javaMessageMetaData.getModSeq,
-      javaMessageMetaData.getFlags,
+      Flags.fromJavaFlags(javaMessageMetaData.getFlags),
       javaMessageMetaData.getSize,
       javaMessageMetaData.getInternalDate.toInstant,
       javaMessageMetaData.getMessageId)
   }
 
-  case class MessageMetaData(uid: MessageUid, modSeq: Long, flags: JavaMailFlags, size: Long, internalDate: Instant, messageId: MessageId) {
-    def toJava: JavaMessageMetaData = new JavaMessageMetaData(uid, modSeq, flags, size, Date.from(internalDate), messageId)
+  case class MessageMetaData(uid: MessageUid, modSeq: Long, flags: Flags, size: Long, internalDate: Instant, messageId: MessageId) {
+    def toJava: JavaMessageMetaData = new JavaMessageMetaData(uid, modSeq, Flags.toJavaFlags(flags), size, Date.from(internalDate), messageId)
   }
 
+  case class UserFlag(value: String) extends AnyVal
+
+  object SystemFlag extends Enumeration {
+    type SystemFlag = Value
+    val Answered, Deleted, Draft, Flagged, Recent, Seen = Value
+  }
+
+  case class Flags(systemFlags: Seq[SystemFlag], userFlags: Seq[UserFlag])
+
   object Flags {
-    val ANSWERED = "\\Answered"
-    val DELETED = "\\Deleted"
-    val DRAFT = "\\Draft"
-    val FLAGGED = "\\Flagged"
-    val RECENT = "\\Recent"
-    val SEEN = "\\Seen"
-    val ALL_SYSTEM_FLAGS = List(ANSWERED, DELETED, DRAFT, FLAGGED, RECENT, SEEN)
-
-    def toJavaFlags(serializedFlags: Array[String]): JavaMailFlags = {
-      serializedFlags
-        .map(toJavaMailFlag)
-        .foldLeft(new FlagsBuilder)((builder, flag) => builder.add(flag))
-        .build()
-    }
 
-    def toJavaMailFlag(flag: String): JavaMailFlags = ALL_SYSTEM_FLAGS.contains(flag) match {
-      case true => new FlagsBuilder().add(stringToSystemFlag(flag)).build()
-      case false => new FlagsBuilder().add(flag).build()
+    def toJavaFlags(scalaFlags: Flags): JavaMailFlags = {
+      new FlagsBuilder { builder =>
+        scalaFlags.userFlags.foreach(flag => builder.add(flag.value))
+        scalaFlags.systemFlags.foreach(flag => addJavaFlag(builder, flag))
+      }.build()
     }
 
-    def fromJavaFlags(flags: JavaMailFlags): Array[String] = {
-      flags.getUserFlags ++ flags.getSystemFlags.map(flag => systemFlagToString(flag))
+    private def addJavaFlag(builder: FlagsBuilder, flag: SystemFlag): FlagsBuilder = flag match {
+      case SystemFlag.Answered => builder.add(Flag.ANSWERED)
+      case SystemFlag.Deleted => builder.add(Flag.DELETED)
+      case SystemFlag.Draft => builder.add(Flag.DRAFT)
+      case SystemFlag.Flagged => builder.add(Flag.FLAGGED)
+      case SystemFlag.Recent => builder.add(Flag.RECENT)
+      case SystemFlag.Seen => builder.add(Flag.SEEN)
     }
 
-    private def stringToSystemFlag(serializedFlag: String): JavaMailFlags.Flag = serializedFlag match {
-      case ANSWERED => JavaMailFlags.Flag.ANSWERED
-      case DELETED => JavaMailFlags.Flag.DELETED
-      case DRAFT => JavaMailFlags.Flag.DRAFT
-      case FLAGGED => JavaMailFlags.Flag.FLAGGED
-      case RECENT => JavaMailFlags.Flag.RECENT
-      case SEEN => JavaMailFlags.Flag.SEEN
-      case _ => throw new IllegalArgumentException(serializedFlag + " is not a system flag")
+    def fromJavaFlags(flags: JavaMailFlags): Flags = {
+      Flags(
+        flags.getSystemFlags.map(javaFlagToSystemFlag),
+        flags.getUserFlags.map(UserFlag))
     }
 
-    private def systemFlagToString(flag: JavaMailFlags.Flag): String = flag match {
-      case JavaMailFlags.Flag.ANSWERED => ANSWERED
-      case JavaMailFlags.Flag.DELETED => DELETED
-      case JavaMailFlags.Flag.DRAFT => DRAFT
-      case JavaMailFlags.Flag.FLAGGED => FLAGGED
-      case JavaMailFlags.Flag.RECENT => RECENT
-      case JavaMailFlags.Flag.SEEN => SEEN
+    private def javaFlagToSystemFlag(flag: JavaMailFlags.Flag): SystemFlag = flag match {
+      case Flag.ANSWERED => SystemFlag.Answered
+      case Flag.DELETED => SystemFlag.Deleted
+      case Flag.DRAFT => SystemFlag.Draft
+      case Flag.FLAGGED => SystemFlag.Flagged
+      case Flag.RECENT => SystemFlag.Recent
+      case Flag.SEEN => SystemFlag.Seen
     }
   }
 
@@ -133,16 +133,16 @@ object DTOs {
     def toUpdatedFlags(javaUpdatedFlags: JavaUpdatedFlags): UpdatedFlags = UpdatedFlags(
       javaUpdatedFlags.getUid,
       javaUpdatedFlags.getModSeq,
-      Flags.fromJavaFlags(javaUpdatedFlags.getOldFlags).toList,
-      Flags.fromJavaFlags(javaUpdatedFlags.getNewFlags).toList)
+      Flags.fromJavaFlags(javaUpdatedFlags.getOldFlags),
+      Flags.fromJavaFlags(javaUpdatedFlags.getNewFlags))
   }
 
-  case class UpdatedFlags(uid: MessageUid, modSeq: Long, oldFlags: List[String], newFlags: List[String]) {
+  case class UpdatedFlags(uid: MessageUid, modSeq: Long, oldFlags: Flags, newFlags: Flags) {
     def toJava: JavaUpdatedFlags = JavaUpdatedFlags.builder()
       .uid(uid)
       .modSeq(modSeq)
-      .oldFlags(Flags.toJavaFlags(oldFlags.toArray))
-      .newFlags(Flags.toJavaFlags(newFlags.toArray))
+      .oldFlags(Flags.toJavaFlags(oldFlags))
+      .newFlags(Flags.toJavaFlags(newFlags))
       .build()
   }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/ae28a25a/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
----------------------------------------------------------------------
diff --git a/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala b/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
index b434164..af2785e 100644
--- a/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
+++ b/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
@@ -22,16 +22,16 @@ package org.apache.james.event.json
 import java.time.Instant
 import java.util.{Optional, TreeMap => JavaTreeMap}
 
-import javax.mail.{Flags => JavaMailFlags}
 import julienrf.json.derived
 import org.apache.james.core.quota.{QuotaCount, QuotaSize, QuotaValue}
 import org.apache.james.core.{Domain, User}
-import org.apache.james.event.json.DTOs.{ACLDiff, Flags, MailboxPath, Quota}
+import org.apache.james.event.json.DTOs.SystemFlag.SystemFlag
+import org.apache.james.event.json.DTOs.{ACLDiff, Flags, MailboxPath, Quota, SystemFlag, UserFlag}
 import org.apache.james.mailbox.MailboxListener.{Added => JavaAdded, Expunged => JavaExpunged, FlagsUpdated => JavaFlagsUpdated, MailboxACLUpdated => JavaMailboxACLUpdated, MailboxAdded => JavaMailboxAdded, MailboxDeletion => JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, QuotaUsageUpdatedEvent => JavaQuotaUsageUpdatedEvent}
 import org.apache.james.mailbox.MailboxSession.SessionId
 import org.apache.james.mailbox.model.{MailboxId, MessageId, MessageMoves, QuotaRoot, MailboxACL => JavaMailboxACL, MessageMetaData => JavaMessageMetaData, Quota => JavaQuota}
 import org.apache.james.mailbox.{MessageUid, Event => JavaEvent, MessageMoveEvent => JavaMessageMoveEvent}
-import play.api.libs.json.{JsArray, JsError, JsNull, JsNumber, JsObject, JsResult, JsString, JsSuccess, Json, OFormat, Reads, Writes}
+import play.api.libs.json.{JsError, JsNull, JsNumber, JsObject, JsResult, JsString, JsSuccess, Json, OFormat, Reads, Writes}
 
 import scala.collection.JavaConverters._
 
@@ -191,6 +191,7 @@ private object ScalaConverter {
 }
 
 private class JsonSerialize(mailboxIdFactory: MailboxId.Factory, messageIdFactory: MessageId.Factory) {
+  implicit val systemFlagsWrites: Writes[SystemFlag] = Writes.enumNameWrites
   implicit val userWriters: Writes[User] = (user: User) => JsString(user.asString)
   implicit val quotaRootWrites: Writes[QuotaRoot] = quotaRoot => JsString(quotaRoot.getValue)
   implicit val quotaValueWrites: Writes[QuotaValue[_]] = value => if (value.isUnlimited) JsNull else JsNumber(value.asLong())
@@ -205,10 +206,14 @@ private class JsonSerialize(mailboxIdFactory: MailboxId.Factory, messageIdFactor
   implicit val aclDiffWrites: Writes[ACLDiff] = Json.writes[ACLDiff]
   implicit val messageIdWrites: Writes[MessageId] = value => JsString(value.serialize())
   implicit val messageUidWrites: Writes[MessageUid] = value => JsNumber(value.asLong())
-  implicit val flagsWrites: Writes[JavaMailFlags] = value => JsArray(Flags.fromJavaFlags(value).map(flag => JsString(flag)))
+  implicit val userFlagWrites: Writes[UserFlag] = value => JsString(value.value)
+  implicit val flagWrites: Writes[Flags] = Json.writes[Flags]
+
   implicit val messageMetaDataWrites: Writes[DTOs.MessageMetaData] = Json.writes[DTOs.MessageMetaData]
   implicit val updatedFlagsWrites: Writes[DTOs.UpdatedFlags] = Json.writes[DTOs.UpdatedFlags]
 
+  implicit val systemFlagsReads: Reads[SystemFlag] = Reads.enumNameReads(SystemFlag)
+
   implicit val aclEntryKeyReads: Reads[JavaMailboxACL.EntryKey] = {
     case JsString(keyAsString) => JsSuccess(JavaMailboxACL.EntryKey.deserialize(keyAsString))
     case _ => JsError()
@@ -255,8 +260,8 @@ private class JsonSerialize(mailboxIdFactory: MailboxId.Factory, messageIdFactor
     case JsNumber(value) => JsSuccess(MessageUid.of(value.toLong))
     case _ => JsError()
   }
-  implicit val flagsReads: Reads[JavaMailFlags] = {
-    case JsArray(seqOfJsValues) => JsSuccess(Flags.toJavaFlags(seqOfJsValues.toArray.map(jsValue => jsValue.toString())))
+  implicit val userFlagsReads: Reads[UserFlag] = {
+    case JsString(x) => JsSuccess(UserFlag(x))
     case _ => JsError()
   }
 
@@ -291,6 +296,7 @@ private class JsonSerialize(mailboxIdFactory: MailboxId.Factory, messageIdFactor
       JsObject(m.map { case (k, v) => (String.valueOf(k.asLong()), vr.writes(v)) }.toSeq)
     }
 
+  implicit val flagsReads: Reads[Flags] = Json.reads[Flags]
   implicit val aclDiffReads: Reads[ACLDiff] = Json.reads[ACLDiff]
   implicit val quotaCReads: Reads[DTOs.Quota[QuotaCount]] = Json.reads[DTOs.Quota[QuotaCount]]
   implicit val quotaSReads: Reads[DTOs.Quota[QuotaSize]] = Json.reads[DTOs.Quota[QuotaSize]]

http://git-wip-us.apache.org/repos/asf/james-project/blob/ae28a25a/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
----------------------------------------------------------------------
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
index cbc481a..a96de11 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
@@ -81,7 +81,9 @@ class AddedSerializationTest {
         "      \"123456\": {" +
         "        \"uid\": 123456," +
         "        \"modSeq\": 35," +
-        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+        "        \"flags\": {" +
+        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+        "          \"userFlags\":[\"User Custom Flag\"]}," +
         "        \"size\": 45,  " +
         "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
         "        \"messageId\": \"42\"" +
@@ -162,7 +164,9 @@ class AddedSerializationTest {
                 "      \"123456\": {" +
                 "        \"uid\": 123456," +
                 "        \"modSeq\": 35," +
-                "        \"flags\": []," +
+                "        \"flags\": {" +
+                "          \"systemFlags\":[], " +
+                "          \"userFlags\":[]}," +
                 "        \"size\": 45,  " +
                 "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                 "        \"messageId\": \"42\"" +
@@ -209,7 +213,9 @@ class AddedSerializationTest {
                 "      \"123456\": {" +
                 "        \"uid\": 123456," +
                 "        \"modSeq\": 35," +
-                "        \"flags\": [\"Custom 1\", \"Custom 2\", \"\"]," +
+                "        \"flags\": {" +
+                "          \"systemFlags\":[], " +
+                "          \"userFlags\":[\"Custom 1\", \"Custom 2\", \"\"]}," +
                 "        \"size\": 45,  " +
                 "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                 "        \"messageId\": \"42\"" +
@@ -257,7 +263,9 @@ class AddedSerializationTest {
                 "      \"123456\": {" +
                 "        \"uid\": 123456," +
                 "        \"modSeq\": 35," +
-                "        \"flags\": [\"\\\\Seen\", \"\\\\Answered\", \"\\\\Deleted\"]," +
+                "        \"flags\": {" +
+                "          \"systemFlags\":[\"Seen\",\"Answered\",\"Deleted\"], " +
+                "          \"userFlags\":[]}," +
                 "        \"size\": 45,  " +
                 "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                 "        \"messageId\": \"42\"" +
@@ -281,44 +289,6 @@ class AddedSerializationTest {
                     .isEqualTo(onlySystemFlagsAddedEvent);
             }
         }
-
-        @Nested
-        class WithFlagCaseSensitive {
-
-            private static final String CASE_SENSITIVE_SYSTEM_FLAGS_EVENT_JSON =
-                "{" +
-                "  \"Added\": {" +
-                "    \"path\": {" +
-                "      \"namespace\": \"#private\"," +
-                "      \"user\": \"user\"," +
-                "      \"name\": \"mailboxName\"" +
-                "    }," +
-                "    \"mailboxId\": \"18\"," +
-                "    \"added\": {" +
-                "      \"123456\": {" +
-                "        \"uid\": 123456," +
-                "        \"modSeq\": 35," +
-                "        \"flags\": [\"User Custom Flag\", \"\\\\answereD\", \"\\\\dRaFt\"]," +
-                "        \"size\": 45,  " +
-                "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
-                "        \"messageId\": \"42\"" +
-                "      }" +
-                "    }," +
-                "    \"sessionId\": 42," +
-                "    \"user\": \"user\"" +
-                "  }" +
-                "}";
-
-             @Test
-            void addedShouldCareAboutSystemFlagsCaseSensitive() {
-                 MailboxListener.Added deSerializedEvent = (MailboxListener.Added) EVENT_SERIALIZER
-                     .fromJson(CASE_SENSITIVE_SYSTEM_FLAGS_EVENT_JSON)
-                     .get();
-
-                 assertThat(deSerializedEvent.getMetaData(MESSAGE_UID).getFlags().getSystemFlags())
-                     .isEmpty();
-            }
-        }
     }
 
     @Nested
@@ -343,7 +313,9 @@ class AddedSerializationTest {
                 "      \"123456\": {" +
                 "        \"uid\": 123456," +
                 "        \"modSeq\": 35," +
-                "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                "        \"flags\": {" +
+                "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                "          \"userFlags\":[\"User Custom Flag\"]}," +
                 "        \"size\": 45,  " +
                 "        \"internalDate\": \"2018-12-14T09:41:51+00:00\"," +
                 "        \"messageId\": \"42\"" +
@@ -375,7 +347,9 @@ class AddedSerializationTest {
                 "      \"123456\": {" +
                 "        \"uid\": 123456," +
                 "        \"modSeq\": 35," +
-                "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                "        \"flags\": {" +
+                "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                "          \"userFlags\":[\"User Custom Flag\"]}," +
                 "        \"size\": 45,  " +
                 "        \"internalDate\": \"2018-12-14T09:41:51Z\"," +
                 "        \"messageId\": \"42\"" +
@@ -407,7 +381,9 @@ class AddedSerializationTest {
                 "      \"123456\": {" +
                 "        \"uid\": 123456," +
                 "        \"modSeq\": 35," +
-                "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                "        \"flags\": {" +
+                "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                "          \"userFlags\":[\"User Custom Flag\"]}," +
                 "        \"size\": 45,  " +
                 "        \"internalDate\": \"2018-12-14T09:41Z\"," +
                 "        \"messageId\": \"42\"" +
@@ -420,6 +396,7 @@ class AddedSerializationTest {
             .isEqualTo(eventRoundToMinute);
         }
     }
+
     @Nested
     class NullOrEmptyNameSpaceInMailboxPath {
 
@@ -437,7 +414,9 @@ class AddedSerializationTest {
                 "      \"123456\": {" +
                 "        \"uid\": 123456," +
                 "        \"modSeq\": 35," +
-                "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                "        \"flags\": {" +
+                "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                "          \"userFlags\":[\"User Custom Flag\"]}," +
                 "        \"size\": 45,  " +
                 "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                 "        \"messageId\": \"42\"" +
@@ -465,7 +444,9 @@ class AddedSerializationTest {
                 "      \"123456\": {" +
                 "        \"uid\": 123456," +
                 "        \"modSeq\": 35," +
-                "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                "        \"flags\": {" +
+                "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                "          \"userFlags\":[\"User Custom Flag\"]}," +
                 "        \"size\": 45,  " +
                 "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                 "        \"messageId\": \"42\"" +
@@ -501,7 +482,9 @@ class AddedSerializationTest {
             "      \"123456\": {" +
             "        \"uid\": 123456," +
             "        \"modSeq\": 35," +
-            "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+            "        \"flags\": {" +
+            "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+            "          \"userFlags\":[\"User Custom Flag\"]}," +
             "        \"size\": 45,  " +
             "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
             "        \"messageId\": \"42\"" +
@@ -545,7 +528,9 @@ class AddedSerializationTest {
                     "      \"123456\": {" +
                     "        \"uid\": 123456," +
                     "        \"modSeq\": 35," +
-                    "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                    "        \"flags\": {" +
+                    "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                    "          \"userFlags\":[\"User Custom Flag\"]}," +
                     "        \"size\": 45,  " +
                     "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                     "        \"messageId\": \"42\"" +
@@ -572,7 +557,9 @@ class AddedSerializationTest {
                     "      \"123456\": {" +
                     "        \"uid\": 123456," +
                     "        \"modSeq\": 35," +
-                    "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                    "        \"flags\": {" +
+                    "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                    "          \"userFlags\":[\"User Custom Flag\"]}," +
                     "        \"size\": 45,  " +
                     "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                     "        \"messageId\": \"42\"" +
@@ -600,7 +587,9 @@ class AddedSerializationTest {
                     "      \"123456\": {" +
                     "        \"uid\": 123456," +
                     "        \"modSeq\": 35," +
-                    "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                    "        \"flags\": {" +
+                    "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                    "          \"userFlags\":[\"User Custom Flag\"]}," +
                     "        \"size\": 45,  " +
                     "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                     "        \"messageId\": \"42\"" +
@@ -631,7 +620,9 @@ class AddedSerializationTest {
                     "      \"123456\": {" +
                     "        \"uid\": 123456," +
                     "        \"modSeq\": 35," +
-                    "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                    "        \"flags\": {" +
+                    "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                    "          \"userFlags\":[\"User Custom Flag\"]}," +
                     "        \"size\": 45,  " +
                     "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                     "        \"messageId\": \"42\"" +
@@ -658,7 +649,9 @@ class AddedSerializationTest {
                     "      \"123456\": {" +
                     "        \"uid\": 123456," +
                     "        \"modSeq\": 35," +
-                    "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                    "        \"flags\": {" +
+                    "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                    "          \"userFlags\":[\"User Custom Flag\"]}," +
                     "        \"size\": 45,  " +
                     "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                     "        \"messageId\": \"42\"" +
@@ -686,7 +679,9 @@ class AddedSerializationTest {
                     "      \"123456\": {" +
                     "        \"uid\": 123456," +
                     "        \"modSeq\": 35," +
-                    "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                    "        \"flags\": {" +
+                    "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                    "          \"userFlags\":[\"User Custom Flag\"]}," +
                     "        \"size\": 45,  " +
                     "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                     "        \"messageId\": \"42\"" +
@@ -716,7 +711,9 @@ class AddedSerializationTest {
                     "      \"123456\": {" +
                     "        \"uid\": 123456," +
                     "        \"modSeq\": 35," +
-                    "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                    "        \"flags\": {" +
+                    "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                    "          \"userFlags\":[\"User Custom Flag\"]}," +
                     "        \"size\": 45,  " +
                     "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                     "        \"messageId\": \"42\"" +
@@ -744,7 +741,9 @@ class AddedSerializationTest {
                     "      \"123456\": {" +
                     "        \"uid\": 123456," +
                     "        \"modSeq\": 35," +
-                    "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                    "        \"flags\": {" +
+                    "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                    "          \"userFlags\":[\"User Custom Flag\"]}," +
                     "        \"size\": 45,  " +
                     "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                     "        \"messageId\": \"42\"" +
@@ -772,7 +771,9 @@ class AddedSerializationTest {
                     "      \"123456\": {" +
                     "        \"uid\": 123456," +
                     "        \"modSeq\": 35," +
-                    "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                    "        \"flags\": {" +
+                    "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                    "          \"userFlags\":[\"User Custom Flag\"]}," +
                     "        \"size\": 45,  " +
                     "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                     "        \"messageId\": \"42\"" +
@@ -806,7 +807,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": \"42\"" +
@@ -837,7 +840,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": \"42\"" +
@@ -869,7 +874,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": \"42\"" +
@@ -897,7 +904,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": \"42\"" +
@@ -951,7 +960,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": \"123456\"," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": \"42\"" +
@@ -979,7 +990,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": null," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": \"42\"" +
@@ -1011,7 +1024,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": \"35\"," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": \"42\"" +
@@ -1039,7 +1054,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": null," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": \"42\"" +
@@ -1053,7 +1070,6 @@ class AddedSerializationTest {
                 }
             }
 
-
             @Nested
             class DeserializationErrorOnSize {
 
@@ -1072,7 +1088,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": \"45\",  " +
                         "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": \"42\"" +
@@ -1100,7 +1118,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": null,  " +
                         "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": \"42\"" +
@@ -1132,7 +1152,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": 42" +
@@ -1160,7 +1182,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": null" +
@@ -1191,7 +1215,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14 12:52:36+07:00\"," +
                         "        \"messageId\": \"42\"" +
@@ -1219,7 +1245,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14\"," +
                         "        \"messageId\": \"42\"" +
@@ -1247,7 +1275,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14TZ\"," +
                         "        \"messageId\": \"42\"" +
@@ -1275,7 +1305,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14T09:41:51.541\"," +
                         "        \"messageId\": \"42\"" +
@@ -1303,7 +1335,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"2018-12-14Z\"," +
                         "        \"messageId\": \"42\"" +
@@ -1331,7 +1365,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": \"\"," +
                         "        \"messageId\": \"42\"" +
@@ -1359,7 +1395,9 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"User Custom Flag\", \"\\\\Answered\", \"\\\\Draft\"]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"Answered\",\"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
                         "        \"internalDate\": null," +
                         "        \"messageId\": \"42\"" +
@@ -1393,7 +1431,7 @@ class AddedSerializationTest {
                         "        \"modSeq\": 35," +
                         "        \"flags\": null," +
                         "        \"size\": 45,  " +
-                        "        \"internalDate\": \"\"," +
+                        "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": \"42\"" +
                         "      }" +
                         "    }," +
@@ -1405,7 +1443,7 @@ class AddedSerializationTest {
                 }
 
                 @Test
-                void addedShouldThrowWhenFlagsContainsNullElements() {
+                void addedShouldThrowWhenSystemFlagsContainsNullElements() {
                     assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                         "{" +
                         "  \"Added\": {" +
@@ -1419,9 +1457,11 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"flag 1\", null, \"flags 2\", null]," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[null, \"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
                         "        \"size\": 45,  " +
-                        "        \"internalDate\": \"\"," +
+                        "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": \"42\"" +
                         "      }" +
                         "    }," +
@@ -1433,7 +1473,7 @@ class AddedSerializationTest {
                 }
 
                 @Test
-                void addedShouldThrowWhenFlagsContainsNumberElements() {
+                void addedShouldThrowWhenUserFlagsContainsNullElements() {
                     assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
                         "{" +
                         "  \"Added\": {" +
@@ -1447,9 +1487,11 @@ class AddedSerializationTest {
                         "      \"123456\": {" +
                         "        \"uid\": 123456," +
                         "        \"modSeq\": 35," +
-                        "        \"flags\": [\"flag 1\", 1254, \"flags 2\", 125.36]," +
+                            "        \"flags\": {" +
+                            "          \"systemFlags\":[\"Draft\"], " +
+                            "          \"userFlags\":[\"User Custom Flag\", null]}," +
                         "        \"size\": 45,  " +
-                        "        \"internalDate\": \"\"," +
+                        "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
                         "        \"messageId\": \"42\"" +
                         "      }" +
                         "    }," +
@@ -1459,6 +1501,154 @@ class AddedSerializationTest {
                         "}").get())
                     .isInstanceOf(NoSuchElementException.class);
                 }
+
+                @Test
+                void addedShouldThrowWhenSystemFlagsContainsNumberElements() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"Added\": {" +
+                        "    \"path\": {" +
+                        "      \"namespace\": \"#private\"," +
+                        "      \"user\": \"user\"," +
+                        "      \"name\": \"mailboxName\"" +
+                        "    }," +
+                        "    \"mailboxId\": \"18\"," +
+                        "    \"added\": {" +
+                        "      \"123456\": {" +
+                        "        \"uid\": 123456," +
+                        "        \"modSeq\": 35," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[42, \"Draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
+                        "        \"size\": 45,  " +
+                        "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
+                        "        \"messageId\": \"42\"" +
+                        "      }" +
+                        "    }," +
+                        "    \"sessionId\": 42," +
+                        "    \"user\": \"user\"" +
+                        "  }" +
+                        "}").get())
+                    .isInstanceOf(NoSuchElementException.class);
+                }
+
+                @Test
+                void addedShouldThrowWhenUserFlagsContainsNumberElements() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"Added\": {" +
+                        "    \"path\": {" +
+                        "      \"namespace\": \"#private\"," +
+                        "      \"user\": \"user\"," +
+                        "      \"name\": \"mailboxName\"" +
+                        "    }," +
+                        "    \"mailboxId\": \"18\"," +
+                        "    \"added\": {" +
+                        "      \"123456\": {" +
+                        "        \"uid\": 123456," +
+                        "        \"modSeq\": 35," +
+                            "        \"flags\": {" +
+                            "          \"systemFlags\":[\"Draft\"], " +
+                            "          \"userFlags\":[\"User Custom Flag\", 42]}," +
+                        "        \"size\": 45,  " +
+                        "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
+                        "        \"messageId\": \"42\"" +
+                        "      }" +
+                        "    }," +
+                        "    \"sessionId\": 42," +
+                        "    \"user\": \"user\"" +
+                        "  }" +
+                        "}").get())
+                    .isInstanceOf(NoSuchElementException.class);
+                }
+
+                @Test
+                void addedShouldThrowWhenSystemFlagsDoNotHaveTheRightCase() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"Added\": {" +
+                        "    \"path\": {" +
+                        "      \"namespace\": \"#private\"," +
+                        "      \"user\": \"user\"," +
+                        "      \"name\": \"mailboxName\"" +
+                        "    }," +
+                        "    \"mailboxId\": \"18\"," +
+                        "    \"added\": {" +
+                        "      \"123456\": {" +
+                        "        \"uid\": 123456," +
+                        "        \"modSeq\": 35," +
+                        "        \"flags\": {" +
+                        "          \"systemFlags\":[\"draft\"], " +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
+                        "        \"size\": 45,  " +
+                        "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
+                        "        \"messageId\": \"42\"" +
+                        "      }" +
+                        "    }," +
+                        "    \"sessionId\": 42," +
+                        "    \"user\": \"user\"" +
+                        "  }" +
+                        "}").get())
+                        .isInstanceOf(NoSuchElementException.class);
+                }
+
+                @Test
+                void addedShouldThrowWhenNoSystemFlags() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"Added\": {" +
+                        "    \"path\": {" +
+                        "      \"namespace\": \"#private\"," +
+                        "      \"user\": \"user\"," +
+                        "      \"name\": \"mailboxName\"" +
+                        "    }," +
+                        "    \"mailboxId\": \"18\"," +
+                        "    \"added\": {" +
+                        "      \"123456\": {" +
+                        "        \"uid\": 123456," +
+                        "        \"modSeq\": 35," +
+                        "        \"flags\": {" +
+                        "          \"userFlags\":[\"User Custom Flag\"]}," +
+                        "        \"size\": 45,  " +
+                        "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
+                        "        \"messageId\": \"42\"" +
+                        "      }" +
+                        "    }," +
+                        "    \"sessionId\": 42," +
+                        "    \"user\": \"user\"" +
+                        "  }" +
+                        "}").get())
+                        .isInstanceOf(NoSuchElementException.class);
+                }
+
+                @Test
+                void addedShouldThrowWhenNoUserFlags() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                            "  \"Added\": {" +
+                            "    \"path\": {" +
+                            "      \"namespace\": \"#private\"," +
+                            "      \"user\": \"user\"," +
+                            "      \"name\": \"mailboxName\"" +
+                            "    }," +
+                            "    \"mailboxId\": \"18\"," +
+                            "    \"added\": {" +
+                            "      \"123456\": {" +
+                            "        \"uid\": 123456," +
+                            "        \"modSeq\": 35," +
+                            "        \"flags\": {" +
+                            "          \"systemFlags\":[\"Draft\"]}," +
+                            "        \"size\": 45,  " +
+                            "        \"internalDate\": \"2018-12-14T09:41:51.541Z\"," +
+                            "        \"messageId\": \"42\"" +
+                            "      }" +
+                            "    }," +
+                            "    \"sessionId\": 42," +
+                            "    \"user\": \"user\"" +
+                            "  }" +
+                            "}").get())
+                        .isInstanceOf(NoSuchElementException.class);
+                }
             }
         }
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org