http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java
index 568db73..f0a7027 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java
@@ -19,12 +19,13 @@
 package org.apache.james.mailbox.cassandra.mail;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertEquals;
+import static org.assertj.guava.api.Assertions.assertThat;
 
 import java.util.stream.LongStream;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraUidModule;
@@ -35,6 +36,7 @@ import org.junit.Before;
 import org.junit.Test;
 
 import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Optional;
 
 public class CassandraUidProviderTest {
 
@@ -67,12 +69,12 @@ public class CassandraUidProviderTest {
     @Test
     public void lastUidShouldRetrieveValueStoredByNextUid() throws Exception {
         int nbEntries = 100;
-        long result = uidProvider.lastUid(null, mailbox);
-        assertEquals(0, result);
+        Optional<MessageUid> result = uidProvider.lastUid(null, mailbox);
+        assertThat(result).isAbsent();
         LongStream.range(0, nbEntries)
             .forEach(Throwing.longConsumer(value -> {
-                        long uid = uidProvider.nextUid(null, mailbox);
-                        assertThat(uid).isEqualTo(uidProvider.lastUid(null, 
mailbox));
+                        MessageUid uid = uidProvider.nextUid(null, mailbox);
+                        assertThat(uid).isEqualTo(uidProvider.lastUid(null, 
mailbox).get());
                 })
             );
     }
@@ -80,11 +82,10 @@ public class CassandraUidProviderTest {
     @Test
     public void nextUidShouldIncrementValueByOne() throws Exception {
         int nbEntries = 100;
-        long lastUid = uidProvider.lastUid(null, mailbox);
-        LongStream.range(lastUid + 1, lastUid + nbEntries)
+        LongStream.range(1, nbEntries)
             .forEach(Throwing.longConsumer(value -> {
-                        long result = uidProvider.nextUid(null, mailbox);
-                        assertThat(value).isEqualTo(result);
+                        MessageUid result = uidProvider.nextUid(null, mailbox);
+                        assertThat(value).isEqualTo(result.asLong());
                 })
             );
     }
@@ -94,7 +95,8 @@ public class CassandraUidProviderTest {
         int nbEntries = 100;
         long nbValues = LongStream.range(0, nbEntries)
             .parallel()
-            .map(Throwing.longUnaryOperator(x -> uidProvider.nextUid(null, 
mailbox)))
+            .mapToObj(x -> x)
+            .map(Throwing.function(x -> uidProvider.nextUid(null, mailbox)))
             .distinct()
             .count();
         assertThat(nbValues).isEqualTo(nbEntries);

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
----------------------------------------------------------------------
diff --git 
a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
 
b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
index 5d24222..c5b1c8d 100644
--- 
a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
+++ 
b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
@@ -31,6 +31,7 @@ import javax.inject.Inject;
 
 import org.apache.james.mailbox.MailboxManager.SearchCapabilities;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.elasticsearch.ElasticSearchIndexer;
 import org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants;
 import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
@@ -80,7 +81,7 @@ public class ElasticSearchListeningMessageSearchIndex extends 
ListeningMessageSe
     }
     
     @Override
-    public Iterator<Long> search(MailboxSession session, Mailbox mailbox, 
SearchQuery searchQuery) throws MailboxException {
+    public Iterator<MessageUid> search(MailboxSession session, Mailbox 
mailbox, SearchQuery searchQuery) throws MailboxException {
         Preconditions.checkArgument(session != null, "'session' is mandatory");
         MailboxId mailboxId = mailbox.getMailboxId();
         MultimailboxesSearchQuery query = 
MultimailboxesSearchQuery.from(searchQuery).inMailboxes(mailboxId).build();
@@ -91,7 +92,7 @@ public class ElasticSearchListeningMessageSearchIndex extends 
ListeningMessageSe
     }
     
     @Override
-    public Map<MailboxId, Collection<Long>> search(MailboxSession session, 
MultimailboxesSearchQuery searchQuery)
+    public Map<MailboxId, Collection<MessageUid>> search(MailboxSession 
session, MultimailboxesSearchQuery searchQuery)
             throws MailboxException {
         Preconditions.checkArgument(session != null, "'session' is mandatory");
         return searcher.search(ImmutableList.of(session.getUser()), 
searchQuery).asMap();
@@ -107,7 +108,7 @@ public class ElasticSearchListeningMessageSearchIndex 
extends ListeningMessageSe
     }
 
     @Override
-    public void delete(MailboxSession session, Mailbox mailbox, List<Long> 
expungedUids) throws MailboxException {
+    public void delete(MailboxSession session, Mailbox mailbox, 
List<MessageUid> expungedUids) throws MailboxException {
         try {
             indexer.deleteMessages(expungedUids.stream()
                 .map(uid ->  indexIdFor(mailbox, uid))
@@ -152,7 +153,7 @@ public class ElasticSearchListeningMessageSearchIndex 
extends ListeningMessageSe
         }
     }
 
-    private String indexIdFor(Mailbox mailbox, long messageId) {
+    private String indexIdFor(Mailbox mailbox, MessageUid messageId) {
         return String.join(ID_SEPARATOR, mailbox.getMailboxId().serialize(), 
String.valueOf(messageId));
     }
     

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
----------------------------------------------------------------------
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 f67e5d1..b474c1b 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
@@ -29,6 +29,7 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import org.apache.james.mailbox.MailboxSession.User;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.elasticsearch.query.DateResolutionFormater;
 import org.apache.james.mailbox.extractor.TextExtractor;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
@@ -118,7 +119,7 @@ public class IndexableMessage {
             .collect(Collectors.joining(" "));
     }
 
-    private Long id;
+    private MessageUid id;
     private String mailboxId;
     private List<String> users;
     private long modSeq;
@@ -149,7 +150,7 @@ public class IndexableMessage {
 
     @JsonProperty(JsonMessageConstants.ID)
     public Long getId() {
-        return id;
+        return id.asLong();
     }
 
     @JsonProperty(JsonMessageConstants.MAILBOX_ID)

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
----------------------------------------------------------------------
diff --git 
a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
 
b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
index 10a1ca4..180bf99 100644
--- 
a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
+++ 
b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
@@ -228,10 +228,10 @@ public class CriterionConverter {
                     .map(this::uidRangeFilter), BoolQueryBuilder::should));
     }
 
-    private QueryBuilder uidRangeFilter(SearchQuery.NumericRange numericRange) 
{
+    private QueryBuilder uidRangeFilter(SearchQuery.UidRange numericRange) {
         return rangeQuery(JsonMessageConstants.ID)
-                .lte(numericRange.getHighValue())
-                .gte(numericRange.getLowValue());
+                .lte(numericRange.getHighValue().asLong())
+                .gte(numericRange.getLowValue().asLong());
     }
 
     private QueryBuilder convertHeader(SearchQuery.HeaderCriterion 
headerCriterion) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
----------------------------------------------------------------------
diff --git 
a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
 
b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
index 2eb4cf1..3b2c012 100644
--- 
a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
+++ 
b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
@@ -28,6 +28,7 @@ import javax.inject.Inject;
 
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.mailbox.MailboxSession.User;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.elasticsearch.ElasticSearchIndexer;
 import org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants;
 import org.apache.james.mailbox.elasticsearch.query.QueryConverter;
@@ -71,7 +72,7 @@ public class ElasticSearchSearcher {
         this.mailboxIdFactory = mailboxIdFactory;
     }
     
-    public Multimap<MailboxId, Long> search(List<User> users, 
MultimailboxesSearchQuery query) throws MailboxException {
+    public Multimap<MailboxId, MessageUid> search(List<User> users, 
MultimailboxesSearchQuery query) throws MailboxException {
         return new ScrollIterable(client, getSearchRequestBuilder(client, 
users, query)).stream()
             .flatMap(this::transformResponseToUidStream)
             .collect(Guavate.toImmutableListMultimap(Pair::getLeft, 
Pair::getRight));
@@ -91,19 +92,19 @@ public class ElasticSearchSearcher {
                 (partialResult1, partialResult2) -> partialResult1);
     }
 
-    private Stream<Pair<MailboxId, Long>> 
transformResponseToUidStream(SearchResponse searchResponse) {
+    private Stream<Pair<MailboxId, MessageUid>> 
transformResponseToUidStream(SearchResponse searchResponse) {
         return StreamSupport.stream(searchResponse.getHits().spliterator(), 
false)
             .map(this::extractContentFromHit)
             .filter(Optional::isPresent)
             .map(Optional::get);
     }
 
-    private Optional<Pair<MailboxId, Long>> extractContentFromHit(SearchHit 
hit) {
+    private Optional<Pair<MailboxId, MessageUid>> 
extractContentFromHit(SearchHit hit) {
         SearchHitField mailboxId = hit.field(JsonMessageConstants.MAILBOX_ID);
         SearchHitField uid = hit.field(JsonMessageConstants.ID);
         if (mailboxId != null && uid != null) {
             Number uidAsNumber = uid.getValue();
-            return 
Optional.of(Pair.of(mailboxIdFactory.fromString(mailboxId.getValue()), 
uidAsNumber.longValue()));
+            return 
Optional.of(Pair.of(mailboxIdFactory.fromString(mailboxId.getValue()), 
MessageUid.of(uidAsNumber.longValue())));
         } else {
             LOGGER.warn("Can not extract UID and/or MailboxId for search 
result " + hit.getId());
             return Optional.empty();

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMailboxMessageSearchIndexTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMailboxMessageSearchIndexTest.java
 
b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMailboxMessageSearchIndexTest.java
index 639eeb5..05b39df 100644
--- 
a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMailboxMessageSearchIndexTest.java
+++ 
b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMailboxMessageSearchIndexTest.java
@@ -32,6 +32,7 @@ import java.util.List;
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.MailboxSession.User;
 import org.apache.james.mailbox.elasticsearch.ElasticSearchIndexer;
 import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
@@ -86,7 +87,7 @@ public class 
ElasticSearchListeningMailboxMessageSearchIndexTest {
             .andReturn(user);
 
         Mailbox mailbox = control.createMock(Mailbox.class);
-        long messageId = 1;
+        MessageUid messageId = MessageUid.of(1);
         TestId mailboxId = TestId.of(12);
         expect(mailbox.getMailboxId()).andReturn(mailboxId);
         MailboxMessage message = mockedMessage(messageId);
@@ -100,7 +101,7 @@ public class 
ElasticSearchListeningMailboxMessageSearchIndexTest {
         control.verify();
     }
 
-    private MailboxMessage mockedMessage(long messageId) throws IOException {
+    private MailboxMessage mockedMessage(MessageUid messageId) throws 
IOException {
         MailboxMessage message = control.createMock(MailboxMessage.class);
         expect(message.getUid()).andReturn(messageId).anyTimes();
         return message;
@@ -115,7 +116,7 @@ public class 
ElasticSearchListeningMailboxMessageSearchIndexTest {
 
         Mailbox mailbox = control.createMock(Mailbox.class);
         
-        long messageId = 1;
+        MessageUid messageId = MessageUid.of(1);
         TestId mailboxId = TestId.of(12);
         MailboxMessage message = mockedMessage(messageId);
         expect(mailbox.getMailboxId()).andReturn(mailboxId);
@@ -133,7 +134,7 @@ public class 
ElasticSearchListeningMailboxMessageSearchIndexTest {
     public void deleteShouldWork() throws Exception {
         MailboxSession session = control.createMock(MailboxSession.class);
         Mailbox mailbox = control.createMock(Mailbox.class);
-        long messageId = 1;
+        MessageUid messageId = MessageUid.of(1);
         TestId mailboxId = TestId.of(12);
         expect(mailbox.getMailboxId()).andReturn(mailboxId);
         
@@ -151,11 +152,11 @@ public class 
ElasticSearchListeningMailboxMessageSearchIndexTest {
     public void deleteShouldWorkWhenMultipleMessageIds() throws Exception {
         MailboxSession session = control.createMock(MailboxSession.class);
         Mailbox mailbox = control.createMock(Mailbox.class);
-        long messageId1 = 1;
-        long messageId2 = 2;
-        long messageId3 = 3;
-        long messageId4 = 4;
-        long messageId5 = 5;
+        MessageUid messageId1 = MessageUid.of(1);
+        MessageUid messageId2 = MessageUid.of(2);
+        MessageUid messageId3 = MessageUid.of(3);
+        MessageUid messageId4 = MessageUid.of(4);
+        MessageUid messageId5 = MessageUid.of(5);
         TestId mailboxId = TestId.of(12);
         expect(mailbox.getMailboxId()).andReturn(mailboxId).times(5);
 
@@ -173,7 +174,7 @@ public class 
ElasticSearchListeningMailboxMessageSearchIndexTest {
     public void deleteShouldNotPropagateExceptionWhenExceptionOccurs() throws 
Exception {
         MailboxSession session = control.createMock(MailboxSession.class);
         Mailbox mailbox = control.createMock(Mailbox.class);
-        long messageId = 1;
+        MessageUid messageId = MessageUid.of(1);
         TestId mailboxId = TestId.of(12);
         expect(mailbox.getMailboxId()).andReturn(mailboxId).times(2);
         
@@ -193,7 +194,7 @@ public class 
ElasticSearchListeningMailboxMessageSearchIndexTest {
         Mailbox mailbox = control.createMock(Mailbox.class);
 
         Flags flags = new Flags();
-        long messageId = 1;
+        MessageUid messageId = MessageUid.of(1);
         UpdatedFlags updatedFlags = new UpdatedFlags(messageId, MODSEQ, flags, 
flags);
         TestId mailboxId = TestId.of(12);
 
@@ -216,7 +217,7 @@ public class 
ElasticSearchListeningMailboxMessageSearchIndexTest {
 
         Mailbox mailbox = control.createMock(Mailbox.class);
         Flags flags = new Flags();
-        long messageId = 1;
+        MessageUid messageId = MessageUid.of(1);
         UpdatedFlags updatedFlags = new UpdatedFlags(messageId, MODSEQ, flags, 
flags);
         TestId mailboxId = TestId.of(12);
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MailboxMessageToElasticSearchJsonTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MailboxMessageToElasticSearchJsonTest.java
 
b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MailboxMessageToElasticSearchJsonTest.java
index ce43184..fa13685 100644
--- 
a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MailboxMessageToElasticSearchJsonTest.java
+++ 
b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/MailboxMessageToElasticSearchJsonTest.java
@@ -35,6 +35,7 @@ import javax.mail.util.SharedByteArrayInputStream;
 import org.apache.commons.io.IOUtils;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MailboxSession.User;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.mock.MockMailboxSession;
 import org.apache.james.mailbox.store.TestId;
 import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
@@ -55,7 +56,7 @@ public class MailboxMessageToElasticSearchJsonTest {
     public static final int BODY_START_OCTET = 100;
     public static final TestId MAILBOX_ID = TestId.of(18L);
     public static final long MOD_SEQ = 42L;
-    public static final long UID = 25L;
+    public static final MessageUid UID = MessageUid.of(25);
     public static final Charset CHARSET = Charsets.UTF_8;
 
     private Date date;
@@ -102,6 +103,7 @@ public class MailboxMessageToElasticSearchJsonTest {
             new Flags(),
             propertyBuilder,
             MAILBOX_ID);
+        spamMail.setUid(UID);
         spamMail.setModSeq(MOD_SEQ);
         assertThatJson(messageToElasticSearchJson.convertToJson(spamMail, 
ImmutableList.of(new MockMailboxSession("username").getUser())))
             .when(IGNORING_ARRAY_ORDER)
@@ -265,6 +267,7 @@ public class MailboxMessageToElasticSearchJsonTest {
             new Flags(),
             propertyBuilder,
             MAILBOX_ID);
+        spamMail.setUid(UID);
         spamMail.setModSeq(MOD_SEQ);
         assertThatJson(messageToElasticSearchJson.convertToJson(spamMail, 
ImmutableList.of(new MockMailboxSession("username").getUser())))
             .when(IGNORING_ARRAY_ORDER)

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseUtils.java
----------------------------------------------------------------------
diff --git 
a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseUtils.java 
b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseUtils.java
index b6d7e35..982f035 100644
--- a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseUtils.java
+++ b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseUtils.java
@@ -69,6 +69,7 @@ import org.apache.hadoop.hbase.client.Delete;
 import org.apache.hadoop.hbase.client.Put;
 import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.hbase.io.ChunkInputStream;
 import org.apache.james.mailbox.hbase.mail.HBaseMailboxMessage;
 import org.apache.james.mailbox.hbase.mail.model.HBaseMailbox;
@@ -215,20 +216,32 @@ public class HBaseUtils {
      * @param uid message uid
      * @return rowkey byte array that can be used with HBase API
      */
-    public static byte[] messageRowKey(HBaseId mailboxUid, long uid) {
+    public static byte[] messageRowKey(HBaseId mailboxUid, MessageUid uid) {
         /**  message uid's are stored in reverse order so we will always have 
the most recent messages first*/
-        return Bytes.add(mailboxUid.toBytes(), Bytes.toBytes(Long.MAX_VALUE - 
uid));
+        return Bytes.add(mailboxUid.toBytes(), Bytes.toBytes(Long.MAX_VALUE - 
uid.asLong()));
     }
 
     /**
+     * Utility method to build row key min limit from mailbox UUID.
+     * The message uid's are stored in reverse order by substracting the uid 
value 
+     * from Long.MAX_VALUE. 
+     * @param mailboxUid mailbox UUID
+     * @return rowkey byte array that can be used with HBase API
+     */
+    public static byte[] minMessageRowKey(HBaseId mailboxUid) {
+        return Bytes.add(mailboxUid.toBytes(), Bytes.toBytes(Long.MAX_VALUE));
+    }
+
+    
+    /**
      * Utility to build row keys from mailboxUID and a value. The value is 
added to 
      * the key without any other operations. 
      * @param mailboxUid mailbox HBaseId
      * @param value
      * @return rowkey byte array that can be used with HBase API
      */
-    public static byte[] customMessageRowKey(HBaseId mailboxUid, long value) {
-        return Bytes.add(mailboxUid.toBytes(), Bytes.toBytes(value));
+    public static byte[] customMessageRowKey(HBaseId mailboxUid, MessageUid 
value) {
+        return Bytes.add(mailboxUid.toBytes(), Bytes.toBytes(value.asLong()));
     }
 
     /**
@@ -246,7 +259,12 @@ public class HBaseUtils {
         List<Property> propList = new ArrayList<Property>();
         KeyValue[] keys = result.raw();
         String mediaType = null, subType = null;
-        Long modSeq = null, uid, bodyOctets = null, contentOctets = null, 
textualLineCount = null;
+        MessageUid uid;
+        Long modSeq = null; 
+        Long bodyOctets = null;
+        Long contentOctets = null;
+        Long textualLineCount = null;
+        
         Date internalDate = null;
 
         int i = 0;
@@ -301,7 +319,7 @@ public class HBaseUtils {
             i++;
         }
         HBaseId uuid = HBaseIdFromRowKey(result.getRow());
-        uid = Long.MAX_VALUE - Bytes.toLong(result.getRow(), 16);
+        uid = MessageUid.of(Long.MAX_VALUE - Bytes.toLong(result.getRow(), 
16));
         PropertyBuilder props = new PropertyBuilder(propList);
         props.setMediaType(mediaType);
         props.setSubType(subType);

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessage.java
----------------------------------------------------------------------
diff --git 
a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessage.java
 
b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessage.java
index 6ff9cd1..5c3bec9 100644
--- 
a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessage.java
+++ 
b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessage.java
@@ -28,6 +28,7 @@ import java.io.InputStream;
 import java.io.SequenceInputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
 
@@ -35,6 +36,7 @@ import javax.mail.Flags;
 
 import org.apache.commons.lang.NotImplementedException;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.hbase.HBaseId;
 import org.apache.james.mailbox.hbase.io.ChunkInputStream;
@@ -44,8 +46,10 @@ import 
org.apache.james.mailbox.store.mail.model.FlagsBuilder;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.MessageId;
 import org.apache.james.mailbox.store.mail.model.Property;
-import org.apache.james.mailbox.store.mail.model.impl.MessageUidComparator;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+import org.apache.james.mailbox.store.search.comparator.UidComparator;
+
+import com.google.common.base.Objects;
 
 /**
  * Concrete HBaseMailboxMessage implementation. This implementation does not 
store any
@@ -54,14 +58,14 @@ import 
org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
  */
 public class HBaseMailboxMessage implements MailboxMessage {
 
-    private static final MessageUidComparator MESSAGE_UID_COMPARATOR = new 
MessageUidComparator();
+    private static final Comparator<MailboxMessage> MESSAGE_UID_COMPARATOR = 
new UidComparator();
     private static final String TOSTRING_SEPARATOR = " ";
     /** Configuration for the HBase cluster */
     private final Configuration conf;
     /** The value for the mailboxId field */
     private final HBaseId mailboxId;
     /** The value for the uid field */
-    private long uid;
+    private MessageUid uid;
     /** The value for the modSeq field */
     private long modSeq;
     /** The value for the internalDate field */
@@ -96,7 +100,7 @@ public class HBaseMailboxMessage implements MailboxMessage {
      * Create a copy of the given message.
      * All properties are cloned except mailbox and UID.
      */
-    public HBaseMailboxMessage(Configuration conf, HBaseId mailboxId, long 
uid, long modSeq, MailboxMessage original) throws MailboxException {
+    public HBaseMailboxMessage(Configuration conf, HBaseId mailboxId, 
MessageUid uid, long modSeq, MailboxMessage original) throws MailboxException {
         this.conf = conf;
         this.mailboxId = mailboxId;
         this.uid = uid;
@@ -151,38 +155,17 @@ public class HBaseMailboxMessage implements 
MailboxMessage {
 
     @Override
     public int hashCode() {
-        final int PRIME = 31;
-        int result = 1;
-        result = PRIME * result + mailboxId.hashCode();
-        result = PRIME * result + (int) (uid ^ (uid >>> 32));
-        return result;
+        return Objects.hashCode(mailboxId, uid);
     }
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final HBaseMailboxMessage other = (HBaseMailboxMessage) obj;
-        if (getMailboxId() != null) {
-            if (!getMailboxId().equals(other.getMailboxId())) {
-                return false;
-            }
-        } else {
-            if (other.getMailboxId() != null) {
-                return false;
-            }
-        }
-        if (uid != other.uid) {
-            return false;
+        if (obj instanceof HBaseMailboxMessage) {
+            HBaseMailboxMessage other = (HBaseMailboxMessage) obj;
+            return Objects.equal(this.mailboxId, other.mailboxId) &&
+                    Objects.equal(this.uid, other.uid) ;
         }
-        return true;
+        return false;
     }
 
     @Override
@@ -266,7 +249,7 @@ public class HBaseMailboxMessage implements MailboxMessage {
     }
 
     @Override
-    public long getUid() {
+    public MessageUid getUid() {
         return uid;
     }
 
@@ -301,7 +284,7 @@ public class HBaseMailboxMessage implements MailboxMessage {
     }
 
     @Override
-    public void setUid(long uid) {
+    public void setUid(MessageUid uid) {
         this.uid = uid;
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java
 
b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java
index 1b9e70b..713f3a3 100644
--- 
a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java
+++ 
b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java
@@ -33,11 +33,11 @@ import static 
org.apache.james.mailbox.hbase.HBaseNames.MESSAGES_TABLE;
 import static org.apache.james.mailbox.hbase.HBaseNames.MESSAGE_DATA_BODY_CF;
 import static 
org.apache.james.mailbox.hbase.HBaseNames.MESSAGE_DATA_HEADERS_CF;
 import static org.apache.james.mailbox.hbase.HBaseNames.MESSAGE_MODSEQ;
-import static org.apache.james.mailbox.hbase.HBaseUtils.customMessageRowKey;
 import static org.apache.james.mailbox.hbase.HBaseUtils.flagsToPut;
 import static org.apache.james.mailbox.hbase.HBaseUtils.messageMetaFromResult;
 import static org.apache.james.mailbox.hbase.HBaseUtils.messageRowKey;
 import static org.apache.james.mailbox.hbase.HBaseUtils.metadataToPut;
+import static org.apache.james.mailbox.hbase.HBaseUtils.minMessageRowKey;
 
 import java.io.BufferedInputStream;
 import java.io.IOException;
@@ -64,6 +64,7 @@ import 
org.apache.hadoop.hbase.filter.SingleColumnValueExcludeFilter;
 import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.hbase.HBaseId;
 import org.apache.james.mailbox.hbase.io.ChunkOutputStream;
@@ -80,6 +81,9 @@ import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.transaction.NonTransactionalMapper;
 
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+
 /**
  * HBase implementation of a {@link MessageMapper}.
  * I don't know if this class is thread-safe! Asume it is not!
@@ -110,8 +114,8 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
         HBaseId mailboxId = (HBaseId) mailbox.getMailboxId();
         try {
             List<MailboxMessage> results;
-            long from = set.getUidFrom();
-            final long to = set.getUidTo();
+            MessageUid from = set.getUidFrom();
+            final MessageUid to = set.getUidTo();
             final Type type = set.getType();
 
             switch (type) {
@@ -139,7 +143,7 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
     private List<MailboxMessage> findMessagesInMailbox(HBaseId mailboxId, int 
batchSize, boolean flaggedForDelete) throws IOException {
         List<MailboxMessage> messageList = new ArrayList<MailboxMessage>();
         HTable messages = new HTable(conf, MESSAGES_TABLE);
-        Scan scan = new Scan(customMessageRowKey(mailboxId, 0L),
+        Scan scan = new Scan(minMessageRowKey(mailboxId),
                 new PrefixFilter(mailboxId.toBytes()));
         if (flaggedForDelete) {
             SingleColumnValueFilter filter = new 
SingleColumnValueFilter(MESSAGES_META_CF, FLAGS_DELETED, CompareOp.EQUAL, 
MARKER_PRESENT);
@@ -165,10 +169,10 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
         return messageList;
     }
 
-    private List<MailboxMessage> findMessagesInMailboxWithUID(HBaseId 
mailboxId, long messageUid, boolean flaggedForDelete) throws IOException {
+    private List<MailboxMessage> findMessagesInMailboxWithUID(HBaseId 
mailboxId, MessageUid from, boolean flaggedForDelete) throws IOException {
         List<MailboxMessage> messageList = new ArrayList<MailboxMessage>();
         HTable messages = new HTable(conf, MESSAGES_TABLE);
-        Get get = new Get(messageRowKey(mailboxId, messageUid));
+        Get get = new Get(messageRowKey(mailboxId, from));
         get.setMaxVersions(1);
         /* we exclude the message content column family because it could be 
too large.
          * the content will be pulled from HBase on demand by using a a 
ChunkedInputStream implementation.
@@ -189,12 +193,12 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
         return messageList;
     }
 
-    private List<MailboxMessage> findMessagesInMailboxAfterUID(HBaseId 
mailboxId, long from, int batchSize, boolean flaggedForDelete) throws 
IOException {
+    private List<MailboxMessage> findMessagesInMailboxAfterUID(HBaseId 
mailboxId, MessageUid messageUid, int batchSize, boolean flaggedForDelete) 
throws IOException {
         List<MailboxMessage> messageList = new ArrayList<MailboxMessage>();
         HTable messages = new HTable(conf, MESSAGES_TABLE);
         // uids are stored in reverse so we need to search
-        Scan scan = new Scan(messageRowKey(mailboxId, Long.MAX_VALUE),
-                messageRowKey(mailboxId, from - 1));
+        
+        Scan scan = new Scan(messageRowKey(mailboxId, MessageUid.MAX_VALUE), 
previousMessageRowKey(mailboxId, messageUid));
         if (flaggedForDelete) {
             SingleColumnValueFilter filter = new 
SingleColumnValueFilter(MESSAGES_META_CF, FLAGS_DELETED, CompareOp.EQUAL, 
MARKER_PRESENT);
             filter.setFilterIfMissing(true);
@@ -219,16 +223,24 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
         return messageList;
     }
 
-    private List<MailboxMessage> findMessagesInMailboxBetweenUIDs(HBaseId 
mailboxId, long from, long to, int batchSize, boolean flaggedForDelete) throws 
IOException {
+    private byte[] previousMessageRowKey(HBaseId mailboxId, MessageUid 
messageUid) {
+        if (messageUid.isFirst()) {
+            return minMessageRowKey(mailboxId);
+        } else {
+            return messageRowKey(mailboxId, messageUid.previous());
+        }
+    }
+
+    private List<MailboxMessage> findMessagesInMailboxBetweenUIDs(HBaseId 
mailboxId, MessageUid from, MessageUid to, int batchSize, boolean 
flaggedForDelete) throws IOException {
         List<MailboxMessage> messageList = new ArrayList<MailboxMessage>();
-        if (from > to) {
+        if (from.compareTo(to) > 0) {
             return messageList;
         }
         HTable messages = new HTable(conf, MESSAGES_TABLE);
         /*TODO: check if Between should be inclusive or exclusive regarding 
limits.
          * HBase scan operaion are exclusive to the upper bound when providing 
stop row key.
          */
-        Scan scan = new Scan(messageRowKey(mailboxId, to), 
messageRowKey(mailboxId, from - 1));
+        Scan scan = new Scan(messageRowKey(mailboxId, to), 
previousMessageRowKey(mailboxId, from));
         if (flaggedForDelete) {
             SingleColumnValueFilter filter = new 
SingleColumnValueFilter(MESSAGES_META_CF, FLAGS_DELETED, CompareOp.EQUAL, 
MARKER_PRESENT);
             filter.setFilterIfMissing(true);
@@ -259,12 +271,12 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
     }
 
     @Override
-    public Map<Long, MessageMetaData> 
expungeMarkedForDeletionInMailbox(Mailbox mailbox, MessageRange set) throws 
MailboxException {
+    public Map<MessageUid, MessageMetaData> 
expungeMarkedForDeletionInMailbox(Mailbox mailbox, MessageRange set) throws 
MailboxException {
         try {
-            final Map<Long, MessageMetaData> data;
+            final Map<MessageUid, MessageMetaData> data;
             final List<MailboxMessage> results;
-            final long from = set.getUidFrom();
-            final long to = set.getUidTo();
+            final MessageUid from = set.getUidFrom();
+            final MessageUid to = set.getUidTo();
             HBaseId mailboxId = (HBaseId) mailbox.getMailboxId();
 
             switch (set.getType()) {
@@ -333,18 +345,15 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
         try {
             messages = new HTable(conf, MESSAGES_TABLE);
             /* Limit the number of entries scanned to just the mails in this 
mailbox */
-            Scan scan = new Scan(messageRowKey(mailboxId, Long.MAX_VALUE),
-                    messageRowKey(mailboxId, 0));
+            Scan scan = new Scan(
+                    messageRowKey(mailboxId, MessageUid.MAX_VALUE),
+                    minMessageRowKey(mailboxId));
             scan.addFamily(MESSAGES_META_CF);
             scan.setFilter(new 
SingleColumnValueExcludeFilter(MESSAGES_META_CF, FLAGS_SEEN, CompareOp.EQUAL, 
MARKER_MISSING));
             
scan.setCaching(messages.getConfiguration().getInt("hbase.client.scanner.caching",
 1) * 2);
             scan.setMaxVersions(1);
             scanner = messages.getScanner(scan);
-            long count = 0;
-            while (scanner.next() != null) {
-                count++;
-            }
-            return count;
+            return Iterables.size(scanner);
         } catch (IOException e) {
             throw new MailboxException("Search of first unseen message failed 
in mailbox " + mailbox, e);
         } finally {
@@ -399,14 +408,16 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
     }
 
     @Override
-    public Long findFirstUnseenMessageUid(Mailbox mailbox) throws 
MailboxException {
+    public MessageUid findFirstUnseenMessageUid(Mailbox mailbox) throws 
MailboxException {
         HTable messages = null;
         ResultScanner scanner = null;
         HBaseId mailboxId = (HBaseId) mailbox.getMailboxId();
         try {
             messages = new HTable(conf, MESSAGES_TABLE);
             /* Limit the number of entries scanned to just the mails in this 
mailbox */
-            Scan scan = new Scan(messageRowKey(mailboxId, Long.MAX_VALUE), 
messageRowKey(mailboxId, 0));
+            Scan scan = new Scan(
+                    messageRowKey(mailboxId, MessageUid.MAX_VALUE), 
+                    minMessageRowKey(mailboxId));
             scan.addFamily(MESSAGES_META_CF);
             // filter out all rows with FLAGS_SEEN qualifier
             SingleColumnValueFilter filter = new 
SingleColumnValueFilter(MESSAGES_META_CF, FLAGS_SEEN, CompareOp.EQUAL, 
MARKER_MISSING);
@@ -415,13 +426,13 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
             scan.setMaxVersions(1);
             scanner = messages.getScanner(scan);
             Result result;
-            Long lastUnseen = null;
+            MessageUid lastUnseen = null;
             byte[] row = null;
             while ((result = scanner.next()) != null) {
                 row = result.getRow();
             }
             if (row != null) {
-                lastUnseen = Long.MAX_VALUE - Bytes.toLong(row, 16, 8);
+                lastUnseen = MessageUid.of(Long.MAX_VALUE - Bytes.toLong(row, 
16, 8));
             }
             return lastUnseen;
         } catch (IOException e) {
@@ -439,7 +450,7 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
     }
 
     @Override
-    public List<Long> findRecentMessageUidsInMailbox(Mailbox mailbox) throws 
MailboxException {
+    public List<MessageUid> findRecentMessageUidsInMailbox(Mailbox mailbox) 
throws MailboxException {
         /** TODO: improve performance by implementing a last seen and last 
recent value per mailbox.
          * maybe one more call to HBase is less expensive than iterating 
throgh all rows.
          */
@@ -449,8 +460,9 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
         try {
             messages = new HTable(conf, MESSAGES_TABLE);
             /* Limit the number of entries scanned to just the mails in this 
mailbox */
-            Scan scan = new Scan(messageRowKey(mailboxId, Long.MAX_VALUE),
-                    messageRowKey(mailboxId, 0));
+            Scan scan = new Scan(
+                    messageRowKey(mailboxId, MessageUid.MAX_VALUE),
+                    minMessageRowKey(mailboxId));
             // we add the column, if it exists, the message is recent, else it 
is not
             scan.addColumn(MESSAGES_META_CF, FLAGS_RECENT);
             SingleColumnValueFilter filter = new 
SingleColumnValueFilter(MESSAGES_META_CF, FLAGS_RECENT, CompareOp.EQUAL, 
MARKER_PRESENT);
@@ -460,9 +472,9 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
 
             scanner = messages.getScanner(scan);
             Result result;
-            List<Long> uids = new ArrayList<Long>();
+            List<MessageUid> uids = new ArrayList<MessageUid>();
             while ((result = scanner.next()) != null) {
-                uids.add(Long.MAX_VALUE - Bytes.toLong(result.getRow(), 16, 
8));
+                uids.add(MessageUid.of(Long.MAX_VALUE - 
Bytes.toLong(result.getRow(), 16, 8)));
             }
             Collections.reverse(uids);
             return uids;
@@ -551,13 +563,9 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
         return updatedFlags.iterator();
     }
 
-    /*
-     * (non-Javadoc)
-     * @see 
org.apache.james.mailbox.store.mail.MessageMapper#copy(org.apache.james.mailbox.store.mail.model.Mailbox,
 org.apache.james.mailbox.store.mail.model.MailboxMessage)
-     */
     @Override
     public MessageMetaData copy(Mailbox mailbox, MailboxMessage original) 
throws MailboxException {
-        long uid = uidProvider.nextUid(mailboxSession, mailbox);
+        MessageUid uid = uidProvider.nextUid(mailboxSession, mailbox);
         long modSeq = -1;
         if (modSeqProvider != null) {
             modSeq = modSeqProvider.nextModSeq(mailboxSession, mailbox);
@@ -569,29 +577,17 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
         return save(mailboxId, message);
     }
 
-    /*
-     * (non-Javadoc)
-     * @see 
org.apache.james.mailbox.store.mail.MessageMapper#copy(org.apache.james.mailbox.store.mail.model.Mailbox,
 org.apache.james.mailbox.store.mail.model.MailboxMessage)
-     */
     @Override
     public MessageMetaData move(Mailbox mailbox, MailboxMessage original) 
throws MailboxException {
        //TODO implement if possible
        throw new UnsupportedOperationException();
     }
 
-    /*
-     * (non-Javadoc)
-     * @see 
org.apache.james.mailbox.store.mail.MessageMapper#getLastUid(org.apache.james.mailbox.store.mail.model.Mailbox)
-     */
     @Override
-    public long getLastUid(Mailbox mailbox) throws MailboxException {
+    public Optional<MessageUid> getLastUid(Mailbox mailbox) throws 
MailboxException {
         return uidProvider.lastUid(mailboxSession, mailbox);
     }
 
-    /*
-     * (non-Javadoc)
-     * @see 
org.apache.james.mailbox.store.mail.MessageMapper#getHighestModSeq(org.apache.james.mailbox.store.mail.model.Mailbox)
-     */
     @Override
     public long getHighestModSeq(Mailbox mailbox) throws MailboxException {
         return modSeqProvider.highestModSeq(mailboxSession, mailbox);
@@ -674,11 +670,11 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
         }
     }
 
-    private void deleteDeletedMessagesInMailboxWithUID(HBaseId mailboxId, long 
uid) throws IOException {
+    private void deleteDeletedMessagesInMailboxWithUID(HBaseId mailboxId, 
MessageUid from) throws IOException {
         //TODO: do I have to check if the message is flagged for delete here?
         HTable messages = new HTable(conf, MESSAGES_TABLE);
         HTable mailboxes = new HTable(conf, MAILBOXES_TABLE);
-        Delete delete = new Delete(messageRowKey(mailboxId, uid));
+        Delete delete = new Delete(messageRowKey(mailboxId, from));
         messages.delete(delete);
         mailboxes.incrementColumnValue(mailboxId.toBytes(), MAILBOX_CF, 
MAILBOX_MESSAGE_COUNT, -1);
         mailboxes.incrementColumnValue(mailboxId.toBytes(), MAILBOX_CF, 
MAILBOX_HIGHEST_MODSEQ, 1);
@@ -686,7 +682,7 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
         messages.close();
     }
 
-    private void deleteDeletedMessagesInMailboxBetweenUIDs(HBaseId mailboxId, 
long fromUid, long toUid) throws IOException {
+    private void deleteDeletedMessagesInMailboxBetweenUIDs(HBaseId mailboxId, 
MessageUid fromUid, MessageUid toUid) throws IOException {
         HTable messages = new HTable(conf, MESSAGES_TABLE);
         HTable mailboxes = new HTable(conf, MAILBOXES_TABLE);
         List<Delete> deletes = new ArrayList<Delete>();
@@ -712,7 +708,7 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
         messages.close();
     }
 
-    private void deleteDeletedMessagesInMailboxAfterUID(HBaseId mailboxId, 
long fromUid) throws IOException {
+    private void deleteDeletedMessagesInMailboxAfterUID(HBaseId mailboxId, 
MessageUid fromUid) throws IOException {
         HTable messages = new HTable(conf, MESSAGES_TABLE);
         HTable mailboxes = new HTable(conf, MAILBOXES_TABLE);
         List<Delete> deletes = new ArrayList<Delete>();
@@ -745,7 +741,7 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
         /*TODO: check if Between should be inclusive or exclusive regarding 
limits.
          * HBase scan operaion are exclusive to the upper bound when providing 
stop row key.
          */
-        Scan scan = new Scan(customMessageRowKey(mailboxId, 0L),
+        Scan scan = new Scan(minMessageRowKey(mailboxId),
                 new PrefixFilter(mailboxId.toBytes()));
         scan.addColumn(MESSAGES_META_CF, FLAGS_DELETED);
         SingleColumnValueFilter filter = new 
SingleColumnValueFilter(MESSAGES_META_CF, FLAGS_DELETED, CompareOp.EQUAL, 
MARKER_PRESENT);
@@ -765,8 +761,8 @@ public class HBaseMessageMapper extends 
NonTransactionalMapper implements Messag
         messages.close();
     }
 
-    private Map<Long, MessageMetaData> createMetaData(List<MailboxMessage> 
uids) {
-        final Map<Long, MessageMetaData> data = new HashMap<Long, 
MessageMetaData>();
+    private Map<MessageUid, MessageMetaData> 
createMetaData(List<MailboxMessage> uids) {
+        final Map<MessageUid, MessageMetaData> data = new HashMap<MessageUid, 
MessageMetaData>();
         for (MailboxMessage m : uids) {
             data.put(m.getUid(), new SimpleMessageMetaData(m));
         }

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseUidProvider.java
----------------------------------------------------------------------
diff --git 
a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseUidProvider.java
 
b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseUidProvider.java
index 23e667d..4079d57 100644
--- 
a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseUidProvider.java
+++ 
b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseUidProvider.java
@@ -30,10 +30,13 @@ import org.apache.hadoop.hbase.client.HTable;
 import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.hbase.HBaseId;
 import org.apache.james.mailbox.store.mail.UidProvider;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
+
+import com.google.common.base.Optional;
 /**
  * Message UidProvider for HBase.
  * 
@@ -52,10 +55,9 @@ public class HBaseUidProvider implements UidProvider {
      * @param session the session
      * @param mailbox the mailbox for which to get the last uid
      * @return the last uid used
-     * @throws MailboxException 
      */
     @Override
-    public long lastUid(MailboxSession session, Mailbox mailbox) throws 
MailboxException {
+    public Optional<MessageUid> lastUid(MailboxSession session, Mailbox 
mailbox) throws MailboxException {
         HTable mailboxes = null;
         HBaseId mailboxId = (HBaseId) mailbox.getMailboxId();
         try {
@@ -68,8 +70,11 @@ public class HBaseUidProvider implements UidProvider {
             if (result == null) {
                 throw new MailboxException("Row or column not found!");
             }
-            long uid = Bytes.toLong(result.getValue(MAILBOX_CF, 
MAILBOX_LASTUID));
-            return uid;
+            long rawUid = Bytes.toLong(result.getValue(MAILBOX_CF, 
MAILBOX_LASTUID));
+            if (rawUid == 0) {
+                return Optional.absent();
+            }
+            return Optional.of(MessageUid.of(rawUid));
         } catch (IOException e) {
             throw new MailboxException("lastUid", e);
         } finally {
@@ -92,12 +97,12 @@ public class HBaseUidProvider implements UidProvider {
      * @throws MailboxException 
      */
     @Override
-    public long nextUid(MailboxSession session, Mailbox mailbox) throws 
MailboxException {
+    public MessageUid nextUid(MailboxSession session, Mailbox mailbox) throws 
MailboxException {
         HTable mailboxes = null;
         HBaseId mailboxId = (HBaseId) mailbox.getMailboxId();
         try {
             mailboxes = new HTable(conf, MAILBOXES_TABLE);
-            long newValue = 
mailboxes.incrementColumnValue(mailboxId.toBytes(), MAILBOX_CF, 
MAILBOX_LASTUID, 1);
+            MessageUid newValue = 
MessageUid.of(mailboxes.incrementColumnValue(mailboxId.toBytes(), MAILBOX_CF, 
MAILBOX_LASTUID, 1));
             mailboxes.close();
             return newValue;
         } catch (IOException e) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/HBaseUtilsTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/HBaseUtilsTest.java
 
b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/HBaseUtilsTest.java
index d6fec12..d5ecb65 100644
--- 
a/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/HBaseUtilsTest.java
+++ 
b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/HBaseUtilsTest.java
@@ -53,6 +53,7 @@ import javax.mail.Flags;
 
 import org.apache.hadoop.hbase.client.Put;
 import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.hbase.mail.model.HBaseMailbox;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.store.mail.model.Property;
@@ -147,6 +148,7 @@ public class HBaseUtilsTest {
         flags.add("userFlag2");
         HBaseId uuid = HBaseId.of(UUID.randomUUID());
         final SimpleMailboxMessage message = new SimpleMailboxMessage(new 
Date(), 100, 10, null, flags, new PropertyBuilder(), uuid);
+        message.setUid(MessageUid.of(1));
         Put put = flagsToPut(message, flags);
         //test for the system flags
         assertTrue(put.has(MESSAGES_META_CF, FLAGS_SEEN, MARKER_PRESENT));

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessageMapperTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessageMapperTest.java
 
b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessageMapperTest.java
index 56fb775..741c1fc 100644
--- 
a/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessageMapperTest.java
+++ 
b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMessageMapperTest.java
@@ -44,6 +44,7 @@ import javax.mail.util.SharedByteArrayInputStream;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.hbase.HBaseClusterSingleton;
 import org.apache.james.mailbox.hbase.mail.model.HBaseMailbox;
 import org.apache.james.mailbox.mock.MockMailboxSession;
@@ -192,8 +193,8 @@ public class HBaseMailboxMessageMapperTest {
      */
     private void testFindFirstUnseenMessageUid() throws Exception {
         LOG.info("findFirstUnseenMessageUid");
-        final long uid = 
messageMapper.findFirstUnseenMessageUid(MBOXES.get(1));
-        assertEquals(1, uid);
+        MessageUid uid = 
messageMapper.findFirstUnseenMessageUid(MBOXES.get(1));
+        assertEquals(MessageUid.of(1), uid);
     }
 
     /**
@@ -202,7 +203,7 @@ public class HBaseMailboxMessageMapperTest {
      */
     private void testFindRecentMessageUidsInMailbox() throws Exception {
         LOG.info("findRecentMessageUidsInMailbox");
-        List<Long> recentMessages = 
messageMapper.findRecentMessageUidsInMailbox(MBOXES.get(1));
+        List<MessageUid> recentMessages = 
messageMapper.findRecentMessageUidsInMailbox(MBOXES.get(1));
         assertEquals(MESSAGE_NO.size() - 1, recentMessages.size());
     }
 
@@ -222,8 +223,8 @@ public class HBaseMailboxMessageMapperTest {
      */
     private void testGetLastUid() throws Exception {
         LOG.info("getLastUid");
-        long lastUid = messageMapper.getLastUid(MBOXES.get(1));
-        assertEquals(MESSAGE_NO.size(), lastUid);
+        MessageUid lastUid = messageMapper.getLastUid(MBOXES.get(1)).get();
+        assertEquals(MessageUid.of(MESSAGE_NO.size()), lastUid);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseUidAndModSeqProviderTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseUidAndModSeqProviderTest.java
 
b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseUidAndModSeqProviderTest.java
index 627cde8..80c4695 100644
--- 
a/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseUidAndModSeqProviderTest.java
+++ 
b/mailbox/hbase/src/test/java/org/apache/james/mailbox/hbase/mail/HBaseUidAndModSeqProviderTest.java
@@ -22,6 +22,8 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.hbase.HBaseClusterSingleton;
 import static org.apache.james.mailbox.hbase.HBaseNames.*;
 import org.apache.james.mailbox.hbase.mail.model.HBaseMailbox;
@@ -32,6 +34,8 @@ import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Optional;
+
 /**
  * Unit tests for UidProvider and ModSeqProvider.
  *
@@ -113,12 +117,12 @@ public class HBaseUidAndModSeqProviderTest {
         mapper.save(newBox);
         mailboxList.add(newBox);
         pathsList.add(path);
-
-        long result = uidProvider.lastUid(null, newBox);
-        assertEquals(0, result);
+        MailboxSession session = null;
+        Optional<MessageUid> result = uidProvider.lastUid(session, newBox);
+        assertEquals(Optional.absent(), result);
         for (int i = 1; i < 10; i++) {
-            long uid = uidProvider.nextUid(null, newBox);
-            assertEquals(uid, uidProvider.lastUid(null, newBox));
+            MessageUid uid = uidProvider.nextUid(session, newBox);
+            assertEquals(uid, uidProvider.lastUid(session, newBox).get());
         }
     }
 
@@ -129,11 +133,16 @@ public class HBaseUidAndModSeqProviderTest {
     public void testNextUid() throws Exception {
         LOG.info("nextUid");
         HBaseMailbox mailbox = mailboxList.get(mailboxList.size() / 2);
-        long lastUid = uidProvider.lastUid(null, mailbox);
-        long result;
-        for (int i = (int) lastUid + 1; i < (lastUid + 10); i++) {
-            result = uidProvider.nextUid(null, mailbox);
-            assertEquals(i, result);
+        MailboxSession session = null;
+        Optional<MessageUid> lastUid = uidProvider.lastUid(session, mailbox);
+        for (int i = 0; i < 10; i++) {
+            if (lastUid.isPresent()) {
+                lastUid = Optional.of(lastUid.get().next());
+            } else {
+                lastUid = Optional.of(MessageUid.MIN_VALUE);
+            }
+            MessageUid result = uidProvider.nextUid(session, mailbox);
+            assertEquals(lastUid.get(), result);
         }
     }
 
@@ -149,12 +158,12 @@ public class HBaseUidAndModSeqProviderTest {
         mapper.save(newBox);
         mailboxList.add(newBox);
         pathsList.add(path);
-
-        long result = modSeqProvider.highestModSeq(null, newBox);
+        MailboxSession session = null;
+        long result = modSeqProvider.highestModSeq(session, newBox);
         assertEquals(0, result);
         for (int i = 1; i < 10; i++) {
-            long uid = modSeqProvider.nextModSeq(null, newBox);
-            assertEquals(uid, modSeqProvider.highestModSeq(null, newBox));
+            long uid = modSeqProvider.nextModSeq(session, newBox);
+            assertEquals(uid, modSeqProvider.highestModSeq(session, newBox));
         }
     }
 
@@ -165,10 +174,11 @@ public class HBaseUidAndModSeqProviderTest {
     public void testNextModSeq() throws Exception {
         LOG.info("nextModSeq");
         HBaseMailbox mailbox = mailboxList.get(mailboxList.size() / 2);
-        long lastUid = modSeqProvider.highestModSeq(null, mailbox);
+        MailboxSession session = null;
+        long lastUid = modSeqProvider.highestModSeq(session, mailbox);
         long result;
         for (int i = (int) lastUid + 1; i < (lastUid + 10); i++) {
-            result = modSeqProvider.nextModSeq(null, mailbox);
+            result = modSeqProvider.nextModSeq(session, mailbox);
             assertEquals(i, result);
         }
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java
 
b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java
index 51e9860..38d2387 100644
--- 
a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java
+++ 
b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMessageMapper.java
@@ -39,6 +39,7 @@ import javax.jcr.query.QueryResult;
 import org.apache.jackrabbit.commons.JcrUtils;
 import org.apache.jackrabbit.util.ISO9075;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.jcr.JCRImapConstants;
 import org.apache.james.mailbox.jcr.MailboxSessionJCRRepository;
@@ -297,8 +298,8 @@ public class JCRMessageMapper extends AbstractMessageMapper 
implements JCRImapCo
             throws MailboxException {
         try {
             List<MailboxMessage> results;
-            long from = set.getUidFrom();
-            final long to = set.getUidTo();
+            MessageUid from = set.getUidFrom();
+            final MessageUid to = set.getUidTo();
             final Type type = set.getType();
 
             switch (type) {
@@ -332,11 +333,11 @@ public class JCRMessageMapper extends 
AbstractMessageMapper implements JCRImapCo
      * @see org.apache.james.mailbox.store.mail.MessageMapper#
      * findRecentMessageUidsInMailbox ()
      */
-    public List<Long> findRecentMessageUidsInMailbox(Mailbox mailbox) throws 
MailboxException {
+    public List<MessageUid> findRecentMessageUidsInMailbox(Mailbox mailbox) 
throws MailboxException {
 
         try {
 
-            List<Long> list = new ArrayList<Long>();
+            List<MessageUid> list = new ArrayList<MessageUid>();
             String queryString = "/jcr:root" + getMailboxPath(mailbox) + 
"//element(*,jamesMailbox:message)[@"
                     + JCRMailboxMessage.RECENT_PROPERTY + "='true'] order by 
@" + JCRMailboxMessage.UID_PROPERTY;
 
@@ -355,14 +356,8 @@ public class JCRMessageMapper extends 
AbstractMessageMapper implements JCRImapCo
         }
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * 
org.apache.james.mailbox.store.mail.MessageMapper#findFirstUnseenMessageUid
-     * (org.apache.james.mailbox.store.mail.model.Mailbox)
-     */
-    public Long findFirstUnseenMessageUid(Mailbox mailbox) throws 
MailboxException {
+    @Override
+    public MessageUid findFirstUnseenMessageUid(Mailbox mailbox) throws 
MailboxException {
         try {
             String queryString = "/jcr:root" + getMailboxPath(mailbox) + 
"//element(*,jamesMailbox:message)[@"
                     + JCRMailboxMessage.SEEN_PROPERTY + "='false'] order by @" 
+ JCRMailboxMessage.UID_PROPERTY;
@@ -385,12 +380,12 @@ public class JCRMessageMapper extends 
AbstractMessageMapper implements JCRImapCo
     }
 
     @Override
-    public Map<Long, MessageMetaData> 
expungeMarkedForDeletionInMailbox(Mailbox mailbox, MessageRange set)
+    public Map<MessageUid, MessageMetaData> 
expungeMarkedForDeletionInMailbox(Mailbox mailbox, MessageRange set)
             throws MailboxException {
         try {
             final List<MailboxMessage> results;
-            final long from = set.getUidFrom();
-            final long to = set.getUidTo();
+            final MessageUid from = set.getUidFrom();
+            final MessageUid to = set.getUidTo();
             final Type type = set.getType();
             switch (type) {
             default:
@@ -407,9 +402,9 @@ public class JCRMessageMapper extends AbstractMessageMapper 
implements JCRImapCo
                 results = findDeletedMessagesInMailboxBetweenUIDs(mailbox, 
from, to);
                 break;
             }
-            Map<Long, MessageMetaData> uids = new HashMap<Long, 
MessageMetaData>();
+            Map<MessageUid, MessageMetaData> uids = new HashMap<MessageUid, 
MessageMetaData>();
             for (MailboxMessage m : results) {
-                long uid = m.getUid();
+                MessageUid uid = m.getUid();
                 uids.put(uid, new SimpleMessageMetaData(m));
                 delete(mailbox, m);
             }
@@ -431,18 +426,18 @@ public class JCRMessageMapper extends 
AbstractMessageMapper implements JCRImapCo
     }
 
     @Override
-    protected MessageMetaData copy(Mailbox mailbox, long uid, long modSeq, 
MailboxMessage original)
+    protected MessageMetaData copy(Mailbox mailbox, MessageUid uid, long 
modSeq, MailboxMessage original)
             throws MailboxException {
         try {
             String newMessagePath = 
getSession().getNodeByIdentifier(mailbox.getMailboxId().serialize()).getPath() 
+ NODE_DELIMITER
-                    + String.valueOf(uid);
+                    + String.valueOf(uid.asLong());
             getSession().getWorkspace().copy(
                     ((JCRMailboxMessage) original).getNode().getPath(),
                     
getSession().getNodeByIdentifier(mailbox.getMailboxId().serialize()).getPath() 
+ NODE_DELIMITER
-                            + String.valueOf(uid));
+                            + String.valueOf(uid.asLong()));
             Node node = getSession().getNode(newMessagePath);
             node.setProperty(JCRMailboxMessage.MAILBOX_UUID_PROPERTY, 
mailbox.getMailboxId().serialize());
-            node.setProperty(JCRMailboxMessage.UID_PROPERTY, uid);
+            node.setProperty(JCRMailboxMessage.UID_PROPERTY, uid.asLong());
             node.setProperty(JCRMailboxMessage.MODSEQ_PROPERTY, modSeq);
             // A copy of a message is recent
             // See MAILBOX-85
@@ -510,8 +505,8 @@ public class JCRMessageMapper extends AbstractMessageMapper 
implements JCRImapCo
     
                 }
     
-                long uid = membership.getUid();
-                messageNode = mailboxNode.addNode(String.valueOf(uid), 
"nt:file");
+                MessageUid uid = membership.getUid();
+                messageNode = 
mailboxNode.addNode(String.valueOf(uid.asLong()), "nt:file");
                 messageNode.addMixin("jamesMailbox:message");
                 try {
                     membership.merge(messageNode);
@@ -545,11 +540,11 @@ public class JCRMessageMapper extends 
AbstractMessageMapper implements JCRImapCo
         return 
ISO9075.encodePath(getSession().getNodeByIdentifier(mailbox.getMailboxId().serialize()).getPath());
     }
 
-    private List<MailboxMessage> findMessagesInMailboxAfterUID(Mailbox 
mailbox, long uid, int batchSize)
+    private List<MailboxMessage> findMessagesInMailboxAfterUID(Mailbox 
mailbox, MessageUid from, int batchSize)
             throws RepositoryException {
         List<MailboxMessage> list = new ArrayList<MailboxMessage>();
         String queryString = "/jcr:root" + getMailboxPath(mailbox) + 
"//element(*,jamesMailbox:message)[@"
-                + JCRMailboxMessage.UID_PROPERTY + ">=" + uid + "] order by @" 
+ JCRMailboxMessage.UID_PROPERTY;
+                + JCRMailboxMessage.UID_PROPERTY + ">=" + from + "] order by 
@" + JCRMailboxMessage.UID_PROPERTY;
 
         QueryManager manager = getSession().getWorkspace().getQueryManager();
         Query query = manager.createQuery(queryString, XPATH_LANGUAGE);
@@ -564,11 +559,11 @@ public class JCRMessageMapper extends 
AbstractMessageMapper implements JCRImapCo
         return list;
     }
 
-    private List<MailboxMessage> findMessageInMailboxWithUID(Mailbox mailbox, 
long uid)
+    private List<MailboxMessage> findMessageInMailboxWithUID(Mailbox mailbox, 
MessageUid from)
             throws RepositoryException {
         List<MailboxMessage> list = new ArrayList<MailboxMessage>();
         String queryString = "/jcr:root" + getMailboxPath(mailbox) + 
"//element(*,jamesMailbox:message)[@"
-                + JCRMailboxMessage.UID_PROPERTY + "=" + uid + "]";
+                + JCRMailboxMessage.UID_PROPERTY + "=" + from + "]";
 
         QueryManager manager = getSession().getWorkspace().getQueryManager();
         Query query = manager.createQuery(queryString, XPATH_LANGUAGE);
@@ -581,7 +576,7 @@ public class JCRMessageMapper extends AbstractMessageMapper 
implements JCRImapCo
         return list;
     }
 
-    private List<MailboxMessage> findMessagesInMailboxBetweenUIDs(Mailbox 
mailbox, long from, long to,
+    private List<MailboxMessage> findMessagesInMailboxBetweenUIDs(Mailbox 
mailbox, MessageUid from, MessageUid to,
                                                                          int 
batchSize) throws RepositoryException {
         List<MailboxMessage> list = new ArrayList<MailboxMessage>();
         String queryString = "/jcr:root" + getMailboxPath(mailbox) + 
"//element(*,jamesMailbox:message)[@"
@@ -620,11 +615,11 @@ public class JCRMessageMapper extends 
AbstractMessageMapper implements JCRImapCo
         return list;
     }
 
-    private List<MailboxMessage> findDeletedMessagesInMailboxAfterUID(Mailbox 
mailbox, long uid)
+    private List<MailboxMessage> findDeletedMessagesInMailboxAfterUID(Mailbox 
mailbox, MessageUid from)
             throws RepositoryException {
         List<MailboxMessage> list = new ArrayList<MailboxMessage>();
         String queryString = "/jcr:root" + getMailboxPath(mailbox) + 
"//element(*,jamesMailbox:message)[@"
-                + JCRMailboxMessage.UID_PROPERTY + ">=" + uid + " and @" + 
JCRMailboxMessage.DELETED_PROPERTY + "='true'] order by @"
+                + JCRMailboxMessage.UID_PROPERTY + ">=" + from + " and @" + 
JCRMailboxMessage.DELETED_PROPERTY + "='true'] order by @"
                 + JCRMailboxMessage.UID_PROPERTY;
 
         QueryManager manager = getSession().getWorkspace().getQueryManager();
@@ -637,11 +632,11 @@ public class JCRMessageMapper extends 
AbstractMessageMapper implements JCRImapCo
         return list;
     }
 
-    private List<MailboxMessage> findDeletedMessageInMailboxWithUID(Mailbox 
mailbox, long uid)
+    private List<MailboxMessage> findDeletedMessageInMailboxWithUID(Mailbox 
mailbox, MessageUid from)
             throws RepositoryException {
         List<MailboxMessage> list = new ArrayList<MailboxMessage>();
         String queryString = "/jcr:root" + getMailboxPath(mailbox) + 
"//element(*,jamesMailbox:message)[@"
-                + JCRMailboxMessage.UID_PROPERTY + "=" + uid + " and @" + 
JCRMailboxMessage.DELETED_PROPERTY + "='true']";
+                + JCRMailboxMessage.UID_PROPERTY + "=" + from + " and @" + 
JCRMailboxMessage.DELETED_PROPERTY + "='true']";
         QueryManager manager = getSession().getWorkspace().getQueryManager();
         Query query = manager.createQuery(queryString, XPATH_LANGUAGE);
         query.setLimit(1);
@@ -655,7 +650,7 @@ public class JCRMessageMapper extends AbstractMessageMapper 
implements JCRImapCo
         return list;
     }
 
-    private List<MailboxMessage> 
findDeletedMessagesInMailboxBetweenUIDs(Mailbox mailbox, long from, long to)
+    private List<MailboxMessage> 
findDeletedMessagesInMailboxBetweenUIDs(Mailbox mailbox, MessageUid from, 
MessageUid to)
             throws RepositoryException {
         List<MailboxMessage> list = new ArrayList<MailboxMessage>();
         String queryString = "/jcr:root" + getMailboxPath(mailbox) + 
"//element(*,jamesMailbox:message)[@"

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRUidProvider.java
----------------------------------------------------------------------
diff --git 
a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRUidProvider.java
 
b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRUidProvider.java
index 21ba5f0..824f953 100644
--- 
a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRUidProvider.java
+++ 
b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRUidProvider.java
@@ -24,12 +24,15 @@ import javax.jcr.Session;
 
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.jcr.MailboxSessionJCRRepository;
 import org.apache.james.mailbox.jcr.mail.model.JCRMailbox;
 import org.apache.james.mailbox.store.mail.AbstractLockingUidProvider;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 
+import com.google.common.base.Optional;
+
 public class JCRUidProvider extends AbstractLockingUidProvider {
 
     private final MailboxSessionJCRRepository repository;
@@ -40,11 +43,15 @@ public class JCRUidProvider extends 
AbstractLockingUidProvider {
     }
 
     @Override
-    public long lastUid(MailboxSession mailboxSession, Mailbox mailbox) throws 
MailboxException {
+    public Optional<MessageUid> lastUid(MailboxSession mailboxSession, Mailbox 
mailbox) throws MailboxException {
         try {
             Session s = repository.login(mailboxSession);
             Node node = 
s.getNodeByIdentifier(mailbox.getMailboxId().serialize());
-            return node.getProperty(JCRMailbox.LASTUID_PROPERTY).getLong();
+            long rawUid = 
node.getProperty(JCRMailbox.LASTUID_PROPERTY).getLong();
+            if (rawUid == 0) {
+                return Optional.absent();
+            }
+            return Optional.of(MessageUid.of(rawUid));
         } catch (RepositoryException e) {
             throw new MailboxException("Unable to get last uid for mailbox " + 
mailbox, e);
         }
@@ -52,15 +59,15 @@ public class JCRUidProvider extends 
AbstractLockingUidProvider {
     }
 
     @Override
-    protected long lockedNextUid(MailboxSession session, Mailbox mailbox) 
throws MailboxException {
+    protected MessageUid lockedNextUid(MailboxSession session, Mailbox 
mailbox) throws MailboxException {
         try {
             Session s = repository.login(session);
             Node node = 
s.getNodeByIdentifier(mailbox.getMailboxId().serialize());
-            long uid = node.getProperty(JCRMailbox.LASTUID_PROPERTY).getLong();
-            uid++;
-            node.setProperty(JCRMailbox.LASTUID_PROPERTY, uid);
+            MessageUid uid = 
MessageUid.of(node.getProperty(JCRMailbox.LASTUID_PROPERTY).getLong());
+            MessageUid nextUid = uid.next();
+            node.setProperty(JCRMailbox.LASTUID_PROPERTY, nextUid.asLong());
             s.save();
-            return uid;
+            return nextUid;
         } catch (RepositoryException e) {
             throw new MailboxException("Unable to consume next uid for mailbox 
" + mailbox, e);
         }

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailboxMessage.java
----------------------------------------------------------------------
diff --git 
a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailboxMessage.java
 
b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailboxMessage.java
index ec1bf07..32c0387 100644
--- 
a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailboxMessage.java
+++ 
b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/JCRMailboxMessage.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
 
@@ -38,6 +39,7 @@ import org.apache.commons.io.input.BoundedInputStream;
 import org.apache.commons.lang.NotImplementedException;
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.commons.JcrUtils;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.jcr.JCRId;
 import org.apache.james.mailbox.jcr.JCRImapConstants;
@@ -48,13 +50,13 @@ import 
org.apache.james.mailbox.store.mail.model.FlagsBuilder;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.MessageId;
 import org.apache.james.mailbox.store.mail.model.Property;
-import org.apache.james.mailbox.store.mail.model.impl.MessageUidComparator;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+import org.apache.james.mailbox.store.search.comparator.UidComparator;
 import org.slf4j.Logger;
 
 public class JCRMailboxMessage implements MailboxMessage, JCRImapConstants, 
Persistent {
 
-    private static final MessageUidComparator MESSAGE_UID_COMPARATOR = new 
MessageUidComparator();
+    private static final Comparator<MailboxMessage> MESSAGE_UID_COMPARATOR = 
new UidComparator();
     
     private Node node;
     private final Logger logger;
@@ -66,7 +68,7 @@ public class JCRMailboxMessage implements MailboxMessage, 
JCRImapConstants, Pers
     private int bodyStartOctet;
     
     private JCRId mailboxUUID;
-    private long uid;
+    private MessageUid uid;
     private Date internalDate;
     private long size;
     private boolean answered;
@@ -131,7 +133,7 @@ public class JCRMailboxMessage implements MailboxMessage, 
JCRImapConstants, Pers
     /**
      * Create a copy of the given message
      */
-    public JCRMailboxMessage(JCRId mailboxUUID, long uid, long modSeq, 
JCRMailboxMessage message, Logger logger) throws MailboxException {
+    public JCRMailboxMessage(JCRId mailboxUUID, MessageUid uid, long modSeq, 
JCRMailboxMessage message, Logger logger) throws MailboxException {
         this.mailboxUUID = mailboxUUID;
         this.internalDate = message.getInternalDate();
         this.size = message.getFullContentOctets();
@@ -275,7 +277,7 @@ public class JCRMailboxMessage implements MailboxMessage, 
JCRImapConstants, Pers
         if (isPersistent() == false) {
             node.setProperty(SIZE_PROPERTY, getFullContentOctets());
             node.setProperty(MAILBOX_UUID_PROPERTY, 
getMailboxId().serialize());
-            node.setProperty(UID_PROPERTY, getUid());
+            node.setProperty(UID_PROPERTY, getUid().asLong());
             node.setProperty(MODSEQ_PROPERTY, getModSeq());
 
             if (getInternalDate() == null) {
@@ -409,15 +411,15 @@ public class JCRMailboxMessage implements MailboxMessage, 
JCRImapConstants, Pers
 
 
     @Override
-    public long getUid() {
+    public MessageUid getUid() {
         if (isPersistent()) {
             try {
-                return node.getProperty(UID_PROPERTY).getLong();
+                return MessageUid.of(node.getProperty(UID_PROPERTY).getLong());
 
             } catch (RepositoryException e) {
                 logger.error("Unable to access property " + UID_PROPERTY, e);
             }
-            return 0;
+            return MessageUid.MIN_VALUE;
         }
         return uid;
     }
@@ -653,10 +655,10 @@ public class JCRMailboxMessage implements MailboxMessage, 
JCRImapConstants, Pers
     }
 
     @Override
-    public void setUid(long uid) {
+    public void setUid(MessageUid uid) {
         if (isPersistent()) {
             try {
-                node.setProperty(UID_PROPERTY, uid);
+                node.setProperty(UID_PROPERTY, uid.asLong());
             } catch (RepositoryException e) {
                 logger.error("Unable to set uid", e);
             }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to