Index: maildir/src/test/java/org/apache/james/imap/functional/maildir/MaildirHostSystem.java
===================================================================
--- maildir/src/test/java/org/apache/james/imap/functional/maildir/MaildirHostSystem.java	(Revision 986087)
+++ maildir/src/test/java/org/apache/james/imap/functional/maildir/MaildirHostSystem.java	(Arbeitskopie)
@@ -71,6 +71,7 @@
         } catch (Exception e) {
         	e.printStackTrace();
         }
+
     }
     
     public void resetUserMetaData() throws Exception {
Index: maildir/src/main/java/org/apache/james/imap/maildir/mail/MaildirMessageMapper.java
===================================================================
--- maildir/src/main/java/org/apache/james/imap/maildir/mail/MaildirMessageMapper.java	(Revision 986733)
+++ maildir/src/main/java/org/apache/james/imap/maildir/mail/MaildirMessageMapper.java	(Arbeitskopie)
@@ -26,8 +26,6 @@
 import java.io.InputStream;
 import java.io.PushbackInputStream;
 import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.SortedMap;
 import java.util.Map.Entry;
@@ -38,19 +36,14 @@
 import org.apache.james.imap.api.display.HumanReadableText;
 import org.apache.james.imap.mailbox.MailboxException;
 import org.apache.james.imap.mailbox.MessageRange;
-import org.apache.james.imap.mailbox.SearchQuery;
 import org.apache.james.imap.mailbox.StorageException;
 import org.apache.james.imap.mailbox.MessageRange.Type;
-import org.apache.james.imap.mailbox.SearchQuery.Criterion;
-import org.apache.james.imap.mailbox.SearchQuery.NumericRange;
 import org.apache.james.imap.maildir.MaildirFolder;
 import org.apache.james.imap.maildir.MaildirMessageName;
 import org.apache.james.imap.maildir.MaildirStore;
-import org.apache.james.imap.maildir.UidConstraint;
 import org.apache.james.imap.maildir.mail.model.MaildirHeader;
 import org.apache.james.imap.maildir.mail.model.MaildirMessage;
-import org.apache.james.imap.store.SearchQueryIterator;
-import org.apache.james.imap.store.mail.MessageMapper;
+import org.apache.james.imap.store.AbstractMessageMapper;
 import org.apache.james.imap.store.mail.model.Header;
 import org.apache.james.imap.store.mail.model.Mailbox;
 import org.apache.james.imap.store.mail.model.MailboxMembership;
@@ -62,7 +55,7 @@
 import org.apache.james.mime4j.parser.MimeEntityConfig;
 import org.apache.james.mime4j.parser.MimeTokenStream;
 
-public class MaildirMessageMapper implements MessageMapper<Integer> {
+public class MaildirMessageMapper extends AbstractMessageMapper<Integer> {
 
     private final MaildirStore maildirStore;
     private final int BUF_SIZE = 2048;
@@ -75,7 +68,7 @@
      * (non-Javadoc)
      * @see org.apache.james.imap.store.mail.MessageMapper#copy(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.store.mail.model.MailboxMembership)
      */
-    public MailboxMembership<Integer> copy(Mailbox<Integer> mailbox, MailboxMembership<Integer> original)
+    public long copy(Mailbox<Integer> mailbox, MailboxMembership<Integer> original)
     throws StorageException {
         MaildirMessage theCopy;
         try {
@@ -83,8 +76,7 @@
         } catch (MailboxException e) {
             throw new StorageException(HumanReadableText.FAILURE_MAIL_PARSE, e);
         }
-        theCopy.setUid(save(mailbox, theCopy));
-        return theCopy;
+        return save(mailbox, theCopy);
     }
 
     /* 
@@ -121,11 +113,12 @@
         return count;
     }
 
-    /* 
+
+    /*
      * (non-Javadoc)
-     * @see org.apache.james.imap.store.mail.MessageMapper#delete(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.store.mail.model.MailboxMembership)
+     * @see org.apache.james.imap.store.AbstractMessageMapper#delete(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.store.mail.model.MailboxMembership)
      */
-    public void delete(Mailbox<Integer> mailbox, MailboxMembership<Integer> message) throws StorageException {
+    protected void delete(Mailbox<Integer> mailbox, MailboxMembership<Integer> message) throws StorageException {
         MaildirFolder folder = maildirStore.createMaildirFolder(mailbox);
         try {
             folder.delete(message.getUid());
@@ -257,16 +250,16 @@
         return messages;
     }
 
-    /* 
+    /*
      * (non-Javadoc)
-     * @see org.apache.james.imap.store.mail.MessageMapper#findRecentMessagesInMailbox(org.apache.james.imap.store.mail.model.Mailbox, int)
+     * @see org.apache.james.imap.store.AbstractMessageMapper#findRecentMessagesInMailbox(org.apache.james.imap.store.mail.model.Mailbox)
      */
-    public List<MailboxMembership<Integer>> findRecentMessagesInMailbox(Mailbox<Integer> mailbox, int limit)
+    protected List<MailboxMembership<Integer>> findRecentMessagesInMailbox(Mailbox<Integer> mailbox)
     throws StorageException {
         MaildirFolder folder = maildirStore.createMaildirFolder(mailbox);
         SortedMap<Long, MaildirMessageName> recentMessageNames;
         try {
-            recentMessageNames = folder.getRecentMessages(limit);
+            recentMessageNames = folder.getRecentMessages(-1);
         } catch (IOException e) {
             throw new StorageException(HumanReadableText.SEARCH_FAILED, e);
         }
@@ -380,61 +373,7 @@
     }
 
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.james.imap.store.mail.MessageMapper#searchMailbox(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.mailbox.SearchQuery)
-     */
-    public Iterator<Long> searchMailbox(Mailbox<Integer> mailbox, SearchQuery query)
-    throws StorageException {
-        final List<Criterion> criteria = query.getCriterias();
-        boolean range = false;
-        int rangeLength = -1;
-        UidConstraint constraint = new UidConstraint();
-        
-        if (criteria.size() == 1) {
-            final Criterion firstCriterion = criteria.get(0);
-            if (firstCriterion instanceof SearchQuery.UidCriterion) {
-                final SearchQuery.UidCriterion uidCriterion = (SearchQuery.UidCriterion) firstCriterion;
-                final NumericRange[] ranges = uidCriterion.getOperator().getRange();
-                rangeLength = ranges.length;
-
-                for (int i = 0; i < ranges.length; i++) {
-                    final long low = ranges[i].getLowValue();
-                    final long high = ranges[i].getHighValue();
-
-                    if (low == Long.MAX_VALUE) {
-                        constraint.lessOrEquals(high);
-                        range = true;
-                    } else if (low == high) {
-                        constraint.equals(low);
-                        range = false;
-                    } else {
-                        constraint.between(low, high);
-                        range = true;
-                    }
-                }
-            }
-        }
-        MaildirFolder folder = maildirStore.createMaildirFolder(mailbox);
-        SortedMap<Long, MaildirMessageName> uidMap;
-        try {
-            uidMap = folder.getUidMap(0, -1);
-        } catch (IOException e) {
-            throw new StorageException(HumanReadableText.SEARCH_FAILED, e);
-        }
-        LinkedList<MailboxMembership<?>> messages = new LinkedList<MailboxMembership<?>>();
-        for (Entry<Long, MaildirMessageName> entry : uidMap.entrySet()) {
-            //System.out.println("check " + entry.getKey());
-            if (constraint.isAllowed(entry.getKey())) {
-                //System.out.println("allow " + entry.getKey());
-                messages.add(loadMessage(mailbox, entry.getValue(), entry.getKey()));
-                // Check if we only need to fetch 1 message, if so we can set a limit to speed up things
-                if (rangeLength == 1 && range == false) break;
-            }
-        }
-        return new SearchQueryIterator(messages.iterator(), query);
-    }
-
+   
     /* 
      * (non-Javadoc)
      * @see org.apache.james.imap.store.transaction.TransactionalMapper#endRequest()
@@ -648,4 +587,22 @@
         return bodyStartOctet;
     }
 
+    @Override
+    protected void begin() throws MailboxException {
+        // nothing todo
+        
+    }
+
+    @Override
+    protected void commit() throws MailboxException {
+        // nothing todo
+        
+    }
+
+    @Override
+    protected void rollback() throws MailboxException {
+        // nothing todo
+        
+    }
+
 }
Index: store/src/main/java/org/apache/james/imap/store/mail/MessageMapper.java
===================================================================
--- store/src/main/java/org/apache/james/imap/store/mail/MessageMapper.java	(Revision 984773)
+++ store/src/main/java/org/apache/james/imap/store/mail/MessageMapper.java	(Arbeitskopie)
@@ -48,14 +48,14 @@
             throws StorageException;
 
     /**
-     * Return a List of {@link MailboxMembership} for the given {@link MessageRange} which are marked for deletion
+     * Return a List of message uids for the given {@link MessageRange} which was marked for deletion and was delete
      * The list must be ordered by the {@link Document} uid
      * @param mailbox
      * @param set 
      * @return list
      * @throws StorageException
      */
-    public abstract List<MailboxMembership<Id>> findMarkedForDeletionInMailbox(
+    public abstract List<Long> deleteMarkedInMailbox(
             Mailbox<Id> mailbox, final MessageRange set)
             throws StorageException;
 
@@ -89,16 +89,8 @@
      */
     public abstract Iterator<Long> searchMailbox(Mailbox<Id> mailbox, SearchQuery query) throws StorageException;
 
+   
     /**
-     * Delete the given {@link MailboxMembership}
-     * 
-     * @param mailbox
-     * @param message
-     * @throws StorageException
-     */
-    public abstract void delete(Mailbox<Id> mailbox, MailboxMembership<Id> message) throws StorageException;
-
-    /**
      * Return the uid of the first unseen message. If non can be found null will get returned
      * 
      * 
@@ -109,17 +101,16 @@
     public abstract Long findFirstUnseenMessageUid(Mailbox<Id> mailbox) throws StorageException;
 
     /**
-     * Return a List of {@link MailboxMembership} which are recent.
+     * Return a List of uids for messages which are flagged recent.
      * The list must be ordered by the {@link Document} uid. 
-     * If a limit was given the list will maximal be the size of the limit. Id a 
-     * limit smaller then 1 is given the List must contain all messages
+     * If reset is given the recent flag is removed from the messages before returning the uids
      * 
      * @param mailbox
-     * @param limit
+     * @param reset
      * @return recentList
      * @throws StorageException
      */
-    public abstract List<MailboxMembership<Id>> findRecentMessagesInMailbox(Mailbox<Id> mailbox, int limit) throws StorageException;
+    public abstract List<Long> findRecentMessageUidsInMailbox(Mailbox<Id> mailbox, boolean reset) throws StorageException;
 
 
     /**
@@ -135,7 +126,7 @@
     
     
     /**
-     * Copy the given {@link MailboxMembership} to a new mailbox
+     * Copy the given {@link MailboxMembership} to a new mailbox and return its uid
      * 
      * @param mailbox the Mailbox to copy to
      * @param uid the uid to use for the new MailboxMembership
@@ -143,6 +134,6 @@
      * @return The copied instance
      * @throws StorageException
      */
-    public abstract MailboxMembership<Id> copy(Mailbox<Id> mailbox, MailboxMembership<Id> original) throws StorageException;
+    public abstract long copy(Mailbox<Id> mailbox, MailboxMembership<Id> original) throws StorageException;
 
 }
\ No newline at end of file
Index: store/src/main/java/org/apache/james/imap/store/transaction/AbstractTransactionalMapper.java
===================================================================
--- store/src/main/java/org/apache/james/imap/store/transaction/AbstractTransactionalMapper.java	(Revision 986733)
+++ store/src/main/java/org/apache/james/imap/store/transaction/AbstractTransactionalMapper.java	(Arbeitskopie)
@@ -32,7 +32,7 @@
      * (non-Javadoc)
      * @see org.apache.james.imap.store.transaction.TransactionalMapper#execute(org.apache.james.imap.store.transaction.TransactionalMapper.Transaction)
      */
-    public final <T> T execute(Transaction<T> transaction) throws MailboxException {
+    public <T> T execute(Transaction<T> transaction) throws MailboxException {
         begin();
         try {
             T value = transaction.run();
Index: store/src/main/java/org/apache/james/imap/store/AbstractMessageMapper.java
===================================================================
--- store/src/main/java/org/apache/james/imap/store/AbstractMessageMapper.java	(Revision 0)
+++ store/src/main/java/org/apache/james/imap/store/AbstractMessageMapper.java	(Revision 0)
@@ -0,0 +1,165 @@
+/****************************************************************
+ * 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.store;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.james.imap.mailbox.MessageRange;
+import org.apache.james.imap.mailbox.SearchQuery;
+import org.apache.james.imap.mailbox.StorageException;
+import org.apache.james.imap.mailbox.SearchQuery.Criterion;
+import org.apache.james.imap.mailbox.SearchQuery.NumericRange;
+import org.apache.james.imap.store.mail.MessageMapper;
+import org.apache.james.imap.store.mail.model.Document;
+import org.apache.james.imap.store.mail.model.Mailbox;
+import org.apache.james.imap.store.mail.model.MailboxMembership;
+import org.apache.james.imap.store.transaction.AbstractTransactionalMapper;
+
+/**
+ * Abstract base class for {@link MessageMapper} implementations
+ * 
+ *
+ */
+public abstract class AbstractMessageMapper<Id> extends AbstractTransactionalMapper implements MessageMapper<Id>{
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.james.imap.store.mail.MessageMapper#findRecentMessageUidsInMailbox(org.apache.james.imap.store.mail.model.Mailbox, boolean)
+     */
+    public List<Long> findRecentMessageUidsInMailbox(Mailbox<Id> mailbox, boolean reset) throws StorageException {
+        final List<MailboxMembership<Id>> members = findRecentMessagesInMailbox(mailbox);
+        final List<Long> results = new ArrayList<Long>();
+
+        for (MailboxMembership<Id> member:members) {
+            results.add(member.getUid());
+            if (reset) {
+                member.unsetRecent();
+                
+                // only call save if we need to
+                save(mailbox, member);
+            }
+        }
+        return results;
+    }
+    
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.james.imap.store.mail.MessageMapper#deleteMarkedInMailbox(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.mailbox.MessageRange)
+     */
+    public List<Long> deleteMarkedInMailbox(Mailbox<Id> mailbox, MessageRange set) throws StorageException {
+        final List<Long> uids = new ArrayList<Long>();
+
+        final List<MailboxMembership<Id>> members = findMarkedForDeletionInMailbox(mailbox, set);
+        for (MailboxMembership<Id> message:members) {
+            uids.add(message.getUid());
+            delete(mailbox, message);
+            
+        }  
+        return uids;
+    }
+
+    /**
+     * Return a list of recent flagged {@link MailboxMembership} instances
+     * 
+     * @param mailbox
+     * @return list
+     * @throws StorageException
+     */
+    protected abstract List<MailboxMembership<Id>> findRecentMessagesInMailbox(Mailbox<Id> mailbox) throws StorageException;
+    
+
+    /**
+     * Return a List of {@link MailboxMembership} for the given {@link MessageRange} which are marked for deletion
+     * The list must be ordered by the {@link Document} uid
+     * @param mailbox
+     * @param set 
+     * @return list
+     * @throws StorageException
+     */
+    protected abstract List<MailboxMembership<Id>> findMarkedForDeletionInMailbox(
+            Mailbox<Id> mailbox, final MessageRange set)
+            throws StorageException;
+    
+    /**
+     * Delete the given {@link MailboxMembership}
+     * 
+     * @param mailbox
+     * @param message
+     * @throws StorageException
+     */
+    protected abstract void delete(Mailbox<Id> mailbox, MailboxMembership<Id> message) throws StorageException;
+    
+
+    /**
+     * This implementation just call {@link #findInMailbox(Mailbox, MessageRange)} and use a {@link SearchQueryIterator}
+     * to filter messages out which are match the {@link SearchQuery}. Extending classes are free
+     * to override this and provide an more performant solution
+     * 
+     * @see org.apache.james.imap.store.mail.MessageMapper#searchMailbox(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.mailbox.SearchQuery)
+     */
+    public Iterator<Long> searchMailbox(Mailbox<Id> mailbox, SearchQuery query) throws StorageException {
+        final List<Criterion> criteria = query.getCriterias();
+        final List<MailboxMembership<Id>> results = new ArrayList<MailboxMembership<Id>>();
+        if (criteria.size() == 1) {
+            final Criterion firstCriterion = criteria.get(0);
+            if (firstCriterion instanceof SearchQuery.UidCriterion) {
+                final SearchQuery.UidCriterion uidCriterion = (SearchQuery.UidCriterion) firstCriterion;
+                final NumericRange[] ranges = uidCriterion.getOperator().getRange();
+
+                for (int i = 0; i < ranges.length; i++) {
+                    final long low = ranges[i].getLowValue();
+                    final long high = ranges[i].getHighValue();
+
+                    if (low == Long.MAX_VALUE) {
+                        results.addAll(findInMailbox(mailbox, MessageRange.range(0, high)));
+                    } else if (low == high) {
+                        results.addAll(findInMailbox(mailbox, MessageRange.one(high)));
+                    } else {
+                        results.addAll(findInMailbox(mailbox, MessageRange.range(low, high)));
+                    }
+                }
+            } else {
+                results.addAll(findInMailbox(mailbox, MessageRange.all()));
+
+            }
+        } else {
+            results.addAll(findInMailbox(mailbox, MessageRange.all()));
+        }
+        final Iterator<MailboxMembership<Id>>resultsIt = results.iterator();
+        return new SearchQueryIterator(new Iterator<MailboxMembership<?>>() {
+
+            public boolean hasNext() {
+                return resultsIt.hasNext();
+            }
+
+            public MailboxMembership<?> next() {
+                return resultsIt.next();
+            }
+
+            public void remove() {
+                resultsIt.remove();
+            }
+            
+        }, query);
+    }
+
+}
Index: store/src/main/java/org/apache/james/imap/store/StoreMessageManager.java
===================================================================
--- store/src/main/java/org/apache/james/imap/store/StoreMessageManager.java	(Revision 986733)
+++ store/src/main/java/org/apache/james/imap/store/StoreMessageManager.java	(Arbeitskopie)
@@ -34,7 +34,6 @@
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
-import java.util.TreeSet;
 
 import javax.mail.Flags;
 import javax.mail.MessagingException;
@@ -373,23 +372,10 @@
      * @throws MailboxException
      */
     protected List<Long> recent(final boolean reset, MailboxSession mailboxSession) throws MailboxException {
-
         return messageMapper.execute(new TransactionalMapper.Transaction<List<Long>>() {
 
             public List<Long> run() throws MailboxException {
-                final List<MailboxMembership<Id>> members = messageMapper.findRecentMessagesInMailbox(mailbox, -1);
-                final List<Long> results = new ArrayList<Long>();
-
-                for (MailboxMembership<Id> member:members) {
-                    results.add(member.getUid());
-                    if (reset) {
-                        member.unsetRecent();
-                        
-                        // only call save if we need to
-                        messageMapper.save(mailbox, member);
-                    }
-                }
-                return results;
+                return messageMapper.findRecentMessageUidsInMailbox(mailbox, reset);         
             }
             
         });
@@ -401,20 +387,11 @@
      * (non-Javadoc)
      * @see org.apache.james.imap.mailbox.Mailbox#expunge(org.apache.james.imap.mailbox.MessageRange, org.apache.james.imap.mailbox.MailboxSession)
      */
-    public Iterator<Long> expunge(final MessageRange set, MailboxSession mailboxSession) throws MailboxException {
-        
+    public Iterator<Long> expunge(final MessageRange set, MailboxSession mailboxSession) throws MailboxException {      
         Collection<Long> uids = messageMapper.execute(new TransactionalMapper.Transaction<Collection<Long>>() {
 
             public Collection<Long> run() throws MailboxException {
-                final Collection<Long> uids = new TreeSet<Long>();
-
-                final List<MailboxMembership<Id>> members = messageMapper.findMarkedForDeletionInMailbox(mailbox, set);
-                for (MailboxMembership<Id> message:members) {
-                    uids.add(message.getUid());
-                    messageMapper.delete(mailbox, message);
-                    
-                }  
-                return uids;
+                return messageMapper.deleteMarkedInMailbox(mailbox, set);
             }
             
         });
@@ -497,26 +474,29 @@
         return true;
     }
 
-    private void copy(final List<MailboxMembership<Id>> originalRows, final MailboxSession session) throws MailboxException {
+    /**
+     * Copy the given List of {@link MailboxMembership} instances in here
+     * 
+     * @param originalRows
+     * @param session
+     * @throws MailboxException
+     */
+    protected void copy(final List<MailboxMembership<Id>> originalRows, final MailboxSession session) throws MailboxException {
         try {
-            final List<MailboxMembership<Id>> copiedRows = new ArrayList<MailboxMembership<Id>>();
+            final List<Long> copiedRows = new ArrayList<Long>();
             for (final MailboxMembership<Id> originalMessage:originalRows) {
-               copiedRows.addAll(messageMapper.execute(new TransactionalMapper.Transaction<List<MailboxMembership<Id>>>() {
+                copiedRows.add(messageMapper.execute(new TransactionalMapper.Transaction<Long>() {
 
-                    public List<MailboxMembership<Id>> run() throws MailboxException {
-                        final List<MailboxMembership<Id>> copiedRows = new ArrayList<MailboxMembership<Id>>();
-
-                        final MailboxMembership<Id> newRow = messageMapper.copy(mailbox, originalMessage);
-                        
-                        copiedRows.add(newRow);
-                        return copiedRows;
+                    public Long run() throws MailboxException {
+                        return messageMapper.copy(mailbox, originalMessage);           
                     }
-                    
+                   
                 }));
             }
+            
             // Wait until commit before issuing events
-            for (MailboxMembership<Id> newMember:copiedRows) {
-                dispatcher.added(newMember.getUid(), session.getSessionId(), new StoreMailboxPath<Id>(getMailboxEntity()));
+            for (Long newMember:copiedRows) {
+                dispatcher.added(newMember, session.getSessionId(), new StoreMailboxPath<Id>(getMailboxEntity()));
             }
         } catch (MessagingException e) {
             throw new MailboxException(HumanReadableText.FAILURE_MAIL_PARSE, e);
Index: memory/src/main/java/org/apache/james/imap/inmemory/mail/InMemoryMessageMapper.java
===================================================================
--- memory/src/main/java/org/apache/james/imap/inmemory/mail/InMemoryMessageMapper.java	(Revision 986733)
+++ memory/src/main/java/org/apache/james/imap/inmemory/mail/InMemoryMessageMapper.java	(Arbeitskopie)
@@ -11,15 +11,13 @@
 import org.apache.james.imap.inmemory.mail.model.SimpleMailboxMembership;
 import org.apache.james.imap.mailbox.MailboxException;
 import org.apache.james.imap.mailbox.MessageRange;
-import org.apache.james.imap.mailbox.SearchQuery;
 import org.apache.james.imap.mailbox.StorageException;
+import org.apache.james.imap.store.AbstractMessageMapper;
 import org.apache.james.imap.store.MailboxMembershipComparator;
-import org.apache.james.imap.store.SearchQueryIterator;
-import org.apache.james.imap.store.mail.MessageMapper;
 import org.apache.james.imap.store.mail.model.Mailbox;
 import org.apache.james.imap.store.mail.model.MailboxMembership;
 
-public class InMemoryMessageMapper implements MessageMapper<Long> {
+public class InMemoryMessageMapper extends AbstractMessageMapper<Long> {
 
     private Map<Long, Map<Long, MailboxMembership<Long>>> mailboxByUid;
     private static final int INITIAL_SIZE = 256;
@@ -59,11 +57,12 @@
         return count;
     }
 
+
     /*
      * (non-Javadoc)
-     * @see org.apache.james.imap.store.mail.MessageMapper#delete(org.apache.james.imap.store.mail.model.MailboxMembership)
+     * @see org.apache.james.imap.store.AbstractMessageMapper#delete(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.store.mail.model.MailboxMembership)
      */
-    public void delete(Mailbox<Long> mailbox, MailboxMembership<Long> message) throws StorageException {
+    protected void delete(Mailbox<Long> mailbox, MailboxMembership<Long> message) throws StorageException {
         getMembershipByUidForMailbox(mailbox).remove(message.getUid());
     }
 
@@ -111,11 +110,12 @@
         return results;
     }
 
+
     /*
      * (non-Javadoc)
-     * @see org.apache.james.imap.store.mail.MessageMapper#findMarkedForDeletionInMailbox(org.apache.james.imap.mailbox.MessageRange)
+     * @see org.apache.james.imap.store.AbstractMessageMapper#findMarkedForDeletionInMailbox(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.mailbox.MessageRange)
      */
-    public List<MailboxMembership<Long>> findMarkedForDeletionInMailbox(Mailbox<Long> mailbox, MessageRange set) throws StorageException {
+    protected List<MailboxMembership<Long>> findMarkedForDeletionInMailbox(Mailbox<Long> mailbox, MessageRange set) throws StorageException {
         final List<MailboxMembership<Long>> results = findInMailbox(mailbox, set);
         for(final Iterator<MailboxMembership<Long>> it=results.iterator();it.hasNext();) {
             if (!it.next().isDeleted()) {
@@ -129,7 +129,7 @@
      * (non-Javadoc)
      * @see org.apache.james.imap.store.mail.MessageMapper#findRecentMessagesInMailbox()
      */
-    public List<MailboxMembership<Long>> findRecentMessagesInMailbox(Mailbox<Long> mailbox,int limit) throws StorageException {
+    protected List<MailboxMembership<Long>> findRecentMessagesInMailbox(Mailbox<Long> mailbox) throws StorageException {
         final List<MailboxMembership<Long>> results = new ArrayList<MailboxMembership<Long>>();
         for(MailboxMembership<Long> member:getMembershipByUidForMailbox(mailbox).values()) {
             if (member.isRecent()) {
@@ -137,9 +137,7 @@
             }
         }
         Collections.sort(results, MailboxMembershipComparator.INSTANCE);
-        if (limit > 0 && limit > results.size()) {
-            return results.subList(0, limit -1);
-        } 
+        
         return results;
     }
 
@@ -168,25 +166,6 @@
         return message.getUid();
     }
 
-
-    /*
-     * (non-Javadoc)
-     * @see org.apache.james.imap.store.mail.MessageMapper#searchMailbox(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.mailbox.SearchQuery)
-     */
-    public Iterator<Long> searchMailbox(Mailbox<Long> mailbox, SearchQuery query) throws StorageException {
-        List<MailboxMembership<?>> memberships = new ArrayList<MailboxMembership<?>>(getMembershipByUidForMailbox(mailbox).values());
-        Collections.sort(memberships, MailboxMembershipComparator.INSTANCE);
-
-        return new SearchQueryIterator(memberships.iterator(), query);
-    }
-
-    /**
-     * There is no really Transaction handling here.. Just run it 
-     */
-    public <T> T execute(Transaction<T> transaction) throws MailboxException {
-        return transaction.run();
-    }
-    
     public void deleteAll() {
         mailboxByUid.clear();
     }
@@ -203,11 +182,28 @@
      * (non-Javadoc)
      * @see org.apache.james.imap.store.mail.MessageMapper#copy(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.store.mail.model.MailboxMembership)
      */
-    public MailboxMembership<Long> copy(Mailbox<Long> mailbox, MailboxMembership<Long> original) throws StorageException {
+    public long copy(Mailbox<Long> mailbox, MailboxMembership<Long> original) throws StorageException {
         ((InMemoryMailbox) mailbox).consumeUid();
         SimpleMailboxMembership membership = new SimpleMailboxMembership(mailbox.getMailboxId(), mailbox.getLastUid(), (SimpleMailboxMembership) original);
-        save(mailbox, membership);
-        return membership;
+        return save(mailbox, membership);
     }
+
+    @Override
+    protected void begin() throws MailboxException {
+        // Do nothing
+        
+    }
+
+    @Override
+    protected void commit() throws MailboxException {
+        // Do nothing
+        
+    }
+
+    @Override
+    protected void rollback() throws MailboxException {
+        // Do nothing
+        
+    }
     
 }
Index: jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMessageMapper.java
===================================================================
--- jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMessageMapper.java	(Revision 984773)
+++ jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMessageMapper.java	(Arbeitskopie)
@@ -18,29 +18,25 @@
  ****************************************************************/
 package org.apache.james.imap.jpa.mail;
 
-import java.util.Iterator;
 import java.util.List;
 
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
 import javax.persistence.LockModeType;
 import javax.persistence.PersistenceException;
 import javax.persistence.Query;
 
 import org.apache.james.imap.api.display.HumanReadableText;
-import org.apache.james.imap.jpa.JPATransactionalMapper;
 import org.apache.james.imap.jpa.mail.model.JPAMailbox;
 import org.apache.james.imap.jpa.mail.model.openjpa.AbstractJPAMailboxMembership;
 import org.apache.james.imap.jpa.mail.model.openjpa.JPAMailboxMembership;
 import org.apache.james.imap.jpa.mail.model.openjpa.JPAStreamingMailboxMembership;
 import org.apache.james.imap.mailbox.MailboxException;
 import org.apache.james.imap.mailbox.MessageRange;
-import org.apache.james.imap.mailbox.SearchQuery;
 import org.apache.james.imap.mailbox.StorageException;
 import org.apache.james.imap.mailbox.MessageRange.Type;
-import org.apache.james.imap.mailbox.SearchQuery.Criterion;
-import org.apache.james.imap.mailbox.SearchQuery.NumericRange;
-import org.apache.james.imap.store.SearchQueryIterator;
+import org.apache.james.imap.store.AbstractMessageMapper;
 import org.apache.james.imap.store.mail.MessageMapper;
 import org.apache.james.imap.store.mail.model.Mailbox;
 import org.apache.james.imap.store.mail.model.MailboxMembership;
@@ -50,13 +46,74 @@
  * JPA implementation of a {@link MessageMapper}. This class is not thread-safe!
  *
  */
-public class JPAMessageMapper extends JPATransactionalMapper implements MessageMapper<Long> {
+public class JPAMessageMapper extends AbstractMessageMapper<Long> {
     
+    protected EntityManagerFactory entityManagerFactory;
+    protected EntityManager entityManager;
+    
     public JPAMessageMapper(final EntityManagerFactory entityManagerFactory) {
-        super(entityManagerFactory);
+        this.entityManagerFactory = entityManagerFactory;
     }
 
+
     /**
+     * Return the currently used {@link EntityManager} or a new one if none exists.
+     * 
+     * @return entitymanger
+     */
+    protected EntityManager getEntityManager() {
+        if (entityManager != null)
+            return entityManager;
+        entityManager = entityManagerFactory.createEntityManager();
+        return entityManager;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.james.imap.store.transaction.AbstractTransactionalMapper#begin()
+     */
+    protected void begin() throws MailboxException {
+        try {
+            getEntityManager().getTransaction().begin();
+        } catch (PersistenceException e) {
+            throw new StorageException(HumanReadableText.START_TRANSACTION_FAILED, e);
+        }
+    }
+
+    /**
+     * Commit the Transaction and close the EntityManager
+     */
+    protected void commit() throws MailboxException {
+        try {
+            getEntityManager().getTransaction().commit();
+        } catch (PersistenceException e) {
+            throw new StorageException(HumanReadableText.COMMIT_TRANSACTION_FAILED, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.james.imap.store.transaction.AbstractTransactionalMapper#rollback()
+     */
+    protected void rollback() throws MailboxException {
+        EntityTransaction transaction = entityManager.getTransaction();
+        // check if we have a transaction to rollback
+        if (transaction.isActive()) {
+            getEntityManager().getTransaction().rollback();
+        }
+    }
+
+    /**
+     * Close open {@link EntityManager}
+     */
+    public void endRequest() {
+        if (entityManager != null) {
+            if (entityManager.isOpen())
+                entityManager.close();
+            entityManager = null;
+        }
+    }
+    /**
      * @see org.apache.james.imap.store.mail.MessageMapper#findInMailbox(org.apache.james.imap.mailbox.MessageRange)
      */
     public List<MailboxMembership<Long>> findInMailbox(Mailbox<Long> mailbox, MessageRange set) throws StorageException {
@@ -113,10 +170,11 @@
         return getEntityManager().createNamedQuery("findMessagesInMailbox").setParameter("idParam", mailbox.getMailboxId()).getResultList();
     }
 
-    /**
-     * @see org.apache.james.imap.store.mail.MessageMapper#findMarkedForDeletionInMailbox(org.apache.james.imap.mailbox.MessageRange)
+    /*
+     * (non-Javadoc)
+     * @see org.apache.james.imap.store.AbstractMessageMapper#findMarkedForDeletionInMailbox(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.mailbox.MessageRange)
      */
-    public List<MailboxMembership<Long>> findMarkedForDeletionInMailbox(Mailbox<Long> mailbox, final MessageRange set) throws StorageException {
+    protected List<MailboxMembership<Long>> findMarkedForDeletionInMailbox(Mailbox<Long> mailbox, final MessageRange set) throws StorageException {
         try {
             final List<MailboxMembership<Long>> results;
             final long from = set.getUidFrom();
@@ -192,68 +250,12 @@
     }
 
 
-
     /*
-     * 
      * (non-Javadoc)
-     * @see org.apache.james.imap.store.mail.MessageMapper#searchMailbox(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.mailbox.SearchQuery)
+     * @see org.apache.james.imap.store.AbstractMessageMapper#delete(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.store.mail.model.MailboxMembership)
      */
-    @SuppressWarnings("unchecked")
-    public Iterator<Long> searchMailbox(Mailbox<Long> mailbox, SearchQuery query) throws StorageException {
+    protected void delete(Mailbox<Long> mailbox, MailboxMembership<Long> message) throws StorageException {
         try {
-            final StringBuilder queryBuilder = new StringBuilder(50);
-            queryBuilder.append("SELECT membership FROM Membership membership WHERE membership.mailboxId = ").append(mailbox.getMailboxId());
-            final List<Criterion> criteria = query.getCriterias();
-            boolean range = false;
-            int rangeLength = -1;
-            
-            if (criteria.size() == 1) {
-                final Criterion firstCriterion = criteria.get(0);
-                if (firstCriterion instanceof SearchQuery.UidCriterion) {
-                    final SearchQuery.UidCriterion uidCriterion = (SearchQuery.UidCriterion) firstCriterion;
-                    final NumericRange[] ranges = uidCriterion.getOperator().getRange();
-                    rangeLength = ranges.length;
-
-                    for (int i = 0; i < ranges.length; i++) {
-                        final long low = ranges[i].getLowValue();
-                        final long high = ranges[i].getHighValue();
-
-                        if (low == Long.MAX_VALUE) {
-                            queryBuilder.append(" AND membership.uid<=").append(high);
-                            range = true;
-                        } else if (low == high) {
-                            queryBuilder.append(" AND membership.uid=").append(low);
-                            range = false;
-                        } else {
-                            queryBuilder.append(" AND membership.uid BETWEEN ").append(low).append(" AND ").append(high);
-                            range = true;
-                        }
-                    }
-                }
-            }        
-            if (rangeLength != 0 || range) {
-                queryBuilder.append(" order by membership.uid");
-            }
-            
-            Query jQuery = getEntityManager().createQuery(queryBuilder.toString());
-
-            // Check if we only need to fetch 1 message, if so we can set a limit to speed up things
-            if (rangeLength == 1 && range == false) {
-                jQuery.setMaxResults(1);
-            }
-            return new SearchQueryIterator(jQuery.getResultList().iterator(), query);
-            
-        } catch (PersistenceException e) {
-            throw new StorageException(HumanReadableText.SEARCH_FAILED, e);
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.apache.james.imap.store.mail.MessageMapper#delete(java.lang.Object, org.apache.james.imap.store.mail.model.MailboxMembership)
-     */
-    public void delete(Mailbox<Long> mailbox, MailboxMembership<Long> message) throws StorageException {
-        try {
             getEntityManager().remove(message);
         } catch (PersistenceException e) {
             throw new StorageException(HumanReadableText.DELETED_FAILED, e);
@@ -285,12 +287,10 @@
      * @see org.apache.james.imap.store.mail.MessageMapper#findRecentMessagesInMailbox()
      */
     @SuppressWarnings("unchecked")
-    public List<MailboxMembership<Long>> findRecentMessagesInMailbox(Mailbox<Long> mailbox, int limit) throws StorageException {
+    protected List<MailboxMembership<Long>> findRecentMessagesInMailbox(Mailbox<Long> mailbox) throws StorageException {
         try {
             Query query = getEntityManager().createNamedQuery("findRecentMessagesInMailbox").setParameter("idParam", mailbox.getMailboxId());
-            if (limit > 0) {
-                query = query.setMaxResults(limit);
-            }
+            
             return query.getResultList();
         } catch (PersistenceException e) {
             throw new StorageException(HumanReadableText.SEARCH_FAILED, e);
@@ -308,7 +308,7 @@
                 ((AbstractJPAMailboxMembership) message).setUid(reserveUid((JPAMailbox)mailbox));
             }
             
-            
+            System.out.println("message uid" + message.getUid());
             getEntityManager().persist(message);
             return message.getUid();
         } catch (PersistenceException e) {
@@ -318,18 +318,17 @@
 
     /*
      * (non-Javadoc)
-     * @see org.apache.james.imap.store.mail.MessageMapper#copy(java.lang.Object, long, org.apache.james.imap.store.mail.model.MailboxMembership)
+     * @see org.apache.james.imap.store.mail.MessageMapper#copy(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.store.mail.model.MailboxMembership)
      */
-    public MailboxMembership<Long> copy(Mailbox<Long> mailbox, MailboxMembership<Long> original) throws StorageException {
+    public long copy(Mailbox<Long> mailbox, MailboxMembership<Long> original) throws StorageException {
         try {
-            MailboxMembership<Long> copy;
+            AbstractJPAMailboxMembership copy;
             if (original instanceof JPAStreamingMailboxMembership) {
                 copy = new JPAStreamingMailboxMembership(mailbox.getMailboxId(), (AbstractJPAMailboxMembership) original);
             } else {
                 copy = new JPAMailboxMembership(mailbox.getMailboxId(), (AbstractJPAMailboxMembership)original);
             }
-            save(mailbox, copy);
-            return copy;
+            return save(mailbox, copy);
         } catch (MailboxException e) {
             throw new StorageException(e.getKey(),e);
         }
@@ -344,7 +343,7 @@
      */
     protected long reserveUid(JPAMailbox mailbox) {
         EntityManager manager = getEntityManager();
-
+        
         // we need to set a pessimistic write lock to be sure we don't get any problems with dirty reads etc.
         JPAMailbox m = manager.find(JPAMailbox.class, mailbox.getMailboxId(), LockModeType.PESSIMISTIC_WRITE);
         manager.refresh(m);
Index: jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java
===================================================================
--- jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java	(Revision 984773)
+++ jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java	(Arbeitskopie)
@@ -22,7 +22,6 @@
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
-import java.util.Iterator;
 import java.util.List;
 
 import javax.jcr.ItemNotFoundException;
@@ -30,6 +29,7 @@
 import javax.jcr.NodeIterator;
 import javax.jcr.Property;
 import javax.jcr.RepositoryException;
+import javax.jcr.Session;
 import javax.jcr.query.Query;
 import javax.jcr.query.QueryManager;
 import javax.jcr.query.QueryResult;
@@ -39,20 +39,18 @@
 import org.apache.jackrabbit.commons.JcrUtils;
 import org.apache.jackrabbit.util.ISO9075;
 import org.apache.james.imap.api.display.HumanReadableText;
-import org.apache.james.imap.jcr.AbstractJCRMapper;
+import org.apache.james.imap.jcr.JCRImapConstants;
 import org.apache.james.imap.jcr.MailboxSessionJCRRepository;
 import org.apache.james.imap.jcr.NodeLocker;
 import org.apache.james.imap.jcr.NodeLocker.NodeLockedExecution;
 import org.apache.james.imap.jcr.mail.model.JCRMailbox;
 import org.apache.james.imap.jcr.mail.model.JCRMessage;
+import org.apache.james.imap.mailbox.MailboxException;
 import org.apache.james.imap.mailbox.MailboxSession;
 import org.apache.james.imap.mailbox.MessageRange;
-import org.apache.james.imap.mailbox.SearchQuery;
 import org.apache.james.imap.mailbox.StorageException;
 import org.apache.james.imap.mailbox.MessageRange.Type;
-import org.apache.james.imap.mailbox.SearchQuery.Criterion;
-import org.apache.james.imap.mailbox.SearchQuery.NumericRange;
-import org.apache.james.imap.store.SearchQueryIterator;
+import org.apache.james.imap.store.AbstractMessageMapper;
 import org.apache.james.imap.store.mail.MessageMapper;
 import org.apache.james.imap.store.mail.model.Mailbox;
 import org.apache.james.imap.store.mail.model.MailboxMembership;
@@ -61,7 +59,7 @@
  * JCR implementation of a {@link MessageMapper}
  *
  */
-public class JCRMessageMapper extends AbstractJCRMapper implements MessageMapper<String> {
+public class JCRMessageMapper extends AbstractMessageMapper<String> implements JCRImapConstants{
 
     /**
      * Store the messages directly in the mailbox:
@@ -101,6 +99,14 @@
     public final static int MESSAGE_SCALE_MINUTE = 5;
 
     private final int scaleType;
+
+    private MailboxSessionJCRRepository repository;
+
+    private MailboxSession  mSession;
+
+    private Log logger;
+
+    private NodeLocker locker;
     
 
     /**
@@ -124,11 +130,85 @@
      *                  {@link #MESSAGE_SCALE_HOUR}, {@link #MESSAGE_SCALE_MINUTE}  
      */
     public JCRMessageMapper(final MailboxSessionJCRRepository repos, MailboxSession session, NodeLocker locker, final Log logger, int scaleType) {
-        super(repos, session, locker, logger);
         this.scaleType = scaleType;
+        this.repository = repos;
+        this.mSession = session;
+        this.logger = logger;
+        this.locker = locker;
     }
     
+    
+
+
+    protected NodeLocker getNodeLocker() {
+        return locker;
+    }
+
     /**
+     * Return the logger
+     * 
+     * @return logger
+     */
+    protected Log getLogger() {
+        return logger;
+    }
+
+    /**
+     * Return the JCR Session
+     * 
+     * @return session
+     */
+    protected Session getSession() throws RepositoryException {
+        return repository.login(mSession);
+    }
+
+    /**
+     * Begin is not supported by level 1 JCR implementations, however we refresh
+     * the session
+     */
+    protected void begin() throws MailboxException {
+        try {
+            getSession().refresh(true);
+        } catch (RepositoryException e) {
+            // do nothin on refresh
+        }
+        // Do nothing
+    }
+
+    /**
+     * Just call save on the underlying JCR Session, because level 1 JCR
+     * implementation does not offer Transactions
+     */
+    protected void commit() throws MailboxException {
+        try {
+            if (getSession().hasPendingChanges()) {
+                getSession().save();
+            }
+        } catch (RepositoryException e) {
+            throw new MailboxException(HumanReadableText.COMMIT_TRANSACTION_FAILED, e);
+        }
+    }
+
+    /**
+     * Rollback is not supported by level 1 JCR implementations, so just do
+     * nothing
+     */
+    protected void rollback() throws MailboxException {
+        try {
+            // just refresh session and discard all pending changes
+            getSession().refresh(false);
+        } catch (RepositoryException e) {
+            // just catch on rollback by now
+        }
+    }
+
+    /**
+     * Logout from open JCR Session
+     */
+    public void endRequest() {
+        repository.logout(mSession);
+    }
+    /**
      * Return the path to the mailbox. This path is escaped to be able to use it in xpath queries
      * 
      * See http://wiki.apache.org/jackrabbit/EncodingAndEscaping
@@ -200,11 +280,12 @@
         }
     }
 
+
     /*
      * (non-Javadoc)
-     * @see org.apache.james.imap.store.mail.MessageMapper#delete(java.lang.Object, org.apache.james.imap.store.mail.model.MailboxMembership)
+     * @see org.apache.james.imap.store.AbstractMessageMapper#delete(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.store.mail.model.MailboxMembership)
      */
-    public void delete(Mailbox<String> mailbox, MailboxMembership<String> message) throws StorageException {
+    protected void delete(Mailbox<String> mailbox, MailboxMembership<String> message) throws StorageException {
         JCRMessage membership = (JCRMessage) message;
         if (membership.isPersistent()) {
             try {
@@ -413,7 +494,7 @@
      * org.apache.james.imap.store.mail.MessageMapper#findRecentMessagesInMailbox
      * ()
      */
-    public List<MailboxMembership<String>> findRecentMessagesInMailbox(Mailbox<String> mailbox, int limit) throws StorageException {
+    protected List<MailboxMembership<String>> findRecentMessagesInMailbox(Mailbox<String> mailbox) throws StorageException {
         
         try {
  
@@ -422,9 +503,7 @@
             
             QueryManager manager = getSession().getWorkspace().getQueryManager();
             Query query = manager.createQuery(queryString, Query.XPATH);
-            if (limit > 0) {
-                query.setLimit(limit);
-            }
+            
             QueryResult result = query.execute();
             
             NodeIterator iterator = result.getNodes();
@@ -602,104 +681,14 @@
         }
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.james.imap.store.mail.MessageMapper#searchMailbox(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.mailbox.SearchQuery)
-     */
-    public Iterator<Long> searchMailbox(Mailbox<String> mailbox, SearchQuery query) throws StorageException {
-        try {
-            final Query xQuery = formulateXPath(mailbox, query);
-            
-            QueryResult result = xQuery.execute();
-            
-            final NodeIterator it = result.getNodes();
+  
 
-            
-            // Lazy build the JCRMessage instances
-            return new SearchQueryIterator(new Iterator<MailboxMembership<?>>() {
-
-                public boolean hasNext() {
-                    return it.hasNext();
-                }
-
-                public MailboxMembership<?> next() {
-                    return new JCRMessage(it.nextNode(), getLogger());
-                    
-                }
-
-                public void remove() {
-                    it.remove();
-                }
-                
-            }, query, getLogger());
-        } catch (RepositoryException e) {
-            throw new StorageException(HumanReadableText.SEARCH_FAILED, e);
-        }
-    }
-
-    /**
-     * Generate the XPath query for the SearchQuery
-     * 
-     * @param uuid
-     * @param query
-     * @return xpathQuery
-     * @throws RepositoryException 
-     * @throws ItemNotFoundException 
-     */
-    private Query formulateXPath(Mailbox<String> mailbox, SearchQuery query) throws ItemNotFoundException, RepositoryException {
-        final StringBuilder queryBuilder = new StringBuilder();
-        queryBuilder.append("/jcr:root" + getMailboxPath(mailbox) + "//element(*,jamesMailbox:message)");
-        final List<Criterion> criteria = query.getCriterias();
-        boolean range = false;
-        int rangeLength = -1;
-        if (criteria.size() == 1) {
-            final Criterion firstCriterion = criteria.get(0);
-            if (firstCriterion instanceof SearchQuery.UidCriterion) {
-                final SearchQuery.UidCriterion uidCriterion = (SearchQuery.UidCriterion) firstCriterion;
-                final NumericRange[] ranges = uidCriterion.getOperator().getRange();
-                rangeLength = ranges.length;
-                for (int i = 0; i < ranges.length; i++) {
-                    final long low = ranges[i].getLowValue();
-                    final long high = ranges[i].getHighValue();
-                    if (i > 0) {
-                        queryBuilder.append(" and ");
-                    } else {
-                        queryBuilder.append("[");
-                    }
-                    if (low == Long.MAX_VALUE) {
-                        range = true;
-                        queryBuilder.append("@" + JCRMessage.UID_PROPERTY +"<=").append(high);
-                    } else if (low == high) {
-                        range = false;
-                        queryBuilder.append("@" + JCRMessage.UID_PROPERTY +"=").append(low);
-                    } else {
-                        range = true;
-                        queryBuilder.append("@" + JCRMessage.UID_PROPERTY +"<=").append(high).append(" and @" + JCRMessage.UID_PROPERTY + ">=").append(low);
-                    }
-                }
-            }
-        }
-        if (rangeLength > 0) queryBuilder.append("]");
-        
-        if (rangeLength != 0 || range) {
-            queryBuilder.append(" order by @" + JCRMessage.UID_PROPERTY);
-        }
-        
-        QueryManager manager = getSession().getWorkspace().getQueryManager();
-        Query xQuery = manager.createQuery(queryBuilder.toString(), Query.XPATH);
-        
-        // Check if we only need to fetch 1 message, if so we can set a limit to speed up things
-        if (rangeLength == 1 && range == false) {
-            xQuery.setLimit(1);
-        }
-        return xQuery;
-    }
     
     /*
      * (non-Javadoc)
-     * @see org.apache.james.imap.store.mail.MessageMapper#copy(java.lang.Object, long, org.apache.james.imap.store.mail.model.MailboxMembership)
+     * @see org.apache.james.imap.store.mail.MessageMapper#copy(org.apache.james.imap.store.mail.model.Mailbox, org.apache.james.imap.store.mail.model.MailboxMembership)
      */
-    public MailboxMembership<String> copy(Mailbox<String> mailbox, MailboxMembership<String> oldmessage) throws StorageException{
+    public long copy(Mailbox<String> mailbox, MailboxMembership<String> oldmessage) throws StorageException{
         try {
             long uid = reserveNextUid((JCRMailbox) mailbox);
             String newMessagePath = getSession().getNodeByIdentifier(mailbox.getMailboxId()).getPath() + NODE_DELIMITER + String.valueOf(uid);
@@ -707,7 +696,7 @@
             Node node = getSession().getNode(newMessagePath);
             node.setProperty(JCRMessage.MAILBOX_UUID_PROPERTY, mailbox.getMailboxId());
             node.setProperty(JCRMessage.UID_PROPERTY, uid);
-            return new JCRMessage(node,getLogger());
+            return uid;
         } catch (RepositoryException e) {
             throw new StorageException(HumanReadableText.SAVE_FAILED, e);
         } catch (InterruptedException e) {
