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 rc...@apache.org on 2019/11/25 09:06:59 UTC

[james-project] 16/22: [Refactoring] Strong typing for ModSeq

This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 1d2ff49561b6a2612ef3c2faa069820540785f42
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Nov 20 13:35:28 2019 +0700

    [Refactoring] Strong typing for ModSeq
---
 .../org/apache/james/mailbox/MessageManager.java   |  2 +-
 .../java/org/apache/james/mailbox/ModSeq.java}     | 80 ++++++++++----------
 .../model/ComposedMessageIdWithMetaData.java       | 12 +--
 .../james/mailbox/model/MessageMetaData.java       |  7 +-
 .../apache/james/mailbox/model/MessageResult.java  |  3 +-
 .../apache/james/mailbox/model/UpdatedFlags.java   | 11 +--
 .../apache/james/mailbox/MailboxListenerTest.java  |  5 +-
 .../apache/james/mailbox/MailboxManagerTest.java   |  2 +-
 .../model/ComposedMessageIdWithMetaDataTest.java   |  7 +-
 .../james/mailbox/model/UpdatedFlagsTest.java      |  3 +-
 .../cassandra/mail/CassandraMessageIdDAO.java      |  7 +-
 .../mail/CassandraMessageIdToImapUidDAO.java       | 12 +--
 .../cassandra/mail/CassandraMessageMapper.java     | 13 ++--
 .../cassandra/mail/CassandraModSeqProvider.java    | 52 ++++---------
 .../cassandra/mail/MessageWithoutAttachment.java   |  5 +-
 .../mail/CassandraIndexTableHandlerTest.java       |  3 +-
 .../cassandra/mail/CassandraMapperProvider.java    |  5 +-
 .../cassandra/mail/CassandraMessageDAOTest.java    |  3 +-
 .../cassandra/mail/CassandraMessageIdDAOTest.java  | 71 +++++++++---------
 .../mail/CassandraMessageIdToImapUidDAOTest.java   | 87 +++++++++++-----------
 .../mail/CassandraModSeqProviderTest.java          | 17 +++--
 .../mail/utils/FlagsUpdateStageResultTest.java     |  5 +-
 .../elasticsearch/json/IndexableMessage.java       |  7 +-
 .../json/MessageToElasticSearchJson.java           |  3 +-
 .../elasticsearch/json/MessageUpdateJson.java      |  6 +-
 ...asticSearchListeningMessageSearchIndexTest.java |  3 +-
 .../json/MessageToElasticSearchJsonTest.java       |  3 +-
 .../scala/org/apache/james/event/json/DTOs.scala   |  6 +-
 .../apache/james/event/json/EventSerializer.scala  |  7 +-
 .../james/event/json/AddedSerializationTest.java   |  3 +-
 .../event/json/ExpungedSerializationTest.java      |  3 +-
 .../event/json/FlagsUpdatedSerializationTest.java  |  5 +-
 .../apache/james/event/json/dtos/ModSeqTest.java   | 58 +++++++++++++++
 .../james/mailbox/jpa/mail/JPAMessageMapper.java   |  5 +-
 .../james/mailbox/jpa/mail/JPAModSeqProvider.java  | 17 +++--
 .../model/openjpa/AbstractJPAMailboxMessage.java   | 15 ++--
 .../model/openjpa/JPAEncryptedMailboxMessage.java  |  3 +-
 .../jpa/mail/model/openjpa/JPAMailboxMessage.java  |  3 +-
 .../model/openjpa/JPAStreamingMailboxMessage.java  |  3 +-
 .../james/mailbox/jpa/mail/JPAMapperProvider.java  |  5 +-
 .../jpa/mail/TransactionalMessageMapper.java       |  4 +-
 .../james/mailbox/maildir/MaildirFolder.java       |  5 +-
 .../apache/james/mailbox/maildir/MaildirStore.java | 13 ++--
 .../mailbox/maildir/mail/MaildirMessageMapper.java |  7 +-
 .../maildir/mail/model/MaildirMailboxMessage.java  |  9 ++-
 .../inmemory/mail/InMemoryMessageMapper.java       |  3 +-
 .../inmemory/mail/InMemoryModSeqProvider.java      | 29 ++++----
 .../inmemory/mail/InMemoryMapperProvider.java      |  5 +-
 .../james/mailbox/store/MailboxMetaData.java       | 10 +--
 .../james/mailbox/store/MessageResultImpl.java     |  3 +-
 .../james/mailbox/store/StoreMessageIdManager.java |  3 +-
 .../james/mailbox/store/StoreMessageManager.java   |  3 +-
 .../mailbox/store/StoreMessageResultIterator.java  |  3 +-
 .../mailbox/store/mail/AbstractMessageMapper.java  | 22 +++---
 .../james/mailbox/store/mail/MessageMapper.java    |  3 +-
 .../james/mailbox/store/mail/MessageUtils.java     |  8 +-
 .../james/mailbox/store/mail/ModSeqProvider.java   |  9 ++-
 .../mailbox/store/mail/model/MailboxMessage.java   |  5 +-
 .../mail/model/impl/SimpleMailboxMessage.java      | 12 +--
 .../mailbox/store/search/MessageSearches.java      |  9 ++-
 .../store/AbstractCombinationManagerTest.java      |  2 +-
 .../AbstractMessageIdManagerSideEffectTest.java    |  4 +-
 .../store/AbstractMessageIdManagerStorageTest.java | 13 ++--
 .../mailbox/store/MessageIdManagerTestSystem.java  |  3 +-
 .../james/mailbox/store/PreDeletionHooksTest.java  |  3 +-
 .../StoreMailboxMessageResultIteratorTest.java     |  4 +-
 .../james/mailbox/store/mail/MessageUtilsTest.java |  5 +-
 .../store/mail/model/ListMessageAssertTest.java    |  3 +-
 .../mailbox/store/mail/model/MapperProvider.java   |  6 +-
 .../store/mail/model/MessageIdMapperTest.java      | 25 ++++---
 .../store/mail/model/MessageMapperTest.java        | 25 ++++---
 .../store/mail/model/MetadataMapAssertTest.java    |  3 +-
 .../mail/model/impl/SimpleMailboxMessageTest.java  | 11 +--
 .../quota/ListeningCurrentQuotaUpdaterTest.java    |  9 ++-
 .../imap/api/message/response/StatusResponse.java  |  5 +-
 .../james/imap/encode/ESearchResponseEncoder.java  |  5 +-
 .../james/imap/encode/FetchResponseEncoder.java    |  5 +-
 .../imap/encode/MailboxStatusResponseEncoder.java  |  5 +-
 .../james/imap/encode/SearchResponseEncoder.java   |  5 +-
 .../imap/message/response/ESearchResponse.java     |  7 +-
 .../james/imap/message/response/FetchResponse.java |  7 +-
 .../message/response/MailboxStatusResponse.java    |  7 +-
 .../imap/message/response/SearchResponse.java      |  7 +-
 .../imap/processor/AbstractMailboxProcessor.java   |  8 +-
 .../imap/processor/AbstractSelectionProcessor.java |  3 +-
 .../james/imap/processor/SearchProcessor.java      | 11 +--
 .../james/imap/processor/StatusProcessor.java      |  5 +-
 .../james/imap/processor/StoreProcessor.java       |  5 +-
 .../james/imap/processor/fetch/FetchProcessor.java |  2 +-
 .../imap/processor/fetch/FetchResponseBuilder.java |  7 +-
 .../processor/base/MailboxEventAnalyserTest.java   |  9 ++-
 .../processor/base/SelectedMailboxImplTest.java    |  3 +-
 .../model/message/view/MessageFullViewFactory.java | 15 ++--
 93 files changed, 536 insertions(+), 433 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
index 73b967d..58a887e 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
@@ -395,7 +395,7 @@ public interface MessageManager {
          * 
          * @return higestModSeq
          */
-        long getHighestModSeq();
+        ModSeq getHighestModSeq();
 
         /**
          * Gets the number of messages that this mailbox contains. This is an
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java b/mailbox/api/src/main/java/org/apache/james/mailbox/ModSeq.java
similarity index 50%
copy from mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java
copy to mailbox/api/src/main/java/org/apache/james/mailbox/ModSeq.java
index f059317..c4be664 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/ModSeq.java
@@ -1,5 +1,3 @@
-
-
 /****************************************************************
  * Licensed to the Apache Software Foundation (ASF) under one   *
  * or more contributor license agreements.  See the NOTICE file *
@@ -19,61 +17,63 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.elasticsearch.json;
+package org.apache.james.mailbox;
 
-import javax.mail.Flags;
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
+public class ModSeq implements Comparable<ModSeq> {
+    public static ModSeq of(long modSeq) {
+        return new ModSeq(modSeq);
+    }
 
-public class MessageUpdateJson {
+    public static ModSeq first() {
+        return of(0L);
+    }
 
-    private final Flags flags;
     private final long modSeq;
 
-    public MessageUpdateJson(Flags flags, long modSeq) {
-        this.flags = flags;
+    private ModSeq(long modSeq) {
+        Preconditions.checkArgument(modSeq >= 0, "A modseq needs to be positive");
         this.modSeq = modSeq;
     }
 
-    @JsonProperty(JsonMessageConstants.IS_ANSWERED)
-    public boolean isAnswered() {
-        return flags.contains(Flags.Flag.ANSWERED);
+    public long asLong() {
+        return modSeq;
     }
 
-    @JsonProperty(JsonMessageConstants.IS_DELETED)
-    public boolean isDeleted() {
-        return flags.contains(Flags.Flag.DELETED);
+    public ModSeq next() {
+        if (modSeq == Long.MAX_VALUE) {
+            throw new RuntimeException("Long overflow upon modseq generation");
+        }
+        return new ModSeq(modSeq + 1);
     }
 
-    @JsonProperty(JsonMessageConstants.IS_DRAFT)
-    public boolean isDraft() {
-        return flags.contains(Flags.Flag.DRAFT);
+    public boolean isFirst() {
+        return this.equals(ModSeq.first());
     }
 
-    @JsonProperty(JsonMessageConstants.IS_FLAGGED)
-    public boolean isFlagged() {
-        return flags.contains(Flags.Flag.FLAGGED);
+    @Override
+    public int compareTo(ModSeq o) {
+        return Long.compare(modSeq, o.modSeq);
     }
-
-    @JsonProperty(JsonMessageConstants.IS_RECENT)
-    public boolean isRecent() {
-        return flags.contains(Flags.Flag.RECENT);
+    
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(modSeq);
     }
-
-    @JsonProperty(JsonMessageConstants.IS_UNREAD)
-    public boolean isUnRead() {
-        return !flags.contains(Flags.Flag.SEEN);
+    
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof ModSeq) {
+            ModSeq other = (ModSeq) obj;
+            return other.modSeq == this.modSeq;
+        }
+        return false;
     }
-
-
-    @JsonProperty(JsonMessageConstants.USER_FLAGS)
-    public String[] getUserFlags() {
-        return flags.getUserFlags();
-    }
-
-    @JsonProperty(JsonMessageConstants.MODSEQ)
-    public long getModSeq() {
-        return modSeq;
+    
+    @Override
+    public String toString() {
+        return "ModSeq{uid=" + modSeq + "}";
     }
-
 }
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/ComposedMessageIdWithMetaData.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ComposedMessageIdWithMetaData.java
index fc5923e..ad05c0d 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/ComposedMessageIdWithMetaData.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ComposedMessageIdWithMetaData.java
@@ -21,6 +21,8 @@ package org.apache.james.mailbox.model;
 
 import javax.mail.Flags;
 
+import org.apache.james.mailbox.ModSeq;
+
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
@@ -35,7 +37,7 @@ public class ComposedMessageIdWithMetaData {
 
         private ComposedMessageId composedMessageId;
         private Flags flags;
-        private Long modSeq;
+        private ModSeq modSeq;
 
         private Builder() {
         }
@@ -50,7 +52,7 @@ public class ComposedMessageIdWithMetaData {
             return this;
         }
 
-        public Builder modSeq(long modSeq) {
+        public Builder modSeq(ModSeq modSeq) {
             this.modSeq = modSeq;
             return this;
         }
@@ -65,9 +67,9 @@ public class ComposedMessageIdWithMetaData {
 
     private final ComposedMessageId composedMessageId;
     private final Flags flags;
-    private final long modSeq;
+    private final ModSeq modSeq;
 
-    public ComposedMessageIdWithMetaData(ComposedMessageId composedMessageId, Flags flags, long modSeq) {
+    public ComposedMessageIdWithMetaData(ComposedMessageId composedMessageId, Flags flags, ModSeq modSeq) {
         this.composedMessageId = composedMessageId;
         this.flags = flags;
         this.modSeq = modSeq;
@@ -81,7 +83,7 @@ public class ComposedMessageIdWithMetaData {
         return flags;
     }
 
-    public long getModSeq() {
+    public ModSeq getModSeq() {
         return modSeq;
     }
 
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageMetaData.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageMetaData.java
index 03b26f3..1a6dfa2 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageMetaData.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageMetaData.java
@@ -23,6 +23,7 @@ import java.util.Date;
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 
 import com.google.common.base.Objects;
 
@@ -31,10 +32,10 @@ public class MessageMetaData {
     private final Flags flags;
     private final long size;
     private final Date internalDate;
-    private final long modSeq;
+    private final ModSeq modSeq;
     private final MessageId messageId;
 
-    public MessageMetaData(MessageUid uid, long modSeq, Flags flags, long size, Date internalDate, MessageId messageId) {
+    public MessageMetaData(MessageUid uid, ModSeq modSeq, Flags flags, long size, Date internalDate, MessageId messageId) {
         this.uid = uid;
         this.flags = flags;
         this.size = size;
@@ -76,7 +77,7 @@ public class MessageMetaData {
      * Return the modify-sequence number of the message. This is kind of optional and the mailbox
      * implementation may not support this. If so it will return -1
      */
-    public long getModSeq() {
+    public ModSeq getModSeq() {
         return modSeq;
     }
 
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java
index 40f75cf..2cb24c1 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java
@@ -28,6 +28,7 @@ import java.util.Set;
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 
 
@@ -72,7 +73,7 @@ public interface MessageResult extends Comparable<MessageResult> {
 
     MessageUid getUid();
 
-    long getModSeq();
+    ModSeq getModSeq();
 
     /**
      * Indicates the results fetched.
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/UpdatedFlags.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/UpdatedFlags.java
index f1c0562..650a4b3 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/UpdatedFlags.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/UpdatedFlags.java
@@ -27,6 +27,7 @@ import java.util.Optional;
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
@@ -44,7 +45,7 @@ public class UpdatedFlags {
         private MessageUid uid;
         private Flags oldFlags;
         private Flags newFlags;
-        private Optional<Long> modSeq = Optional.empty();
+        private Optional<ModSeq> modSeq = Optional.empty();
 
         private Builder() {
         }
@@ -64,7 +65,7 @@ public class UpdatedFlags {
             return this;
         }
 
-        public Builder modSeq(long modSeq) {
+        public Builder modSeq(ModSeq modSeq) {
             this.modSeq = Optional.of(modSeq);
             return this;
         }
@@ -82,9 +83,9 @@ public class UpdatedFlags {
     private final Flags oldFlags;
     private final Flags newFlags;
     private final Flags modifiedFlags;
-    private final long modSeq;
+    private final ModSeq modSeq;
 
-    private UpdatedFlags(MessageUid uid, long modSeq, Flags oldFlags, Flags newFlags) {
+    private UpdatedFlags(MessageUid uid, ModSeq modSeq, Flags oldFlags, Flags newFlags) {
        this.uid = uid;
        this.modSeq = modSeq;
        this.oldFlags = oldFlags;
@@ -197,7 +198,7 @@ public class UpdatedFlags {
     /**
      * Return the new mod-sequence for the message
      */
-    public long getModSeq() {
+    public ModSeq getModSeq() {
         return modSeq;
     }
     
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java
index fdaaf67..0036592 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxListenerTest.java
@@ -48,6 +48,7 @@ import org.junit.jupiter.api.Test;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSortedMap;
+
 import nl.jqno.equalsverifier.EqualsVerifier;
 
 class MailboxListenerTest {
@@ -64,7 +65,7 @@ class MailboxListenerTest {
     private static final MailboxACL ACL_2 = new MailboxACL(
         Pair.of(MailboxACL.EntryKey.createUserEntryKey(Username.of("Bob")), new MailboxACL.Rfc4314Rights(MailboxACL.Right.Read)));
     private static final MessageUid UID = MessageUid.of(85);
-    private static final MessageMetaData META_DATA = new MessageMetaData(UID, 45, new Flags(), 45, new Date(), TestMessageId.of(75));
+    private static final MessageMetaData META_DATA = new MessageMetaData(UID, ModSeq.of(45), new Flags(), 45, new Date(), TestMessageId.of(75));
 
     @Test
     void mailboxAddedShouldMatchBeanContract() {
@@ -193,7 +194,7 @@ class MailboxListenerTest {
         MailboxListener.FlagsUpdated flagsUpdated = new MailboxListener.FlagsUpdated(SESSION_ID, BOB, PATH, MAILBOX_ID,
             ImmutableList.of(UpdatedFlags.builder()
                 .uid(UID)
-                .modSeq(45)
+                .modSeq(ModSeq.of(45))
                 .newFlags(new Flags())
                 .oldFlags(new Flags(Flags.Flag.ANSWERED))
                 .build()),
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
index fac59ae..d3cb1a1 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
@@ -1387,7 +1387,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
                 softly -> {
                     softly.assertThat(metaData)
                         .extracting(MessageManager.MetaData::getHighestModSeq)
-                        .isEqualTo(0L);
+                        .isEqualTo(ModSeq.first());
                     softly.assertThat(metaData)
                         .extracting(MessageManager.MetaData::getUidNext)
                         .isEqualTo(MessageUid.MIN_VALUE);
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/ComposedMessageIdWithMetaDataTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/ComposedMessageIdWithMetaDataTest.java
index b120c87..77070ee 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/ComposedMessageIdWithMetaDataTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/ComposedMessageIdWithMetaDataTest.java
@@ -25,6 +25,7 @@ import javax.mail.Flags;
 import javax.mail.Flags.Flag;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
@@ -62,7 +63,7 @@ class ComposedMessageIdWithMetaDataTest {
     @Test
     void buildShoudWork() {
         Flags flags = new Flags(Flag.RECENT);
-        long modSeq = 1;
+        ModSeq modSeq = ModSeq.of(1);
 
         ComposedMessageIdWithMetaData composedMessageIdWithMetaData = ComposedMessageIdWithMetaData.builder()
             .composedMessageId(COMPOSED_MESSAGE_ID)
@@ -80,7 +81,7 @@ class ComposedMessageIdWithMetaDataTest {
         ComposedMessageIdWithMetaData composedMessageIdWithMetaData = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(TEST_ID, TEST_MESSAGE_ID, MESSAGE_UID))
                 .flags(new Flags(Flag.RECENT))
-                .modSeq((long) 1)
+                .modSeq(ModSeq.of(1))
                 .build();
 
         assertThat(composedMessageIdWithMetaData.isMatching(TEST_MESSAGE_ID)).isTrue();
@@ -91,7 +92,7 @@ class ComposedMessageIdWithMetaDataTest {
         ComposedMessageIdWithMetaData composedMessageIdWithMetaData = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(COMPOSED_MESSAGE_ID)
                 .flags(new Flags(Flag.RECENT))
-                .modSeq((long) 1)
+                .modSeq(ModSeq.of(1))
                 .build();
 
         assertThat(composedMessageIdWithMetaData.isMatching(new TestMessageId("3"))).isFalse();
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/UpdatedFlagsTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/UpdatedFlagsTest.java
index 1c81a4d..aee926e 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/UpdatedFlagsTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/UpdatedFlagsTest.java
@@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
@@ -31,7 +32,7 @@ import nl.jqno.equalsverifier.EqualsVerifier;
 class UpdatedFlagsTest {
 
     public static final MessageUid UID = MessageUid.of(45L);
-    public static final long MOD_SEQ = 47L;
+    public static final ModSeq MOD_SEQ = ModSeq.of(47L);
 
     @Test
     void shouldMatchBeanContract() {
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdDAO.java
index e74a667..11b6045 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdDAO.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdDAO.java
@@ -50,6 +50,7 @@ import javax.mail.Flags.Flag;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId.Factory;
@@ -173,7 +174,7 @@ public class CassandraMessageIdDAO {
                 .setUUID(MAILBOX_ID, ((CassandraId) composedMessageId.getMailboxId()).asUuid())
                 .setLong(IMAP_UID, composedMessageId.getUid().asLong())
                 .setUUID(MESSAGE_ID, ((CassandraMessageId) composedMessageId.getMessageId()).get())
-                .setLong(MOD_SEQ, composedMessageIdWithMetaData.getModSeq())
+                .setLong(MOD_SEQ, composedMessageIdWithMetaData.getModSeq().asLong())
                 .setBool(ANSWERED, flags.contains(Flag.ANSWERED))
                 .setBool(DELETED, flags.contains(Flag.DELETED))
                 .setBool(DRAFT, flags.contains(Flag.DRAFT))
@@ -188,7 +189,7 @@ public class CassandraMessageIdDAO {
         ComposedMessageId composedMessageId = composedMessageIdWithMetaData.getComposedMessageId();
         Flags flags = composedMessageIdWithMetaData.getFlags();
         return cassandraAsyncExecutor.executeVoid(update.bind()
-                .setLong(MOD_SEQ, composedMessageIdWithMetaData.getModSeq())
+                .setLong(MOD_SEQ, composedMessageIdWithMetaData.getModSeq().asLong())
                 .setBool(ANSWERED, flags.contains(Flag.ANSWERED))
                 .setBool(DELETED, flags.contains(Flag.DELETED))
                 .setBool(DRAFT, flags.contains(Flag.DRAFT))
@@ -262,7 +263,7 @@ public class CassandraMessageIdDAO {
                         messageIdFactory.of(row.getUUID(MESSAGE_ID)),
                         MessageUid.of(row.getLong(IMAP_UID))))
                 .flags(new FlagsExtractor(row).getFlags())
-                .modSeq(row.getLong(MOD_SEQ))
+                .modSeq(ModSeq.of(row.getLong(MOD_SEQ)))
                 .build();
     }
 }
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdToImapUidDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdToImapUidDAO.java
index 8c31e8d..bbd693d 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdToImapUidDAO.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdToImapUidDAO.java
@@ -49,6 +49,7 @@ import javax.mail.Flags.Flag;
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId.Factory;
@@ -63,6 +64,7 @@ import com.datastax.driver.core.Statement;
 import com.datastax.driver.core.querybuilder.QueryBuilder;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableSet;
+
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
@@ -162,7 +164,7 @@ public class CassandraMessageIdToImapUidDAO {
                 .setUUID(MESSAGE_ID, ((CassandraMessageId) composedMessageId.getMessageId()).get())
                 .setUUID(MAILBOX_ID, ((CassandraId) composedMessageId.getMailboxId()).asUuid())
                 .setLong(IMAP_UID, composedMessageId.getUid().asLong())
-                .setLong(MOD_SEQ, composedMessageIdWithMetaData.getModSeq())
+                .setLong(MOD_SEQ, composedMessageIdWithMetaData.getModSeq().asLong())
                 .setBool(ANSWERED, flags.contains(Flag.ANSWERED))
                 .setBool(DELETED, flags.contains(Flag.DELETED))
                 .setBool(DRAFT, flags.contains(Flag.DRAFT))
@@ -173,11 +175,11 @@ public class CassandraMessageIdToImapUidDAO {
                 .setSet(USER_FLAGS, ImmutableSet.copyOf(flags.getUserFlags())));
     }
 
-    public Mono<Boolean> updateMetadata(ComposedMessageIdWithMetaData composedMessageIdWithMetaData, long oldModSeq) {
+    public Mono<Boolean> updateMetadata(ComposedMessageIdWithMetaData composedMessageIdWithMetaData, ModSeq oldModSeq) {
         ComposedMessageId composedMessageId = composedMessageIdWithMetaData.getComposedMessageId();
         Flags flags = composedMessageIdWithMetaData.getFlags();
         return cassandraAsyncExecutor.executeReturnApplied(update.bind()
-                .setLong(MOD_SEQ, composedMessageIdWithMetaData.getModSeq())
+                .setLong(MOD_SEQ, composedMessageIdWithMetaData.getModSeq().asLong())
                 .setBool(ANSWERED, flags.contains(Flag.ANSWERED))
                 .setBool(DELETED, flags.contains(Flag.DELETED))
                 .setBool(DRAFT, flags.contains(Flag.DRAFT))
@@ -189,7 +191,7 @@ public class CassandraMessageIdToImapUidDAO {
                 .setUUID(MESSAGE_ID, ((CassandraMessageId) composedMessageId.getMessageId()).get())
                 .setUUID(MAILBOX_ID, ((CassandraId) composedMessageId.getMailboxId()).asUuid())
                 .setLong(IMAP_UID, composedMessageId.getUid().asLong())
-                .setLong(MOD_SEQ_CONDITION, oldModSeq));
+                .setLong(MOD_SEQ_CONDITION, oldModSeq.asLong()));
     }
 
     public Flux<ComposedMessageIdWithMetaData> retrieve(CassandraMessageId messageId, Optional<CassandraId> mailboxId) {
@@ -206,7 +208,7 @@ public class CassandraMessageIdToImapUidDAO {
                     messageIdFactory.of(row.getUUID(MESSAGE_ID)),
                     MessageUid.of(row.getLong(IMAP_UID))))
                 .flags(new FlagsExtractor(row).getFlags())
-                .modSeq(row.getLong(MOD_SEQ))
+                .modSeq(ModSeq.of(row.getLong(MOD_SEQ)))
                 .build();
     }
 
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
index b11c836..0d3b43c 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
@@ -34,6 +34,7 @@ import org.apache.james.mailbox.ApplicableFlagBuilder;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.mail.utils.FlagsUpdateStageResult;
@@ -261,7 +262,7 @@ public class CassandraMessageMapper implements MessageMapper {
     }
 
     @Override
-    public long getHighestModSeq(Mailbox mailbox) throws MailboxException {
+    public ModSeq getHighestModSeq(Mailbox mailbox) throws MailboxException {
         return modSeqProvider.highestModSeq(mailboxSession, mailbox);
     }
 
@@ -277,7 +278,7 @@ public class CassandraMessageMapper implements MessageMapper {
 
     private MailboxMessage addUidAndModseq(MailboxMessage message, CassandraId mailboxId) throws MailboxException {
         final Mono<MessageUid> messageUidMono = uidProvider.nextUid(mailboxId).cache();
-        final Mono<Long> nextModSeqMono = modSeqProvider.nextModSeq(mailboxId).cache();
+        final Mono<ModSeq> nextModSeqMono = modSeqProvider.nextModSeq(mailboxId).cache();
         Flux.merge(messageUidMono, nextModSeqMono).then();
 
         message.setUid(messageUidMono.blockOptional()
@@ -326,14 +327,14 @@ public class CassandraMessageMapper implements MessageMapper {
     }
 
     private Mono<FlagsUpdateStageResult> runUpdateStage(CassandraId mailboxId, Flux<ComposedMessageIdWithMetaData> toBeUpdated, FlagsUpdateCalculator flagsUpdateCalculator) {
-        Mono<Long> newModSeq = computeNewModSeq(mailboxId);
+        Mono<ModSeq> newModSeq = computeNewModSeq(mailboxId);
         return toBeUpdated
             .concatMap(metadata -> newModSeq.flatMap(modSeq -> tryFlagsUpdate(flagsUpdateCalculator, modSeq, metadata)))
             .reduce(FlagsUpdateStageResult.none(), FlagsUpdateStageResult::merge)
             .flatMap(result -> updateIndexesForUpdatesResult(mailboxId, result));
     }
 
-    private Mono<Long> computeNewModSeq(CassandraId mailboxId) {
+    private Mono<ModSeq> computeNewModSeq(CassandraId mailboxId) {
         return modSeqProvider.nextModSeq(mailboxId)
             .switchIfEmpty(ReactorUtils.executeAndEmpty(() -> new RuntimeException("ModSeq generation failed for mailbox " + mailboxId.asUuid())));
     }
@@ -402,7 +403,7 @@ public class CassandraMessageMapper implements MessageMapper {
     }
 
 
-    private Mono<FlagsUpdateStageResult> tryFlagsUpdate(FlagsUpdateCalculator flagUpdateCalculator, long newModSeq, ComposedMessageIdWithMetaData oldMetaData) {
+    private Mono<FlagsUpdateStageResult> tryFlagsUpdate(FlagsUpdateCalculator flagUpdateCalculator, ModSeq newModSeq, ComposedMessageIdWithMetaData oldMetaData) {
         Flags oldFlags = oldMetaData.getFlags();
         Flags newFlags = flagUpdateCalculator.buildNewFlags(oldFlags);
 
@@ -434,7 +435,7 @@ public class CassandraMessageMapper implements MessageMapper {
         return oldFlags.equals(newFlags);
     }
 
-    private Mono<Boolean> updateFlags(ComposedMessageIdWithMetaData oldMetadata, Flags newFlags, long newModSeq) {
+    private Mono<Boolean> updateFlags(ComposedMessageIdWithMetaData oldMetadata, Flags newFlags, ModSeq newModSeq) {
         ComposedMessageIdWithMetaData newMetadata = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(oldMetadata.getComposedMessageId())
                 .modSeq(newModSeq)
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java
index 97fe21f..b2e7460 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProvider.java
@@ -39,6 +39,7 @@ import javax.inject.Inject;
 import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration;
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
@@ -49,7 +50,6 @@ import org.apache.james.util.FunctionalUtils;
 import com.datastax.driver.core.ConsistencyLevel;
 import com.datastax.driver.core.PreparedStatement;
 import com.datastax.driver.core.Session;
-import com.google.common.base.MoreObjects;
 
 import reactor.core.publisher.Mono;
 import reactor.core.scheduler.Schedulers;
@@ -83,8 +83,6 @@ public class CassandraModSeqProvider implements ModSeqProvider {
         }
     }
 
-    private static final ModSeq FIRST_MODSEQ = new ModSeq(0);
-
     private final CassandraAsyncExecutor cassandraAsyncExecutor;
     private final PreparedStatement select;
     private final PreparedStatement update;
@@ -122,7 +120,7 @@ public class CassandraModSeqProvider implements ModSeqProvider {
 
 
     @Override
-    public long nextModSeq(MailboxSession mailboxSession, Mailbox mailbox) throws MailboxException {
+    public ModSeq nextModSeq(MailboxSession mailboxSession, Mailbox mailbox) throws MailboxException {
         CassandraId mailboxId = (CassandraId) mailbox.getMailboxId();
         return nextModSeq(mailboxId)
             .blockOptional()
@@ -130,20 +128,20 @@ public class CassandraModSeqProvider implements ModSeqProvider {
     }
 
     @Override
-    public long nextModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
+    public ModSeq nextModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
         return nextModSeq((CassandraId) mailboxId)
             .blockOptional()
             .orElseThrow(() -> new MailboxException("Can not retrieve modseq for " + mailboxId));
     }
 
     @Override
-    public long highestModSeq(MailboxSession mailboxSession, Mailbox mailbox) throws MailboxException {
+    public ModSeq highestModSeq(MailboxSession mailboxSession, Mailbox mailbox) throws MailboxException {
         return highestModSeq(mailboxSession, mailbox.getMailboxId());
     }
 
     @Override
-    public long highestModSeq(MailboxSession mailboxSession, MailboxId mailboxId) throws MailboxException {
-        return unbox(() -> findHighestModSeq((CassandraId) mailboxId).block().orElse(FIRST_MODSEQ).getValue());
+    public ModSeq highestModSeq(MailboxSession mailboxSession, MailboxId mailboxId) throws MailboxException {
+        return unbox(() -> findHighestModSeq((CassandraId) mailboxId).block().orElse(ModSeq.first()));
     }
 
     private Mono<Optional<ModSeq>> findHighestModSeq(CassandraId mailboxId) {
@@ -151,7 +149,7 @@ public class CassandraModSeqProvider implements ModSeqProvider {
             select.bind()
                 .setUUID(MAILBOX_ID, mailboxId.asUuid())
                 .setConsistencyLevel(ConsistencyLevel.SERIAL))
-            .map(maybeRow -> maybeRow.map(row -> new ModSeq(row.getLong(NEXT_MODSEQ))));
+            .map(maybeRow -> maybeRow.map(row -> ModSeq.of(row.getLong(NEXT_MODSEQ))));
     }
 
     private Mono<ModSeq> tryInsertModSeq(CassandraId mailboxId, ModSeq modSeq) {
@@ -159,7 +157,7 @@ public class CassandraModSeqProvider implements ModSeqProvider {
         return cassandraAsyncExecutor.executeReturnApplied(
             insert.bind()
                 .setUUID(MAILBOX_ID, mailboxId.asUuid())
-                .setLong(NEXT_MODSEQ, nextModSeq.getValue()))
+                .setLong(NEXT_MODSEQ, nextModSeq.asLong()))
             .flatMap(success -> successToModSeq(nextModSeq, success));
     }
 
@@ -168,8 +166,8 @@ public class CassandraModSeqProvider implements ModSeqProvider {
         return cassandraAsyncExecutor.executeReturnApplied(
             update.bind()
                 .setUUID(MAILBOX_ID, mailboxId.asUuid())
-                .setLong(NEXT_MODSEQ, nextModSeq.getValue())
-                .setLong(MOD_SEQ_CONDITION, modSeq.getValue()))
+                .setLong(NEXT_MODSEQ, nextModSeq.asLong())
+                .setLong(MOD_SEQ_CONDITION, modSeq.asLong()))
             .flatMap(success -> successToModSeq(nextModSeq, success));
     }
 
@@ -179,13 +177,12 @@ public class CassandraModSeqProvider implements ModSeqProvider {
             .map(any -> modSeq);
     }
 
-    public Mono<Long> nextModSeq(CassandraId mailboxId) {
+    public Mono<ModSeq> nextModSeq(CassandraId mailboxId) {
         return findHighestModSeq(mailboxId)
             .flatMap(maybeHighestModSeq -> maybeHighestModSeq
                         .map(highestModSeq -> tryUpdateModSeq(mailboxId, highestModSeq))
-                        .orElseGet(() -> tryInsertModSeq(mailboxId, FIRST_MODSEQ)))
-            .switchIfEmpty(handleRetries(mailboxId))
-            .map(ModSeq::getValue);
+                        .orElseGet(() -> tryInsertModSeq(mailboxId, ModSeq.first())))
+            .switchIfEmpty(handleRetries(mailboxId));
     }
 
     private Mono<ModSeq> handleRetries(CassandraId mailboxId) {
@@ -201,27 +198,4 @@ public class CassandraModSeqProvider implements ModSeqProvider {
             .flatMap(highestModSeq -> tryUpdateModSeq(mailboxId, highestModSeq)));
     }
 
-    private static class ModSeq {
-        private final long value;
-        
-        public ModSeq(long value) {
-            this.value = value;
-        }
-        
-        public ModSeq next() {
-            return new ModSeq(value + 1);
-        }
-        
-        public long getValue() {
-            return value;
-        }
-
-        @Override
-        public String toString() {
-            return MoreObjects.toStringHelper(this)
-                    .add("value", value)
-                    .toString();
-        }
-    }
-
 }
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageWithoutAttachment.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageWithoutAttachment.java
index 226e8bc..618ebb5 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageWithoutAttachment.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageWithoutAttachment.java
@@ -26,6 +26,7 @@ import javax.mail.Flags;
 import javax.mail.util.SharedByteArrayInputStream;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
 import org.apache.james.mailbox.model.MailboxId;
@@ -44,11 +45,11 @@ public class MessageWithoutAttachment {
     private final PropertyBuilder propertyBuilder;
     private final MailboxId mailboxId;
     private final MessageUid messageUid;
-    private final long modSeq;
+    private final ModSeq modSeq;
     private final boolean hasAttachment;
 
     public MessageWithoutAttachment(MessageId messageId, Date internalDate, Long size, Integer bodySize, SharedByteArrayInputStream content,
-                                    Flags flags, PropertyBuilder propertyBuilder, MailboxId mailboxId, MessageUid messageUid, long modSeq,
+                                    Flags flags, PropertyBuilder propertyBuilder, MailboxId mailboxId, MessageUid messageUid, ModSeq modSeq,
                                     boolean hasAttachment) {
         this.messageId = messageId;
         this.internalDate = internalDate;
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandlerTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandlerTest.java
index d7ff535..33f0d05 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandlerTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandlerTest.java
@@ -32,6 +32,7 @@ import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.modules.CassandraApplicableFlagsModule;
@@ -58,7 +59,7 @@ class CassandraIndexTableHandlerTest {
     private static final MessageUid MESSAGE_UID = MessageUid.of(18L);
     private static final CassandraMessageId CASSANDRA_MESSAGE_ID = new CassandraMessageId.Factory().generate();
     private static final int UID_VALIDITY = 15;
-    private static final long MODSEQ = 17;
+    private static final ModSeq MODSEQ = ModSeq.of(17);
 
     @RegisterExtension
     static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMapperProvider.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMapperProvider.java
index 0e3a48c..cc84fad 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMapperProvider.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMapperProvider.java
@@ -26,6 +26,7 @@ import org.apache.james.core.Username;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.cassandra.CassandraMailboxSessionMapperFactory;
 import org.apache.james.mailbox.cassandra.TestCassandraMailboxSessionMapperFactory;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
@@ -112,13 +113,13 @@ public class CassandraMapperProvider implements MapperProvider {
     }
 
     @Override
-    public long generateModSeq(Mailbox mailbox) throws MailboxException {
+    public ModSeq generateModSeq(Mailbox mailbox) throws MailboxException {
         MailboxSession mailboxSession = null;
         return cassandraModSeqProvider.nextModSeq(mailboxSession, mailbox);
     }
 
     @Override
-    public long highestModSeq(Mailbox mailbox) throws MailboxException {
+    public ModSeq highestModSeq(Mailbox mailbox) throws MailboxException {
         MailboxSession mailboxSession = null;
         return cassandraModSeqProvider.highestModSeq(mailboxSession, mailbox);
     }
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAOTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAOTest.java
index 1dbde73..90b136d 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAOTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAOTest.java
@@ -42,6 +42,7 @@ import org.apache.james.blob.api.HashBlobId;
 import org.apache.james.blob.cassandra.CassandraBlobModule;
 import org.apache.james.blob.cassandra.CassandraBlobStore;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageDAO.MessageIdAttachmentIds;
@@ -103,7 +104,7 @@ class CassandraMessageDAOTest {
         messageIds = ImmutableList.of(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(MAILBOX_ID, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build());
     }
 
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdDAOTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdDAOTest.java
index b42f6a2..f556a2e 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdDAOTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdDAOTest.java
@@ -31,6 +31,7 @@ import org.apache.james.backends.cassandra.CassandraRestartExtension;
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.modules.CassandraMessageModule;
@@ -76,7 +77,7 @@ class CassandraMessageIdDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
@@ -97,12 +98,12 @@ class CassandraMessageIdDAOTest {
             ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build()),
             testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId2, messageUid2))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build()))
         .blockLast();
 
@@ -123,7 +124,7 @@ class CassandraMessageIdDAOTest {
         ComposedMessageIdWithMetaData composedMessageIdWithMetaData = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         testee.insert(composedMessageIdWithMetaData).block();
 
@@ -141,14 +142,14 @@ class CassandraMessageIdDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
         testee.updateMetadata(expectedComposedMessageId).block();
 
@@ -166,14 +167,14 @@ class CassandraMessageIdDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.ANSWERED))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
         testee.updateMetadata(expectedComposedMessageId).block();
 
@@ -191,14 +192,14 @@ class CassandraMessageIdDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.DELETED))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
         testee.updateMetadata(expectedComposedMessageId).block();
 
@@ -216,14 +217,14 @@ class CassandraMessageIdDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.DRAFT))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
         testee.updateMetadata(expectedComposedMessageId).block();
 
@@ -241,14 +242,14 @@ class CassandraMessageIdDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.FLAGGED))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
         testee.updateMetadata(expectedComposedMessageId).block();
 
@@ -266,14 +267,14 @@ class CassandraMessageIdDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.RECENT))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
         testee.updateMetadata(expectedComposedMessageId).block();
 
@@ -291,14 +292,14 @@ class CassandraMessageIdDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.SEEN))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
         testee.updateMetadata(expectedComposedMessageId).block();
 
@@ -316,14 +317,14 @@ class CassandraMessageIdDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.USER))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
         testee.updateMetadata(expectedComposedMessageId).block();
 
@@ -341,7 +342,7 @@ class CassandraMessageIdDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
@@ -350,7 +351,7 @@ class CassandraMessageIdDAOTest {
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(flags)
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
         testee.updateMetadata(expectedComposedMessageId).block();
 
@@ -366,7 +367,7 @@ class CassandraMessageIdDAOTest {
         ComposedMessageIdWithMetaData composedMessageIdWithMetaData = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         testee.insert(composedMessageIdWithMetaData).block();
 
@@ -386,12 +387,12 @@ class CassandraMessageIdDAOTest {
         ComposedMessageIdWithMetaData composedMessageIdWithMetaData = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         ComposedMessageIdWithMetaData composedMessageIdWithMetaData2 = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId2, messageUid2))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         Flux.merge(testee.insert(composedMessageIdWithMetaData),
                 testee.insert(composedMessageIdWithMetaData2))
@@ -414,18 +415,18 @@ class CassandraMessageIdDAOTest {
         ComposedMessageIdWithMetaData composedMessageIdWithMetaData = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId2, messageUid2))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         ComposedMessageIdWithMetaData composedMessageIdWithMetaData2 = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId3, messageUid3))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         Flux.merge(testee.insert(
                 ComposedMessageIdWithMetaData.builder()
                     .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                     .flags(new Flags())
-                    .modSeq(1)
+                    .modSeq(ModSeq.of(1))
                     .build()),
                 testee.insert(composedMessageIdWithMetaData),
                 testee.insert(composedMessageIdWithMetaData2))
@@ -450,27 +451,27 @@ class CassandraMessageIdDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData composedMessageIdWithMetaData = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId2, messageUid2))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
 
         ComposedMessageIdWithMetaData composedMessageIdWithMetaData2 = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId3, messageUid3))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         Flux.merge(testee.insert(composedMessageIdWithMetaData),
                 testee.insert(composedMessageIdWithMetaData2),
                 testee.insert(ComposedMessageIdWithMetaData.builder()
                     .composedMessageId(new ComposedMessageId(mailboxId, messageId4, messageUid4))
                     .flags(new Flags())
-                    .modSeq(1)
+                    .modSeq(ModSeq.of(1))
                     .build()))
         .blockLast();
 
@@ -491,19 +492,19 @@ class CassandraMessageIdDAOTest {
         ComposedMessageIdWithMetaData composedMessageIdWithMetaData = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId2, messageUid2))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         Flux.merge(testee.insert(
                 ComposedMessageIdWithMetaData.builder()
                     .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                     .flags(new Flags())
-                    .modSeq(1)
+                    .modSeq(ModSeq.of(1))
                     .build()),
                 testee.insert(composedMessageIdWithMetaData),
                 testee.insert(ComposedMessageIdWithMetaData.builder()
                     .composedMessageId(new ComposedMessageId(mailboxId, messageId3, messageUid3))
                     .flags(new Flags())
-                    .modSeq(1)
+                    .modSeq(ModSeq.of(1))
                     .build()))
         .blockLast();
 
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdToImapUidDAOTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdToImapUidDAOTest.java
index 530addd..8d5d508 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdToImapUidDAOTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageIdToImapUidDAOTest.java
@@ -32,6 +32,7 @@ import org.apache.james.backends.cassandra.CassandraRestartExtension;
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.backends.cassandra.versions.CassandraSchemaVersionModule;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.modules.CassandraMessageModule;
@@ -79,7 +80,7 @@ class CassandraMessageIdToImapUidDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                     .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                     .flags(new Flags())
-                    .modSeq(1)
+                    .modSeq(ModSeq.of(1))
                     .build())
                 .block();
 
@@ -100,12 +101,12 @@ class CassandraMessageIdToImapUidDAOTest {
             testee.insert(ComposedMessageIdWithMetaData.builder()
                     .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                     .flags(new Flags())
-                    .modSeq(1)
+                    .modSeq(ModSeq.of(1))
                     .build()),
             testee.insert(ComposedMessageIdWithMetaData.builder()
                     .composedMessageId(new ComposedMessageId(mailboxId2, messageId, messageUid2))
                     .flags(new Flags())
-                    .modSeq(1)
+                    .modSeq(ModSeq.of(1))
                     .build()))
         .blockLast();
 
@@ -114,7 +115,7 @@ class CassandraMessageIdToImapUidDAOTest {
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId2, messageId, messageUid2))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         List<ComposedMessageIdWithMetaData> messages = testee.retrieve(messageId, Optional.empty()).collectList().block();
         assertThat(messages).containsOnly(expectedComposedMessageId);
@@ -129,14 +130,14 @@ class CassandraMessageIdToImapUidDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         List<ComposedMessageIdWithMetaData> messages = testee.retrieve(messageId, Optional.of(mailboxId)).collectList().block();
         assertThat(messages).containsOnly(expectedComposedMessageId);
@@ -151,11 +152,11 @@ class CassandraMessageIdToImapUidDAOTest {
         ComposedMessageIdWithMetaData composedMessageIdWithFlags = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         testee.insert(composedMessageIdWithFlags).block();
 
-        Boolean result = testee.updateMetadata(composedMessageIdWithFlags, 1).block();
+        Boolean result = testee.updateMetadata(composedMessageIdWithFlags, ModSeq.of(1)).block();
 
         assertThat(result).isTrue();
     }
@@ -169,11 +170,11 @@ class CassandraMessageIdToImapUidDAOTest {
         ComposedMessageIdWithMetaData composedMessageIdWithFlags = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         testee.insert(composedMessageIdWithFlags).block();
 
-        Boolean result = testee.updateMetadata(composedMessageIdWithFlags, 3).block();
+        Boolean result = testee.updateMetadata(composedMessageIdWithFlags, ModSeq.of(3)).block();
 
         assertThat(result).isFalse();
     }
@@ -188,16 +189,16 @@ class CassandraMessageIdToImapUidDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
-        testee.updateMetadata(expectedComposedMessageId, 1).block();
+        testee.updateMetadata(expectedComposedMessageId, ModSeq.of(1)).block();
 
         List<ComposedMessageIdWithMetaData> messages = testee.retrieve(messageId, Optional.of(mailboxId)).collectList().block();
         assertThat(messages).containsOnly(expectedComposedMessageId);
@@ -213,16 +214,16 @@ class CassandraMessageIdToImapUidDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.ANSWERED))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
-        testee.updateMetadata(expectedComposedMessageId, 1).block();
+        testee.updateMetadata(expectedComposedMessageId, ModSeq.of(1)).block();
 
         List<ComposedMessageIdWithMetaData> messages = testee.retrieve(messageId, Optional.of(mailboxId)).collectList().block();
         assertThat(messages).containsOnly(expectedComposedMessageId);
@@ -238,16 +239,16 @@ class CassandraMessageIdToImapUidDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.DELETED))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
-        testee.updateMetadata(expectedComposedMessageId, 1).block();
+        testee.updateMetadata(expectedComposedMessageId, ModSeq.of(1)).block();
 
         List<ComposedMessageIdWithMetaData> messages = testee.retrieve(messageId, Optional.of(mailboxId)).collectList().block();
         assertThat(messages).containsOnly(expectedComposedMessageId);
@@ -263,16 +264,16 @@ class CassandraMessageIdToImapUidDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.DRAFT))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
-        testee.updateMetadata(expectedComposedMessageId, 1).block();
+        testee.updateMetadata(expectedComposedMessageId, ModSeq.of(1)).block();
 
         List<ComposedMessageIdWithMetaData> messages = testee.retrieve(messageId, Optional.of(mailboxId)).collectList().block();
         assertThat(messages).containsOnly(expectedComposedMessageId);
@@ -288,16 +289,16 @@ class CassandraMessageIdToImapUidDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.FLAGGED))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
-        testee.updateMetadata(expectedComposedMessageId, 1).block();
+        testee.updateMetadata(expectedComposedMessageId, ModSeq.of(1)).block();
 
         List<ComposedMessageIdWithMetaData> messages = testee.retrieve(messageId, Optional.of(mailboxId)).collectList().block();
         assertThat(messages).containsOnly(expectedComposedMessageId);
@@ -313,16 +314,16 @@ class CassandraMessageIdToImapUidDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.RECENT))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
-        testee.updateMetadata(expectedComposedMessageId, 1).block();
+        testee.updateMetadata(expectedComposedMessageId, ModSeq.of(1)).block();
 
         List<ComposedMessageIdWithMetaData> messages = testee.retrieve(messageId, Optional.of(mailboxId)).collectList().block();
         assertThat(messages).containsOnly(expectedComposedMessageId);
@@ -338,16 +339,16 @@ class CassandraMessageIdToImapUidDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.SEEN))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
-        assertThat(testee.updateMetadata(expectedComposedMessageId, 1).block())
+        assertThat(testee.updateMetadata(expectedComposedMessageId, ModSeq.of(1)).block())
             .isTrue();
 
         List<ComposedMessageIdWithMetaData> messages = testee.retrieve(messageId, Optional.of(mailboxId)).collectList().block();
@@ -364,16 +365,16 @@ class CassandraMessageIdToImapUidDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags(Flag.USER))
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
-        testee.updateMetadata(expectedComposedMessageId, 1).block();
+        testee.updateMetadata(expectedComposedMessageId, ModSeq.of(1)).block();
 
         List<ComposedMessageIdWithMetaData> messages = testee.retrieve(messageId, Optional.of(mailboxId)).collectList().block();
         assertThat(messages).containsOnly(expectedComposedMessageId);
@@ -389,7 +390,7 @@ class CassandraMessageIdToImapUidDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
@@ -398,9 +399,9 @@ class CassandraMessageIdToImapUidDAOTest {
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(composedMessageId)
                 .flags(flags)
-                .modSeq(2)
+                .modSeq(ModSeq.of(2))
                 .build();
-        testee.updateMetadata(expectedComposedMessageId, 1).block();
+        testee.updateMetadata(expectedComposedMessageId, ModSeq.of(1)).block();
 
         List<ComposedMessageIdWithMetaData> messages = testee.retrieve(messageId, Optional.of(mailboxId)).collectList().block();
         assertThat(messages).containsOnly(expectedComposedMessageId);
@@ -414,14 +415,14 @@ class CassandraMessageIdToImapUidDAOTest {
         testee.insert(ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build())
             .block();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         List<ComposedMessageIdWithMetaData> messages = testee.retrieve(messageId, Optional.of(mailboxId)).collectList().block();
 
@@ -439,24 +440,24 @@ class CassandraMessageIdToImapUidDAOTest {
                 testee.insert(ComposedMessageIdWithMetaData.builder()
                     .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                     .flags(new Flags())
-                    .modSeq(1)
+                    .modSeq(ModSeq.of(1))
                     .build()),
                 testee.insert(ComposedMessageIdWithMetaData.builder()
                     .composedMessageId(new ComposedMessageId(mailboxId2, messageId, messageUid2))
                     .flags(new Flags())
-                    .modSeq(1)
+                    .modSeq(ModSeq.of(1))
                     .build()))
         .blockLast();
 
         ComposedMessageIdWithMetaData expectedComposedMessageId = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId, messageId, messageUid))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         ComposedMessageIdWithMetaData expectedComposedMessageId2 = ComposedMessageIdWithMetaData.builder()
                 .composedMessageId(new ComposedMessageId(mailboxId2, messageId, messageUid2))
                 .flags(new Flags())
-                .modSeq(1)
+                .modSeq(ModSeq.of(1))
                 .build();
         List<ComposedMessageIdWithMetaData> messages = testee.retrieve(messageId, Optional.empty()).collectList().block();
 
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProviderTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProviderTest.java
index f956fd3..b0f0af4 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProviderTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProviderTest.java
@@ -30,6 +30,7 @@ import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.backends.cassandra.CassandraRestartExtension;
 import org.apache.james.backends.cassandra.init.configuration.CassandraConfiguration;
 import org.apache.james.core.Username;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.modules.CassandraModSeqModule;
 import org.apache.james.mailbox.model.Mailbox;
@@ -64,12 +65,12 @@ class CassandraModSeqProviderTest {
     @Test
     void highestModSeqShouldRetrieveValueStoredNextModSeq() throws Exception {
         int nbEntries = 100;
-        long result = modSeqProvider.highestModSeq(null, mailbox);
+        ModSeq result = modSeqProvider.highestModSeq(null, mailbox);
         assertThat(result).isEqualTo(0);
         LongStream.range(0, nbEntries)
             .forEach(Throwing.longConsumer(value -> {
-                        long uid = modSeqProvider.nextModSeq(null, mailbox);
-                        assertThat(uid).isEqualTo(modSeqProvider.highestModSeq(null, mailbox));
+                    ModSeq modSeq = modSeqProvider.nextModSeq(null, mailbox);
+                    assertThat(modSeq).isEqualTo(modSeqProvider.highestModSeq(null, mailbox));
                 })
             );
     }
@@ -77,11 +78,11 @@ class CassandraModSeqProviderTest {
     @Test
     void nextModSeqShouldIncrementValueByOne() throws Exception {
         int nbEntries = 100;
-        long lastUid = modSeqProvider.highestModSeq(null, mailbox);
-        LongStream.range(lastUid + 1, lastUid + nbEntries)
+        ModSeq lastModSeq = modSeqProvider.highestModSeq(null, mailbox);
+        LongStream.range(lastModSeq.asLong() + 1, lastModSeq.asLong() + nbEntries)
             .forEach(Throwing.longConsumer(value -> {
-                long result = modSeqProvider.nextModSeq(null, mailbox);
-                assertThat(value).isEqualTo(result);
+                ModSeq result = modSeqProvider.nextModSeq(null, mailbox);
+                assertThat(result.asLong()).isEqualTo(value);
             }));
     }
 
@@ -89,7 +90,7 @@ class CassandraModSeqProviderTest {
     void nextModSeqShouldGenerateUniqueValuesWhenParallelCalls() throws ExecutionException, InterruptedException {
         int nbEntries = 10;
 
-        ConcurrentSkipListSet<Long> modSeqs = new ConcurrentSkipListSet<>();
+        ConcurrentSkipListSet<ModSeq> modSeqs = new ConcurrentSkipListSet<>();
         ConcurrentTestRunner.builder()
             .operation(
                 (threadNumber, step) -> modSeqs.add(modSeqProvider.nextModSeq(null, mailbox)))
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/utils/FlagsUpdateStageResultTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/utils/FlagsUpdateStageResultTest.java
index ee959c3..3317b6b 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/utils/FlagsUpdateStageResultTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/utils/FlagsUpdateStageResultTest.java
@@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.model.UpdatedFlags;
 import org.junit.jupiter.api.Test;
 
@@ -37,13 +38,13 @@ class FlagsUpdateStageResultTest {
     private static final MessageUid OTHER_UID = MessageUid.of(2L);
     private static final UpdatedFlags UPDATED_FLAGS = UpdatedFlags.builder()
         .uid(UID)
-        .modSeq(18L)
+        .modSeq(ModSeq.of(18))
         .oldFlags(new Flags())
         .newFlags(new Flags(Flags.Flag.SEEN))
         .build();
     private static final UpdatedFlags OTHER_UPDATED_FLAGS = UpdatedFlags.builder()
         .uid(OTHER_UID)
-        .modSeq(18L)
+        .modSeq(ModSeq.of(18))
         .oldFlags(new Flags())
         .newFlags(new Flags(Flags.Flag.SEEN))
         .build();
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
index 3409607..40d2b1c 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
@@ -28,6 +28,7 @@ import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.elasticsearch.IndexAttachments;
 import org.apache.james.mailbox.elasticsearch.query.DateResolutionFormater;
 import org.apache.james.mailbox.extractor.TextExtractor;
@@ -137,7 +138,7 @@ public class IndexableMessage {
 
             long uid = message.getUid().asLong();
             String mailboxId = message.getMailboxId().serialize();
-            long modSeq = message.getModSeq();
+            ModSeq modSeq = message.getModSeq();
             long size = message.getFullContentOctets();
             String date = DateResolutionFormater.DATE_TIME_FOMATTER.format(getSanitizedInternalDate(message, zoneId));
             String mediaType = message.getMediaType();
@@ -243,7 +244,7 @@ public class IndexableMessage {
                              boolean isUnRead,
                              String mailboxId,
                              String mediaType, String messageId,
-                             long modSeq,
+                             ModSeq modSeq,
                              String sentDate,
                              long size,
                              Subjects subjects,
@@ -270,7 +271,7 @@ public class IndexableMessage {
         this.mailboxId = mailboxId;
         this.mediaType = mediaType;
         this.messageId = messageId;
-        this.modSeq = modSeq;
+        this.modSeq = modSeq.asLong();
         this.sentDate = sentDate;
         this.size = size;
         this.subjects = subjects;
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJson.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJson.java
index 3494c49..3892cbe 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJson.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJson.java
@@ -26,6 +26,7 @@ import javax.inject.Inject;
 import javax.mail.Flags;
 
 import org.apache.james.core.Username;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.elasticsearch.IndexAttachments;
 import org.apache.james.mailbox.extractor.TextExtractor;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
@@ -77,7 +78,7 @@ public class MessageToElasticSearchJson {
                 .build());
     }
 
-    public String getUpdatedJsonMessagePart(Flags flags, long modSeq) throws JsonProcessingException {
+    public String getUpdatedJsonMessagePart(Flags flags, ModSeq modSeq) throws JsonProcessingException {
         Preconditions.checkNotNull(flags);
         return mapper.writeValueAsString(new MessageUpdateJson(flags, modSeq));
     }
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java
index f059317..e26b25d 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/MessageUpdateJson.java
@@ -23,6 +23,8 @@ package org.apache.james.mailbox.elasticsearch.json;
 
 import javax.mail.Flags;
 
+import org.apache.james.mailbox.ModSeq;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 public class MessageUpdateJson {
@@ -30,9 +32,9 @@ public class MessageUpdateJson {
     private final Flags flags;
     private final long modSeq;
 
-    public MessageUpdateJson(Flags flags, long modSeq) {
+    public MessageUpdateJson(Flags flags, ModSeq modSeq) {
         this.flags = flags;
-        this.modSeq = modSeq;
+        this.modSeq = modSeq.asLong();
     }
 
     @JsonProperty(JsonMessageConstants.IS_ANSWERED)
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
index 670177e..b7ec704 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
@@ -37,6 +37,7 @@ import org.apache.james.core.Username;
 import org.apache.james.mailbox.DefaultMailboxes;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.elasticsearch.IndexAttachments;
 import org.apache.james.mailbox.elasticsearch.MailboxElasticSearchConstants;
 import org.apache.james.mailbox.elasticsearch.MailboxIdRoutingKeyFactory;
@@ -83,7 +84,7 @@ public class ElasticSearchListeningMessageSearchIndexTest {
     private static final int SIZE = 25;
     private static final int BODY_START_OCTET = 100;
     private static final TestId MAILBOX_ID = TestId.of(1L);
-    private static final long MOD_SEQ = 42L;
+    private static final ModSeq MOD_SEQ = ModSeq.of(42L);
     private static final Username USERNAME = Username.of("user");
     private static final MessageUid MESSAGE_UID_1 = MessageUid.of(25);
     private static final MessageUid MESSAGE_UID_2 = MessageUid.of(26);
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJsonTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJsonTest.java
index 30cddf8..81f3d20 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJsonTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MessageToElasticSearchJsonTest.java
@@ -34,6 +34,7 @@ import javax.mail.Flags;
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.elasticsearch.IndexAttachments;
 import org.apache.james.mailbox.extractor.TextExtractor;
 import org.apache.james.mailbox.model.MessageId;
@@ -61,7 +62,7 @@ public class MessageToElasticSearchJsonTest {
     private static final int BODY_START_OCTET = 100;
     private static final TestId MAILBOX_ID = TestId.of(18L);
     private static final MessageId MESSAGE_ID = TestMessageId.of(184L);
-    private static final long MOD_SEQ = 42L;
+    private static final ModSeq MOD_SEQ = ModSeq.of(42L);
     private static final MessageUid UID = MessageUid.of(25);
     private static final Username USERNAME = Username.of("username");
 
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 880e676..f18690a 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
@@ -29,7 +29,7 @@ import org.apache.james.core.quota.{QuotaLimitValue, QuotaUsageValue}
 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}
+import org.apache.james.mailbox.{FlagsBuilder, MessageUid, ModSeq}
 
 import scala.collection.JavaConverters._
 
@@ -83,7 +83,7 @@ object DTOs {
       javaMessageMetaData.getMessageId)
   }
 
-  case class MessageMetaData(uid: MessageUid, modSeq: Long, flags: Flags, size: Long, internalDate: Instant, messageId: MessageId) {
+  case class MessageMetaData(uid: MessageUid, modSeq: ModSeq, flags: Flags, size: Long, internalDate: Instant, messageId: MessageId) {
     def toJava: JavaMessageMetaData = new JavaMessageMetaData(uid, modSeq, Flags.toJavaFlags(flags), size, Date.from(internalDate), messageId)
   }
 
@@ -138,7 +138,7 @@ object DTOs {
       Flags.fromJavaFlags(javaUpdatedFlags.getNewFlags))
   }
 
-  case class UpdatedFlags(uid: MessageUid, modSeq: Long, oldFlags: Flags, newFlags: Flags) {
+  case class UpdatedFlags(uid: MessageUid, modSeq: ModSeq, oldFlags: Flags, newFlags: Flags) {
     def toJava: JavaUpdatedFlags = JavaUpdatedFlags.builder()
       .uid(uid)
       .modSeq(modSeq)
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 87b6e21..d7596e7 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
@@ -29,12 +29,12 @@ import org.apache.james.core.quota.{QuotaCountLimit, QuotaCountUsage, QuotaLimit
 import org.apache.james.event.json.DTOs.SystemFlag.SystemFlag
 import org.apache.james.event.json.DTOs._
 import org.apache.james.mailbox.MailboxSession.SessionId
-import org.apache.james.mailbox.MessageUid
 import org.apache.james.mailbox.events.Event.EventId
 import org.apache.james.mailbox.events.MailboxListener.{Added => JavaAdded, Expunged => JavaExpunged, FlagsUpdated => JavaFlagsUpdated, MailboxACLUpdated => JavaMailboxACLUpdated, MailboxAdded => JavaMailboxAdded, MailboxDeletion => JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, QuotaUsageUpdatedEvent => JavaQuotaUsageUpdatedEvent}
 import org.apache.james.mailbox.events.{Event => JavaEvent, MessageMoveEvent => JavaMessageMoveEvent}
 import org.apache.james.mailbox.model.{MailboxId, MessageId, MessageMoves, QuotaRoot, MailboxACL => JavaMailboxACL, MessageMetaData => JavaMessageMetaData, Quota => JavaQuota}
 import org.apache.james.mailbox.quota.QuotaRootDeserializer
+import org.apache.james.mailbox.{MessageUid, ModSeq}
 import play.api.libs.json._
 
 import scala.collection.JavaConverters._
@@ -218,6 +218,7 @@ class JsonSerialize(mailboxIdFactory: MailboxId.Factory, messageIdFactory: Messa
   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 modSeqWrites: Writes[ModSeq] = value => JsNumber(value.asLong())
   implicit val userFlagWrites: Writes[UserFlag] = value => JsString(value.value)
   implicit val flagWrites: Writes[Flags] = Json.writes[Flags]
   implicit val eventIdWrites: Writes[EventId] = value => JsString(value.getId.toString)
@@ -281,6 +282,10 @@ class JsonSerialize(mailboxIdFactory: MailboxId.Factory, messageIdFactory: Messa
     case JsNumber(value) => JsSuccess(MessageUid.of(value.toLong))
     case _ => JsError()
   }
+  implicit val modSeqReads: Reads[ModSeq] = {
+    case JsNumber(value) => JsSuccess(ModSeq.of(value.toLong))
+    case _ => JsError()
+  }
   implicit val userFlagsReads: Reads[UserFlag] = {
     case JsString(x) => JsSuccess(UserFlag(x))
     case _ => JsError()
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 0bad42a..483123f 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
@@ -36,6 +36,7 @@ import org.apache.james.core.Username;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.events.MailboxListener;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
@@ -58,7 +59,7 @@ class AddedSerializationTest {
     private static final MessageUid MESSAGE_UID = MessageUid.of(123456);
     private static final Instant INSTANT = Instant.parse("2018-12-14T09:41:51.541Z");
     private static final TestMessageId MESSAGE_ID = TestMessageId.of(42);
-    private static final int MOD_SEQ = 35;
+    private static final ModSeq MOD_SEQ = ModSeq.of(35);
     private static final int SIZE = 45;
     private static final Flags FLAGS = FlagsBuilder.builder()
         .add(Flags.Flag.ANSWERED, Flags.Flag.DRAFT)
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
index 921fd07..06066c3 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
@@ -36,6 +36,7 @@ import org.apache.james.core.Username;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.events.MailboxListener;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
@@ -58,7 +59,7 @@ class ExpungedSerializationTest {
     private static final MessageUid MESSAGE_UID = MessageUid.of(123456);
     private static final Instant INSTANT = Instant.parse("2018-12-14T09:41:51.541Z");
     private static final TestMessageId MESSAGE_ID = TestMessageId.of(42);
-    private static final int MOD_SEQ = 35;
+    private static final ModSeq MOD_SEQ = ModSeq.of(35);
     private static final int SIZE = 45;
     private static final Flags FLAGS = FlagsBuilder.builder()
         .add(Flags.Flag.ANSWERED, Flags.Flag.DRAFT)
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
index 3140c62..8a2347e 100644
--- a/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
@@ -34,6 +34,7 @@ import org.apache.james.core.Username;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.events.MailboxListener;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
@@ -57,7 +58,7 @@ class FlagsUpdatedSerializationTest {
     private static final MessageUid MESSAGE_UID_1 = MessageUid.of(123456);
     private static final MessageUid MESSAGE_UID_2 = MessageUid.of(654321);
 
-    private static final int MOD_SEQ_1 = 35;
+    private static final ModSeq MOD_SEQ_1 = ModSeq.of(35);
     private static final Flags OLD_FLAGS_1 = FlagsBuilder.builder()
         .add(Flags.Flag.SEEN, Flags.Flag.DELETED)
         .add("Old Flag 1")
@@ -73,7 +74,7 @@ class FlagsUpdatedSerializationTest {
         .newFlags(NEW_FLAGS_1)
         .build();
 
-    private static final int MOD_SEQ_2 = 36;
+    private static final ModSeq MOD_SEQ_2 = ModSeq.of(36);
     private static final Flags OLD_FLAGS_2 = FlagsBuilder.builder()
         .add(Flags.Flag.RECENT, Flags.Flag.FLAGGED)
         .add("Old Flag 2")
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/dtos/ModSeqTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/dtos/ModSeqTest.java
new file mode 100644
index 0000000..f0044b1
--- /dev/null
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/dtos/ModSeqTest.java
@@ -0,0 +1,58 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.event.json.dtos;
+
+import static org.apache.james.event.json.SerializerFixture.DTO_JSON_SERIALIZE;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.james.mailbox.ModSeq;
+import org.junit.jupiter.api.Test;
+
+import play.api.libs.json.JsError;
+import play.api.libs.json.JsNull$;
+import play.api.libs.json.JsNumber;
+import play.api.libs.json.JsString;
+import scala.math.BigDecimal;
+
+class ModSeqTest {
+    @Test
+    void messageUidShouldBeWellSerialized() {
+        assertThat(DTO_JSON_SERIALIZE.modSeqWrites().writes(ModSeq.of(18)))
+            .isEqualTo(new JsNumber(BigDecimal.valueOf(18)));
+    }
+
+    @Test
+    void messageUidShouldBeWellDeSerialized() {
+        assertThat(DTO_JSON_SERIALIZE.modSeqReads().reads(new JsNumber(BigDecimal.valueOf(18))).get())
+            .isEqualTo(ModSeq.of(18));
+    }
+
+    @Test
+    void messageUidShouldReturnErrorWhenString() {
+        assertThat(DTO_JSON_SERIALIZE.modSeqReads().reads(new JsString("18")))
+            .isInstanceOf(JsError.class);
+    }
+
+    @Test
+    void messageUidShouldReturnErrorWhenNull() {
+        assertThat(DTO_JSON_SERIALIZE.modSeqReads().reads(JsNull$.MODULE$))
+            .isInstanceOf(JsError.class);
+    }
+}
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
index a2475fe..c29f6d7 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
@@ -32,6 +32,7 @@ import javax.persistence.Query;
 
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.jpa.JPAId;
 import org.apache.james.mailbox.jpa.JPATransactionalMapper;
@@ -324,7 +325,7 @@ public class JPAMessageMapper extends JPATransactionalMapper implements MessageM
     }
 
     @Override
-    public long getHighestModSeq(Mailbox mailbox) throws MailboxException {
+    public ModSeq getHighestModSeq(Mailbox mailbox) throws MailboxException {
         return messageMetadataMapper.getHighestModSeq(mailbox);
     }
 
@@ -335,7 +336,7 @@ public class JPAMessageMapper extends JPATransactionalMapper implements MessageM
             .computeApplicableFlags();
     }
 
-    private MessageMetaData copy(Mailbox mailbox, MessageUid uid, long modSeq, MailboxMessage original)
+    private MessageMetaData copy(Mailbox mailbox, MessageUid uid, ModSeq modSeq, MailboxMessage original)
             throws MailboxException {
         MailboxMessage copy;
         JPAMailbox currentMailbox = JPAMailbox.from(mailbox);
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAModSeqProvider.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAModSeqProvider.java
index d1da257..ff1a5e2 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAModSeqProvider.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAModSeqProvider.java
@@ -24,6 +24,7 @@ import javax.persistence.EntityManagerFactory;
 import javax.persistence.PersistenceException;
 
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.jpa.JPAId;
 import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
@@ -41,27 +42,27 @@ public class JPAModSeqProvider implements ModSeqProvider {
     }
 
     @Override
-    public long highestModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException {
+    public ModSeq highestModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException {
         JPAId mailboxId = (JPAId) mailbox.getMailboxId();
         return highestModSeq(mailboxId);
     }
 
     @Override
-    public long nextModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException {
+    public ModSeq nextModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException {
         return nextModSeq((JPAId) mailbox.getMailboxId());
     }
 
     @Override
-    public long nextModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
+    public ModSeq nextModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
         return nextModSeq((JPAId) mailboxId);
     }
 
     @Override
-    public long highestModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
+    public ModSeq highestModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
         return highestModSeq((JPAId) mailboxId);
     }
 
-    private long nextModSeq(JPAId mailboxId) throws MailboxException {
+    private ModSeq nextModSeq(JPAId mailboxId) throws MailboxException {
         EntityManager manager = null;
         try {
             manager = factory.createEntityManager();
@@ -70,7 +71,7 @@ public class JPAModSeqProvider implements ModSeqProvider {
             long modSeq = m.consumeModSeq();
             manager.persist(m);
             manager.getTransaction().commit();
-            return modSeq;
+            return ModSeq.of(modSeq);
         } catch (PersistenceException e) {
             if (manager != null && manager.getTransaction().isActive()) {
                 manager.getTransaction().rollback();
@@ -83,14 +84,14 @@ public class JPAModSeqProvider implements ModSeqProvider {
         }
     }
 
-    private long highestModSeq(JPAId mailboxId) throws MailboxException {
+    private ModSeq highestModSeq(JPAId mailboxId) throws MailboxException {
         EntityManager manager = null;
         try {
             manager = factory.createEntityManager();
             long highest = (Long) manager.createNamedQuery("findHighestModSeq")
                 .setParameter("idParam", mailboxId.getRawId())
                 .getSingleResult();
-            return highest;
+            return ModSeq.of(highest);
         } catch (PersistenceException e) {
             throw new MailboxException("Unable to get highest mod-sequence for mailbox " + mailboxId.serialize(), e);
         } finally {
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
index 55986fc..18bcf7c 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
@@ -42,6 +42,7 @@ import javax.persistence.OneToMany;
 import javax.persistence.OrderBy;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.jpa.JPAId;
 import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
@@ -275,12 +276,12 @@ public abstract class AbstractJPAMailboxMessage implements MailboxMessage {
      * @param original
      *            message to be copied, not null
      */
-    public AbstractJPAMailboxMessage(JPAMailbox mailbox, MessageUid uid, long modSeq, MailboxMessage original)
+    public AbstractJPAMailboxMessage(JPAMailbox mailbox, MessageUid uid, ModSeq modSeq, MailboxMessage original)
             throws MailboxException {
         super();
         this.mailbox = mailbox;
         this.uid = uid.asLong();
-        this.modSeq = modSeq;
+        this.modSeq = modSeq.asLong();
         this.userFlags = new ArrayList<>();
         setFlags(original.createFlags());
 
@@ -322,20 +323,20 @@ public abstract class AbstractJPAMailboxMessage implements MailboxMessage {
     @Override
     public ComposedMessageIdWithMetaData getComposedMessageIdWithMetaData() {
         return ComposedMessageIdWithMetaData.builder()
-            .modSeq(modSeq)
+            .modSeq(getModSeq())
             .flags(createFlags())
             .composedMessageId(new ComposedMessageId(mailbox.getMailboxId(), getMessageId(), MessageUid.of(uid)))
             .build();
     }
 
     @Override
-    public long getModSeq() {
-        return modSeq;
+    public ModSeq getModSeq() {
+        return ModSeq.of(modSeq);
     }
 
     @Override
-    public void setModSeq(long modSeq) {
-        this.modSeq = modSeq;
+    public void setModSeq(ModSeq modSeq) {
+        this.modSeq = modSeq.asLong();
     }
 
     @Override
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAEncryptedMailboxMessage.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAEncryptedMailboxMessage.java
index cb03b02..e67f52b 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAEncryptedMailboxMessage.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAEncryptedMailboxMessage.java
@@ -34,6 +34,7 @@ import javax.persistence.Table;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
@@ -80,7 +81,7 @@ public class JPAEncryptedMailboxMessage extends AbstractJPAMailboxMessage {
         /**
          * Create a copy of the given message
          */
-        public JPAEncryptedMailboxMessage(JPAMailbox mailbox, MessageUid uid, long modSeq, MailboxMessage message) throws MailboxException {
+        public JPAEncryptedMailboxMessage(JPAMailbox mailbox, MessageUid uid, ModSeq modSeq, MailboxMessage message) throws MailboxException {
             super(mailbox, uid, modSeq, message);
             try {
                 this.body = IOUtils.toByteArray(message.getBodyContent());
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAMailboxMessage.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAMailboxMessage.java
index 816380d..90c8eee 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAMailboxMessage.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAMailboxMessage.java
@@ -34,6 +34,7 @@ import javax.persistence.Table;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
@@ -89,7 +90,7 @@ public class JPAMailboxMessage extends AbstractJPAMailboxMessage {
     /**
      * Create a copy of the given message
      */
-    public JPAMailboxMessage(JPAMailbox mailbox, MessageUid uid, long modSeq, MailboxMessage message) throws MailboxException {
+    public JPAMailboxMessage(JPAMailbox mailbox, MessageUid uid, ModSeq modSeq, MailboxMessage message) throws MailboxException {
         super(mailbox, uid, modSeq, message);
         try {
             this.body = IOUtils.toByteArray(message.getBodyContent());
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAStreamingMailboxMessage.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAStreamingMailboxMessage.java
index 3055303..9ba8999 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAStreamingMailboxMessage.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAStreamingMailboxMessage.java
@@ -32,6 +32,7 @@ import javax.persistence.Table;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
@@ -78,7 +79,7 @@ public class JPAStreamingMailboxMessage extends AbstractJPAMailboxMessage {
     /**
      * Create a copy of the given message
      */
-    public JPAStreamingMailboxMessage(JPAMailbox mailbox, MessageUid uid, long modSeq, MailboxMessage message) throws MailboxException {
+    public JPAStreamingMailboxMessage(JPAMailbox mailbox, MessageUid uid, ModSeq modSeq, MailboxMessage message) throws MailboxException {
         super(mailbox, uid, modSeq, message);
         try {
             this.content = new SharedByteArrayInputStream(IOUtils.toByteArray(message.getFullContent()));
diff --git a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/JPAMapperProvider.java b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/JPAMapperProvider.java
index eb164f0..a8af899 100644
--- a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/JPAMapperProvider.java
+++ b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/JPAMapperProvider.java
@@ -29,6 +29,7 @@ import org.apache.james.backends.jpa.JpaTestCluster;
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.jpa.JPAId;
 import org.apache.james.mailbox.model.Mailbox;
@@ -104,12 +105,12 @@ public class JPAMapperProvider implements MapperProvider {
     }
 
     @Override
-    public long generateModSeq(Mailbox mailbox) throws MailboxException {
+    public ModSeq generateModSeq(Mailbox mailbox) throws MailboxException {
         throw new NotImplementedException("not implemented");
     }
 
     @Override
-    public long highestModSeq(Mailbox mailbox) throws MailboxException {
+    public ModSeq highestModSeq(Mailbox mailbox) throws MailboxException {
         throw new NotImplementedException("not implemented");
     }
 
diff --git a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMessageMapper.java b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMessageMapper.java
index 658547c..2242197 100644
--- a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMessageMapper.java
+++ b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMessageMapper.java
@@ -29,10 +29,10 @@ import javax.mail.Flags;
 
 import org.apache.commons.lang3.NotImplementedException;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxCounters;
-import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.UpdatedFlags;
@@ -146,7 +146,7 @@ public class TransactionalMessageMapper implements MessageMapper {
     }
 
     @Override
-    public long getHighestModSeq(Mailbox mailbox) throws MailboxException {
+    public ModSeq getHighestModSeq(Mailbox mailbox) throws MailboxException {
         return messageMapper.getHighestModSeq(mailbox);
     }
 
diff --git a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirFolder.java b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirFolder.java
index 946f6f2..f744f94 100644
--- a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirFolder.java
+++ b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirFolder.java
@@ -47,6 +47,7 @@ import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxPathLocker.LockAwareExecution;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxACL.EntryKey;
@@ -206,13 +207,13 @@ public class MaildirFolder {
         return lastUid;
     }
     
-    public long getHighestModSeq() throws IOException {
+    public ModSeq getHighestModSeq() throws IOException {
         long newModified = getNewFolder().lastModified();
         long curModified = getCurFolder().lastModified();
         if (newModified  == 0L && curModified == 0L) {
             throw new IOException("Unable to read highest modSeq");
         }
-        return Math.max(newModified, curModified);
+        return ModSeq.of(Math.max(newModified, curModified));
     }
 
     /**
diff --git a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirStore.java b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirStore.java
index a2384ec..63f2a96 100644
--- a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirStore.java
+++ b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirStore.java
@@ -28,6 +28,7 @@ import org.apache.james.core.Username;
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.model.Mailbox;
@@ -260,12 +261,12 @@ public class MaildirStore implements UidProvider, ModSeqProvider {
     }
 
     @Override
-    public long nextModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException {
-        return System.currentTimeMillis();
+    public ModSeq nextModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException {
+        return ModSeq.of(System.currentTimeMillis());
     }
 
     @Override
-    public long highestModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException {
+    public ModSeq highestModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException {
         try {
             return createMaildirFolder(mailbox).getHighestModSeq();
         } catch (IOException e) {
@@ -299,8 +300,8 @@ public class MaildirStore implements UidProvider, ModSeqProvider {
     }
 
     @Override
-    public long nextModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
-        return System.currentTimeMillis();
+    public ModSeq nextModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
+        return ModSeq.of(System.currentTimeMillis());
     }
 
     @Override
@@ -309,7 +310,7 @@ public class MaildirStore implements UidProvider, ModSeqProvider {
     }
 
     @Override
-    public long highestModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
+    public ModSeq highestModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
         throw new NotImplementedException("Not implemented");
     }
 }
diff --git a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
index 6fccddd..5d87d48 100644
--- a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
+++ b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
@@ -38,6 +38,7 @@ import javax.mail.Flags.Flag;
 import org.apache.commons.io.FileUtils;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.maildir.MaildirFolder;
 import org.apache.james.mailbox.maildir.MaildirMessageName;
@@ -197,7 +198,7 @@ public class MaildirMessageMapper extends AbstractMessageMapper {
                     } else {
                         modSeq = messageFile.lastModified();
                     }
-                    member.setModSeq(modSeq);
+                    member.setModSeq(ModSeq.of(modSeq));
 
                     updatedFlags.add(UpdatedFlags.builder()
                         .uid(member.getUid())
@@ -273,7 +274,7 @@ public class MaildirMessageMapper extends AbstractMessageMapper {
     }
 
     @Override
-    protected MessageMetaData copy(Mailbox mailbox, MessageUid uid, long modSeq, MailboxMessage original)
+    protected MessageMetaData copy(Mailbox mailbox, MessageUid uid, ModSeq modSeq, MailboxMessage original)
             throws MailboxException {
         SimpleMailboxMessage theCopy = SimpleMailboxMessage.copyWithoutAttachments(mailbox.getMailboxId(), original);
         Flags flags = theCopy.createFlags();
@@ -337,7 +338,7 @@ public class MaildirMessageMapper extends AbstractMessageMapper {
         try {
             uid = folder.appendMessage(newMessageFile.getName());
             message.setUid(uid);
-            message.setModSeq(newMessageFile.lastModified());
+            message.setModSeq(ModSeq.of(newMessageFile.lastModified()));
             return message.metaData();
         } catch (MailboxException e) {
             throw new MailboxException("Failure while save MailboxMessage " + message + " in Mailbox " + mailbox, e);
diff --git a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMailboxMessage.java b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMailboxMessage.java
index 03af11a..70ffdaa 100644
--- a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMailboxMessage.java
+++ b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMailboxMessage.java
@@ -25,6 +25,7 @@ import java.io.IOException;
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.maildir.MaildirFolder;
 import org.apache.james.mailbox.maildir.MaildirId;
 import org.apache.james.mailbox.maildir.MaildirMessageName;
@@ -44,14 +45,14 @@ public class MaildirMailboxMessage extends DelegatingMailboxMessage {
     private final Mailbox mailbox;
     private MessageUid uid;
     protected boolean newMessage;
-    private long modSeq;
+    private ModSeq modSeq;
     
     public MaildirMailboxMessage(Mailbox mailbox, MessageUid messageUid, MaildirMessageName messageName) throws IOException {
         super(new MaildirMessage(messageName));
 
         this.mailbox = mailbox;
         setUid(messageUid);
-        setModSeq(messageName.getFile().lastModified());
+        setModSeq(ModSeq.of(messageName.getFile().lastModified()));
         Flags flags = messageName.getFlags();
         
         // Set the flags for the message and respect if its RECENT
@@ -149,12 +150,12 @@ public class MaildirMailboxMessage extends DelegatingMailboxMessage {
     }
 
     @Override
-    public long getModSeq() {
+    public ModSeq getModSeq() {
         return modSeq;
     }
 
     @Override
-    public void setModSeq(long modSeq) {
+    public void setModSeq(ModSeq modSeq) {
         this.modSeq = modSeq;
     }
 
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMessageMapper.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMessageMapper.java
index f87f946..e2c991c 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMessageMapper.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMessageMapper.java
@@ -32,6 +32,7 @@ import javax.mail.Flags.Flag;
 
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.model.Mailbox;
@@ -202,7 +203,7 @@ public class InMemoryMessageMapper extends AbstractMessageMapper {
     }
 
     @Override
-    protected MessageMetaData copy(Mailbox mailbox, MessageUid uid, long modSeq, MailboxMessage original)
+    protected MessageMetaData copy(Mailbox mailbox, MessageUid uid, ModSeq modSeq, MailboxMessage original)
             throws MailboxException {
         SimpleMailboxMessage message = SimpleMailboxMessage.copy(mailbox.getMailboxId(), original);
         message.setUid(uid);
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryModSeqProvider.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryModSeqProvider.java
index 34f7b6d..08c1007 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryModSeqProvider.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryModSeqProvider.java
@@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.model.Mailbox;
@@ -34,36 +35,36 @@ public class InMemoryModSeqProvider implements ModSeqProvider {
     private final ConcurrentMap<InMemoryId, AtomicLong> map = new ConcurrentHashMap<>();
 
     @Override
-    public long nextModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException {
-        return nextModSeq((InMemoryId) mailbox.getMailboxId());
+    public ModSeq nextModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException {
+        return ModSeq.of(nextModSeq((InMemoryId) mailbox.getMailboxId()));
 
     }
 
     @Override
-    public long nextModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
-        return nextModSeq((InMemoryId) mailboxId);
+    public ModSeq nextModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
+        return ModSeq.of(nextModSeq((InMemoryId) mailboxId));
     }
 
     @Override
-    public long highestModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException {
-        return getHighest((InMemoryId) mailbox.getMailboxId()).get();
+    public ModSeq highestModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException {
+        return ModSeq.of(getHighest((InMemoryId) mailbox.getMailboxId()).get());
     }
 
     @Override
-    public long highestModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
-        return getHighest((InMemoryId) mailboxId).get();
+    public ModSeq highestModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException {
+        return ModSeq.of(getHighest((InMemoryId) mailboxId).get());
     }
 
     private AtomicLong getHighest(InMemoryId id) {
-        AtomicLong uid = map.get(id);
-        if (uid == null) {
-            uid = new AtomicLong(0);
-            AtomicLong u = map.putIfAbsent(id, uid);
+        AtomicLong modSeq = map.get(id);
+        if (modSeq == null) {
+            modSeq = new AtomicLong(0);
+            AtomicLong u = map.putIfAbsent(id, modSeq);
             if (u != null) {
-                uid = u;
+                modSeq = u;
             }
         }
-        return uid;
+        return modSeq;
     }
 
     private long nextModSeq(InMemoryId mailboxId) {
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMapperProvider.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMapperProvider.java
index a15ecd1..99ccba0 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMapperProvider.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMapperProvider.java
@@ -26,6 +26,7 @@ import org.apache.james.core.Username;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
@@ -112,13 +113,13 @@ public class InMemoryMapperProvider implements MapperProvider {
     }
 
     @Override
-    public long generateModSeq(Mailbox mailbox) throws MailboxException {
+    public ModSeq generateModSeq(Mailbox mailbox) throws MailboxException {
         return inMemoryMailboxSessionMapperFactory.getModSeqProvider()
                 .nextModSeq(MAILBOX_SESSION, mailbox);
     }
 
     @Override
-    public long highestModSeq(Mailbox mailbox) throws MailboxException {
+    public ModSeq highestModSeq(Mailbox mailbox) throws MailboxException {
         return inMemoryMailboxSessionMapperFactory.getModSeqProvider()
             .highestModSeq(MAILBOX_SESSION, mailbox);
     }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxMetaData.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxMetaData.java
index a9a4f26..479f598 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxMetaData.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxMetaData.java
@@ -27,6 +27,7 @@ import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxACL;
 
@@ -40,7 +41,7 @@ public class MailboxMetaData implements MessageManager.MetaData {
     public static MailboxMetaData sensibleInformationFree(MailboxACL resolvedAcl, long uidValidity, boolean writeable, boolean modSeqPermanent) throws MailboxException {
         ImmutableList<MessageUid> recents = ImmutableList.of();
         MessageUid uidNext = MessageUid.MIN_VALUE;
-        long highestModSeq = 0L;
+        ModSeq highestModSeq = ModSeq.first();
         long messageCount = 0L;
         long unseenCount = 0L;
         MessageUid firstUnseen = null;
@@ -67,12 +68,11 @@ public class MailboxMetaData implements MessageManager.MetaData {
     private final long unseenCount;
     private final MessageUid firstUnseen;
     private final boolean writeable;
-    private final long highestModSeq;
+    private final ModSeq highestModSeq;
     private final boolean modSeqPermanent;
     private final MailboxACL acl;
 
-    public MailboxMetaData(List<MessageUid> recent, Flags permanentFlags, long uidValidity, MessageUid uidNext, long highestModSeq, long messageCount, long unseenCount, MessageUid firstUnseen, boolean writeable, boolean modSeqPermanent, MailboxACL acl) {
-        super();
+    public MailboxMetaData(List<MessageUid> recent, Flags permanentFlags, long uidValidity, MessageUid uidNext, ModSeq highestModSeq, long messageCount, long unseenCount, MessageUid firstUnseen, boolean writeable, boolean modSeqPermanent, MailboxACL acl) {
         this.recent = Optional.ofNullable(recent).orElseGet(ArrayList::new);
         this.highestModSeq = highestModSeq;
         this.recentCount = this.recent.size();
@@ -134,7 +134,7 @@ public class MailboxMetaData implements MessageManager.MetaData {
     }
 
     @Override
-    public long getHighestModSeq() {
+    public ModSeq getHighestModSeq() {
         return highestModSeq;
     }
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageResultImpl.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageResultImpl.java
index a39e379..0e4e4a1 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageResultImpl.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageResultImpl.java
@@ -30,6 +30,7 @@ import java.util.Map;
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Content;
 import org.apache.james.mailbox.model.Headers;
@@ -96,7 +97,7 @@ public class MessageResultImpl implements MessageResult {
     }
 
     @Override
-    public long getModSeq() {
+    public ModSeq getModSeq() {
         return messageMetaData().getModSeq();
     }
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
index c440924..c4a8bd1 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
@@ -36,6 +36,7 @@ import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.MetadataWithMailboxId;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.MailboxException;
@@ -395,7 +396,7 @@ public class StoreMessageIdManager implements MessageIdManager {
     }
 
     private void save(MailboxSession mailboxSession, MessageIdMapper messageIdMapper, MailboxMessage mailboxMessage) throws MailboxException {
-        long modSeq = mailboxSessionMapperFactory.getModSeqProvider().nextModSeq(mailboxSession, mailboxMessage.getMailboxId());
+        ModSeq modSeq = mailboxSessionMapperFactory.getModSeqProvider().nextModSeq(mailboxSession, mailboxMessage.getMailboxId());
         MessageUid uid = mailboxSessionMapperFactory.getUidProvider().nextUid(mailboxSession, mailboxMessage.getMailboxId());
         mailboxMessage.setModSeq(modSeq);
         mailboxMessage.setUid(uid);
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index 73954ff..b7e5df3 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -51,6 +51,7 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.MetadataWithMailboxId;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.events.MailboxListener;
@@ -537,7 +538,7 @@ public class StoreMessageManager implements MessageManager {
         MessageUid uidNext = mapperFactory.getMessageMapper(mailboxSession).getLastUid(mailbox)
                 .map(MessageUid::next)
                 .orElse(MessageUid.MIN_VALUE);
-        long highestModSeq = mapperFactory.getMessageMapper(mailboxSession).getHighestModSeq(mailbox);
+        ModSeq highestModSeq = mapperFactory.getMessageMapper(mailboxSession).getHighestModSeq(mailbox);
         long messageCount;
         long unseenCount;
         MessageUid firstUnseen;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageResultIterator.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageResultIterator.java
index 68ddee2..f2cb048 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageResultIterator.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageResultIterator.java
@@ -27,6 +27,7 @@ import java.util.Objects;
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Content;
 import org.apache.james.mailbox.model.Headers;
@@ -242,7 +243,7 @@ public class StoreMessageResultIterator implements MessageResultIterator {
         }
 
         @Override
-        public long getModSeq() {
+        public ModSeq getModSeq() {
             return messageMetaData().getModSeq();
         }
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractMessageMapper.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractMessageMapper.java
index f183728..915be78 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractMessageMapper.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractMessageMapper.java
@@ -27,6 +27,7 @@ import javax.mail.Flags;
 
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxCounters;
@@ -37,6 +38,7 @@ import org.apache.james.mailbox.store.FlagsUpdateCalculator;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.transaction.TransactionalMapper;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterators;
 
 /**
@@ -59,7 +61,7 @@ public abstract class AbstractMessageMapper extends TransactionalMapper implemen
     }
     
     @Override
-    public long getHighestModSeq(Mailbox mailbox) throws MailboxException {
+    public ModSeq getHighestModSeq(Mailbox mailbox) throws MailboxException {
         return modSeqProvider.highestModSeq(mailboxSession, mailbox);
     }
 
@@ -81,14 +83,11 @@ public abstract class AbstractMessageMapper extends TransactionalMapper implemen
     public Iterator<UpdatedFlags> updateFlags(Mailbox mailbox, FlagsUpdateCalculator flagsUpdateCalculator, MessageRange set) throws MailboxException {
         final List<UpdatedFlags> updatedFlags = new ArrayList<>();
         Iterator<MailboxMessage> messages = findInMailbox(mailbox, set, FetchType.Metadata, UNLIMITED);
-        
-        long modSeq = -1;
-        if (messages.hasNext()) {
-            // if a mailbox does not support mod-sequences the provider may be null
-            if (modSeqProvider != null) {
-                modSeq = modSeqProvider.nextModSeq(mailboxSession, mailbox);
-            }
+
+        if (!messages.hasNext()) {
+            return ImmutableList.<UpdatedFlags>of().iterator();
         }
+        ModSeq modSeq = modSeqProvider.nextModSeq(mailboxSession, mailbox);
         while (messages.hasNext()) {
             final MailboxMessage member = messages.next();
             Flags originalFlags = member.createFlags();
@@ -131,10 +130,7 @@ public abstract class AbstractMessageMapper extends TransactionalMapper implemen
     @Override
     public MessageMetaData copy(Mailbox mailbox, MailboxMessage original) throws MailboxException {
         MessageUid uid = uidProvider.nextUid(mailboxSession, mailbox);
-        long modSeq = -1;
-        if (modSeqProvider != null) {
-            modSeq = modSeqProvider.nextModSeq(mailboxSession, mailbox);
-        }
+        ModSeq modSeq = modSeqProvider.nextModSeq(mailboxSession, mailbox);
         final MessageMetaData metaData = copy(mailbox, uid, modSeq, original);  
         
         return metaData;
@@ -149,7 +145,7 @@ public abstract class AbstractMessageMapper extends TransactionalMapper implemen
     /**
      * Copy the MailboxMessage to the Mailbox, using the given uid and modSeq for the new MailboxMessage
      */
-    protected abstract MessageMetaData copy(Mailbox mailbox, MessageUid uid, long modSeq, MailboxMessage original) throws MailboxException;
+    protected abstract MessageMetaData copy(Mailbox mailbox, MessageUid uid, ModSeq modSeq, MailboxMessage original) throws MailboxException;
 
     @Override
     public Iterator<MessageUid> listAllMessageUids(Mailbox mailbox) throws MailboxException {
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java
index f01ddb0..a978a67 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java
@@ -27,6 +27,7 @@ import java.util.Optional;
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxCounters;
@@ -142,7 +143,7 @@ public interface MessageMapper extends Mapper {
     /**
      * Return the higest mod-sequence which were used for storing a MailboxMessage in the {@link Mailbox}
      */
-    long getHighestModSeq(Mailbox mailbox) throws MailboxException;
+    ModSeq getHighestModSeq(Mailbox mailbox) throws MailboxException;
 
     Flags getApplicableFlag(Mailbox mailbox) throws MailboxException;
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MessageUtils.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MessageUtils.java
index a2d1c9c..b72e314 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MessageUtils.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MessageUtils.java
@@ -22,10 +22,12 @@ package org.apache.james.mailbox.store.mail;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Optional;
+
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.UpdatedFlags;
@@ -48,7 +50,7 @@ public class MessageUtils {
         this.modSeqProvider = modSeqProvider;
     }
     
-    public long getHighestModSeq(Mailbox mailbox) throws MailboxException {
+    public ModSeq getHighestModSeq(Mailbox mailbox) throws MailboxException {
         return modSeqProvider.highestModSeq(mailboxSession, mailbox);
     }
 
@@ -61,7 +63,7 @@ public class MessageUtils {
         return uidProvider.nextUid(mailboxSession, mailbox);
     }
 
-    public long nextModSeq(Mailbox mailbox) throws MailboxException {
+    public ModSeq nextModSeq(Mailbox mailbox) throws MailboxException {
         return modSeqProvider.nextModSeq(mailboxSession, mailbox);
     }
 
@@ -75,7 +77,7 @@ public class MessageUtils {
         ImmutableList.Builder<UpdatedFlags> updatedFlags = ImmutableList.builder();
         ImmutableList.Builder<MailboxMessage> changedFlags = ImmutableList.builder();
 
-        long modSeq = nextModSeq(mailbox);
+        ModSeq modSeq = nextModSeq(mailbox);
 
         while (messages.hasNext()) {
             MailboxMessage member = messages.next();
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/ModSeqProvider.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/ModSeqProvider.java
index 22d08e6..716e7d1 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/ModSeqProvider.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/ModSeqProvider.java
@@ -19,6 +19,7 @@
 package org.apache.james.mailbox.store.mail;
 
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxId;
@@ -36,7 +37,7 @@ public interface ModSeqProvider {
      * 
      * The first mod-seq must be >= 1
      */
-    long nextModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException;
+    ModSeq nextModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException;
 
     /**
      * Return the next mod-sequence which can be used for the {@link Mailbox}.
@@ -45,15 +46,15 @@ public interface ModSeqProvider {
      * 
      * The first mod-seq must be >= 1
      */
-    long nextModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException;
+    ModSeq nextModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException;
     
     /**
      * Return the highest mod-sequence which were used for the {@link Mailbox}
      */
-    long highestModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException;
+    ModSeq highestModSeq(MailboxSession session, Mailbox mailbox) throws MailboxException;
     
     /**
      * Return the highest mod-sequence which were used for the {@link Mailbox}
      */
-    long highestModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException;
+    ModSeq highestModSeq(MailboxSession session, MailboxId mailboxId) throws MailboxException;
 }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/MailboxMessage.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/MailboxMessage.java
index 399fc10..2ecf5b0 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/MailboxMessage.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/MailboxMessage.java
@@ -21,6 +21,7 @@ package org.apache.james.mailbox.store.mail.model;
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageMetaData;
@@ -54,12 +55,12 @@ public interface MailboxMessage extends Message, Comparable<MailboxMessage> {
      * Set the mod-sequence for the message. This must be called before the message is added to the store
      * or any flags are changed. This must be unique / sequential.
      */
-    void setModSeq(long modSeq);
+    void setModSeq(ModSeq modSeq);
 
     /**
      * Return the mod-sequence for the message
      */
-    long getModSeq();
+    ModSeq getModSeq();
 
     /**
      * Return if it was marked as answered
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessage.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessage.java
index c947f25..1a198d2 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessage.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessage.java
@@ -31,6 +31,7 @@ import javax.mail.util.SharedByteArrayInputStream;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
@@ -62,7 +63,7 @@ public class SimpleMailboxMessage extends DelegatingMailboxMessage {
         private PropertyBuilder propertyBuilder;
         private MailboxId mailboxId;
         private Optional<MessageUid> uid = Optional.empty();
-        private Optional<Long> modseq = Optional.empty();
+        private Optional<ModSeq> modseq = Optional.empty();
         private ImmutableList.Builder<MessageAttachment> attachments = ImmutableList.builder();
         private Optional<Boolean> hasAttachment = Optional.empty();
 
@@ -76,8 +77,7 @@ public class SimpleMailboxMessage extends DelegatingMailboxMessage {
             return this;
         }
 
-        public Builder modseq(long modseq) {
-            Preconditions.checkArgument(modseq >= 0, "modseq can not be negative");
+        public Builder modseq(ModSeq modseq) {
             this.modseq = Optional.of(modseq);
             return this;
         }
@@ -201,7 +201,7 @@ public class SimpleMailboxMessage extends DelegatingMailboxMessage {
     private boolean recent;
     private boolean seen;
     private String[] userFlags;
-    private long modSeq;
+    private ModSeq modSeq;
 
     public SimpleMailboxMessage(MessageId messageId, Date internalDate, long size, int bodyStartOctet,
             SharedInputStream content, Flags flags,
@@ -293,12 +293,12 @@ public class SimpleMailboxMessage extends DelegatingMailboxMessage {
     }
 
     @Override
-    public long getModSeq() {
+    public ModSeq getModSeq() {
         return modSeq;
     }
 
     @Override
-    public void setModSeq(long modSeq) {
+    public void setModSeq(ModSeq modSeq) {
         this.modSeq = modSeq;
     }
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
index b02bbc4..ebbccbd 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
@@ -40,6 +40,7 @@ import java.util.stream.Stream;
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.UnsupportedSearchException;
 import org.apache.james.mailbox.extractor.TextExtractor;
@@ -566,15 +567,15 @@ public class MessageSearches implements Iterable<SimpleMessageSearchIndex.Search
     private boolean matches(SearchQuery.ModSeqCriterion criterion, MailboxMessage message)
             throws UnsupportedSearchException {
         SearchQuery.NumericOperator operator = criterion.getOperator();
-        long modSeq = message.getModSeq();
+        ModSeq modSeq = message.getModSeq();
         long value = operator.getValue();
         switch (operator.getType()) {
         case LESS_THAN:
-            return modSeq < value;
+            return modSeq.asLong() < value;
         case GREATER_THAN:
-            return modSeq > value;
+            return modSeq.asLong() > value;
         case EQUALS:
-            return modSeq == value;
+            return modSeq.asLong() == value;
         default:
             throw new UnsupportedSearchException();
         }
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractCombinationManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractCombinationManagerTest.java
index c817e8c..15e934b 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractCombinationManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractCombinationManagerTest.java
@@ -329,7 +329,7 @@ public abstract class AbstractCombinationManagerTest {
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
-        assertThat(messageManager2.getMetaData(true, session, FetchGroup.FIRST_UNSEEN).getHighestModSeq()).isNotNegative();
+        assertThat(messageManager2.getMetaData(true, session, FetchGroup.FIRST_UNSEEN).getHighestModSeq().asLong()).isNotNegative();
     }
 
     @Test
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
index b850249..de0169f 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
@@ -45,6 +45,7 @@ import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageManager.FlagsUpdateMode;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.MetadataWithMailboxId;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.InVMEventBus;
 import org.apache.james.mailbox.events.MailboxListener;
@@ -75,6 +76,7 @@ import org.mockito.ArgumentCaptor;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSortedMap;
+
 import reactor.core.publisher.Mono;
 
 public abstract class AbstractMessageIdManagerSideEffectTest {
@@ -461,7 +463,7 @@ public abstract class AbstractMessageIdManagerSideEffectTest {
         assertThat(messages).hasSize(1);
         MessageResult messageResult = messages.get(0);
         MessageUid messageUid = messageResult.getUid();
-        long modSeq = messageResult.getModSeq();
+        ModSeq modSeq = messageResult.getModSeq();
         UpdatedFlags updatedFlags = UpdatedFlags.builder()
             .uid(messageUid)
             .modSeq(modSeq)
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java
index 9099406..2874746 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java
@@ -35,6 +35,7 @@ import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.fixture.MailboxFixture;
@@ -180,10 +181,10 @@ public abstract class AbstractMessageIdManagerStorageTest {
 
         messageIdManager.setInMailboxes(messageId2, ImmutableList.of(aliceMailbox1.getMailboxId(), aliceMailbox2.getMailboxId()), aliceSession);
 
-        long modSeqMessage1Mailbox1 = messageIdManager.getMessages(ImmutableList.of(messageId1), FetchGroupImpl.MINIMAL, aliceSession)
+        ModSeq modSeqMessage1Mailbox1 = messageIdManager.getMessages(ImmutableList.of(messageId1), FetchGroupImpl.MINIMAL, aliceSession)
             .get(0)
             .getModSeq();
-        long modSeqMessage2Mailbox1 = messageIdManager.getMessages(ImmutableList.of(messageId2), FetchGroupImpl.MINIMAL, aliceSession)
+        ModSeq modSeqMessage2Mailbox1 = messageIdManager.getMessages(ImmutableList.of(messageId2), FetchGroupImpl.MINIMAL, aliceSession)
             .stream()
             .filter(inMailbox(aliceMailbox1.getMailboxId()))
             .findFirst()
@@ -198,7 +199,7 @@ public abstract class AbstractMessageIdManagerStorageTest {
         MessageId messageId = testingData.persist(aliceMailbox1.getMailboxId(), messageUid1, FLAGS, aliceSession);
         MessageResult messageResult1 = messageIdManager.getMessages(ImmutableList.of(messageId), FetchGroupImpl.MINIMAL, aliceSession).get(0);
         MessageUid messageUid1 = messageResult1.getUid();
-        long modSeq1 = messageResult1.getModSeq();
+        ModSeq modSeq1 = messageResult1.getModSeq();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(aliceMailbox1.getMailboxId(), aliceMailbox2.getMailboxId()), aliceSession);
 
@@ -208,7 +209,7 @@ public abstract class AbstractMessageIdManagerStorageTest {
             .findFirst()
             .get();
         MessageUid messageUid2 = messageResult2.getUid();
-        long modSeq2 = messageResult2.getModSeq();
+        ModSeq modSeq2 = messageResult2.getModSeq();
 
         assertThat(messageUid1).isEqualTo(messageUid2);
         assertThat(modSeq1).isEqualTo(modSeq2);
@@ -390,12 +391,12 @@ public abstract class AbstractMessageIdManagerStorageTest {
         MessageId messageId = testingData.persist(aliceMailbox1.getMailboxId(), messageUid1, FLAGS, aliceSession);
 
         MessageResult messageResult1 = messageIdManager.getMessages(ImmutableList.of(messageId), FetchGroupImpl.MINIMAL, aliceSession).get(0);
-        long modSeq1 = messageResult1.getModSeq();
+        ModSeq modSeq1 = messageResult1.getModSeq();
 
         messageIdManager.setFlags(newFlags, MessageManager.FlagsUpdateMode.ADD, messageId, ImmutableList.of(aliceMailbox1.getMailboxId()), aliceSession);
 
         MessageResult messageResult2 = messageIdManager.getMessages(ImmutableList.of(messageId), FetchGroupImpl.MINIMAL, aliceSession).get(0);
-        long modSeq2 = messageResult2.getModSeq();
+        ModSeq modSeq2 = messageResult2.getModSeq();
 
         assertThat(modSeq2).isGreaterThan(modSeq1);
     }
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageIdManagerTestSystem.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageIdManagerTestSystem.java
index 30a4817..ecbcbd8 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageIdManagerTestSystem.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageIdManagerTestSystem.java
@@ -28,6 +28,7 @@ import javax.mail.util.SharedByteArrayInputStream;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
@@ -42,7 +43,7 @@ import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
 
 public class MessageIdManagerTestSystem {
     private static final byte[] MESSAGE_CONTENT = "subject: any\n\nbody".getBytes(StandardCharsets.UTF_8);
-    public static final int MOD_SEQ = 452;
+    public static final ModSeq MOD_SEQ = ModSeq.of(452);
 
     private final MessageIdManager messageIdManager;
     private final MessageId.Factory messageIdFactory;
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/PreDeletionHooksTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/PreDeletionHooksTest.java
index 4e86487..bcfc430 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/PreDeletionHooksTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/PreDeletionHooksTest.java
@@ -38,6 +38,7 @@ import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.MetadataWithMailboxId;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.extension.PreDeletionHook;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.TestId;
@@ -56,7 +57,7 @@ import reactor.core.publisher.Mono;
 class PreDeletionHooksTest {
 
     private static final TestId MAILBOX_ID = TestId.of(45);
-    private static final int MOD_SEQ = 18;
+    private static final ModSeq MOD_SEQ = ModSeq.of(18);
     private static final int SIZE = 12;
     private static final MessageMetaData MESSAGE_META_DATA = new MessageMetaData(MessageUid.of(1), MOD_SEQ, new Flags(), SIZE, new Date(), TestMessageId.of(42));
     private static final PreDeletionHook.DeleteOperation DELETE_OPERATION = PreDeletionHook.DeleteOperation.from(ImmutableList.of(MetadataWithMailboxId.from(
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxMessageResultIteratorTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxMessageResultIteratorTest.java
index b3f7528..1e4a787 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxMessageResultIteratorTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxMessageResultIteratorTest.java
@@ -35,10 +35,10 @@ import javax.mail.Flags;
 import javax.mail.util.SharedByteArrayInputStream;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxCounters;
-import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageResult.FetchGroup;
@@ -183,7 +183,7 @@ public class StoreMailboxMessageResultIteratorTest {
         }
 
         @Override
-        public long getHighestModSeq(Mailbox mailbox) throws MailboxException {
+        public ModSeq getHighestModSeq(Mailbox mailbox) throws MailboxException {
             throw new UnsupportedOperationException();
         }
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/MessageUtilsTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/MessageUtilsTest.java
index 840890b..0c8d05e 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/MessageUtilsTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/MessageUtilsTest.java
@@ -33,6 +33,7 @@ import org.apache.james.core.Username;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.model.DefaultMessageId;
@@ -110,11 +111,11 @@ public class MessageUtilsTest {
     @Test
     public void enrichMesageShouldEnrichUidAndModSeq() throws Exception {
         when(uidProvider.nextUid(eq(mailboxSession), eq(mailbox))).thenReturn(MESSAGE_UID);
-        when(modSeqProvider.nextModSeq(eq(mailboxSession), eq(mailbox))).thenReturn(11L);
+        when(modSeqProvider.nextModSeq(eq(mailboxSession), eq(mailbox))).thenReturn(ModSeq.of(11));
 
         messageUtils.enrichMessage(mailbox, message);
         
         assertThat(message.getUid()).isEqualTo(MESSAGE_UID);
-        assertThat(message.getModSeq()).isEqualTo(11L);
+        assertThat(message.getModSeq()).isEqualTo(ModSeq.of(11));
     }
 }
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMessageAssertTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMessageAssertTest.java
index 95b4a39..23eb451 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMessageAssertTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/ListMessageAssertTest.java
@@ -31,6 +31,7 @@ import javax.mail.util.SharedByteArrayInputStream;
 
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
@@ -84,7 +85,7 @@ public class ListMessageAssertTest {
         SimpleMailboxMessage simpleMailboxMessage = new SimpleMailboxMessage(messageId, internalDate, content.length(),
             bodyStart, new SharedByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), new Flags(), propertyBuilder, mailboxId);
         simpleMailboxMessage.setUid(uid);
-        simpleMailboxMessage.setModSeq(0);
+        simpleMailboxMessage.setModSeq(ModSeq.first());
         return simpleMailboxMessage;
     }
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MapperProvider.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MapperProvider.java
index 6e5c670..2db1faa 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MapperProvider.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MapperProvider.java
@@ -22,11 +22,11 @@ package org.apache.james.mailbox.store.mail.model;
 import java.util.List;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.store.mail.AnnotationMapper;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.MessageIdMapper;
@@ -59,9 +59,9 @@ public interface MapperProvider {
 
     MessageUid generateMessageUid();
 
-    long generateModSeq(Mailbox mailbox) throws MailboxException;
+    ModSeq generateModSeq(Mailbox mailbox) throws MailboxException;
 
-    long highestModSeq(Mailbox mailbox) throws MailboxException;
+    ModSeq highestModSeq(Mailbox mailbox) throws MailboxException;
 
     boolean supportPartialAttachmentFetch();
     
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageIdMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageIdMapperTest.java
index 349b39c..e286a5b 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageIdMapperTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageIdMapperTest.java
@@ -35,6 +35,7 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MessageManager.FlagsUpdateMode;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.model.Mailbox;
@@ -368,7 +369,7 @@ public abstract class MessageIdMapperTest {
         Flags newFlags = new Flags(Flag.ANSWERED);
         Map<MailboxId, UpdatedFlags> flags = sut.setFlags(messageId, ImmutableList.of(message1.getMailboxId()), newFlags, FlagsUpdateMode.ADD);
 
-        long modSeq = mapperProvider.highestModSeq(benwaInboxMailbox);
+        ModSeq modSeq = mapperProvider.highestModSeq(benwaInboxMailbox);
         UpdatedFlags expectedUpdatedFlags = UpdatedFlags.builder()
             .uid(message1.getUid())
             .modSeq(modSeq)
@@ -395,7 +396,7 @@ public abstract class MessageIdMapperTest {
 
         Map<MailboxId, UpdatedFlags> flags = sut.setFlags(messageId, ImmutableList.of(message1.getMailboxId()), newFlags, FlagsUpdateMode.REPLACE);
 
-        long modSeq = mapperProvider.highestModSeq(benwaInboxMailbox);
+        ModSeq modSeq = mapperProvider.highestModSeq(benwaInboxMailbox);
         UpdatedFlags expectedUpdatedFlags = UpdatedFlags.builder()
             .uid(message1.getUid())
             .modSeq(modSeq)
@@ -423,7 +424,7 @@ public abstract class MessageIdMapperTest {
 
         Map<MailboxId, UpdatedFlags> flags = sut.setFlags(messageId, ImmutableList.of(message1.getMailboxId()), newFlags, FlagsUpdateMode.REMOVE);
 
-        long modSeq = mapperProvider.highestModSeq(benwaInboxMailbox);
+        ModSeq modSeq = mapperProvider.highestModSeq(benwaInboxMailbox);
         UpdatedFlags expectedUpdatedFlags = UpdatedFlags.builder()
             .uid(message1.getUid())
             .modSeq(modSeq)
@@ -494,7 +495,7 @@ public abstract class MessageIdMapperTest {
             .add(Flag.RECENT)
             .add(Flag.ANSWERED)
             .build();
-        long modSeq = mapperProvider.highestModSeq(benwaInboxMailbox);
+        ModSeq modSeq = mapperProvider.highestModSeq(benwaInboxMailbox);
         UpdatedFlags expectedUpdatedFlags = UpdatedFlags.builder()
             .uid(message1.getUid())
             .modSeq(modSeq)
@@ -519,8 +520,8 @@ public abstract class MessageIdMapperTest {
         Flags newFlags = new Flags(Flag.ANSWERED);
         Map<MailboxId, UpdatedFlags> flags = sut.setFlags(messageId, ImmutableList.of(message1.getMailboxId(), message1InOtherMailbox.getMailboxId()), newFlags, FlagsUpdateMode.ADD);
 
-        long modSeqBenwaInboxMailbox = mapperProvider.highestModSeq(benwaInboxMailbox);
-        long modSeqBenwaWorkMailbox = mapperProvider.highestModSeq(benwaWorkMailbox);
+        ModSeq modSeqBenwaInboxMailbox = mapperProvider.highestModSeq(benwaInboxMailbox);
+        ModSeq modSeqBenwaWorkMailbox = mapperProvider.highestModSeq(benwaWorkMailbox);
         UpdatedFlags expectedUpdatedFlags = UpdatedFlags.builder()
             .uid(message1.getUid())
             .modSeq(modSeqBenwaInboxMailbox)
@@ -554,7 +555,7 @@ public abstract class MessageIdMapperTest {
     @Test
     void setFlagsShouldNotModifyModSeqWhenMailboxIdsIsEmpty() throws Exception {
         message1.setUid(mapperProvider.generateMessageUid());
-        long modSeq = mapperProvider.generateModSeq(benwaInboxMailbox);
+        ModSeq modSeq = mapperProvider.generateModSeq(benwaInboxMailbox);
         message1.setModSeq(modSeq);
         sut.save(message1);
 
@@ -570,7 +571,7 @@ public abstract class MessageIdMapperTest {
     @Test
     void setFlagsShouldUpdateModSeqWhenMessageIsInOneMailbox() throws Exception {
         message1.setUid(mapperProvider.generateMessageUid());
-        long modSeq = mapperProvider.generateModSeq(benwaInboxMailbox);
+        ModSeq modSeq = mapperProvider.generateModSeq(benwaInboxMailbox);
         message1.setModSeq(modSeq);
         sut.save(message1);
 
@@ -585,7 +586,7 @@ public abstract class MessageIdMapperTest {
     @Test
     void setFlagsShouldNotModifyFlagsWhenMailboxIdsIsEmpty() throws Exception {
         message1.setUid(mapperProvider.generateMessageUid());
-        long modSeq = mapperProvider.generateModSeq(benwaInboxMailbox);
+        ModSeq modSeq = mapperProvider.generateModSeq(benwaInboxMailbox);
         message1.setModSeq(modSeq);
         Flags initialFlags = new Flags(Flags.Flag.DRAFT);
         message1.setFlags(initialFlags);
@@ -813,7 +814,7 @@ public abstract class MessageIdMapperTest {
     @Test
     void setFlagsShouldNotUpdateModSeqWhenNoop() throws Exception {
         message1.setUid(mapperProvider.generateMessageUid());
-        long modSeq = mapperProvider.generateModSeq(benwaInboxMailbox);
+        ModSeq modSeq = mapperProvider.generateModSeq(benwaInboxMailbox);
         message1.setModSeq(modSeq);
         message1.setFlags(new Flags(Flag.SEEN));
         sut.save(message1);
@@ -831,7 +832,7 @@ public abstract class MessageIdMapperTest {
     @Test
     void addingFlagToAMessageThatAlreadyHasThisFlagShouldResultInNoChange() throws Exception {
         message1.setUid(mapperProvider.generateMessageUid());
-        long modSeq = mapperProvider.generateModSeq(benwaInboxMailbox);
+        ModSeq modSeq = mapperProvider.generateModSeq(benwaInboxMailbox);
         message1.setModSeq(modSeq);
         Flags flags = new Flags(Flag.SEEN);
         message1.setFlags(flags);
@@ -850,7 +851,7 @@ public abstract class MessageIdMapperTest {
     @Test
     void setFlagsShouldReturnUpdatedFlagsWhenNoop() throws Exception {
         message1.setUid(mapperProvider.generateMessageUid());
-        long modSeq = mapperProvider.generateModSeq(benwaInboxMailbox);
+        ModSeq modSeq = mapperProvider.generateModSeq(benwaInboxMailbox);
         message1.setModSeq(modSeq);
         Flags flags = new Flags(Flag.SEEN);
         message1.setFlags(flags);
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java
index 68083f8..bbe4b40 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageMapperTest.java
@@ -40,6 +40,7 @@ import org.apache.james.core.Username;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MessageManager.FlagsUpdateMode;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxCounters;
@@ -526,14 +527,14 @@ public abstract class MessageMapperTest {
 
     @Test
     void getHighestMoseqShouldBeEqualToZeroOnEmptyMailbox() throws MailboxException {
-        assertThat(messageMapper.getHighestModSeq(benwaInboxMailbox)).isEqualTo(0);
+        assertThat(messageMapper.getHighestModSeq(benwaInboxMailbox)).isEqualTo(ModSeq.first());
     }
 
     @Test
     void insertingAMessageShouldIncrementModSeq() throws MailboxException {
         messageMapper.add(benwaInboxMailbox, message1);
-        long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
-        assertThat(modSeq).isGreaterThan(0);
+        ModSeq modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
+        assertThat(modSeq).isGreaterThan(ModSeq.first());
         messageMapper.add(benwaInboxMailbox, message2);
         assertThat(messageMapper.getHighestModSeq(benwaInboxMailbox)).isGreaterThan(modSeq);
     }
@@ -577,7 +578,7 @@ public abstract class MessageMapperTest {
     @Test
     void copyShouldIncrementModSeq() throws MailboxException, IOException {
         saveMessages();
-        long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
+        ModSeq modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
         messageMapper.copy(benwaInboxMailbox, SimpleMailboxMessage.copy(benwaInboxMailbox.getMailboxId(), message6));
         assertThat(messageMapper.getHighestModSeq(benwaInboxMailbox)).isGreaterThan(modSeq);
     }
@@ -663,13 +664,13 @@ public abstract class MessageMapperTest {
     @Test
     void flagsReplacementShouldReturnAnUpdatedFlagHighlightingTheReplacement() throws MailboxException {
         saveMessages();
-        long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
+        ModSeq modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
         Iterator<UpdatedFlags> updatedFlags = messageMapper.updateFlags(benwaInboxMailbox,
                 new FlagsUpdateCalculator(new Flags(Flags.Flag.FLAGGED), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid()));
         assertThat(Lists.newArrayList(updatedFlags))
             .containsOnly(UpdatedFlags.builder()
                 .uid(message1.getUid())
-                .modSeq(modSeq + 1)
+                .modSeq(modSeq.next())
                 .oldFlags(new Flags())
                 .newFlags(new Flags(Flags.Flag.FLAGGED))
                 .build());
@@ -679,12 +680,12 @@ public abstract class MessageMapperTest {
     void flagsAdditionShouldReturnAnUpdatedFlagHighlightingTheAddition() throws MailboxException {
         saveMessages();
         messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.FLAGGED), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid()));
-        long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
+        ModSeq modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
         assertThat(messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.ADD), MessageRange.one(message1.getUid())))
             .toIterable()
             .containsOnly(UpdatedFlags.builder()
                     .uid(message1.getUid())
-                    .modSeq(modSeq + 1)
+                    .modSeq(modSeq.next())
                     .oldFlags(new Flags(Flags.Flag.FLAGGED))
                     .newFlags(new FlagsBuilder().add(Flags.Flag.SEEN, Flags.Flag.FLAGGED).build())
                     .build());
@@ -712,13 +713,13 @@ public abstract class MessageMapperTest {
     void flagsRemovalShouldReturnAnUpdatedFlagHighlightingTheRemoval() throws MailboxException {
         saveMessages();
         messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new FlagsBuilder().add(Flags.Flag.FLAGGED, Flags.Flag.SEEN).build(), FlagsUpdateMode.REPLACE), MessageRange.one(message1.getUid()));
-        long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
+        ModSeq modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
         assertThat(messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REMOVE), MessageRange.one(message1.getUid())))
             .toIterable()
             .containsOnly(
                 UpdatedFlags.builder()
                     .uid(message1.getUid())
-                    .modSeq(modSeq + 1)
+                    .modSeq(modSeq.next())
                     .oldFlags(new FlagsBuilder().add(Flags.Flag.SEEN, Flags.Flag.FLAGGED).build())
                     .newFlags(new Flags(Flags.Flag.FLAGGED))
                     .build());
@@ -839,13 +840,13 @@ public abstract class MessageMapperTest {
     @Test
     void userFlagsUpdateShouldReturnCorrectUpdatedFlags() throws Exception {
         saveMessages();
-        long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
+        ModSeq modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
         assertThat(messageMapper.updateFlags(benwaInboxMailbox, new FlagsUpdateCalculator(new Flags(USER_FLAG), FlagsUpdateMode.ADD), MessageRange.one(message1.getUid())))
             .toIterable()
             .containsOnly(
                 UpdatedFlags.builder()
                     .uid(message1.getUid())
-                    .modSeq(modSeq + 1)
+                    .modSeq(modSeq.next())
                     .oldFlags(new Flags())
                     .newFlags(new Flags(USER_FLAG))
                     .build());
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MetadataMapAssertTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MetadataMapAssertTest.java
index e8870b9..8cf829a 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MetadataMapAssertTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MetadataMapAssertTest.java
@@ -27,6 +27,7 @@ import javax.mail.Flags;
 import javax.mail.util.SharedByteArrayInputStream;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.TestId;
@@ -39,7 +40,7 @@ public class MetadataMapAssertTest {
 
     private static final MessageUid UID = MessageUid.of(18);
     private static final MessageId MESSAGE_ID = new DefaultMessageId();
-    private static final Long MODSEQ = 24L;
+    private static final ModSeq MODSEQ = ModSeq.of(24L);
     private static final Date DATE = new Date();
     private static final String HEADER_STRING = "name: headerName\n\n";
     private static final String BODY_STRING = "body\\n.\\n";
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java
index 15b8c88..9baff66 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java
@@ -33,6 +33,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
@@ -143,14 +144,6 @@ public class SimpleMailboxMessageTest {
     }
 
     @Test
-    public void modseqShouldThrowWhenNegative() {
-        expectedException.expect(IllegalArgumentException.class);
-
-        SimpleMailboxMessage.builder()
-            .modseq(-1);
-    }
-
-    @Test
     public void sizeShouldThrowWhenNegative() {
         expectedException.expect(IllegalArgumentException.class);
 
@@ -188,7 +181,7 @@ public class SimpleMailboxMessageTest {
         Date internalDate = new Date();
         Flags flags = new Flags();
         PropertyBuilder propertyBuilder = new PropertyBuilder();
-        int modseq = 145;
+        ModSeq modseq = ModSeq.of(145);
         MessageUid uid = MessageUid.of(45);
         MessageAttachment messageAttachment = MessageAttachment.builder()
             .attachment(Attachment.builder()
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdaterTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdaterTest.java
index c7f8820..3dff2d7 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdaterTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdaterTest.java
@@ -38,6 +38,7 @@ import org.apache.james.core.Username;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.events.Event;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.Group;
@@ -88,8 +89,8 @@ public class ListeningCurrentQuotaUpdaterTest {
     public void addedEventShouldIncreaseCurrentQuotaValues() throws Exception {
         MailboxListener.Added added = mock(MailboxListener.Added.class);
         when(added.getMailboxId()).thenReturn(MAILBOX_ID);
-        when(added.getMetaData(MessageUid.of(36))).thenReturn(new MessageMetaData(MessageUid.of(36),0,new Flags(), SIZE, new Date(), new DefaultMessageId()));
-        when(added.getMetaData(MessageUid.of(38))).thenReturn(new MessageMetaData(MessageUid.of(38),0,new Flags(), SIZE, new Date(), new DefaultMessageId()));
+        when(added.getMetaData(MessageUid.of(36))).thenReturn(new MessageMetaData(MessageUid.of(36), ModSeq.first(),new Flags(), SIZE, new Date(), new DefaultMessageId()));
+        when(added.getMetaData(MessageUid.of(38))).thenReturn(new MessageMetaData(MessageUid.of(38), ModSeq.first(),new Flags(), SIZE, new Date(), new DefaultMessageId()));
         when(added.getUids()).thenReturn(Lists.newArrayList(MessageUid.of(36), MessageUid.of(38)));
         when(added.getUsername()).thenReturn(USERNAME_BENWA);
         when(mockedQuotaRootResolver.getQuotaRoot(eq(MAILBOX_ID))).thenReturn(QUOTA_ROOT);
@@ -102,8 +103,8 @@ public class ListeningCurrentQuotaUpdaterTest {
     @Test
     public void expungedEventShouldDecreaseCurrentQuotaValues() throws Exception {
         MailboxListener.Expunged expunged = mock(MailboxListener.Expunged.class);
-        when(expunged.getMetaData(MessageUid.of(36))).thenReturn(new MessageMetaData(MessageUid.of(36),0,new Flags(), SIZE, new Date(), new DefaultMessageId()));
-        when(expunged.getMetaData(MessageUid.of(38))).thenReturn(new MessageMetaData(MessageUid.of(38),0,new Flags(), SIZE, new Date(), new DefaultMessageId()));
+        when(expunged.getMetaData(MessageUid.of(36))).thenReturn(new MessageMetaData(MessageUid.of(36), ModSeq.first(), new Flags(), SIZE, new Date(), new DefaultMessageId()));
+        when(expunged.getMetaData(MessageUid.of(38))).thenReturn(new MessageMetaData(MessageUid.of(38), ModSeq.first(), new Flags(), SIZE, new Date(), new DefaultMessageId()));
         when(expunged.getUids()).thenReturn(Lists.newArrayList(MessageUid.of(36), MessageUid.of(38)));
         when(expunged.getMailboxId()).thenReturn(MAILBOX_ID);
         when(expunged.getUsername()).thenReturn(USERNAME_BENWA);
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/api/message/response/StatusResponse.java b/protocols/imap/src/main/java/org/apache/james/imap/api/message/response/StatusResponse.java
index 3c700fe..4066bef 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/api/message/response/StatusResponse.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/api/message/response/StatusResponse.java
@@ -35,6 +35,7 @@ import org.apache.james.imap.api.message.IdRange;
 import org.apache.james.imap.api.message.MessageFlags;
 import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 
 import com.github.steveash.guavate.Guavate;
 
@@ -319,8 +320,8 @@ public interface StatusResponse extends ImapResponseMessage {
          * @param modSeq positive non-zero long
          * @return <code>ResponseCode</code>
          */
-        public static ResponseCode highestModSeq(long modSeq) {
-            return new ResponseCode("HIGHESTMODSEQ", modSeq);
+        public static ResponseCode highestModSeq(ModSeq modSeq) {
+            return new ResponseCode("HIGHESTMODSEQ", modSeq.asLong());
         }
         
         /**
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/encode/ESearchResponseEncoder.java b/protocols/imap/src/main/java/org/apache/james/imap/encode/ESearchResponseEncoder.java
index 487ad07..8a4b65d 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/encode/ESearchResponseEncoder.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/encode/ESearchResponseEncoder.java
@@ -29,6 +29,7 @@ import org.apache.james.imap.api.message.request.SearchResultOption;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.encode.base.AbstractChainedImapEncoder;
 import org.apache.james.imap.message.response.ESearchResponse;
+import org.apache.james.mailbox.ModSeq;
 
 /**
  * Encoders IMAP4rev1 <code>ESEARCH</code> responses.
@@ -49,7 +50,7 @@ public class ESearchResponseEncoder extends AbstractChainedImapEncoder {
         IdRange[] all = response.getAll();
         UidRange[] allUids = response.getAllUids();
         boolean useUid = response.getUseUid();
-        Long highestModSeq = response.getHighestModSeq();
+        ModSeq highestModSeq = response.getHighestModSeq();
         List<SearchResultOption> options = response.getSearchResultOptions();
         
         composer.untagged().message("ESEARCH").openParen().message("TAG").quote(tag.asString()).closeParen();
@@ -79,7 +80,7 @@ public class ESearchResponseEncoder extends AbstractChainedImapEncoder {
         // see RFC4731 3.2.  Interaction with CONDSTORE extension
         if (highestModSeq != null) {
             composer.message("MODSEQ");
-            composer.message(highestModSeq);
+            composer.message(highestModSeq.asLong());
         }
         composer.end();
     }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/encode/FetchResponseEncoder.java b/protocols/imap/src/main/java/org/apache/james/imap/encode/FetchResponseEncoder.java
index 1ae8171..344ebe1 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/encode/FetchResponseEncoder.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/encode/FetchResponseEncoder.java
@@ -37,6 +37,7 @@ import org.apache.james.imap.encode.base.AbstractChainedImapEncoder;
 import org.apache.james.imap.message.response.FetchResponse;
 import org.apache.james.imap.message.response.FetchResponse.Structure;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -91,12 +92,12 @@ public class FetchResponseEncoder extends AbstractChainedImapEncoder {
 
     // Handle the MODSEQ 
     private void encodeModSeq(ImapResponseComposer composer, FetchResponse response) throws IOException {
-        Long modSeq = response.getModSeq();
+        ModSeq modSeq = response.getModSeq();
         if (modSeq != null) {
             composer.message(ImapConstants.FETCH_MODSEQ);
             composer.openParen();
             composer.skipNextSpace();
-            composer.message(modSeq);
+            composer.message(modSeq.asLong());
             composer.closeParen();
         }
     }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/encode/MailboxStatusResponseEncoder.java b/protocols/imap/src/main/java/org/apache/james/imap/encode/MailboxStatusResponseEncoder.java
index 4deb1ee..20a961d 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/encode/MailboxStatusResponseEncoder.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/encode/MailboxStatusResponseEncoder.java
@@ -27,6 +27,7 @@ import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.encode.base.AbstractChainedImapEncoder;
 import org.apache.james.imap.message.response.MailboxStatusResponse;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 
 /**
  * Encodes <code>STATUS</code> responses.
@@ -43,7 +44,7 @@ public class MailboxStatusResponseEncoder extends AbstractChainedImapEncoder imp
         Long messages = response.getMessages();
         Long recent = response.getRecent();
         MessageUid uidNext = response.getUidNext();
-        Long highestModSeq = response.getHighestModSeq();
+        ModSeq highestModSeq = response.getHighestModSeq();
         Long uidValidity = response.getUidValidity();
         Long unseen = response.getUnseen();
         String mailboxName = response.getMailbox();
@@ -73,7 +74,7 @@ public class MailboxStatusResponseEncoder extends AbstractChainedImapEncoder imp
         
         if (highestModSeq != null) {
             composer.message(STATUS_HIGHESTMODSEQ);
-            composer.message(highestModSeq);
+            composer.message(highestModSeq.asLong());
         }
 
         if (uidValidity != null) {
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/encode/SearchResponseEncoder.java b/protocols/imap/src/main/java/org/apache/james/imap/encode/SearchResponseEncoder.java
index f60030c..e5020f0 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/encode/SearchResponseEncoder.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/encode/SearchResponseEncoder.java
@@ -25,6 +25,7 @@ import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.encode.base.AbstractChainedImapEncoder;
 import org.apache.james.imap.message.response.SearchResponse;
+import org.apache.james.mailbox.ModSeq;
 
 /**
  * Encoders IMAP4rev1 <code>SEARCH</code> responses.
@@ -39,7 +40,7 @@ public class SearchResponseEncoder extends AbstractChainedImapEncoder {
     protected void doEncode(ImapMessage acceptableMessage, ImapResponseComposer composer, ImapSession session) throws IOException {
         SearchResponse response = (SearchResponse) acceptableMessage;
         final long[] ids = response.getIds();
-        Long highestModSeq = response.getHighestModSeq();
+        ModSeq highestModSeq = response.getHighestModSeq();
         composer.untagged();
         composer.message(ImapConstants.SEARCH_RESPONSE_NAME);
         if (ids != null) {
@@ -52,7 +53,7 @@ public class SearchResponseEncoder extends AbstractChainedImapEncoder {
         if (highestModSeq != null) {
             composer.openParen();
             composer.message("MODSEQ");
-            composer.message(highestModSeq);
+            composer.message(highestModSeq.asLong());
             composer.closeParen();
         }
         composer.end();
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/message/response/ESearchResponse.java b/protocols/imap/src/main/java/org/apache/james/imap/message/response/ESearchResponse.java
index 414a5d9..b45ac89 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/message/response/ESearchResponse.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/message/response/ESearchResponse.java
@@ -26,6 +26,7 @@ import org.apache.james.imap.api.message.IdRange;
 import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.imap.api.message.request.SearchResultOption;
 import org.apache.james.imap.api.message.response.ImapResponseMessage;
+import org.apache.james.mailbox.ModSeq;
 
 public class ESearchResponse implements ImapResponseMessage {
 
@@ -36,10 +37,10 @@ public class ESearchResponse implements ImapResponseMessage {
     private final Tag tag;
     private final boolean useUid;
     private final List<SearchResultOption> options;
-    private final Long highestModSeq;
+    private final ModSeq highestModSeq;
     private UidRange[] allUids;
 
-    public ESearchResponse(long minUid, long maxUid, long count, IdRange[] all, UidRange[] allUids, Long highestModSeq, Tag tag, boolean useUid, List<SearchResultOption> options) {
+    public ESearchResponse(long minUid, long maxUid, long count, IdRange[] all, UidRange[] allUids, ModSeq highestModSeq, Tag tag, boolean useUid, List<SearchResultOption> options) {
         super();
         this.options = options;
         this.minUid = minUid;
@@ -84,7 +85,7 @@ public class ESearchResponse implements ImapResponseMessage {
         return options;
     }
     
-    public final Long getHighestModSeq() {
+    public final ModSeq getHighestModSeq() {
         return highestModSeq;
     }
     
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/message/response/FetchResponse.java b/protocols/imap/src/main/java/org/apache/james/imap/message/response/FetchResponse.java
index 35c6991..aaa5cc1 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/message/response/FetchResponse.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/message/response/FetchResponse.java
@@ -27,6 +27,7 @@ import javax.mail.Flags;
 
 import org.apache.james.imap.api.message.response.ImapResponseMessage;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 
 public final class FetchResponse implements ImapResponseMessage {
 
@@ -48,9 +49,9 @@ public final class FetchResponse implements ImapResponseMessage {
 
     private final Structure bodystructure;
 
-    private final Long modSeq;
+    private final ModSeq modSeq;
 
-    public FetchResponse(int messageNumber, Flags flags, MessageUid uid, Long modSeq, Date internalDate, Long size, Envelope envelope, Structure body, Structure bodystructure, List<BodyElement> elements) {
+    public FetchResponse(int messageNumber, Flags flags, MessageUid uid, ModSeq modSeq, Date internalDate, Long size, Envelope envelope, Structure body, Structure bodystructure, List<BodyElement> elements) {
         super();
         this.messageNumber = messageNumber;
         this.flags = flags;
@@ -159,7 +160,7 @@ public final class FetchResponse implements ImapResponseMessage {
      * 
      * @return modSeq
      */
-    public Long getModSeq() {
+    public ModSeq getModSeq() {
         return modSeq;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/message/response/MailboxStatusResponse.java b/protocols/imap/src/main/java/org/apache/james/imap/message/response/MailboxStatusResponse.java
index 0773c88..9608625 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/message/response/MailboxStatusResponse.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/message/response/MailboxStatusResponse.java
@@ -21,6 +21,7 @@ package org.apache.james.imap.message.response;
 
 import org.apache.james.imap.api.message.response.ImapResponseMessage;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 
 /**
  * Represents a <code>STATUS</code> response. See <code>RFC3501 7.2.4</code>.
@@ -39,9 +40,9 @@ public class MailboxStatusResponse implements ImapResponseMessage {
 
     private final String mailbox;
 
-    private final Long highestModSeq;
+    private final ModSeq highestModSeq;
 
-    public MailboxStatusResponse(Long messages, Long recent, MessageUid uidNext, Long highestModSeq, Long uidValidity, Long unseen, String mailbox) {
+    public MailboxStatusResponse(Long messages, Long recent, MessageUid uidNext, ModSeq highestModSeq, Long uidValidity, Long unseen, String mailbox) {
         super();
         this.messages = messages;
         this.recent = recent;
@@ -112,7 +113,7 @@ public class MailboxStatusResponse implements ImapResponseMessage {
      * 
      * @return the mailbox highestModSeq (if requested) or null (if not)
      */
-    public final Long getHighestModSeq() {
+    public final ModSeq getHighestModSeq() {
         return highestModSeq;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/message/response/SearchResponse.java b/protocols/imap/src/main/java/org/apache/james/imap/message/response/SearchResponse.java
index 9557228..e11f8bb 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/message/response/SearchResponse.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/message/response/SearchResponse.java
@@ -22,13 +22,14 @@ package org.apache.james.imap.message.response;
 import java.util.Arrays;
 
 import org.apache.james.imap.api.message.response.ImapResponseMessage;
+import org.apache.james.mailbox.ModSeq;
 
 /**
  * A <code>SEARCH</code> response.
  */
 public class SearchResponse implements ImapResponseMessage {
     private final long[] ids;
-    private final Long highestModSeq;
+    private final ModSeq highestModSeq;
 
     /**
      * Constructs a <code>SEARCH</code> response.
@@ -36,7 +37,7 @@ public class SearchResponse implements ImapResponseMessage {
      * @param ids ids, not null
      * @param highestModSeq
      */
-    public SearchResponse(long[] ids, Long highestModSeq) {
+    public SearchResponse(long[] ids, ModSeq highestModSeq) {
         super();
         this.ids = ids;
         this.highestModSeq = highestModSeq;
@@ -57,7 +58,7 @@ public class SearchResponse implements ImapResponseMessage {
      *  
      * @return highestMod
      */
-    public final Long getHighestModSeq() {
+    public final ModSeq getHighestModSeq() {
         return highestModSeq;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractMailboxProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractMailboxProcessor.java
index 712925e..b8930db 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractMailboxProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractMailboxProcessor.java
@@ -54,6 +54,7 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageManager.MetaData;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MessageRangeException;
 import org.apache.james.mailbox.model.FetchGroupImpl;
@@ -282,16 +283,13 @@ public abstract class AbstractMailboxProcessor<R extends ImapRequest> extends Ab
         if (!enabled.contains(ImapConstants.SUPPORTS_CONDSTORE)) {
             if (sendHighestModSeq) {
                 if (metaData.isModSeqPermanent()) {
-
-                    final long highestModSeq = metaData.getHighestModSeq();
+                    ModSeq highestModSeq = metaData.getHighestModSeq();
 
                     StatusResponse untaggedOk = getStatusResponseFactory().untaggedOk(HumanReadableText.HIGHEST_MOD_SEQ, ResponseCode.highestModSeq(highestModSeq));
                     responder.respond(untaggedOk);        
                 }
             }
             enabled.add(ImapConstants.SUPPORTS_CONDSTORE);
-
-
         }
     }
     
@@ -547,7 +545,7 @@ public abstract class AbstractMailboxProcessor<R extends ImapRequest> extends Ab
         //      A client providing message sequence match data can reduce the scope
         //      as above.  In the case where there have been no expunges, the server
         //      can ignore this data.
-        if (metaData.getHighestModSeq() > changedSince) {
+        if (metaData.getHighestModSeq().asLong() > changedSince) {
             SearchQuery searchQuery = new SearchQuery();
             SearchQuery.UidRange[] nRanges = new SearchQuery.UidRange[ranges.size()];
             Set<MessageUid> vanishedUids = new HashSet<>();
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java
index 2a03651..9ceb8a5 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java
@@ -47,6 +47,7 @@ import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageManager.MetaData;
 import org.apache.james.mailbox.MessageManager.MetaData.FetchGroup;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
@@ -317,7 +318,7 @@ abstract class AbstractSelectionProcessor<R extends AbstractMailboxSelectionRequ
     private void highestModSeq(Responder responder, MetaData metaData, SelectedMailbox selected) {
         final StatusResponse untaggedOk;
         if (metaData.isModSeqPermanent()) {
-            final long highestModSeq = metaData.getHighestModSeq();
+            final ModSeq highestModSeq = metaData.getHighestModSeq();
             untaggedOk = statusResponseFactory.untaggedOk(HumanReadableText.HIGHEST_MOD_SEQ, ResponseCode.highestModSeq(highestModSeq));
         } else {
             untaggedOk = statusResponseFactory.untaggedOk(HumanReadableText.NO_MOD_SEQ, ResponseCode.noModSeq());
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/SearchProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
index 9750c6a..6185386 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
@@ -52,6 +52,7 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageManager.MetaData;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MessageRangeException;
 import org.apache.james.mailbox.model.FetchGroupImpl;
@@ -100,7 +101,7 @@ public class SearchProcessor extends AbstractMailboxProcessor<SearchRequest> imp
             // Check if the search did contain the MODSEQ searchkey. If so we need to include the highest mod in the response.
             //
             // See RFC4551: 3.4. MODSEQ Search Criterion in SEARCH
-            final Long highestModSeq;
+            final ModSeq highestModSeq;
             if (session.getAttribute(SEARCH_MODSEQ) != null) {
                 MetaData metaData = mailbox.getMetaData(false, msession, MessageManager.MetaData.FetchGroup.NO_COUNT);
                 highestModSeq = findHighestModSeq(msession, mailbox, MessageRange.toRanges(uids), metaData.getHighestModSeq());
@@ -237,16 +238,16 @@ public class SearchProcessor extends AbstractMailboxProcessor<SearchRequest> imp
      * @return highestModSeq
      * @throws MailboxException
      */
-    private Long findHighestModSeq(MailboxSession session, MessageManager mailbox, List<MessageRange> ranges, long currentHighest) throws MailboxException {
-        Long highestModSeq = null;
+    private ModSeq findHighestModSeq(MailboxSession session, MessageManager mailbox, List<MessageRange> ranges, ModSeq currentHighest) throws MailboxException {
+        ModSeq highestModSeq = null;
         
         // Reverse loop over the ranges as its more likely that we find a match at the end
         int size = ranges.size();
         for (int i = size - 1; i > 0; i--) {
             MessageResultIterator results = mailbox.getMessages(ranges.get(i), FetchGroupImpl.MINIMAL, session);
             while (results.hasNext()) {
-                long modSeq = results.next().getModSeq();
-                if (highestModSeq == null || modSeq > highestModSeq) {
+                ModSeq modSeq = results.next().getModSeq();
+                if (highestModSeq == null || modSeq.asLong() > highestModSeq.asLong()) {
                     highestModSeq = modSeq;
                 }
                 if (highestModSeq == currentHighest) {
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
index f067be9..4303e58 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
@@ -34,6 +34,7 @@ import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.metrics.api.MetricFactory;
@@ -87,7 +88,7 @@ public class StatusProcessor extends AbstractMailboxProcessor<StatusRequest> {
         MessageUid uidNext = uidNext(statusDataItems, metaData);
         Long uidValidity = uidValidity(statusDataItems, metaData);
         Long unseen = unseen(statusDataItems, metaData);
-        Long highestModSeq = highestModSeq(statusDataItems, metaData);
+        ModSeq highestModSeq = highestModSeq(statusDataItems, metaData);
         return new MailboxStatusResponse(messages, recent, uidNext, highestModSeq, uidValidity, unseen, request.getMailboxName());
     }
 
@@ -115,7 +116,7 @@ public class StatusProcessor extends AbstractMailboxProcessor<StatusRequest> {
         }
     }
 
-    private Long highestModSeq(StatusDataItems statusDataItems, MessageManager.MetaData metaData) {
+    private ModSeq highestModSeq(StatusDataItems statusDataItems, MessageManager.MetaData metaData) {
         if (statusDataItems.isHighestModSeq()) {
             return metaData.getHighestModSeq();
         } else {
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/StoreProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/StoreProcessor.java
index 05692ea..daed075 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/StoreProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/StoreProcessor.java
@@ -49,6 +49,7 @@ import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageManager.MetaData;
 import org.apache.james.mailbox.MessageManager.MetaData.FetchGroup;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MessageRangeException;
 import org.apache.james.mailbox.model.FetchGroupImpl;
@@ -151,7 +152,7 @@ public class StoreProcessor extends AbstractMailboxProcessor<StoreRequest> {
                             // Check if the mod-sequence of the message is <= the unchangedsince.
                             //
                             // See RFC4551 3.2. STORE and UID STORE Commands
-                            if (!fail && r.getModSeq() <= unchangedSince) {
+                            if (!fail && r.getModSeq().asLong() <= unchangedSince) {
                                 uids.add(uid);
                             } else {
                                 if (useUids) {
@@ -253,7 +254,7 @@ public class StoreProcessor extends AbstractMailboxProcessor<StoreRequest> {
         boolean condstoreEnabled = enabled.contains(ImapConstants.SUPPORTS_CONDSTORE);
         
         if (!silent || unchangedSince != -1 || qresyncEnabled || condstoreEnabled) {
-            final Map<MessageUid, Long> modSeqs = new HashMap<>();
+            final Map<MessageUid, ModSeq> modSeqs = new HashMap<>();
            
             // Check if we need to also send the the mod-sequences back to the client
             //
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchProcessor.java
index dd7c52b..d35b7bd 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchProcessor.java
@@ -157,7 +157,7 @@ public class FetchProcessor extends AbstractMailboxProcessor<FetchRequest> {
                 final MessageResult result = messages.next();
 
                 //skip unchanged messages - this should be filtered at the mailbox level to take advantage of indexes
-                if (fetch.isModSeq() && result.getModSeq() <= fetch.getChangedSince()) {
+                if (fetch.isModSeq() && result.getModSeq().asLong() <= fetch.getChangedSince()) {
                     continue;
                 }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java
index fb1e78c..a56e0fc 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java
@@ -40,6 +40,7 @@ import org.apache.james.imap.message.response.FetchResponse;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MessageRangeException;
 import org.apache.james.mailbox.model.Content;
@@ -60,7 +61,7 @@ public final class FetchResponseBuilder {
 
     private Long size;
     
-    private Long modSeq;
+    private ModSeq modSeq;
 
     private List<FetchResponse.BodyElement> elements;
 
@@ -91,7 +92,7 @@ public final class FetchResponseBuilder {
         this.uid = resultUid;
     }
 
-    private void setModSeq(long modSeq) {
+    private void setModSeq(ModSeq modSeq) {
         this.modSeq = modSeq;
     }
 
@@ -188,7 +189,7 @@ public final class FetchResponseBuilder {
             long changedSince = fetch.getChangedSince();
             if (changedSince != -1) {
                 // check if the modsequence if higher then the one specified by the CHANGEDSINCE option
-                if (changedSince < result.getModSeq()) {
+                if (changedSince < result.getModSeq().asLong()) {
                     setModSeq(result.getModSeq());
                 }
             } else {
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java b/protocols/imap/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java
index b6e2419..bf70ce3 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java
@@ -39,6 +39,7 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.events.Event;
 import org.apache.james.mailbox.events.InVMEventBus;
 import org.apache.james.mailbox.events.MailboxListener;
@@ -62,19 +63,19 @@ public class MailboxEventAnalyserTest {
     private static final MessageUid UID = MessageUid.of(900);
     private static final UpdatedFlags ADD_RECENT_UPDATED_FLAGS = UpdatedFlags.builder()
         .uid(UID)
-        .modSeq(-1)
+        .modSeq(ModSeq.first())
         .oldFlags(new Flags())
         .newFlags(new Flags(Flags.Flag.RECENT))
         .build();
     private static final UpdatedFlags ADD_ANSWERED_UPDATED_FLAGS = UpdatedFlags.builder()
         .uid(UID)
-        .modSeq(-1)
+        .modSeq(ModSeq.first())
         .oldFlags(new Flags())
         .newFlags(new Flags(Flags.Flag.ANSWERED))
         .build();
     private static final UpdatedFlags NOOP_UPDATED_FLAGS = UpdatedFlags.builder()
         .uid(UID)
-        .modSeq(-1)
+        .modSeq(ModSeq.first())
         .oldFlags(new Flags())
         .newFlags(new Flags())
         .build();
@@ -123,7 +124,7 @@ public class MailboxEventAnalyserTest {
         .randomEventId()
         .mailboxSession(MAILBOX_SESSION)
         .mailbox(DEFAULT_MAILBOX)
-        .addMetaData(new MessageMetaData(MessageUid.of(11), 0, new Flags(), 45, new Date(), new DefaultMessageId()))
+        .addMetaData(new MessageMetaData(MessageUid.of(11), ModSeq.first(), new Flags(), 45, new Date(), new DefaultMessageId()))
         .build();
 
     private SelectedMailboxImpl testee;
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java b/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java
index 011d74e..95a25c1 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/processor/base/SelectedMailboxImplTest.java
@@ -44,6 +44,7 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.events.MailboxListener;
@@ -67,7 +68,7 @@ public class SelectedMailboxImplTest {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(SelectedMailboxImplTest.class);
     private static final MessageUid EMITTED_EVENT_UID = MessageUid.of(5);
-    private static final int MOD_SEQ = 12;
+    private static final ModSeq MOD_SEQ = ModSeq.of(12);
     private static final int SIZE = 38;
 
     private ExecutorService executorService;
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactory.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactory.java
index dec75d8..d233993 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactory.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactory.java
@@ -37,6 +37,7 @@ import org.apache.james.jmap.draft.model.MessagePreviewGenerator;
 import org.apache.james.jmap.draft.utils.HtmlTextExtractor;
 import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Cid;
 import org.apache.james.mailbox.model.MailboxId;
@@ -196,7 +197,7 @@ public class MessageFullViewFactory implements MessageViewFactory<MessageFullVie
         
         public static class Builder {
             private MessageUid uid;
-            private Long modSeq;
+            private ModSeq modSeq;
             private Keywords keywords;
             private Long size;
             private Instant internalDate;
@@ -211,7 +212,7 @@ public class MessageFullViewFactory implements MessageViewFactory<MessageFullVie
                 return this;
             }
             
-            public Builder modSeq(long modSeq) {
+            public Builder modSeq(ModSeq modSeq) {
                 this.modSeq = modSeq;
                 return this;
             }
@@ -263,9 +264,7 @@ public class MessageFullViewFactory implements MessageViewFactory<MessageFullVie
             
             public MetaDataWithContent build() {
                 Preconditions.checkArgument(uid != null);
-                if (modSeq == null) {
-                    modSeq = -1L;
-                }
+                Preconditions.checkArgument(modSeq != null);
                 Preconditions.checkArgument(keywords != null);
                 Preconditions.checkArgument(size != null);
                 Preconditions.checkArgument(internalDate != null);
@@ -278,7 +277,7 @@ public class MessageFullViewFactory implements MessageViewFactory<MessageFullVie
         }
 
         private final MessageUid uid;
-        private final long modSeq;
+        private final ModSeq modSeq;
         private final Keywords keywords;
         private final long size;
         private final Instant internalDate;
@@ -289,7 +288,7 @@ public class MessageFullViewFactory implements MessageViewFactory<MessageFullVie
         private final MessageId messageId;
 
         private MetaDataWithContent(MessageUid uid,
-                                    long modSeq,
+                                    ModSeq modSeq,
                                     Keywords keywords,
                                     long size,
                                     Instant internalDate,
@@ -314,7 +313,7 @@ public class MessageFullViewFactory implements MessageViewFactory<MessageFullVie
             return uid;
         }
 
-        public long getModSeq() {
+        public ModSeq getModSeq() {
             return modSeq;
         }
 


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