james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From adup...@apache.org
Subject [02/11] james-project git commit: JAMES-1825 use a MessageUid strong type instead of long in the whole code base
Date Mon, 10 Oct 2016 10:34:20 GMT
http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
----------------------------------------------------------------------
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 c3a1e87..98a1848 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
@@ -35,6 +35,7 @@ import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.ImapSessionUtils;
 import org.apache.james.imap.api.display.HumanReadableText;
 import org.apache.james.imap.api.message.IdRange;
+import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.imap.api.message.request.DayMonthYear;
 import org.apache.james.imap.api.message.request.SearchKey;
 import org.apache.james.imap.api.message.request.SearchOperation;
@@ -52,6 +53,7 @@ import org.apache.james.mailbox.MailboxManager;
 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.exception.MailboxException;
 import org.apache.james.mailbox.exception.MessageRangeException;
 import org.apache.james.mailbox.model.FetchGroupImpl;
@@ -62,6 +64,8 @@ import org.apache.james.mailbox.model.SearchQuery.AddressType;
 import org.apache.james.mailbox.model.SearchQuery.Criterion;
 import org.apache.james.mailbox.model.SearchQuery.DateResolution;
 
+import com.google.common.base.Optional;
+
 public class SearchProcessor extends AbstractMailboxProcessor<SearchRequest> implements CapabilityImplementingProcessor {
 
     protected final static String SEARCH_MODSEQ = "SEARCH_MODSEQ";
@@ -71,14 +75,6 @@ public class SearchProcessor extends AbstractMailboxProcessor<SearchRequest> imp
         super(SearchRequest.class, next, mailboxManager, factory);
     }
 
-    /**
-     * @see
-     * org.apache.james.imap.processor.AbstractMailboxProcessor
-     * #doProcess(org.apache.james.imap.api.message.request.ImapRequest,
-     * org.apache.james.imap.api.process.ImapSession, java.lang.String,
-     * org.apache.james.imap.api.ImapCommand,
-     * org.apache.james.imap.api.process.ImapProcessor.Responder)
-     */
     protected void doProcess(SearchRequest request, ImapSession session, String tag, ImapCommand command, Responder responder) {
         final SearchOperation operation = request.getSearchOperation();
         final SearchKey searchKey = operation.getSearchKey();
@@ -91,24 +87,25 @@ public class SearchProcessor extends AbstractMailboxProcessor<SearchRequest> imp
 
             final SearchQuery query = toQuery(searchKey, session);
             MailboxSession msession = ImapSessionUtils.getMailboxSession(session);
-            final Iterator<Long> it = mailbox.search(query, msession);
+            final Iterator<MessageUid> it = mailbox.search(query, msession);
             
             final Collection<Long> results = new TreeSet<Long>();
-            final Collection<Long> uids = new TreeSet<Long>();
+            final Collection<MessageUid> uids = new TreeSet<MessageUid>();
             
             while (it.hasNext()) {
-                final long uid = it.next();
+                final MessageUid uid = it.next();
                 final Long number;
                 if (useUids) {
-                    number = uid;
+                    uids.add(uid);
+                    results.add(uid.asLong());
                 } else {
                     final int msn = session.getSelected().msn(uid);
                     number = (long) msn;
+                    if (number == SelectedMailbox.NO_SUCH_MESSAGE == false) {
+                        results.add(number);
+                    }
                 }
-                if (number == SelectedMailbox.NO_SUCH_MESSAGE == false)
-                    results.add(number);
                 
-                uids.add(uid);
             }
             
             // Check if the search did contain the MODSEQ searchkey. If so we need to include the highest mod in the response.
@@ -131,17 +128,22 @@ public class SearchProcessor extends AbstractMailboxProcessor<SearchRequest> imp
             if (resultOptions == null || resultOptions.isEmpty()) {
                 response = new SearchResponse(ids, highestModSeq);
             } else {
-                IdRange[] idRanges;
                 List<Long> idList = new ArrayList<Long>(ids.length);
                 for (long id : ids) {
                     idList.add(id);
                 }
-                List<MessageRange> ranges = MessageRange.toRanges(idList);
-                idRanges = new IdRange[ranges.size()];
-                for (int i = 0 ; i <ranges.size(); i++) {
-                    MessageRange range = ranges.get(i);
-                    idRanges[i] = new IdRange(range.getUidFrom(), range.getUidTo());
+                
+                List<IdRange> idsAsRanges = new ArrayList<IdRange>();
+                for (Long id: idList) {
+                    idsAsRanges.add(new IdRange(id));
                 }
+                IdRange[] idRanges = IdRange.mergeRanges(idsAsRanges).toArray(new IdRange[0]);
+                
+                List<UidRange> uidsAsRanges = new ArrayList<UidRange>();
+                for (MessageUid uid: uids) {
+                    uidsAsRanges.add(new UidRange(uid));
+                }
+                UidRange[] uidRanges = UidRange.mergeRanges(uidsAsRanges).toArray(new UidRange[0]);
                 
                 boolean esearch = false;
                 for (SearchResultOption resultOption : resultOptions) {
@@ -180,7 +182,7 @@ public class SearchProcessor extends AbstractMailboxProcessor<SearchRequest> imp
                             SearchResUtil.saveSequenceSet(session, savedRanges.toArray(new IdRange[0]));
                         }
                     }
-                    response = new ESearchResponse(min, max, count, idRanges, highestModSeq, tag, useUids, resultOptions);
+                    response = new ESearchResponse(min, max, count, idRanges, uidRanges, highestModSeq, tag, useUids, resultOptions);
                 } else {
                     // Just save the returned sequence-set as this is not SEARCHRES + ESEARCH
                     SearchResUtil.saveSequenceSet(session, idRanges);
@@ -331,7 +333,7 @@ public class SearchProcessor extends AbstractMailboxProcessor<SearchRequest> imp
             Criterion afterCrit = SearchQuery.headerDateAfter(ImapConstants.RFC822_DATE, date.toDate(), DateResolution.Day);
             return SearchQuery.or(onCrit, afterCrit);
         case SearchKey.TYPE_SEQUENCE_SET:
-            return sequence(key.getSequenceNumbers(), session, true);
+            return sequence(key.getSequenceNumbers(), session);
         case SearchKey.TYPE_SINCE:
             // Include the date which is used as search param. See IMAP-293
             return SearchQuery.or(SearchQuery.internalDateOn(date.toDate(), DateResolution.Day), SearchQuery.internalDateAfter(date.toDate(), DateResolution.Day));
@@ -344,7 +346,7 @@ public class SearchProcessor extends AbstractMailboxProcessor<SearchRequest> imp
         case SearchKey.TYPE_TO:
             return SearchQuery.address(AddressType.To, key.getValue());
         case SearchKey.TYPE_UID:
-            return sequence(key.getSequenceNumbers(), session, false);
+            return uids(key.getUidRanges(), session);
         case SearchKey.TYPE_UNANSWERED:
             return SearchQuery.flagIsUnSet(Flag.ANSWERED);
         case SearchKey.TYPE_UNDELETED:
@@ -379,81 +381,96 @@ public class SearchProcessor extends AbstractMailboxProcessor<SearchRequest> imp
     }
 
     /**
-     * Create a {@link Criterion} for the given sequence-sets. This include special handling which is needed for SEARCH to not return a BAD response on a invalid message-set. 
+     * Create a {@link Criterion} for the given sequence-sets. 
+     * This include special handling which is needed for SEARCH to not return a BAD response on a invalid message-set. 
      * See IMAP-292 for more details.
-     * 
-     * 
-     * @param sequenceNumbers
-     * @param session
-     * @param msn
-     * @return crit
-     * @throws MessageRangeException
      */
-    private Criterion sequence(IdRange[] sequenceNumbers, ImapSession session, boolean msn) throws MessageRangeException {
-        final List<SearchQuery.NumericRange> ranges = new ArrayList<SearchQuery.NumericRange>();
+    private Criterion sequence(IdRange[] sequenceNumbers, ImapSession session) throws MessageRangeException {
+        
         final SelectedMailbox selected = session.getSelected();
-        boolean useUids = !msn;
 
         // First of check if we have any messages in the mailbox
         // if not we don't need to go through all of this
+        final List<SearchQuery.UidRange> ranges = new ArrayList<SearchQuery.UidRange>();
         if (selected.existsCount() > 0) {
             for (IdRange range : sequenceNumbers) {
                 long lowVal = range.getLowVal();
                 long highVal = range.getHighVal();
-                if (useUids) {
-                    // Take care of "*" and "*:*" values by return the last
-                    // message in
-                    // the mailbox. See IMAP-289
-                    if (lowVal == Long.MAX_VALUE && highVal == Long.MAX_VALUE) {
-                        ranges.add(new SearchQuery.NumericRange(selected.getLastUid()));
-                    } else if (highVal == Long.MAX_VALUE && selected.getLastUid() < lowVal) {
-                        // Sequence uid ranges which use
-                        // *:<uid-higher-then-last-uid>
-                        // MUST return at least the highest uid in the mailbox
-                        // See IMAP-291
-                        ranges.add(new SearchQuery.NumericRange(selected.getLastUid()));
-                    } else {
-                        ranges.add(new SearchQuery.NumericRange(lowVal, highVal));
-                    }
-                } else {
-                    // Take care of "*" and "*:*" values by return the last
-                    // message in
-                    // the mailbox. See IMAP-289
-                    if (lowVal == Long.MAX_VALUE && highVal == Long.MAX_VALUE) {
-                        highVal = selected.getLastUid();
+                // Take care of "*" and "*:*" values by return the last
+                // message in
+                // the mailbox. See IMAP-289
+                if (lowVal == Long.MAX_VALUE && highVal == Long.MAX_VALUE) {
+                    MessageUid highUid = selected.getLastUid().or(MessageUid.MIN_VALUE);
 
-                        ranges.add(new SearchQuery.NumericRange(highVal));
+                    ranges.add(new SearchQuery.UidRange(highUid));
+                } else {
+                    Optional<MessageUid> lowUid;
+                    if (lowVal != Long.MIN_VALUE) {
+                        lowUid = selected.uid((int) lowVal);
                     } else {
-                        if (lowVal != Long.MIN_VALUE) {
-                            lowVal = selected.uid((int) lowVal);
-                        } else {
-                            lowVal = selected.getFirstUid();
-                        }
+                        lowUid = selected.getFirstUid();
+                    }
 
-                        // The lowVal should never be
-                        // SelectedMailbox.NO_SUCH_MESSAGE but we check for it
-                        // just to be safe
-                        if (lowVal != SelectedMailbox.NO_SUCH_MESSAGE) {
-                            if (highVal != Long.MAX_VALUE) {
-                                highVal = selected.uid((int) highVal);
-                                if (highVal == SelectedMailbox.NO_SUCH_MESSAGE) {
-                                    // we requested a message with a MSN higher
-                                    // then
-                                    // the current msg count. So just use the
-                                    // highest uid as max
-                                    highVal = selected.getLastUid();
-                                }
-                            } else {
-                                highVal = selected.getLastUid();
+                    // The lowVal should never be
+                    // SelectedMailbox.NO_SUCH_MESSAGE but we check for it
+                    // just to be safe
+                    if (lowUid.isPresent()) {
+                        Optional<MessageUid> highUid = Optional.absent();
+                        if (highVal != Long.MAX_VALUE) {
+                            highUid = selected.uid((int) highVal);
+                            if (!highUid.isPresent()) {
+                                // we requested a message with a MSN higher
+                                // then
+                                // the current msg count. So just use the
+                                // highest uid as max
+                                highUid = selected.getLastUid();
                             }
-                            ranges.add(new SearchQuery.NumericRange(lowVal, highVal));
+                        } else {
+                            highUid = selected.getLastUid();
                         }
+                        ranges.add(new SearchQuery.UidRange(lowUid.or(MessageUid.MIN_VALUE), highUid.or(MessageUid.MAX_VALUE)));
                     }
                 }
             }
         }
 
-        return SearchQuery.uid(ranges.toArray(new SearchQuery.NumericRange[0]));
+        return SearchQuery.uid(ranges.toArray(new SearchQuery.UidRange[0]));
+    }
+    
+    /**
+     * Create a {@link Criterion} for the given uid-sets. 
+     * This include special handling which is needed for SEARCH to not return a BAD response on a invalid message-set. 
+     * See IMAP-292 for more details.
+     */
+    private Criterion uids(UidRange[] uids, ImapSession session) throws MessageRangeException {
+        
+        final SelectedMailbox selected = session.getSelected();
+
+        // First of check if we have any messages in the mailbox
+        // if not we don't need to go through all of this
+        final List<SearchQuery.UidRange> ranges = new ArrayList<SearchQuery.UidRange>();
+        if (selected.existsCount() > 0) {
+            for (UidRange range : uids) {
+                MessageUid lowVal = range.getLowVal();
+                MessageUid highVal = range.getHighVal();
+                // Take care of "*" and "*:*" values by return the last
+                // message in
+                // the mailbox. See IMAP-289
+                if (lowVal.equals(MessageUid.MAX_VALUE) && highVal.equals(MessageUid.MAX_VALUE)) {
+                    ranges.add(new SearchQuery.UidRange(selected.getLastUid().or(MessageUid.MIN_VALUE)));
+                } else if (highVal.equals(MessageUid.MAX_VALUE) && selected.getLastUid().or(MessageUid.MIN_VALUE).compareTo(lowVal) < 0) {
+                    // Sequence uid ranges which use
+                    // *:<uid-higher-then-last-uid>
+                    // MUST return at least the highest uid in the mailbox
+                    // See IMAP-291
+                    ranges.add(new SearchQuery.UidRange(selected.getLastUid().or(MessageUid.MIN_VALUE)));
+                } else {
+                    ranges.add(new SearchQuery.UidRange(lowVal, highVal));
+                }
+            }
+        }
+
+        return SearchQuery.uid(ranges.toArray(new SearchQuery.UidRange[0]));
     }
 
     private Criterion or(List<SearchKey> keys, ImapSession session) throws MessageRangeException {

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
----------------------------------------------------------------------
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 2488270..34b7308 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
@@ -31,6 +31,7 @@ import org.apache.james.imap.message.response.MailboxStatusResponse;
 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.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.slf4j.Logger;
@@ -72,7 +73,7 @@ public class StatusProcessor extends AbstractMailboxProcessor<StatusRequest> {
 
             final Long messages = messages(statusDataItems, metaData);
             final Long recent = recent(statusDataItems, metaData);
-            final Long uidNext = uidNext(statusDataItems, metaData);
+            final MessageUid uidNext = uidNext(statusDataItems, metaData);
             final Long uidValidity = uidValidity(statusDataItems, metaData);
             final Long unseen = unseen(statusDataItems, metaData);
             final Long highestModSeq = highestModSeq(statusDataItems, metaData);
@@ -126,8 +127,8 @@ public class StatusProcessor extends AbstractMailboxProcessor<StatusRequest> {
     }
 
     
-    private Long uidNext(StatusDataItems statusDataItems, MessageManager.MetaData metaData) throws MailboxException {
-        final Long uidNext;
+    private MessageUid uidNext(StatusDataItems statusDataItems, MessageManager.MetaData metaData) throws MailboxException {
+        final MessageUid uidNext;
         if (statusDataItems.isUidNext()) {
             uidNext = metaData.getUidNext();
         } else {

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/main/java/org/apache/james/imap/processor/StoreProcessor.java
----------------------------------------------------------------------
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 efe162f..bc854a9 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
@@ -33,6 +33,7 @@ import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.ImapSessionUtils;
 import org.apache.james.imap.api.display.HumanReadableText;
 import org.apache.james.imap.api.message.IdRange;
+import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.imap.api.message.response.StatusResponse;
 import org.apache.james.imap.api.message.response.StatusResponse.ResponseCode;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
@@ -46,6 +47,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.MessageManager.MetaData.FetchGroup;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MessageRangeException;
 import org.apache.james.mailbox.model.MessageRange;
@@ -106,7 +108,8 @@ public class StoreProcessor extends AbstractMailboxProcessor<StoreRequest> {
                 }
               
             } 
-            final List<Long> failed = new ArrayList<Long>();
+            final List<MessageUid> failed = new ArrayList<MessageUid>();
+            List<Long> failedMsns = new ArrayList<Long>();
             final List<String> userFlags = Arrays.asList(flags.getUserFlags());
             for (IdRange range : idSet) {
                 final SelectedMailbox selected = session.getSelected();
@@ -117,12 +120,12 @@ public class StoreProcessor extends AbstractMailboxProcessor<StoreRequest> {
                         // Ok we have a CONDSTORE option so use the CONDSTORE_COMMAND
                         imapCommand = CONDSTORE_COMMAND;
 
-                        List<Long> uids = new ArrayList<Long>();
+                        List<MessageUid> uids = new ArrayList<MessageUid>();
 
                         MessageResultIterator results = mailbox.getMessages(messageSet, FetchGroupImpl.MINIMAL, mailboxSession);
                         while (results.hasNext()) {
                             MessageResult r = results.next();
-                            long uid = r.getUid();
+                            MessageUid uid = r.getUid();
 
                             boolean fail = false;
 
@@ -152,7 +155,7 @@ public class StoreProcessor extends AbstractMailboxProcessor<StoreRequest> {
                                 if (useUids) {
                                     failed.add(uid);
                                 } else {
-                                    failed.add((long) selected.msn(uid));
+                                    failedMsns.add((long)selected.msn(uid));
                                 }
                             }
                         }
@@ -172,27 +175,36 @@ public class StoreProcessor extends AbstractMailboxProcessor<StoreRequest> {
             unsolicitedResponses(session, responder, omitExpunged, useUids);
             
             // check if we had some failed uids which didn't pass the UNCHANGEDSINCE filter
-            if (failed.isEmpty()) {
+            if (failed.isEmpty() && failedMsns.isEmpty()) {
                 okComplete(imapCommand, tag, responder);
             } else {
-                // Convert the MessageRanges to an array of IdRange. 
-                // TODO: Maybe this should get moved in an util class
-                List<MessageRange> ranges = MessageRange.toRanges(failed);
-                IdRange[] idRanges = new IdRange[ranges.size()];
-                for (int i = 0 ; i < ranges.size(); i++) {
-                    MessageRange r = ranges.get(i);
-                    if (r.getType() == Type.ONE) {
-                        idRanges[i] = new IdRange(r.getUidFrom());
-                    } else {
-                        idRanges[i] = new IdRange(r.getUidFrom(), r.getUidTo());
+                if (useUids) {
+                    List<MessageRange> ranges = MessageRange.toRanges(failed);
+                    UidRange[] idRanges = new UidRange[ranges.size()];
+                    for (int i = 0 ; i < ranges.size(); i++) {
+                        MessageRange r = ranges.get(i);
+                        if (r.getType() == Type.ONE) {
+                            idRanges[i] = new UidRange(r.getUidFrom());
+                        } else {
+                            idRanges[i] = new UidRange(r.getUidFrom(), r.getUidTo());
+                        }
+                    }
+                    // we need to return the failed sequences
+                    //
+                    // See RFC4551 3.2. STORE and UID STORE Commands
+                    final StatusResponse response = getStatusResponseFactory().taggedOk(tag, command, HumanReadableText.FAILED, ResponseCode.condStore(idRanges));
+                    responder.respond(response);
+                } else {
+                    List<IdRange> ranges = new ArrayList<IdRange>();
+                    for (long msn: failedMsns) {
+                        ranges.add(new IdRange(msn));
                     }
+                    IdRange[] failedRanges = IdRange.mergeRanges(ranges).toArray(new IdRange[0]);
+                    // See RFC4551 3.2. STORE and UID STORE Commands
+                    final StatusResponse response = getStatusResponseFactory().taggedOk(tag, command, HumanReadableText.FAILED, ResponseCode.condStore(failedRanges));
+                    responder.respond(response);
+                    
                 }
-                // we need to return the failed sequences
-                //
-                // See RFC4551 3.2. STORE and UID STORE Commands
-                final StatusResponse response = getStatusResponseFactory().taggedOk(tag, command, HumanReadableText.FAILED, ResponseCode.condStore(idRanges));
-                responder.respond(response);
-               
             }
         } catch (MessageRangeException e) {
             if (session.getLog().isDebugEnabled()) {
@@ -238,7 +250,7 @@ public class StoreProcessor extends AbstractMailboxProcessor<StoreRequest> {
         }
         
         SelectedMailbox selected = session.getSelected();
-        final Map<Long, Flags> flagsByUid = mailbox.setFlags(flags, mode, messageSet, mailboxSession);
+        final Map<MessageUid, Flags> flagsByUid = mailbox.setFlags(flags, mode, messageSet, mailboxSession);
         // As the STORE command is allowed to create a new "flag/keyword", we need to send a FLAGS and PERMANENTFLAGS response before the FETCH response
         // if some new flag/keyword was used
         // See IMAP-303
@@ -253,7 +265,7 @@ public class StoreProcessor extends AbstractMailboxProcessor<StoreRequest> {
         boolean condstoreEnabled = enabled.contains(ImapConstants.SUPPORTS_CONDSTORE);
         
         if (!silent || unchangedSince != -1 || qresyncEnabled || condstoreEnabled) {
-            final Map<Long, Long> modSeqs = new HashMap<Long, Long>();
+            final Map<MessageUid, Long> modSeqs = new HashMap<MessageUid, Long>();
            
             // Check if we need to also send the the mod-sequences back to the client
             //
@@ -271,8 +283,8 @@ public class StoreProcessor extends AbstractMailboxProcessor<StoreRequest> {
                 }
             }
             
-            for (Map.Entry<Long, Flags> entry : flagsByUid.entrySet()) {
-                final long uid = entry.getKey();
+            for (Map.Entry<MessageUid, Flags> entry : flagsByUid.entrySet()) {
+                final MessageUid uid = entry.getKey();
                 final int msn = selected.msn(uid);
 
                 if (msn == SelectedMailbox.NO_SUCH_MESSAGE) {
@@ -287,7 +299,7 @@ public class StoreProcessor extends AbstractMailboxProcessor<StoreRequest> {
                 }
 
                 final Flags resultFlags = entry.getValue();
-                final Long resultUid;
+                final MessageUid resultUid;
                 
                 // Check if we need to include the uid. T
                 //

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
index f9a14a5..a59e5d1 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/base/SelectedMailboxImpl.java
@@ -38,6 +38,7 @@ import org.apache.james.imap.api.process.SelectedMailbox;
 import org.apache.james.mailbox.MailboxListener;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.FetchGroupImpl;
 import org.apache.james.mailbox.model.MailboxPath;
@@ -46,12 +47,14 @@ import org.apache.james.mailbox.model.MessageResult;
 import org.apache.james.mailbox.model.MessageResultIterator;
 import org.apache.james.mailbox.model.UpdatedFlags;
 
+import com.google.common.base.Optional;
+
 /**
  * Default implementation of {@link SelectedMailbox}
  */
 public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener{
 
-    private final Set<Long> recentUids = new TreeSet<Long>();
+    private final Set<MessageUid> recentUids = new TreeSet<MessageUid>();
 
     private boolean recentUidRemoved = false;
 
@@ -72,9 +75,9 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener{
     }
     
     private final long sessionId;
-    private final Set<Long> flagUpdateUids = new TreeSet<Long>();
+    private final Set<MessageUid> flagUpdateUids = new TreeSet<MessageUid>();
     private final Flags.Flag uninterestingFlag = Flags.Flag.RECENT;
-    private final Set<Long> expungedUids = new TreeSet<Long>();
+    private final Set<MessageUid> expungedUids = new TreeSet<MessageUid>();
 
     private boolean isDeletedByOtherSession = false;
     private boolean sizeChanged = false;
@@ -83,11 +86,11 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener{
 
     private boolean applicableFlagsChanged;
     
-    private final SortedMap<Integer, Long> msnToUid =new TreeMap<Integer, Long>();
+    private final SortedMap<Integer, MessageUid> msnToUid =new TreeMap<Integer, MessageUid>();
 
-    private final SortedMap<Long, Integer> uidToMsn = new TreeMap<Long, Integer>();
+    private final SortedMap<MessageUid, Integer> uidToMsn = new TreeMap<MessageUid, Integer>();
 
-    private long highestUid = 0;
+    private MessageUid highestUid = MessageUid.MIN_VALUE;
 
     private int highestMsn = 0;
     
@@ -132,8 +135,8 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener{
        
     }
 
-    private void add(int msn, long uid) {
-        if (uid > highestUid) {
+    private void add(int msn, MessageUid uid) {
+        if (uid.compareTo(highestUid) > 0) {
             highestUid = uid;
         }
         msnToUid.put(msn, uid);
@@ -142,23 +145,23 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener{
 
     /**
      * Expunge the message with the given uid
-     * 
-     * @param uid
      */
-    private void expunge(long uid) {
+    private void expunge(MessageUid uid) {
         final int msn = msn(uid);
         remove(msn, uid);
         final List<Integer> renumberMsns = new ArrayList<Integer>(msnToUid.tailMap(msn + 1).keySet());
         for (Integer msnInteger : renumberMsns) {
             int aMsn = msnInteger.intValue();
-            long aUid = uid(aMsn);
-            remove(aMsn, aUid);
-            add(aMsn - 1, aUid);
+            Optional<MessageUid> aUid = uid(aMsn);
+            if (aUid.isPresent()) {
+                remove(aMsn, aUid.get());
+                add(aMsn - 1, aUid.get());
+            }
         }
         highestMsn--;
     }
 
-    private void remove(int msn, long uid) {
+    private void remove(int msn, MessageUid uid) {
         uidToMsn.remove(uid);
         msnToUid.remove(msn);
     }
@@ -168,37 +171,28 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener{
      * 
      * @param uid
      */
-    private void add(long uid) {
+    private void add(MessageUid uid) {
         if (!uidToMsn.containsKey(uid)) {
             highestMsn++;
             add(highestMsn, uid);
         }
     }
 
-    /**
-     * @see org.apache.james.mailbox.MailboxListener#event(org.apache.james.mailbox.MailboxListener.Event)
-     */
-
-
-    /**
-     * @see SelectedMailbox#getFirstUid()
-     */
-    public synchronized long getFirstUid() {
+    @Override
+    public synchronized Optional<MessageUid> getFirstUid() {
         if (uidToMsn.isEmpty()) {
-            return -1;
+            return Optional.absent();
         } else {
-            return uidToMsn.firstKey();
+            return Optional.of(uidToMsn.firstKey());
         }
     }
 
-    /**
-     * @see SelectedMailbox#getLastUid()
-     */
-    public synchronized long getLastUid() {
+    @Override
+    public synchronized Optional<MessageUid> getLastUid() {
         if (uidToMsn.isEmpty()) {
-            return -1;
+            return Optional.absent();
         } else {
-            return uidToMsn.lastKey();
+            return Optional.of(uidToMsn.lastKey());
         }
     }
 
@@ -225,11 +219,8 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener{
 
     }
 
-    /**
-     * @see org.apache.james.imap.api.process.SelectedMailbox#removeRecent(long)
-     */
-    
-    public synchronized  boolean removeRecent(long uid) {
+    @Override
+    public synchronized  boolean removeRecent(MessageUid uid) {
         final boolean result = recentUids.remove(uid);
         if (result) {
             recentUidRemoved = true;
@@ -237,74 +228,50 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener{
         return result;
     }
 
-    /**
-     * @see org.apache.james.imap.api.process.SelectedMailbox#addRecent(long)
-     */
-    public synchronized boolean addRecent(long uid) {
+    @Override
+    public synchronized boolean addRecent(MessageUid uid) {
         return recentUids.add(uid);
     }
 
-    /**
-     * @see org.apache.james.imap.api.process.SelectedMailbox#getRecent()
-     */
-    
-    public synchronized Collection<Long> getRecent() {
+    @Override
+    public synchronized Collection<MessageUid> getRecent() {
         checkExpungedRecents();
-        return new ArrayList<Long>(recentUids);
+        return new ArrayList<MessageUid>(recentUids);
     }
 
-    /**
-     * @see org.apache.james.imap.api.process.SelectedMailbox#recentCount()
-     */
-    
+    @Override
     public synchronized int recentCount() {
         checkExpungedRecents();
         return recentUids.size();
     }
 
-    /**
-     * @see org.apache.james.imap.api.process.SelectedMailbox#getPath()
-     */
-    
+    @Override
     public synchronized MailboxPath getPath() {
         return path;
     }
 
     private void checkExpungedRecents() {
-        for (long uid : expungedUids()) {
+        for (MessageUid uid : expungedUids()) {
             removeRecent(uid);
         }
     }
 
-    /**
-     * @see org.apache.james.imap.api.process.SelectedMailbox#isRecent(long)
-     */
-    
-    public synchronized boolean isRecent(long uid) {
+    @Override
+    public synchronized boolean isRecent(MessageUid uid) {
         return recentUids.contains(uid);
     }
 
-    /**
-     * @see
-     * org.apache.james.imap.api.process.SelectedMailbox#isRecentUidRemoved()
-     */
-    
+    @Override
     public synchronized boolean isRecentUidRemoved() {
         return recentUidRemoved;
     }
 
-    /**
-     * @see
-     * org.apache.james.imap.api.process.SelectedMailbox#resetRecentUidRemoved()
-     */
-    
+    @Override
     public synchronized void resetRecentUidRemoved() {
         recentUidRemoved = false;
     }
 
-    /**
-     * @see org.apache.james.imap.api.process.SelectedMailbox#resetEvents()
-     */
+    @Override
     public synchronized void resetEvents() {
         sizeChanged = false;
         flagUpdateUids.clear();
@@ -312,12 +279,8 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener{
         applicableFlagsChanged = false;
     }
 
-    /**
-     * @see
-     * org.apache.james.imap.api.process.SelectedMailbox#remove(java.lang.Long)
-     */
-    
-    public synchronized  int remove(Long uid) {
+    @Override
+    public synchronized  int remove(MessageUid uid) {
         final int result = msn(uid);
         expunge(uid);
         return result;
@@ -396,29 +359,22 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener{
 
     /**
      * Return a unmodifiable {@link Collection} of uids which have updated flags
-     * 
-     * @return uids
      */
-    
-    public synchronized Collection<Long> flagUpdateUids() {
+    @Override
+    public synchronized Collection<MessageUid> flagUpdateUids() {
         // copy the TreeSet to fix possible
         // java.util.ConcurrentModificationException
         // See IMAP-278
-        return Collections.unmodifiableSet(new TreeSet<Long>(flagUpdateUids));
+        return Collections.unmodifiableSet(new TreeSet<MessageUid>(flagUpdateUids));
         
     }
 
-    /**
-     * Return a unmodifiable {@link Collection} of uids that where expunged
-     * 
-     * @return uids
-     */
-    
-    public synchronized Collection<Long> expungedUids() {
+    @Override
+    public synchronized Collection<MessageUid> expungedUids() {
         // copy the TreeSet to fix possible
         // java.util.ConcurrentModificationException
         // See IMAP-278
-        return Collections.unmodifiableSet(new TreeSet<Long>(expungedUids));
+        return Collections.unmodifiableSet(new TreeSet<MessageUid>(expungedUids));
         
     }
 
@@ -448,11 +404,10 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener{
             final long eventSessionId = event.getSession().getSessionId();
             if (event instanceof MessageEvent) {
                 final MessageEvent messageEvent = (MessageEvent) event;
-                // final List<Long> uids = messageEvent.getUids();
                 if (messageEvent instanceof Added) {
                     sizeChanged = true;
-                    final List<Long> uids = ((Added) event).getUids();
-                    for (Long uid : uids) {
+                    final List<MessageUid> uids = ((Added) event).getUids();
+                    for (MessageUid uid : uids) {
                         add(uid);
                     }
                 } else if (messageEvent instanceof FlagsUpdated) {
@@ -523,8 +478,8 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener{
         }
     }
 
-    
-    public synchronized int msn(long uid) {
+    @Override
+    public synchronized int msn(MessageUid uid) {
         Integer msn = uidToMsn.get(uid);
         if (msn != null) {
             return msn.intValue();
@@ -533,16 +488,16 @@ public class SelectedMailboxImpl implements SelectedMailbox, MailboxListener{
         }
     }
 
-    
-    public synchronized long uid(int msn) {
+    @Override
+    public synchronized Optional<MessageUid> uid(int msn) {
         if (msn == -1) {
-            return SelectedMailbox.NO_SUCH_MESSAGE;
+            return Optional.absent();
         }
-        Long uid = msnToUid.get(msn);
+        MessageUid uid = msnToUid.get(msn);
         if (uid != null) {
-            return uid.longValue();
+            return Optional.of(uid);
         } else {
-            return SelectedMailbox.NO_SUCH_MESSAGE;
+            return Optional.absent();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java
----------------------------------------------------------------------
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 55d6a71..d9f1fe5 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
@@ -39,6 +39,7 @@ import org.apache.james.imap.api.process.SelectedMailbox;
 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.exception.MailboxException;
 import org.apache.james.mailbox.exception.MessageRangeException;
 import org.apache.james.mailbox.model.Content;
@@ -51,7 +52,7 @@ public final class FetchResponseBuilder {
 
     private int msn;
 
-    private Long uid;
+    private MessageUid uid;
 
     private Flags flags;
 
@@ -86,8 +87,8 @@ public final class FetchResponseBuilder {
         modSeq = null;
     }
 
-    public void setUid(long uid) {
-        this.uid = uid;
+    public void setUid(MessageUid resultUid) {
+        this.uid = resultUid;
     }
 
     private void setModSeq(long modSeq) {
@@ -105,7 +106,7 @@ public final class FetchResponseBuilder {
 
     public FetchResponse build(FetchData fetch, MessageResult result, MessageManager mailbox, ImapSession session, boolean useUids) throws MessageRangeException, MailboxException {
         final SelectedMailbox selected = session.getSelected();
-        final long resultUid = result.getUid();
+        final MessageUid resultUid = result.getUid();
         final int resultMsn = selected.msn(resultUid);
 
         if (resultMsn == SelectedMailbox.NO_SUCH_MESSAGE)

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/test/java/org/apache/james/imap/api/message/UidRangeTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/api/message/UidRangeTest.java b/protocols/imap/src/test/java/org/apache/james/imap/api/message/UidRangeTest.java
new file mode 100644
index 0000000..06d400d
--- /dev/null
+++ b/protocols/imap/src/test/java/org/apache/james/imap/api/message/UidRangeTest.java
@@ -0,0 +1,184 @@
+/****************************************************************
+ * 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.imap.api.message;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.List;
+
+import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.model.MessageRange;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import com.google.common.collect.ImmutableList;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class UidRangeTest {
+
+    @Rule public ExpectedException exception = ExpectedException.none();
+    
+    private static final MessageUid _1 = MessageUid.of(1);
+    private static final MessageUid _2 = MessageUid.of(2);
+    private static final MessageUid _3 = MessageUid.of(3);
+    private static final MessageUid _4 = MessageUid.of(4);
+    private static final MessageUid _5 = MessageUid.of(5);
+    private static final MessageUid _10 = MessageUid.of(10);
+
+    @Test
+    public void singleArgConstructorShouldBuildSingletonRange() {
+        assertThat(new UidRange(_1)).containsOnly(_1);
+    }
+
+    @Test
+    public void lowBoundArgShouldBeGreaterThanHighBound() {
+        exception.expect(IllegalArgumentException.class);
+        new UidRange(_2, _1);
+    }
+    
+    @Test
+    public void identicalLowBoundAndHighBoundShouldBuildASingleton() {
+        assertThat(new UidRange(_2, _2)).hasSize(1);
+    }
+
+    
+    @Test
+    public void regularRangeShouldBuild() {
+        assertThat(new UidRange(_1, _2)).hasSize(2);
+    }
+
+    @Test
+    public void includesShouldReturnFalseWhenSmallerValue() {
+        assertThat(new UidRange(_2, _3).includes(_1)).isFalse();
+    }
+
+    @Test
+    public void includesShouldReturnFalseWhenGreaterValue() {
+        assertThat(new UidRange(_2, _3).includes(_4)).isFalse();
+    }
+
+    @Test
+    public void includesShouldReturnTrueWhenLowBoundValue() {
+        assertThat(new UidRange(_2, _3).includes(_2)).isTrue();
+    }
+
+    @Test
+    public void includesShouldReturnTrueWhenHighBoundValue() {
+        assertThat(new UidRange(_2, _3).includes(_3)).isTrue();
+    }
+
+    @Test
+    public void includesShouldReturnTrueWhenInRange() {
+        assertThat(new UidRange(_2, _4).includes(_3)).isTrue();
+    }
+    
+    @Test
+    public void shouldRespectBeanContract() {
+        EqualsVerifier.forClass(UidRange.class).verify();
+    }
+    
+    @Test
+    public void toMessageRangeShouldContainSameValues() {
+        assertThat(new UidRange(_1, _4).toMessageRange()).isEqualTo(MessageRange.range(_1, _4));
+    }
+    
+    @Test
+    public void formattedStringShouldUseImapRangeNotationForRange() {
+        assertThat(new UidRange(_1, _3).getFormattedString()).isEqualTo("1:3");
+    }
+    
+    @Test
+    public void formattedStringShouldUseImapRangeNotationForSingleton() {
+        assertThat(new UidRange(_2).getFormattedString()).isEqualTo("2");
+    }
+
+    @Test
+    public void shouldBeIterable() {
+        assertThat(new UidRange(_1, _4)).containsExactly(_1, _2, _3, _4);
+    }
+    
+    @Test
+    public void mergeZeroRangeShouldOutputZeroRange() {
+        assertThat(UidRange.mergeRanges(ImmutableList.<UidRange>of())).isEmpty();
+    }
+
+    @Test
+    public void mergeSingleRangeShouldOutputSameRange() {
+        List<UidRange> actual = UidRange.mergeRanges(ImmutableList.of(new UidRange(_1, _4)));
+        assertThat(actual).containsOnly(new UidRange(_1, _4));
+    }
+
+    @Test
+    public void mergeContiguousRangeShouldOutputMergedRange() {
+        List<UidRange> actual = UidRange
+                .mergeRanges(
+                        ImmutableList.of(
+                                new UidRange(_1, _2),
+                                new UidRange(_3, _4)));
+        assertThat(actual).containsOnly(new UidRange(_1, _4));
+    }
+    
+
+    @Test
+    public void mergeContiguousRangesShouldOutputMergedRange() {
+        List<UidRange> actual = UidRange
+                .mergeRanges(
+                        ImmutableList.of(
+                                new UidRange(_1, _2),
+                                new UidRange(_1, _5),
+                                new UidRange(_3, _4),
+                                new UidRange(_2, _10)));
+        assertThat(actual).containsOnly(new UidRange(_1, _10));
+    }
+    
+    @Test
+    public void mergeOverlappingRangeShouldOutputMergedRange() {
+        List<UidRange> actual = UidRange
+                .mergeRanges(
+                        ImmutableList.of(
+                                new UidRange(_1, _3),
+                                new UidRange(_3, _4)));
+        assertThat(actual).containsOnly(new UidRange(_1, _4));
+    }
+    
+    @Test
+    public void mergeShouldNotMergeRangeWithDistanceGreaterThen1() {
+        List<UidRange> actual = UidRange
+                .mergeRanges(
+                        ImmutableList.of(
+                                new UidRange(_1, _2),
+                                new UidRange(_4, _5)));
+        assertThat(actual).containsOnly(new UidRange(_1, _2), new UidRange(_4, _5));
+    }
+    
+
+    @Test
+    public void mergeShouldMergeRangeWhenOverlappingRangesAreNotSorted() {
+        List<UidRange> actual = UidRange
+                .mergeRanges(
+                        ImmutableList.of(
+                                new UidRange(_1, _2),
+                                new UidRange(_5, _10),
+                                new UidRange(_2, _3)));
+        assertThat(actual).containsOnly(new UidRange(_1, _3), new UidRange(_5, _10));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserAndParenthesesTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserAndParenthesesTest.java b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserAndParenthesesTest.java
index 9e79d2a..2e5bb38 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserAndParenthesesTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserAndParenthesesTest.java
@@ -31,10 +31,12 @@ import java.util.List;
 import org.apache.james.imap.api.ImapCommand;
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.message.IdRange;
+import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.imap.api.message.request.DayMonthYear;
 import org.apache.james.imap.api.message.request.SearchKey;
 import org.apache.james.imap.decode.ImapRequestLineReader;
 import org.apache.james.imap.decode.ImapRequestStreamLineReader;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.protocols.imap.DecodingException;
 import org.jmock.Mockery;
 import org.jmock.integration.junit4.JMock;
@@ -78,9 +80,13 @@ public class SearchCommandParserAndParenthesesTest {
     }
 
     public static Input uid() {
-        IdRange[] range = { new IdRange(100, Long.MAX_VALUE), new IdRange(110),
-                new IdRange(200, 201), new IdRange(400, Long.MAX_VALUE) };
-        SearchKey key = SearchKey.buildUidSet(IdRange.mergeRanges(Arrays.asList(range)).toArray(new IdRange[0]));
+        UidRange[] range = { 
+                new UidRange(MessageUid.of(100), MessageUid.MAX_VALUE), 
+                new UidRange(MessageUid.of(110)),
+                new UidRange(MessageUid.of(200), MessageUid.of(201)), 
+                new UidRange(MessageUid.of(400), MessageUid.MAX_VALUE) 
+                };
+        SearchKey key = SearchKey.buildUidSet(UidRange.mergeRanges(Arrays.asList(range)).toArray(new UidRange[0]));
         return new Input("UID *:100,110,200:201,400:*", key);
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserNotTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserNotTest.java b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserNotTest.java
index c83aeb2..891dc71 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserNotTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserNotTest.java
@@ -29,10 +29,12 @@ import java.util.List;
 import org.apache.james.imap.api.ImapCommand;
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.message.IdRange;
+import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.imap.api.message.request.DayMonthYear;
 import org.apache.james.imap.api.message.request.SearchKey;
 import org.apache.james.imap.decode.ImapRequestLineReader;
 import org.apache.james.imap.decode.ImapRequestStreamLineReader;
+import org.apache.james.mailbox.MessageUid;
 import org.jmock.Mockery;
 import org.jmock.integration.junit4.JMock;
 import org.jmock.integration.junit4.JUnit4Mockery;
@@ -69,9 +71,13 @@ public class SearchCommandParserNotTest {
 
     @Test
     public void testShouldParseNotUid() throws Exception {
-        IdRange[] range = { new IdRange(100, Long.MAX_VALUE), new IdRange(110),
-                new IdRange(200, 201), new IdRange(400, Long.MAX_VALUE) };
-        SearchKey notdKey = SearchKey.buildUidSet(IdRange.mergeRanges(Arrays.asList(range)).toArray(new IdRange[0]));
+        UidRange[] range = { 
+                new UidRange(MessageUid.of(100), MessageUid.MAX_VALUE), 
+                new UidRange(MessageUid.of(110)),
+                new UidRange(MessageUid.of(200), MessageUid.of(201)), 
+                new UidRange(MessageUid.of(400), MessageUid.MAX_VALUE) 
+                };
+        SearchKey notdKey = SearchKey.buildUidSet(UidRange.mergeRanges(Arrays.asList(range)).toArray(new UidRange[0]));
         SearchKey key = SearchKey.buildNot(notdKey);
         checkValid("NOT UID *:100,110,200:201,400:*\r\n", key);
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserOrTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserOrTest.java b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserOrTest.java
index de073d3..b7eeb03 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserOrTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserOrTest.java
@@ -28,10 +28,12 @@ import java.util.Arrays;
 import org.apache.james.imap.api.ImapCommand;
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.message.IdRange;
+import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.imap.api.message.request.DayMonthYear;
 import org.apache.james.imap.api.message.request.SearchKey;
 import org.apache.james.imap.decode.ImapRequestLineReader;
 import org.apache.james.imap.decode.ImapRequestStreamLineReader;
+import org.apache.james.mailbox.MessageUid;
 import org.jmock.Mockery;
 import org.jmock.integration.junit4.JMock;
 import org.jmock.integration.junit4.JUnit4Mockery;
@@ -64,9 +66,13 @@ public class SearchCommandParserOrTest {
     }
 
     public Input uid() {
-        IdRange[] range = { new IdRange(100, Long.MAX_VALUE), new IdRange(110),
-                new IdRange(200, 201), new IdRange(400, Long.MAX_VALUE) };
-        SearchKey key = SearchKey.buildUidSet(IdRange.mergeRanges(Arrays.asList(range)).toArray(new IdRange[0]));
+        UidRange[] range = { 
+                new UidRange(MessageUid.of(100), MessageUid.MAX_VALUE), 
+                new UidRange(MessageUid.of(110)),
+                new UidRange(MessageUid.of(200), MessageUid.of(201)), 
+                new UidRange(MessageUid.of(400), MessageUid.MAX_VALUE) 
+                };
+        SearchKey key = SearchKey.buildUidSet(UidRange.mergeRanges(Arrays.asList(range)).toArray(new UidRange[0]));
         return new Input("UID *:100,110,200:201,400:*", key);
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserSearchKeySequenceSetTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserSearchKeySequenceSetTest.java b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserSearchKeySequenceSetTest.java
index 004f1b8..44a4d1f 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserSearchKeySequenceSetTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserSearchKeySequenceSetTest.java
@@ -28,9 +28,11 @@ import java.util.Arrays;
 import org.apache.james.imap.api.ImapCommand;
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.message.IdRange;
+import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.imap.api.message.request.SearchKey;
 import org.apache.james.imap.decode.ImapRequestLineReader;
 import org.apache.james.imap.decode.ImapRequestStreamLineReader;
+import org.apache.james.mailbox.MessageUid;
 import org.jmock.Mockery;
 import org.jmock.integration.junit4.JMock;
 import org.jmock.integration.junit4.JUnit4Mockery;
@@ -58,35 +60,72 @@ public class SearchCommandParserSearchKeySequenceSetTest {
     }
     
     @Test
-    public void testAllNumbers() throws Exception {
+    public void testAllNumbersSequence() throws Exception {
 
         IdRange[] range = { new IdRange(2), new IdRange(4), new IdRange(9),
                 new IdRange(16), new IdRange(25), new IdRange(36),
                 new IdRange(49), new IdRange(64), new IdRange(81),
                 new IdRange(100) };
-        check("2,4,9,16,25,36,49,64,81,100", IdRange.mergeRanges(Arrays.asList(range)).toArray(new IdRange[0]));
+        checkSequence("2,4,9,16,25,36,49,64,81,100", IdRange.mergeRanges(Arrays.asList(range)).toArray(new IdRange[0]));
     }
 
     @Test
-    public void testEndStar() throws Exception {
+    public void testEndStarSequence() throws Exception {
         IdRange[] range = { new IdRange(8), new IdRange(10,11),
                 new IdRange(17), new IdRange(100, Long.MAX_VALUE) };
-        check("8,10:11,17,100:*", IdRange.mergeRanges(Arrays.asList(range)).toArray(new IdRange[0]));
+        checkSequence("8,10:11,17,100:*", IdRange.mergeRanges(Arrays.asList(range)).toArray(new IdRange[0]));
     }
 
     @Test
-    public void testStartStar() throws Exception {
-        IdRange[] range = { new IdRange(9,Long.MAX_VALUE), new IdRange(15),
-                new IdRange(799, 820) };
-        check("*:9,15,799:820", IdRange.mergeRanges(Arrays.asList(range)).toArray(new IdRange[0]));
+    public void testStartStarSequence() throws Exception {
+        IdRange[] range = { 
+                new IdRange(9,Long.MAX_VALUE), 
+                new IdRange(15),
+                new IdRange(799, 820) 
+                };
+        checkSequence("*:9,15,799:820", IdRange.mergeRanges(Arrays.asList(range)).toArray(new IdRange[0]));
     }
 
-    private void check(String sequence, IdRange[] range) throws Exception {
-        checkUid(sequence, range);
-        checkSequence(sequence, range);
+
+    @Test
+    public void testAllNumbersUids() throws Exception {
+
+        UidRange[] range = { 
+                new UidRange(MessageUid.of(2)),
+                new UidRange(MessageUid.of(4)),
+                new UidRange(MessageUid.of(9)),
+                new UidRange(MessageUid.of(16)), 
+                new UidRange(MessageUid.of(25)), 
+                new UidRange(MessageUid.of(36)),
+                new UidRange(MessageUid.of(49)), 
+                new UidRange(MessageUid.of(64)), 
+                new UidRange(MessageUid.of(81)),
+                new UidRange(MessageUid.of(100)) };
+        checkUid("2,4,9,16,25,36,49,64,81,100", UidRange.mergeRanges(Arrays.asList(range)).toArray(new UidRange[0]));
+    }
+
+    @Test
+    public void testEndStarUids() throws Exception {
+        UidRange[] range = { 
+                new UidRange(MessageUid.of(8)), 
+                new UidRange(MessageUid.of(10),MessageUid.of(11)),
+                new UidRange(MessageUid.of(17)), 
+                new UidRange(MessageUid.of(100), MessageUid.MAX_VALUE) };
+        checkUid("8,10:11,17,100:*", UidRange.mergeRanges(Arrays.asList(range)).toArray(new UidRange[0]));
     }
 
-    private void checkUid(String sequence, IdRange[] range) throws Exception {
+    @Test
+    public void testStartStarUids() throws Exception {
+        UidRange[] range = { 
+                new UidRange(MessageUid.of(9), MessageUid.MAX_VALUE), 
+                new UidRange(MessageUid.of(15)),
+                new UidRange(MessageUid.of(799), MessageUid.of(820)) 
+                };
+        checkUid("*:9,15,799:820", UidRange.mergeRanges(Arrays.asList(range)).toArray(new UidRange[0]));
+    }
+
+    
+    private void checkUid(String sequence, UidRange[] range) throws Exception {
         SearchKey key = SearchKey.buildUidSet(range);
         checkValid("UID " + sequence, key);
         checkValid("uid " + sequence, key);

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserSearchKeyTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserSearchKeyTest.java b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserSearchKeyTest.java
index 5f3fd3e..8536640 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserSearchKeyTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserSearchKeyTest.java
@@ -27,10 +27,12 @@ import java.io.ByteArrayOutputStream;
 import org.apache.james.imap.api.ImapCommand;
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.message.IdRange;
+import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.imap.api.message.request.DayMonthYear;
 import org.apache.james.imap.api.message.request.SearchKey;
 import org.apache.james.imap.decode.ImapRequestLineReader;
 import org.apache.james.imap.decode.ImapRequestStreamLineReader;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.protocols.imap.DecodingException;
 import org.jmock.Mockery;
 import org.jmock.integration.junit4.JMock;
@@ -670,7 +672,7 @@ public class SearchCommandParserSearchKeyTest {
 
     @Test
     public void testShouldParseUid() throws Exception {
-        IdRange[] range = { new IdRange(1) };
+        UidRange[] range = { new UidRange(MessageUid.of(1)) };
         SearchKey key = SearchKey.buildUidSet(range);
         checkValid("UID 1\r\n", key);
         checkValid("Uid 1\r\n", key);

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserTopLevelAndTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserTopLevelAndTest.java b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserTopLevelAndTest.java
index 355138c..f8f8957 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserTopLevelAndTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SearchCommandParserTopLevelAndTest.java
@@ -31,10 +31,12 @@ import java.util.List;
 import org.apache.james.imap.api.ImapCommand;
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.message.IdRange;
+import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.imap.api.message.request.DayMonthYear;
 import org.apache.james.imap.api.message.request.SearchKey;
 import org.apache.james.imap.decode.ImapRequestLineReader;
 import org.apache.james.imap.decode.ImapRequestStreamLineReader;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.protocols.imap.DecodingException;
 import org.jmock.Mockery;
 import org.jmock.integration.junit4.JMock;
@@ -63,9 +65,13 @@ public class SearchCommandParserTopLevelAndTest {
     }
 
     public static Input uid() {
-        IdRange[] range = { new IdRange(100, Long.MAX_VALUE), new IdRange(110),
-                new IdRange(200, 201), new IdRange(400, Long.MAX_VALUE) };
-        SearchKey key = SearchKey.buildUidSet(IdRange.mergeRanges(Arrays.asList(range)).toArray(new IdRange[0]));
+        UidRange[] range = { 
+                new UidRange(MessageUid.of(100), MessageUid.MAX_VALUE), 
+                new UidRange(MessageUid.of(110)),
+                new UidRange(MessageUid.of(200), MessageUid.of(201)), 
+                new UidRange(MessageUid.of(400), MessageUid.MAX_VALUE) 
+                };
+        SearchKey key = SearchKey.buildUidSet(UidRange.mergeRanges(Arrays.asList(range)).toArray(new UidRange[0]));
         return new Input("UID *:100,110,200:201,400:*", key);
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderNoExtensionsTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderNoExtensionsTest.java b/protocols/imap/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderNoExtensionsTest.java
index 408c361..860d4cc 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderNoExtensionsTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderNoExtensionsTest.java
@@ -35,6 +35,7 @@ import org.apache.james.imap.encode.ImapResponseComposer;
 import org.apache.james.imap.encode.base.ByteImapResponseWriter;
 import org.apache.james.imap.encode.base.ImapResponseComposerImpl;
 import org.apache.james.imap.message.response.FetchResponse;
+import org.apache.james.mailbox.MessageUid;
 import org.jmock.Expectations;
 import org.jmock.Mockery;
 import org.jmock.integration.junit4.JMock;
@@ -87,7 +88,7 @@ public class FetchResponseEncoderNoExtensionsTest  {
 
     @Test
     public void testShouldEncodeUidResponse() throws Exception {
-        FetchResponse message = new FetchResponse(100, null, new Long(72), null,
+        FetchResponse message = new FetchResponse(100, null, MessageUid.of(72), null,
                 null, null, null, null, null, null);
         encoder.doEncode(message, composer, new FakeImapSession());
         assertEquals("* 100 FETCH (UID 72)\r\n", writer.getString());
@@ -96,7 +97,7 @@ public class FetchResponseEncoderNoExtensionsTest  {
 
     @Test
     public void testShouldEncodeAllResponse() throws Exception {
-        FetchResponse message = new FetchResponse(100, flags, new Long(72), null,
+        FetchResponse message = new FetchResponse(100, flags, MessageUid.of(72), null,
                 null, null, null, null, null, null);
         encoder.doEncode(message, composer, new FakeImapSession());
         assertEquals("* 100 FETCH (FLAGS (\\Deleted) UID 72)\r\n",writer.getString());
@@ -105,7 +106,7 @@ public class FetchResponseEncoderNoExtensionsTest  {
     
     @Test
     public void testShouldNotAddExtensionsWithEncodingBodyStructure() throws Exception {
-        FetchResponse message = new FetchResponse(100, flags, new Long(72), null,
+        FetchResponse message = new FetchResponse(100, flags, MessageUid.of(72), null,
                 null, null, null, null, stubStructure, null);
         final Map<String, String> parameters = new HashMap<String, String>();
         parameters.put("CHARSET", "US-ASCII");

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java b/protocols/imap/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java
index 893f5d7..185d9fb 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java
@@ -29,6 +29,7 @@ import org.apache.james.imap.encode.ImapResponseComposer;
 import org.apache.james.imap.encode.base.ByteImapResponseWriter;
 import org.apache.james.imap.encode.base.ImapResponseComposerImpl;
 import org.apache.james.imap.message.response.FetchResponse;
+import org.apache.james.mailbox.MessageUid;
 import org.jmock.Mockery;
 import org.jmock.integration.junit4.JMock;
 import org.jmock.integration.junit4.JUnit4Mockery;
@@ -79,7 +80,7 @@ public class FetchResponseEncoderTest  {
 
     @Test
     public void testShouldEncodeUidResponse() throws Exception {
-        FetchResponse message = new FetchResponse(100, null, new Long(72), null,
+        FetchResponse message = new FetchResponse(100, null, MessageUid.of(72), null,
                 null, null, null, null, null, null); 
         encoder.doEncode(message, composer, new FakeImapSession());
         assertEquals("* 100 FETCH (UID 72)\r\n", writer.getString());
@@ -89,7 +90,7 @@ public class FetchResponseEncoderTest  {
 
     @Test
     public void testShouldEncodeAllResponse() throws Exception {
-        FetchResponse message = new FetchResponse(100, flags, new Long(72), null,
+        FetchResponse message = new FetchResponse(100, flags, MessageUid.of(72), null,
                 null, null, null, null, null, null);
         encoder.doEncode(message, composer, new FakeImapSession());
         assertEquals("* 100 FETCH (FLAGS (\\Deleted) UID 72)\r\n", writer.getString());

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/test/java/org/apache/james/imap/encode/MailboxStatusResponseEncoderTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/encode/MailboxStatusResponseEncoderTest.java b/protocols/imap/src/test/java/org/apache/james/imap/encode/MailboxStatusResponseEncoderTest.java
index e7f78bf..d5e4e72 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/encode/MailboxStatusResponseEncoderTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/encode/MailboxStatusResponseEncoderTest.java
@@ -28,6 +28,7 @@ import org.apache.james.imap.encode.MailboxStatusResponseEncoder;
 import org.apache.james.imap.encode.base.ByteImapResponseWriter;
 import org.apache.james.imap.encode.base.ImapResponseComposerImpl;
 import org.apache.james.imap.message.response.MailboxStatusResponse;
+import org.apache.james.mailbox.MessageUid;
 import org.jmock.Mockery;
 import org.jmock.integration.junit4.JMock;
 import org.jmock.integration.junit4.JUnit4Mockery;
@@ -66,7 +67,7 @@ public class MailboxStatusResponseEncoderTest  {
     public void testDoEncode() throws Exception {
         final Long messages = new Long(2);
         final Long recent = new Long(3);
-        final Long uidNext = new Long(5);
+        final MessageUid uidNext = MessageUid.of(5);
         final Long uidValidity = new Long(7);
         final Long unseen = new Long(11);
         final String mailbox = "A mailbox named desire";

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/test/java/org/apache/james/imap/processor/CopyProcessorTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/processor/CopyProcessorTest.java b/protocols/imap/src/test/java/org/apache/james/imap/processor/CopyProcessorTest.java
index bacef9d..d381b07 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/processor/CopyProcessorTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/processor/CopyProcessorTest.java
@@ -41,6 +41,7 @@ import org.apache.james.imap.message.request.MoveRequest;
 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.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageRange;
@@ -50,6 +51,7 @@ import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
 
 public class CopyProcessorTest {
@@ -91,17 +93,17 @@ public class CopyProcessorTest {
         MailboxPath inbox = MailboxPath.inbox(mockMailboxSession);
         MailboxPath selected = new MailboxPath(inbox, "selected");
         SelectedMailbox selectedMailbox = mock(SelectedMailbox.class);
-        when(selectedMailbox.getLastUid()).thenReturn(8L);
+        when(selectedMailbox.getLastUid()).thenReturn(Optional.of(MessageUid.of(8)));
         when(selectedMailbox.existsCount()).thenReturn(8L);
         when(selectedMailbox.getPath()).thenReturn(selected);
         when(mockImapSession.getSelected()).thenReturn(selectedMailbox);
         when(mockMailboxManager.mailboxExists(inbox, mockMailboxSession)).thenReturn(true);
         MessageManager targetMessageManager = mock(MessageManager.class);
         when(mockMailboxManager.getMailbox(inbox, mockMailboxSession)).thenReturn(targetMessageManager);
-        when(targetMessageManager.getMetaData(false, mockMailboxSession, MessageManager.MetaData.FetchGroup.NO_UNSEEN)).thenReturn(new MailboxMetaData(null, null, 58L, 18L, 8L, 8L, 8L, 8L, true, true, null));
+        when(targetMessageManager.getMetaData(false, mockMailboxSession, MessageManager.MetaData.FetchGroup.NO_UNSEEN)).thenReturn(new MailboxMetaData(null, null, 58L, MessageUid.of(18), 8L, 8L, 8L, MessageUid.of(8), true, true, null));
         StatusResponse okResponse = mock(StatusResponse.class);
         when(mockStatusResponseFactory.taggedOk(any(String.class), any(ImapCommand.class), any(HumanReadableText.class), any(StatusResponse.ResponseCode.class))).thenReturn(okResponse);
-        when(mockMailboxManager.moveMessages(MessageRange.range(4, 6), selected, inbox, mockMailboxSession)).thenReturn(Lists.<MessageRange>newArrayList(MessageRange.range(4, 6)));
+        when(mockMailboxManager.moveMessages(MessageRange.range(MessageUid.of(4), MessageUid.of(6)), selected, inbox, mockMailboxSession)).thenReturn(Lists.<MessageRange>newArrayList(MessageRange.range(MessageUid.of(4), MessageUid.of(6))));
 
         testee.process(copyRequest, mockResponder, mockImapSession);
 
@@ -109,7 +111,7 @@ public class CopyProcessorTest {
         verify(mockMailboxManager).endProcessingRequest(mockMailboxSession);
         verify(mockMailboxManager).mailboxExists(inbox, mockMailboxSession);
         verify(mockMailboxManager).getMailbox(inbox, mockMailboxSession);
-        verify(mockMailboxManager).copyMessages(MessageRange.range(4, 6), selected, inbox, mockMailboxSession);
+        verify(mockMailboxManager).copyMessages(MessageRange.range(MessageUid.of(4), MessageUid.of(6)), selected, inbox, mockMailboxSession);
         verify(targetMessageManager).getMetaData(false, mockMailboxSession, MessageManager.MetaData.FetchGroup.NO_UNSEEN);
         verify(mockResponder).respond(okResponse);
         verifyNoMoreInteractions(mockMailboxManager, targetMessageManager, mockResponder, mockNextProcessor);
@@ -130,14 +132,14 @@ public class CopyProcessorTest {
         MailboxPath inbox = MailboxPath.inbox(mockMailboxSession);
         MailboxPath selected = new MailboxPath(inbox, "selected");
         SelectedMailbox selectedMailbox = mock(SelectedMailbox.class);
-        when(selectedMailbox.getLastUid()).thenReturn(8L);
+        when(selectedMailbox.getLastUid()).thenReturn(Optional.of(MessageUid.of(8)));
         when(selectedMailbox.existsCount()).thenReturn(8L);
         when(selectedMailbox.getPath()).thenReturn(selected);
         when(mockImapSession.getSelected()).thenReturn(selectedMailbox);
         when(mockMailboxManager.mailboxExists(inbox, mockMailboxSession)).thenReturn(true);
         MessageManager targetMessageManager = mock(MessageManager.class);
         when(mockMailboxManager.getMailbox(inbox, mockMailboxSession)).thenReturn(targetMessageManager);
-        when(targetMessageManager.getMetaData(false, mockMailboxSession, MessageManager.MetaData.FetchGroup.NO_UNSEEN)).thenReturn(new MailboxMetaData(null, null, 58L, 18L, 8L, 8L, 8L, 8L, true, true, null));
+        when(targetMessageManager.getMetaData(false, mockMailboxSession, MessageManager.MetaData.FetchGroup.NO_UNSEEN)).thenReturn(new MailboxMetaData(null, null, 58L, MessageUid.of(18), 8L, 8L, 8L, MessageUid.of(8), true, true, null));
         StatusResponse okResponse = mock(StatusResponse.class);
         when(mockStatusResponseFactory.taggedOk(any(String.class), any(ImapCommand.class), any(HumanReadableText.class), any(StatusResponse.ResponseCode.class))).thenReturn(okResponse);
 
@@ -147,8 +149,8 @@ public class CopyProcessorTest {
         verify(mockMailboxManager).endProcessingRequest(mockMailboxSession);
         verify(mockMailboxManager).mailboxExists(inbox, mockMailboxSession);
         verify(mockMailboxManager).getMailbox(inbox, mockMailboxSession);
-        verify(mockMailboxManager).copyMessages(MessageRange.range(5, 6), selected, inbox, mockMailboxSession);
-        verify(mockMailboxManager).copyMessages(MessageRange.range(1, 3), selected, inbox, mockMailboxSession);
+        verify(mockMailboxManager).copyMessages(MessageRange.range(MessageUid.of(5), MessageUid.of(6)), selected, inbox, mockMailboxSession);
+        verify(mockMailboxManager).copyMessages(MessageRange.range(MessageUid.of(1), MessageUid.of(3)), selected, inbox, mockMailboxSession);
         verify(targetMessageManager).getMetaData(false, mockMailboxSession, MessageManager.MetaData.FetchGroup.NO_UNSEEN);
         verify(mockResponder).respond(okResponse);
         verifyNoMoreInteractions(mockMailboxManager, targetMessageManager, mockResponder, mockNextProcessor);
@@ -168,7 +170,7 @@ public class CopyProcessorTest {
         MailboxPath inbox = MailboxPath.inbox(mockMailboxSession);
         MailboxPath selected = new MailboxPath(inbox, "selected");
         SelectedMailbox selectedMailbox = mock(SelectedMailbox.class);
-        when(selectedMailbox.getLastUid()).thenReturn(8L);
+        when(selectedMailbox.getLastUid()).thenReturn(Optional.of(MessageUid.of(8)));
         when(selectedMailbox.existsCount()).thenReturn(8L);
         when(selectedMailbox.getPath()).thenReturn(selected);
         when(mockImapSession.getSelected()).thenReturn(selectedMailbox);
@@ -201,7 +203,7 @@ public class CopyProcessorTest {
         MailboxPath inbox = MailboxPath.inbox(mockMailboxSession);
         MailboxPath selected = new MailboxPath(inbox, "selected");
         SelectedMailbox selectedMailbox = mock(SelectedMailbox.class);
-        when(selectedMailbox.getLastUid()).thenReturn(8L);
+        when(selectedMailbox.getLastUid()).thenReturn(Optional.of(MessageUid.of(8)));
         when(selectedMailbox.existsCount()).thenReturn(8L);
         when(selectedMailbox.getPath()).thenReturn(selected);
         when(mockImapSession.getSelected()).thenReturn(selectedMailbox);

http://git-wip-us.apache.org/repos/asf/james-project/blob/34242a5b/protocols/imap/src/test/java/org/apache/james/imap/processor/MoveProcessorTest.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/processor/MoveProcessorTest.java b/protocols/imap/src/test/java/org/apache/james/imap/processor/MoveProcessorTest.java
index 7bc14b6..82ea4ef 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/processor/MoveProcessorTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/processor/MoveProcessorTest.java
@@ -44,6 +44,7 @@ import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxManager.MailboxCapabilities;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageRange;
@@ -53,6 +54,7 @@ import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
 
 public class MoveProcessorTest {
@@ -107,17 +109,19 @@ public class MoveProcessorTest {
         MailboxPath inbox = MailboxPath.inbox(mockMailboxSession);
         MailboxPath selected = new MailboxPath(inbox, "selected");
         SelectedMailbox selectedMailbox = mock(SelectedMailbox.class);
-        when(selectedMailbox.getLastUid()).thenReturn(8L);
+        when(selectedMailbox.getLastUid()).thenReturn(Optional.of(MessageUid.of(8)));
         when(selectedMailbox.existsCount()).thenReturn(8L);
         when(selectedMailbox.getPath()).thenReturn(selected);
         when(mockImapSession.getSelected()).thenReturn(selectedMailbox);
         when(mockMailboxManager.mailboxExists(inbox, mockMailboxSession)).thenReturn(true);
         MessageManager targetMessageManager = mock(MessageManager.class);
         when(mockMailboxManager.getMailbox(inbox, mockMailboxSession)).thenReturn(targetMessageManager);
-        when(targetMessageManager.getMetaData(false, mockMailboxSession, MessageManager.MetaData.FetchGroup.NO_UNSEEN)).thenReturn(new MailboxMetaData(null, null, 58L, 18L, 8L, 8L, 8L, 8L, true, true, null));
+        when(targetMessageManager.getMetaData(false, mockMailboxSession, MessageManager.MetaData.FetchGroup.NO_UNSEEN))
+            .thenReturn(new MailboxMetaData(null, null, 58L, MessageUid.of(18), 8L, 8L, 8L, MessageUid.of(8), true, true, null));
         StatusResponse okResponse = mock(StatusResponse.class);
         when(mockStatusResponseFactory.taggedOk(any(String.class), any(ImapCommand.class), any(HumanReadableText.class), any(StatusResponse.ResponseCode.class))).thenReturn(okResponse);
-        when(mockMailboxManager.moveMessages(MessageRange.range(4, 6), selected, inbox, mockMailboxSession)).thenReturn(Lists.<MessageRange>newArrayList(MessageRange.range(4, 6)));
+        when(mockMailboxManager.moveMessages(MessageRange.range(MessageUid.of(4), MessageUid.of(6)), selected, inbox, mockMailboxSession))
+            .thenReturn(Lists.<MessageRange>newArrayList(MessageRange.range(MessageUid.of(4), MessageUid.of(6))));
 
         testee.process(moveRequest, mockResponder, mockImapSession);
 
@@ -125,7 +129,7 @@ public class MoveProcessorTest {
         verify(mockMailboxManager).endProcessingRequest(mockMailboxSession);
         verify(mockMailboxManager).mailboxExists(inbox, mockMailboxSession);
         verify(mockMailboxManager).getMailbox(inbox, mockMailboxSession);
-        verify(mockMailboxManager).moveMessages(MessageRange.range(4, 6), selected, inbox, mockMailboxSession);
+        verify(mockMailboxManager).moveMessages(MessageRange.range(MessageUid.of(4), MessageUid.of(6)), selected, inbox, mockMailboxSession);
         verify(targetMessageManager).getMetaData(false, mockMailboxSession, MessageManager.MetaData.FetchGroup.NO_UNSEEN);
         verify(mockResponder).respond(okResponse);
         verifyNoMoreInteractions(mockMailboxManager, targetMessageManager, mockResponder, mockNextProcessor);
@@ -146,14 +150,15 @@ public class MoveProcessorTest {
         MailboxPath inbox = MailboxPath.inbox(mockMailboxSession);
         MailboxPath selected = new MailboxPath(inbox, "selected");
         SelectedMailbox selectedMailbox = mock(SelectedMailbox.class);
-        when(selectedMailbox.getLastUid()).thenReturn(8L);
+        when(selectedMailbox.getLastUid()).thenReturn(Optional.of(MessageUid.of(8)));
         when(selectedMailbox.existsCount()).thenReturn(8L);
         when(selectedMailbox.getPath()).thenReturn(selected);
         when(mockImapSession.getSelected()).thenReturn(selectedMailbox);
         when(mockMailboxManager.mailboxExists(inbox, mockMailboxSession)).thenReturn(true);
         MessageManager targetMessageManager = mock(MessageManager.class);
         when(mockMailboxManager.getMailbox(inbox, mockMailboxSession)).thenReturn(targetMessageManager);
-        when(targetMessageManager.getMetaData(false, mockMailboxSession, MessageManager.MetaData.FetchGroup.NO_UNSEEN)).thenReturn(new MailboxMetaData(null, null, 58L, 18L, 8L, 8L, 8L, 8L, true, true, null));
+        when(targetMessageManager.getMetaData(false, mockMailboxSession, MessageManager.MetaData.FetchGroup.NO_UNSEEN))
+            .thenReturn(new MailboxMetaData(null, null, 58L, MessageUid.of(18), 8L, 8L, 8L, MessageUid.of(8), true, true, null));
         StatusResponse okResponse = mock(StatusResponse.class);
         when(mockStatusResponseFactory.taggedOk(any(String.class), any(ImapCommand.class), any(HumanReadableText.class), any(StatusResponse.ResponseCode.class))).thenReturn(okResponse);
 
@@ -163,8 +168,8 @@ public class MoveProcessorTest {
         verify(mockMailboxManager).endProcessingRequest(mockMailboxSession);
         verify(mockMailboxManager).mailboxExists(inbox, mockMailboxSession);
         verify(mockMailboxManager).getMailbox(inbox, mockMailboxSession);
-        verify(mockMailboxManager).moveMessages(MessageRange.range(5, 6), selected, inbox, mockMailboxSession);
-        verify(mockMailboxManager).moveMessages(MessageRange.range(1, 3), selected, inbox, mockMailboxSession);
+        verify(mockMailboxManager).moveMessages(MessageRange.range(MessageUid.of(5), MessageUid.of(6)), selected, inbox, mockMailboxSession);
+        verify(mockMailboxManager).moveMessages(MessageRange.range(MessageUid.of(1), MessageUid.of(3)), selected, inbox, mockMailboxSession);
         verify(targetMessageManager).getMetaData(false, mockMailboxSession, MessageManager.MetaData.FetchGroup.NO_UNSEEN);
         verify(mockResponder).respond(okResponse);
         verifyNoMoreInteractions(mockMailboxManager, targetMessageManager, mockResponder, mockNextProcessor);
@@ -184,7 +189,7 @@ public class MoveProcessorTest {
         MailboxPath inbox = MailboxPath.inbox(mockMailboxSession);
         MailboxPath selected = new MailboxPath(inbox, "selected");
         SelectedMailbox selectedMailbox = mock(SelectedMailbox.class);
-        when(selectedMailbox.getLastUid()).thenReturn(8L);
+        when(selectedMailbox.getLastUid()).thenReturn(Optional.of(MessageUid.of(8)));
         when(selectedMailbox.existsCount()).thenReturn(8L);
         when(selectedMailbox.getPath()).thenReturn(selected);
         when(mockImapSession.getSelected()).thenReturn(selectedMailbox);
@@ -217,7 +222,7 @@ public class MoveProcessorTest {
         MailboxPath inbox = MailboxPath.inbox(mockMailboxSession);
         MailboxPath selected = new MailboxPath(inbox, "selected");
         SelectedMailbox selectedMailbox = mock(SelectedMailbox.class);
-        when(selectedMailbox.getLastUid()).thenReturn(8L);
+        when(selectedMailbox.getLastUid()).thenReturn(Optional.of(MessageUid.of(8)));
         when(selectedMailbox.existsCount()).thenReturn(8L);
         when(selectedMailbox.getPath()).thenReturn(selected);
         when(mockImapSession.getSelected()).thenReturn(selectedMailbox);


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


Mime
View raw message