Index: spring/pom.xml
===================================================================
--- spring/pom.xml	(Revision 5814)
+++ spring/pom.xml	(Revision 5832)
@@ -50,7 +50,7 @@
         </dependency>
         <dependency>
             <groupId>org.apache.james</groupId>
-            <artifactId>apache-james-mailbox-jpa</artifactId>
+            <artifactId>apache-james-mailbox-openjpa</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.james</groupId>

Eigenschaftsänderungen: spring
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target



Eigenschaftsänderungen: memory
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target



Eigenschaftsänderungen: api
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target


Index: jpa/src/test/java/org/apache/james/mailbox/jpa/JPAStressTest.java
===================================================================
--- jpa/src/test/java/org/apache/james/mailbox/jpa/JPAStressTest.java	(Revision 5814)
+++ jpa/src/test/java/org/apache/james/mailbox/jpa/JPAStressTest.java	(Revision 5832)
@@ -1,118 +0,0 @@
-/****************************************************************
- * 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.mailbox.jpa;
-
-import java.util.HashMap;
-
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-
-import org.apache.james.mailbox.AbstractStressTest;
-import org.apache.james.mailbox.MailboxManager;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.acl.GroupMembershipResolver;
-import org.apache.james.mailbox.acl.MailboxACLResolver;
-import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
-import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
-import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.jpa.mail.JPAModSeqProvider;
-import org.apache.james.mailbox.jpa.mail.JPAUidProvider;
-import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
-import org.apache.james.mailbox.jpa.mail.model.JPAProperty;
-import org.apache.james.mailbox.jpa.mail.model.JPAUserFlag;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.AbstractJPAMessage;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMessage;
-import org.apache.james.mailbox.jpa.openjpa.OpenJPAMailboxManager;
-import org.apache.james.mailbox.jpa.user.model.JPASubscription;
-import org.apache.james.mailbox.store.JVMMailboxPathLocker;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.junit.After;
-import org.junit.Before;
-import org.slf4j.LoggerFactory;
-
-/**
- * Proof of bug https://issues.apache.org/jira/browse/IMAP-137
- */
-public class JPAStressTest extends AbstractStressTest {
-    
-    private OpenJPAMailboxManager mailboxManager;
-    
-    private long locktimeout = 60000;
-    
-    private EntityManagerFactory entityManagerFactory;
-    
-    @Before
-    public void setUp() throws MailboxException {
-        
-        HashMap<String, String> properties = new HashMap<String, String>();
-        properties.put("openjpa.ConnectionDriverName", org.h2.Driver.class.getName());
-        properties.put("openjpa.ConnectionURL", "jdbc:h2:mem:mailboxintegrationstress;DB_CLOSE_DELAY=-1");
-        properties.put("openjpa.Log", "JDBC=WARN, SQL=WARN, Runtime=WARN");
-        properties.put("openjpa.ConnectionFactoryProperties", "PrettyPrint=true, PrettyPrintLineLength=72");
-        properties.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");
-        properties.put("openjpa.MetaDataFactory", "jpa(Types=" +
-                JPAMailbox.class.getName() + ";" +
-                AbstractJPAMessage.class.getName() + ";" +
-                JPAMessage.class.getName() + ";" +
-                JPAProperty.class.getName() + ";" +
-                JPAUserFlag.class.getName() + ";" +
-                JPASubscription.class.getName() + ")");
-        properties.put("openjpa.LockTimeout", locktimeout + "");
-       
-        entityManagerFactory = OpenJPAPersistence.getEntityManagerFactory(properties);
-        JVMMailboxPathLocker locker = new JVMMailboxPathLocker();
-        JPAMailboxSessionMapperFactory mf = new JPAMailboxSessionMapperFactory(entityManagerFactory, new JPAUidProvider(locker, entityManagerFactory), new JPAModSeqProvider(locker, entityManagerFactory));
-
-        MailboxACLResolver aclResolver = new UnionMailboxACLResolver();
-        GroupMembershipResolver groupMembershipResolver = new SimpleGroupMembershipResolver();
-
-        mailboxManager = new OpenJPAMailboxManager(mf, null, aclResolver, groupMembershipResolver);
-        mailboxManager.init();
-
-        // Set the lock timeout via SQL because of a bug in openJPA
-        // https://issues.apache.org/jira/browse/OPENJPA-1656
-        setH2LockTimeout();
-    
-    }
-    
-    private void setH2LockTimeout() {
-        EntityManager manager = entityManagerFactory.createEntityManager();
-        manager.getTransaction().begin();
-        manager.createNativeQuery("SET DEFAULT_LOCK_TIMEOUT " + locktimeout).executeUpdate();
-        manager.getTransaction().commit();
-        manager.close();
-    }
-    
-    @After
-    public void tearDown() {
-        MailboxSession session = mailboxManager.createSystemSession("test", LoggerFactory.getLogger("Test"));
-        try {
-            mailboxManager.deleteEverything(session);
-        } catch (MailboxException e) {
-            e.printStackTrace();
-        }
-        session.close();
-    }
-
-    @Override
-    protected MailboxManager getMailboxManager() {
-        return mailboxManager;
-    }
-
-}
Index: jpa/src/test/java/org/apache/james/mailbox/jpa/JPAMailboxManagerTest.java
===================================================================
--- jpa/src/test/java/org/apache/james/mailbox/jpa/JPAMailboxManagerTest.java	(Revision 5814)
+++ jpa/src/test/java/org/apache/james/mailbox/jpa/JPAMailboxManagerTest.java	(Revision 5832)
@@ -1,128 +0,0 @@
-/****************************************************************
- * 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.mailbox.jpa;
-
-import java.util.HashMap;
-
-import javax.persistence.EntityManagerFactory;
-
-import org.apache.james.mailbox.AbstractMailboxManagerTest;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.acl.GroupMembershipResolver;
-import org.apache.james.mailbox.acl.MailboxACLResolver;
-import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
-import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
-import org.apache.james.mailbox.exception.BadCredentialsException;
-import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.jpa.mail.JPAModSeqProvider;
-import org.apache.james.mailbox.jpa.mail.JPAUidProvider;
-import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
-import org.apache.james.mailbox.jpa.mail.model.JPAProperty;
-import org.apache.james.mailbox.jpa.mail.model.JPAUserFlag;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.AbstractJPAMessage;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMessage;
-import org.apache.james.mailbox.jpa.openjpa.OpenJPAMailboxManager;
-import org.apache.james.mailbox.jpa.user.model.JPASubscription;
-import org.apache.james.mailbox.store.JVMMailboxPathLocker;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.junit.After;
-import org.junit.Before;
-import org.slf4j.LoggerFactory;
-
-/**
- * JPAMailboxManagerTest that extends the StoreMailboxManagerTest.
- */
-public class JPAMailboxManagerTest extends AbstractMailboxManagerTest {
-    
-    /**
-     * The entity manager factory.
-     */
-    private static EntityManagerFactory entityManagerFactory;
-    
-    /**
-     * Setup the mailboxManager.
-     * 
-     * @throws Exception
-     */
-    @Before
-    public void setup() throws Exception {
-        createMailboxManager();
-    }
-    
-    /**
-     * Close the system session and entityManagerFactory
-     * 
-     * @throws MailboxException 
-     * @throws BadCredentialsException 
-     */
-    @After
-    public void tearDown() throws BadCredentialsException, MailboxException {
-        deleteAllMailboxes();
-        MailboxSession session = getMailboxManager().createSystemSession("test", LoggerFactory.getLogger("Test"));
-        session.close();
-        entityManagerFactory.close();
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.james.mailbox.MailboxManagerTest#createMailboxManager()
-     */
-    @Override
-    protected void createMailboxManager() throws MailboxException {
-        
-        HashMap<String, String> properties = new HashMap<String, String>();
-        properties.put("openjpa.ConnectionDriverName", "org.h2.Driver");
-        properties.put("openjpa.ConnectionURL", "jdbc:h2:mem:imap;DB_CLOSE_DELAY=-1");
-        properties.put("openjpa.Log", "JDBC=WARN, SQL=WARN, Runtime=WARN");
-        properties.put("openjpa.ConnectionFactoryProperties", "PrettyPrint=true, PrettyPrintLineLength=72");
-        properties.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");
-        properties.put("openjpa.MetaDataFactory", "jpa(Types=" +
-                JPAMailbox.class.getName() + ";" +
-                AbstractJPAMessage.class.getName() + ";" +
-                JPAMessage.class.getName() + ";" +
-                JPAProperty.class.getName() + ";" +
-                JPAUserFlag.class.getName() + ";" +
-                JPASubscription.class.getName() + ")");
-       
-        entityManagerFactory = OpenJPAPersistence.getEntityManagerFactory(properties);
-        JVMMailboxPathLocker locker = new JVMMailboxPathLocker();
-        JPAMailboxSessionMapperFactory mf = new JPAMailboxSessionMapperFactory(entityManagerFactory, new JPAUidProvider(locker, entityManagerFactory), new JPAModSeqProvider(locker, entityManagerFactory));
-
-        MailboxACLResolver aclResolver = new UnionMailboxACLResolver();
-        GroupMembershipResolver groupMembershipResolver = new SimpleGroupMembershipResolver();
-
-        JPAMailboxManager mailboxManager = new OpenJPAMailboxManager(mf, null, aclResolver, groupMembershipResolver);
-        mailboxManager.init();
-
-        setMailboxManager(mailboxManager);
-        
-        deleteAllMailboxes();
-        
-    }
-    
-    private void deleteAllMailboxes() throws BadCredentialsException, MailboxException {
-        MailboxSession session = getMailboxManager().createSystemSession("test", LoggerFactory.getLogger("Test"));
-        try {
-            ((OpenJPAMailboxManager) mailboxManager).deleteEverything(session);
-        } catch (MailboxException e) {
-            e.printStackTrace();
-        }
-        session.close();
-    }
-
-}
Index: jpa/src/test/java/org/apache/james/mailbox/jpa/JPASubscriptionManagerTest.java
===================================================================
--- jpa/src/test/java/org/apache/james/mailbox/jpa/JPASubscriptionManagerTest.java	(Revision 5814)
+++ jpa/src/test/java/org/apache/james/mailbox/jpa/JPASubscriptionManagerTest.java	(Revision 5832)
@@ -1,78 +0,0 @@
-/****************************************************************
- * 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.mailbox.jpa;
-
-import java.util.HashMap;
-
-import org.apache.james.mailbox.AbstractSubscriptionManagerTest;
-import org.apache.james.mailbox.SubscriptionManager;
-import org.apache.james.mailbox.jpa.mail.JPAModSeqProvider;
-import org.apache.james.mailbox.jpa.mail.JPAUidProvider;
-import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
-import org.apache.james.mailbox.jpa.mail.model.JPAProperty;
-import org.apache.james.mailbox.jpa.mail.model.JPAUserFlag;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.AbstractJPAMessage;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMessage;
-import org.apache.james.mailbox.jpa.user.model.JPASubscription;
-import org.apache.james.mailbox.store.JVMMailboxPathLocker;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.junit.After;
-import org.junit.Before;
-
-public class JPASubscriptionManagerTest extends AbstractSubscriptionManagerTest{
-
-    private OpenJPAEntityManagerFactory entityManagerFactory;
-
-    @Before
-    public void setUp() {
-
-        HashMap<String, String> properties = new HashMap<String, String>();
-        properties.put("openjpa.ConnectionDriverName", "org.h2.Driver");
-        properties.put("openjpa.ConnectionURL", "jdbc:h2:mem:imap;DB_CLOSE_DELAY=-1");
-        properties.put("openjpa.Log", "JDBC=WARN, SQL=WARN, Runtime=WARN");
-        properties.put("openjpa.ConnectionFactoryProperties", "PrettyPrint=true, PrettyPrintLineLength=72");
-        properties.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");
-        properties.put("openjpa.MetaDataFactory", "jpa(Types=" +
-                JPAMailbox.class.getName() + ";" +
-                AbstractJPAMessage.class.getName() + ";" +
-                JPAMessage.class.getName() + ";" +
-                JPAProperty.class.getName() + ";" +
-                JPAUserFlag.class.getName() + ";" +
-                JPASubscription.class.getName() + ")");
-       
-        entityManagerFactory = OpenJPAPersistence.getEntityManagerFactory(properties);
-    }
-    
-    @Override
-    public SubscriptionManager createSubscriptionManager() {
-        JVMMailboxPathLocker locker = new JVMMailboxPathLocker();
-
-        JPAMailboxSessionMapperFactory mf = new JPAMailboxSessionMapperFactory(entityManagerFactory, new JPAUidProvider(locker, entityManagerFactory), new JPAModSeqProvider(locker, entityManagerFactory));
-
-        JPASubscriptionManager sm = new JPASubscriptionManager(mf);
-        
-        return sm;
-    }
-
-    @After
-    public void tearDown() {
-        entityManagerFactory.close();
-    }
-}
Index: jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java
===================================================================
--- jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java	(Revision 5814)
+++ jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java	(Revision 5832)
@@ -29,7 +29,7 @@
 import org.apache.james.mailbox.acl.MailboxACLResolver;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMessage;
+import org.apache.james.mailbox.jpa.mail.model.JPAMessage;
 import org.apache.james.mailbox.store.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.StoreMessageManager;
Index: jpa/src/main/java/org/apache/james/mailbox/jpa/JPASubscriptionManager.java
===================================================================
--- jpa/src/main/java/org/apache/james/mailbox/jpa/JPASubscriptionManager.java	(Revision 5814)
+++ jpa/src/main/java/org/apache/james/mailbox/jpa/JPASubscriptionManager.java	(Revision 5832)
@@ -36,6 +36,7 @@
     /**
      * @see org.apache.james.mailbox.store.StoreSubscriptionManager#createSubscription(org.apache.james.mailbox.MailboxSession, java.lang.String)
      */
+    @Override
     protected Subscription createSubscription(final MailboxSession session, final String mailbox) {
         final Subscription newSubscription = new JPASubscription(session.getUser().getUserName(), mailbox);
         return newSubscription;
Index: jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxManager.java
===================================================================
--- jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxManager.java	(Revision 5814)
+++ jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxManager.java	(Revision 5832)
@@ -28,16 +28,18 @@
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.store.Authenticator;
 import org.apache.james.mailbox.store.StoreMailboxManager;
+import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.transaction.TransactionalMapper;
 
 /**
  * JPA implementation of {@link StoreMailboxManager}
  */
-public abstract class JPAMailboxManager extends StoreMailboxManager<Long> {
+public class JPAMailboxManager extends StoreMailboxManager<Long> {
     
     public JPAMailboxManager(JPAMailboxSessionMapperFactory mailboxSessionMapperFactory,
-            final Authenticator authenticator, final MailboxPathLocker locker, MailboxACLResolver aclResolver, GroupMembershipResolver groupMembershipResolver) {
+            final Authenticator authenticator, final MailboxPathLocker locker, MailboxACLResolver aclResolver,
+            GroupMembershipResolver groupMembershipResolver) {
         super(mailboxSessionMapperFactory, authenticator, locker, aclResolver, groupMembershipResolver);
     }
     
@@ -55,15 +57,25 @@
     public void deleteEverything(MailboxSession mailboxSession) throws MailboxException {
         final JPAMailboxMapper mapper = (JPAMailboxMapper) getMapperFactory().getMailboxMapper(mailboxSession);
         mapper.execute(new TransactionalMapper.VoidTransaction() {
+            @Override
             public void runVoid() throws MailboxException {
                 mapper.deleteAllMemberships(); 
             }
         });
         mapper.execute(new TransactionalMapper.VoidTransaction() {
+            @Override
             public void runVoid() throws MailboxException {
                 mapper.deleteAllMailboxes(); 
             }
         });
     }
 
+    @Override
+    protected StoreMessageManager<Long> createMessageManager(Mailbox<Long> mailboxRow, MailboxSession session)
+            throws MailboxException {
+        StoreMessageManager<Long> result =  new JPAMessageManager(getMapperFactory(), getMessageSearchIndex(),
+                getEventDispatcher(), getLocker(), mailboxRow, getAclResolver(), getGroupMembershipResolver());
+        return result;
+    }
+
 }
Index: jpa/src/main/java/org/apache/james/mailbox/jpa/JPATransactionalMapper.java
===================================================================
--- jpa/src/main/java/org/apache/james/mailbox/jpa/JPATransactionalMapper.java	(Revision 5814)
+++ jpa/src/main/java/org/apache/james/mailbox/jpa/JPATransactionalMapper.java	(Revision 5832)
@@ -52,8 +52,10 @@
     }
 
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.transaction.TransactionalMapper#begin()
      */
+    @Override
     protected void begin() throws MailboxException {
         try {
             getEntityManager().getTransaction().begin();
@@ -64,7 +66,9 @@
 
     /**
      * Commit the Transaction and close the EntityManager
+     * @throws org.apache.james.mailbox.exception.MailboxException
      */
+    @Override
     protected void commit() throws MailboxException {
         try {
             getEntityManager().getTransaction().commit();
@@ -74,8 +78,10 @@
     }
 
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.transaction.TransactionalMapper#rollback()
      */
+    @Override
     protected void rollback() throws MailboxException {
         EntityTransaction transaction = entityManager.getTransaction();
         // check if we have a transaction to rollback
@@ -87,6 +93,7 @@
     /**
      * Close open {@link EntityManager}
      */
+    @Override
     public void endRequest() {
         if (entityManager != null) {
             if (entityManager.isOpen())
Index: jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java
===================================================================
--- jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java	(Revision 5814)
+++ jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java	(Revision 5832)
@@ -51,6 +51,7 @@
     /**
      * Commit the transaction. If the commit fails due a conflict in a unique key constraint a {@link MailboxExistsException}
      * will get thrown
+     * @throws org.apache.james.mailbox.exception.MailboxException
      */
     @Override
     protected void commit() throws MailboxException {
@@ -69,8 +70,10 @@
     }
     
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.mail.MailboxMapper#save(Mailbox)
      */
+    @Override
     public void save(Mailbox<Long> mailbox) throws MailboxException {
         try {
             this.lastMailboxName = mailbox.getName();
@@ -81,8 +84,11 @@
     }
 
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
+     * @throws org.apache.james.mailbox.exception.MailboxNotFoundException
      * @see org.apache.james.mailbox.store.mail.MailboxMapper#findMailboxByPath(MailboxPath)
      */
+    @Override
     public Mailbox<Long> findMailboxByPath(MailboxPath mailboxPath) throws MailboxException, MailboxNotFoundException {
         try {
             if (mailboxPath.getUser() == null) {
@@ -98,8 +104,10 @@
     }
 
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.mail.MailboxMapper#delete(Mailbox)
      */
+    @Override
     public void delete(Mailbox<Long> mailbox) throws MailboxException {
         try {  
             getEntityManager().createNamedQuery("deleteMessages").setParameter("idParam", mailbox.getMailboxId()).executeUpdate();
@@ -110,9 +118,11 @@
     }
 
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.mail.MailboxMapper#findMailboxWithPathLike(MailboxPath)
      */
     @SuppressWarnings("unchecked")
+    @Override
     public List<Mailbox<Long>> findMailboxWithPathLike(MailboxPath path) throws MailboxException {
         try {
             if (path.getUser() == null) {
@@ -142,8 +152,11 @@
     }
     
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
+     * @throws org.apache.james.mailbox.exception.MailboxNotFoundException
      * @see org.apache.james.mailbox.store.mail.MailboxMapper#hasChildren(Mailbox, char)
      */
+    @Override
     public boolean hasChildren(Mailbox<Long> mailbox, char delimiter) throws MailboxException,
             MailboxNotFoundException {
         final String name = mailbox.getName() + delimiter + SQL_WILDCARD_CHAR; 
@@ -157,9 +170,11 @@
     }
 
 	/**
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.mail.MailboxMapper#list()
      */
     @SuppressWarnings("unchecked")
+    @Override
     public List<Mailbox<Long>> list() throws MailboxException{
         try {
             return getEntityManager().createNamedQuery("listMailboxes").getResultList();
Index: jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMessage.java
===================================================================
--- jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMessage.java	(Revision 0)
+++ jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMessage.java	(Revision 5832)
@@ -0,0 +1,112 @@
+/****************************************************************
+ * 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.mailbox.jpa.mail.model;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+
+import javax.mail.Flags;
+import javax.mail.internet.SharedInputStream;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Index;
+import javax.persistence.Lob;
+import javax.persistence.Table;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.mail.model.Message;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+
+@Entity(name="Message")
+@Table(name="JAMES_MAIL", indexes = {
+    @Index(columnList="MAIL_MODSEQ"),
+    @Index(columnList="MAIL_IS_DELETED"),
+    @Index(columnList="MAIL_IS_RECENT"),
+    @Index(columnList="MAIL_IS_SEEN")
+})
+public class JPAMessage extends AbstractJPAMessage {
+
+    /** The value for the body field. Lazy loaded */
+    /** We use a max length to represent 1gb data. Thats prolly overkill, but who knows */
+    @Basic(optional = false, fetch = FetchType.LAZY)
+    @Column(name = "MAIL_BYTES", length = 1048576000, nullable = false)
+    @Lob private byte[] body;
+
+
+    /** The value for the header field. Lazy loaded */
+    /** We use a max length to represent 10mb data. Thats prolly overkill, but who knows */
+    @Basic(optional = false, fetch = FetchType.LAZY)
+    @Column(name = "HEADER_BYTES", length = 10485760, nullable = false)
+    @Lob private byte[] header;
+    
+    @Deprecated
+    public JPAMessage() {}
+
+    public JPAMessage(JPAMailbox mailbox,Date internalDate, int size, Flags flags, SharedInputStream content, int bodyStartOctet, final PropertyBuilder propertyBuilder) throws MailboxException {
+        super(mailbox, internalDate, flags, size ,bodyStartOctet, propertyBuilder);
+        try {
+            int headerEnd = bodyStartOctet;
+            if (headerEnd < 0) {
+                headerEnd = 0;
+            }
+            this.header = IOUtils.toByteArray(content.newStream(0, headerEnd));
+            this.body = IOUtils.toByteArray(content.newStream(getBodyStartOctet(), -1));
+
+        } catch (IOException e) {
+            throw new MailboxException("Unable to parse message",e);
+        }
+    }
+
+    /**
+     * Create a copy of the given message
+     * 
+     * @param message
+     * @throws MailboxException 
+     */
+    public JPAMessage(JPAMailbox mailbox, long uid, long modSeq, Message<?> message) throws MailboxException{
+        super(mailbox, uid, modSeq, message);
+        try {
+            this.body = IOUtils.toByteArray(message.getBodyContent());
+            this.header = IOUtils.toByteArray(message.getHeaderContent());
+        } catch (IOException e) {
+            throw new MailboxException("Unable to parse message",e);
+        }
+    }
+
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getBodyContent()
+     */
+    public InputStream getBodyContent() throws IOException {
+        return new ByteArrayInputStream(body);
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getHeaderContent()
+     */
+    public InputStream getHeaderContent() throws IOException {
+        return new ByteArrayInputStream(header);
+    }
+
+}
Index: jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAProperty.java
===================================================================
--- jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAProperty.java	(Revision 5814)
+++ jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAProperty.java	(Revision 5832)
@@ -23,28 +23,29 @@
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
+import javax.persistence.Index;
 import javax.persistence.Table;
-
+import javax.persistence.Version;
 import org.apache.james.mailbox.store.mail.model.Property;
-import org.apache.openjpa.persistence.jdbc.Index;
 
 @Entity(name = "Property")
-@Table(name = "JAMES_MAIL_PROPERTY")
+@Table(
+    name = "JAMES_MAIL_PROPERTY",
+    indexes = {
+        @Index(name = "INDEX_PROPERTY_LINE_NUMBER", columnList = "PROPERTY_LINE_NUMBER")
+    }
+)
 public class JPAProperty implements Property {
 
     /** The system unique key */
     @Id
     @GeneratedValue
     @Column(name = "PROPERTY_ID", nullable = true)
-    // TODO The columnNames are not interpreted, see OPENJPA-223 to fix
-    // MAILBOX-186
-    @Index(name = "INDEX_PROPERTY_MSG_ID", columnNames = { "MAILBOX_ID", "MAIL_UID" })
     private long id;
 
     /** Order within the list of properties */
     @Basic(optional = false)
     @Column(name = "PROPERTY_LINE_NUMBER", nullable = false)
-    @Index(name = "INDEX_PROPERTY_LINE_NUMBER")
     private int line;
 
     /** Local part of the name of this property */
@@ -62,6 +63,9 @@
     @Column(name = "PROPERTY_VALUE", nullable = false, length = 1024)
     private String value;
 
+    @Version
+    private long version;
+
     /**
      * @deprecated enhancement only
      */
@@ -142,6 +146,14 @@
         return value;
     }
 
+    public long getVersion() {
+        return version;
+    }
+
+    public void setVersion(long _version) {
+        version = _version;
+    }
+
     @Override
     public int hashCode() {
         final int PRIME = 31;
Index: jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/AbstractJPAMessage.java
===================================================================
--- jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/AbstractJPAMessage.java	(Revision 0)
+++ jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/AbstractJPAMessage.java	(Revision 5832)
@@ -0,0 +1,533 @@
+/****************************************************************
+ * 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.mailbox.jpa.mail.model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import javax.mail.Flags;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.OrderBy;
+import javax.persistence.Version;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.mail.model.AbstractMessage;
+import org.apache.james.mailbox.store.mail.model.Message;
+import org.apache.james.mailbox.store.mail.model.Property;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+
+/**
+ * Abstract base class for JPA based implementations of {@link AbstractMessage}
+ */
+@IdClass(AbstractJPAMessage.MailboxIdUidKey.class)
+@NamedQueries({
+    @NamedQuery(name="findRecentMessageUidsInMailbox",
+            query="SELECT message.uid FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.recent = TRUE"),
+    @NamedQuery(name="findUnseenMessagesInMailboxOrderByUid",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.seen = FALSE ORDER BY message.uid ASC"),
+    @NamedQuery(name="findMessagesInMailbox",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam"),
+    @NamedQuery(name="findMessagesInMailboxBetweenUIDs",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid BETWEEN :fromParam AND :toParam"),        
+    @NamedQuery(name="findMessagesInMailboxWithUID",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid=:uidParam"),                    
+    @NamedQuery(name="findMessagesInMailboxAfterUID",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid>=:uidParam"),                    
+    @NamedQuery(name="findDeletedMessagesInMailbox",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.deleted=TRUE"),        
+    @NamedQuery(name="findDeletedMessagesInMailboxBetweenUIDs",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid BETWEEN :fromParam AND :toParam AND message.deleted=TRUE"),        
+    @NamedQuery(name="findDeletedMessagesInMailboxWithUID",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid=:uidParam AND message.deleted=TRUE"),                    
+    @NamedQuery(name="findDeletedMessagesInMailboxAfterUID",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid>=:uidParam AND message.deleted=TRUE"),          
+
+    @NamedQuery(name="deleteDeletedMessagesInMailbox",
+            query="DELETE FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.deleted=TRUE"),        
+    @NamedQuery(name="deleteDeletedMessagesInMailboxBetweenUIDs",
+            query="DELETE FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid BETWEEN :fromParam AND :toParam AND message.deleted=TRUE"),        
+    @NamedQuery(name="deleteDeletedMessagesInMailboxWithUID",
+            query="DELETE FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid=:uidParam AND message.deleted=TRUE"),                    
+    @NamedQuery(name="deleteDeletedMessagesInMailboxAfterUID",
+            query="DELETE FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid>=:uidParam AND message.deleted=TRUE"),  
+                    
+    @NamedQuery(name="countUnseenMessagesInMailbox",
+            query="SELECT COUNT(message) FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.seen=FALSE"),                     
+    @NamedQuery(name="countMessagesInMailbox",
+            query="SELECT COUNT(message) FROM Message message WHERE message.mailbox.mailboxId = :idParam"),                    
+    @NamedQuery(name="deleteMessages",
+            query="DELETE FROM Message message WHERE message.mailbox.mailboxId = :idParam"),
+    @NamedQuery(name="findLastUidInMailbox",
+            query="SELECT message.uid FROM Message message WHERE message.mailbox.mailboxId = :idParam ORDER BY message.uid DESC"),
+    @NamedQuery(name="findHighestModSeqInMailbox",
+            query="SELECT message.modSeq FROM Message message WHERE message.mailbox.mailboxId = :idParam ORDER BY message.modSeq DESC"),
+    @NamedQuery(name="deleteAllMemberships",
+            query="DELETE FROM Message message")
+})
+@MappedSuperclass
+public abstract class AbstractJPAMessage extends AbstractMessage<Long> {
+
+
+
+    private static final String TOSTRING_SEPARATOR = " ";
+
+    /** Identifies composite key */
+    public static class MailboxIdUidKey implements Serializable {
+
+        private static final long serialVersionUID = 7847632032426660997L;
+
+        public MailboxIdUidKey() {}
+
+        /** The value for the mailbox field */
+        public long mailbox;
+        
+        /** The value for the uid field */
+        public long uid;
+
+        @Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + (int) (mailbox ^ (mailbox >>> 32));
+            result = PRIME * result + (int) (uid ^ (uid >>> 32));
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final MailboxIdUidKey other = (MailboxIdUidKey) obj;
+            if (mailbox != other.mailbox)
+                return false;
+            if (uid != other.uid)
+                return false;
+            return true;
+        }
+
+    }
+
+    /** The value for the mailboxId field */
+    @Id
+    @ManyToOne(
+            cascade = {
+                    CascadeType.PERSIST, 
+                    CascadeType.REFRESH, 
+                    CascadeType.MERGE}, 
+            fetch=FetchType.LAZY)
+    @JoinColumn(name = "MAILBOX_ID", nullable = true)
+    private JPAMailbox mailbox;
+
+    /** The value for the uid field */
+    @Id
+    @Column(name = "MAIL_UID")
+    private long uid;
+
+    /** The value for the modSeq field */
+    @Column(name = "MAIL_MODSEQ")
+    private long modSeq;
+
+    /** The value for the internalDate field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_DATE")
+    private Date internalDate;
+
+    /** The value for the answered field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_IS_ANSWERED", nullable = false)
+    private boolean answered = false;
+
+    /** The value for the deleted field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_IS_DELETED", nullable = false)
+    private boolean deleted = false;
+
+    /** The value for the draft field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_IS_DRAFT", nullable = false)
+    private boolean draft = false;
+
+    /** The value for the flagged field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_IS_FLAGGED", nullable = false)
+    private boolean flagged = false;
+
+    /** The value for the recent field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_IS_RECENT", nullable = false)
+    private boolean recent = false;
+
+    /** The value for the seen field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_IS_SEEN", nullable = false)
+    private boolean seen = false;
+
+    
+    /** The first body octet */
+    @Basic(optional = false)
+    @Column(name = "MAIL_BODY_START_OCTET", nullable = false)
+    private int bodyStartOctet;
+    
+    /** Number of octets in the full document content */
+    @Basic(optional = false)
+    @Column(name = "MAIL_CONTENT_OCTETS_COUNT", nullable = false)
+    private long contentOctets;
+    
+    /** MIME media type */
+    @Basic(optional = true)
+    @Column(name = "MAIL_MIME_TYPE", nullable = true, length = 200)
+    private String mediaType;
+    
+    /** MIME sub type */
+    @Basic(optional = true)
+    @Column(name = "MAIL_MIME_SUBTYPE", nullable = true, length = 200)
+    private String subType;
+    
+    /** THE CRFL count when this document is textual, null otherwise */
+    @Basic(optional = true)
+    @Column(name = "MAIL_TEXTUAL_LINE_COUNT", nullable = true)
+    private Long textualLineCount;
+    
+    @Version
+    private long version;
+
+    /** Meta data for this message */
+    @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY)
+    @OrderBy("line")
+    private List<JPAProperty> properties;
+
+    @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY)
+    @OrderBy("id")
+    private List<JPAUserFlag> userFlags;
+    
+    @Deprecated
+    public AbstractJPAMessage() {}
+
+    public AbstractJPAMessage(JPAMailbox mailbox, Date internalDate, Flags flags, final long contentOctets, final int bodyStartOctet, final PropertyBuilder propertyBuilder) {
+        super();
+        this.mailbox = mailbox;
+        this.internalDate = internalDate;
+        userFlags = new ArrayList<JPAUserFlag>();
+
+        setFlags(flags);        
+        this.contentOctets = contentOctets;
+        this.bodyStartOctet = bodyStartOctet;
+        this.textualLineCount = propertyBuilder.getTextualLineCount();
+        this.mediaType = propertyBuilder.getMediaType();
+        this.subType = propertyBuilder.getSubType();
+        final List<Property> properties = propertyBuilder.toProperties();
+        this.properties = new ArrayList<JPAProperty>(properties.size());
+        int order = 0;
+        for (final Property property:properties) {
+            this.properties.add(new JPAProperty(property, order++));
+        }
+        
+    }
+
+    /**
+     * Constructs a copy of the given message.
+     * All properties are cloned except mailbox and UID.
+     * @param mailbox new mailbox
+     * @param uid new UID
+     * @param modSeq new modSeq
+     * @param original message to be copied, not null
+     * @throws IOException 
+     */
+    public AbstractJPAMessage(JPAMailbox mailbox, long uid, long modSeq,  Message<?> original) throws MailboxException {
+        super();
+        this.mailbox = mailbox;
+        this.uid = uid;
+        this.modSeq = modSeq;
+        this.userFlags = new ArrayList<JPAUserFlag>();
+        setFlags(original.createFlags());
+        
+        // A copy of a message is recent 
+        // See MAILBOX-85
+        // FIXME: does not belong here in a logical sense (there should be a testMailbox85 unit test
+        // in some mailbox storage-independent module like API)
+        this.recent = true;
+
+        this.contentOctets = original.getFullContentOctets();
+        this.bodyStartOctet = (int) (original.getFullContentOctets() - original.getBodyOctets());
+        this.internalDate = original.getInternalDate();
+
+
+        PropertyBuilder pBuilder = new PropertyBuilder(original.getProperties());
+        this.textualLineCount = original.getTextualLineCount();
+        this.mediaType = original.getMediaType();
+        this.subType = original.getSubType();
+        final List<Property> properties = pBuilder.toProperties();
+        this.properties = new ArrayList<JPAProperty>(properties.size());
+        int order = 0;
+        for (final Property property:properties) {
+            this.properties.add(new JPAProperty(property, order++));
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        final int PRIME = 31;
+        int result = 1;
+        result = PRIME * result + (int) (getMailboxId() ^ (getMailboxId() >>> 32));
+        result = PRIME * result + (int) (uid ^ (uid >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final AbstractJPAMessage other = (AbstractJPAMessage) obj;
+        if (getMailboxId() != null) {
+            if (!getMailboxId().equals(other.getMailboxId()))
+            return false;
+        } else {
+            if (other.getMailboxId() != null)
+            return false;
+        }
+        if (uid != other.uid)
+            return false;
+        return true;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getModSeq()
+     */
+    public long getModSeq() {
+        return modSeq;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#setModSeq(long)
+     */
+    public void setModSeq(long modSeq) {
+        this.modSeq = modSeq;
+    }
+    
+    /**
+     * Gets the top level MIME content media type.
+     * 
+     * @return top level MIME content media type, or null if default
+     */
+    public String getMediaType() {
+        return mediaType;
+    }
+    
+    /**
+     * Gets the MIME content subtype.
+     * 
+     * @return the MIME content subtype, or null if default
+     */
+    public String getSubType() {
+        return subType;
+    }
+
+    /**
+     * Gets a read-only list of meta-data properties.
+     * For properties with multiple values, this list will contain
+     * several enteries with the same namespace and local name.
+     * @return unmodifiable list of meta-data, not null
+     */
+    public List<Property> getProperties() {
+        return new ArrayList<Property>(properties);
+    }
+    
+    /**
+     * Gets the number of CRLF in a textual document.
+     * @return CRLF count when document is textual,
+     * null otherwise
+     */
+    public Long getTextualLineCount() {
+        return textualLineCount;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getFullContentOctets()
+     */
+    public long getFullContentOctets() {
+        return contentOctets;
+    }
+
+    @Override
+    protected int getBodyStartOctet() {
+        return bodyStartOctet;
+    }
+    
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getInternalDate()
+     */
+    public Date getInternalDate() {
+        return internalDate;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getMailboxId()
+     */
+    public Long getMailboxId() {
+        return getMailbox().getMailboxId();
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getUid()
+     */
+    public long getUid() {
+        return uid;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#isAnswered()
+     */
+    public boolean isAnswered() {
+        return answered;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#isDeleted()
+     */
+    public boolean isDeleted() {
+        return deleted;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#isDraft()
+     */
+    public boolean isDraft() {
+        return draft;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#isFlagged()
+     */
+    public boolean isFlagged() {
+        return flagged;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#isRecent()
+     */
+    public boolean isRecent() {
+        return recent;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#isSeen()
+     */
+    public boolean isSeen() {
+        return seen;
+    }
+    
+    public void setUid(long uid) {
+        this.uid = uid;
+    }
+
+    public long getVersion() {
+        return version;
+    }
+
+    public void setVersion(long _version) {
+        version = _version;
+    }
+    
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#setFlags(javax.mail.Flags)
+     */
+    @Override
+    public void setFlags(Flags flags) {
+        answered = flags.contains(Flags.Flag.ANSWERED);
+        deleted = flags.contains(Flags.Flag.DELETED);
+        draft = flags.contains(Flags.Flag.DRAFT);
+        flagged = flags.contains(Flags.Flag.FLAGGED);
+        recent = flags.contains(Flags.Flag.RECENT);
+        seen = flags.contains(Flags.Flag.SEEN);
+        
+        String[] userflags =  flags.getUserFlags();
+        userFlags.clear();
+        for (int i = 0 ; i< userflags.length; i++) {
+            userFlags.add(new JPAUserFlag(userflags[i]));
+        }
+    }
+
+    /**
+     * Utility getter on Mailbox.
+     */
+    public JPAMailbox getMailbox() {
+        return mailbox;
+    }
+
+    /**
+     * This implementation supports user flags
+     * 
+     * 
+     */
+    @Override
+    protected String[] createUserFlags() {
+        String[] flags = new String[userFlags.size()];
+        for (int i = 0; i < userFlags.size(); i++) {
+            flags[i] = userFlags.get(i).getName();
+        }
+        return flags;
+    }
+
+    /**
+     * Utility setter on Mailbox.
+     */
+    public void setMailbox(JPAMailbox mailbox) {
+        this.mailbox = mailbox;
+    }
+
+
+    @Override
+    public String toString() {
+        final String retValue = 
+            "message("
+            + "mailboxId = " + this.getMailboxId() + TOSTRING_SEPARATOR
+            + "uid = " + this.uid + TOSTRING_SEPARATOR
+            + "internalDate = " + this.internalDate + TOSTRING_SEPARATOR
+            + "answered = " + this.answered + TOSTRING_SEPARATOR
+            + "deleted = " + this.deleted + TOSTRING_SEPARATOR
+            + "draft = " + this.draft + TOSTRING_SEPARATOR
+            + "flagged = " + this.flagged + TOSTRING_SEPARATOR
+            + "recent = " + this.recent + TOSTRING_SEPARATOR
+            + "seen = " + this.seen + TOSTRING_SEPARATOR
+            + " )";
+        return retValue;
+    }
+    
+
+}
Index: jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAUserFlag.java
===================================================================
--- jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAUserFlag.java	(Revision 5814)
+++ jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAUserFlag.java	(Revision 5832)
@@ -24,6 +24,7 @@
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
 import javax.persistence.Table;
+import javax.persistence.Version;
 
 @Entity(name="UserFlag")
 @Table(name="JAMES_MAIL_USERFLAG")
@@ -40,8 +41,10 @@
     @Basic(optional = false)
     @Column(name = "USERFLAG_NAME", nullable = false, length = 500)
     private String name;
+
+    @Version
+    private long version;
     
-    
     /**
      * @deprecated enhancement only
      */
@@ -75,6 +78,14 @@
         return name;
     }
 
+    public long getVersion() {
+        return version;
+    }
+
+    public void setVersion(long _version) {
+        version = _version;
+    }
+
     @Override
     public int hashCode() {
         final int PRIME = 31;
Index: jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMailbox.java
===================================================================
--- jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMailbox.java	(Revision 5814)
+++ jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMailbox.java	(Revision 5832)
@@ -26,7 +26,7 @@
 import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
 import javax.persistence.Table;
-
+import javax.persistence.Version;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.SimpleMailboxACL;
@@ -36,7 +36,7 @@
 @Table(name="JAMES_MAILBOX")
 @NamedQueries({
     @NamedQuery(name="findMailboxById",
-        query="SELECT mailbox FROM Mailbox mailbox WHERE mailbox.mailbox.mailboxId = :idParam"),
+        query="SELECT mailbox FROM Mailbox mailbox WHERE mailbox.mailboxId = :idParam"),
     @NamedQuery(name="findMailboxByName",
         query="SELECT mailbox FROM Mailbox mailbox WHERE mailbox.name = :nameParam and mailbox.user is NULL and mailbox.namespace= :namespaceParam"),
     @NamedQuery(name="findMailboxByNameWithUser",
@@ -93,7 +93,10 @@
     @Basic(optional = false)
     @Column(name = "MAILBOX_HIGHEST_MODSEQ", nullable = false)
     private long highestModSeq;
-    
+
+    @Version
+    private long version;
+
     /**
      * JPA only
      */
@@ -215,6 +218,14 @@
         return ++highestModSeq;
     }
     
+    public long getVersion() {
+        return version;
+    }
+
+    public void setVersion(long _version) {
+        version = _version;
+    }
+
     /* (non-Javadoc)
      * @see org.apache.james.mailbox.store.mail.model.Mailbox#getACL()
      */
Index: jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java
===================================================================
--- jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java	(Revision 5814)
+++ jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMessageMapper.java	(Revision 5832)
@@ -18,24 +18,22 @@
  ****************************************************************/
 package org.apache.james.mailbox.jpa.mail;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.EntityTransaction;
 import javax.persistence.PersistenceException;
 import javax.persistence.Query;
-
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.jpa.mail.model.AbstractJPAMessage;
 import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.AbstractJPAMessage;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAEncryptedMessage;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMessage;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAStreamingMessage;
+import org.apache.james.mailbox.jpa.mail.model.JPAMessage;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageRange.Type;
@@ -46,7 +44,6 @@
 import org.apache.james.mailbox.store.mail.UidProvider;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.mail.model.Message;
-import org.apache.openjpa.persistence.ArgumentException;
 
 /**
  * JPA implementation of a {@link MessageMapper}. This class is not thread-safe!
@@ -68,15 +65,18 @@
      * @return entitymanger
      */
     public EntityManager getEntityManager() {
-        if (entityManager != null)
+        if (entityManager != null) {
             return entityManager;
+        }
         entityManager = entityManagerFactory.createEntityManager();
         return entityManager;
     }
 
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.transaction.TransactionalMapper#begin()
      */
+    @Override
     protected void begin() throws MailboxException {
         try {
             getEntityManager().getTransaction().begin();
@@ -87,7 +87,9 @@
 
     /**
      * Commit the Transaction and close the EntityManager
+     * @throws org.apache.james.mailbox.exception.MailboxException
      */
+    @Override
     protected void commit() throws MailboxException {
         try {
             getEntityManager().getTransaction().commit();
@@ -97,8 +99,10 @@
     }
 
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.transaction.TransactionalMapper#rollback()
      */
+    @Override
     protected void rollback() throws MailboxException {
         EntityTransaction transaction = entityManager.getTransaction();
         // check if we have a transaction to rollback
@@ -110,19 +114,26 @@
     /**
      * Close open {@link EntityManager}
      */
+    @Override
     public void endRequest() {
         if (entityManager != null) {
-            if (entityManager.isOpen())
+            if (entityManager.isOpen()) {
                 entityManager.close();
+            }
             entityManager = null;
         }
     }
 
     /**
+     * @param fType
+     * @param max
+     * @return
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.mail.MessageMapper#findInMailbox(org.apache.james.mailbox.store.mail.model.Mailbox,
      *      org.apache.james.mailbox.model.MessageRange,
      *      org.apache.james.mailbox.store.mail.MessageMapper.FetchType, int)
      */
+    @Override
     public Iterator<Message<Long>> findInMailbox(Mailbox<Long> mailbox, MessageRange set, FetchType fType, int max)
             throws MailboxException {
         try {
@@ -155,8 +166,10 @@
     }
 
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.mail.MessageMapper#countMessagesInMailbox(Mailbox)
      */
+    @Override
     public long countMessagesInMailbox(Mailbox<Long> mailbox) throws MailboxException {
         try {
             return (Long) getEntityManager().createNamedQuery("countMessagesInMailbox")
@@ -167,8 +180,10 @@
     }
 
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.mail.MessageMapper#countUnseenMessagesInMailbox(Mailbox)
      */
+    @Override
     public long countUnseenMessagesInMailbox(Mailbox<Long> mailbox) throws MailboxException {
         try {
             return (Long) getEntityManager().createNamedQuery("countUnseenMessagesInMailbox")
@@ -179,9 +194,11 @@
     }
 
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.mail.MessageMapper#delete(org.apache.james.mailbox.store.mail.model.Mailbox,
      *      org.apache.james.mailbox.store.mail.model.Message)
      */
+    @Override
     public void delete(Mailbox<Long> mailbox, Message<Long> message) throws MailboxException {
         try {
             getEntityManager().remove(message);
@@ -191,9 +208,11 @@
     }
 
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.mail.MessageMapper#findFirstUnseenMessageUid(Mailbox)
      */
     @SuppressWarnings("unchecked")
+    @Override
     public Long findFirstUnseenMessageUid(Mailbox<Long> mailbox) throws MailboxException {
         try {
             Query query = getEntityManager().createNamedQuery("findUnseenMessagesInMailboxOrderByUid").setParameter(
@@ -211,9 +230,11 @@
     }
 
     /**
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.mail.MessageMapper#findRecentMessageUidsInMailbox(Mailbox)
      */
     @SuppressWarnings("unchecked")
+    @Override
     public List<Long> findRecentMessageUidsInMailbox(Mailbox<Long> mailbox) throws MailboxException {
         try {
             Query query = getEntityManager().createNamedQuery("findRecentMessageUidsInMailbox").setParameter("idParam",
@@ -266,6 +287,8 @@
     /**
      * (non-Javadoc)
      * 
+     * @return
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.mail.MessageMapper#move(org.apache.james.mailbox.store.mail.model.Mailbox,
      *      org.apache.james.mailbox.store.mail.model.Message)
      */
@@ -275,31 +298,30 @@
     }
 
     /**
+     * @return
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.mail.AbstractMessageMapper#copy(Mailbox,
      *      long, long, Message)
      */
+    @Override
     protected MessageMetaData copy(Mailbox<Long> mailbox, long uid, long modSeq, Message<Long> original)
             throws MailboxException {
         Message<Long> copy;
-        if (original instanceof JPAStreamingMessage) {
-            copy = new JPAStreamingMessage((JPAMailbox) mailbox, uid, modSeq, original);
-        } else if (original instanceof JPAEncryptedMessage) {
-            copy = new JPAEncryptedMessage((JPAMailbox) mailbox, uid, modSeq, original);
-        } else {
-            copy = new JPAMessage((JPAMailbox) mailbox, uid, modSeq, original);
-        }
+        copy = new JPAMessage((JPAMailbox) mailbox, uid, modSeq, original);
         return save(mailbox, copy);
     }
 
     /**
+     * @return
+     * @throws org.apache.james.mailbox.exception.MailboxException
      * @see org.apache.james.mailbox.store.mail.AbstractMessageMapper#save(Mailbox,
      *      Message)
      */
+    @Override
     protected MessageMetaData save(Mailbox<Long> mailbox, Message<Long> message) throws MailboxException {
 
         try {
-
-            // We need to reload a "JPA attached" mailbox, because the provide
+            // We need to reload a "JPA attached" mailbox, because the provided
             // mailbox is already "JPA detached"
             // If we don't this, we will get an
             // org.apache.openjpa.persistence.ArgumentException.
@@ -310,8 +332,6 @@
             return new SimpleMessageMetaData(message);
         } catch (PersistenceException e) {
             throw new MailboxException("Save of message " + message + " failed in mailbox " + mailbox, e);
-        } catch (ArgumentException e) {
-            throw new MailboxException("Save of message " + message + " failed in mailbox " + mailbox, e);
         }
     }
 
@@ -320,8 +340,9 @@
         Query query = getEntityManager().createNamedQuery("findMessagesInMailboxAfterUID")
                 .setParameter("idParam", mailbox.getMailboxId()).setParameter("uidParam", uid);
 
-        if (batchSize > 0)
+        if (batchSize > 0) {
             query.setMaxResults(batchSize);
+        }
 
         return query.getResultList();
     }
@@ -340,8 +361,9 @@
                 .setParameter("idParam", mailbox.getMailboxId()).setParameter("fromParam", from)
                 .setParameter("toParam", to);
 
-        if (batchSize > 0)
+        if (batchSize > 0) {
             query.setMaxResults(batchSize);
+        }
 
         return query.getResultList();
     }
@@ -357,8 +379,7 @@
 
     private Map<Long, MessageMetaData> createMetaData(List<Message<Long>> uids) {
         final Map<Long, MessageMetaData> data = new HashMap<Long, MessageMetaData>();
-        for (int i = 0; i < uids.size(); i++) {
-            Message<Long> m = uids.get(i);
+        for (Message<Long> m : uids) {
             data.put(m.getUid(), new SimpleMessageMetaData(m));
         }
         return data;
Index: jpa/src/main/resources/james-database.properties
===================================================================
--- jpa/src/main/resources/james-database.properties	(Revision 5814)
+++ jpa/src/main/resources/james-database.properties	(Revision 5832)
@@ -1,26 +0,0 @@
-#  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.
-#
-
-# See http://james.apache.org/server/3/config.html for usage
-
-database.driverClassName=org.apache.derby.jdbc.EmbeddedDriver
-database.url=jdbc:derby:../var/store/derby;create=true
-database.username=app
-database.password=app
-vendorAdapter.database=DERBY
-openjpa.streaming=false
Index: jpa/src/main/resources/META-INF/persistence.xml
===================================================================
--- jpa/src/main/resources/META-INF/persistence.xml	(Revision 5814)
+++ jpa/src/main/resources/META-INF/persistence.xml	(Revision 5832)
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.    
--->
-
-<persistence xmlns="http://java.sun.com/xml/ns/persistence"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
-    version="2.0">
-
-    <persistence-unit name="James" transaction-type="RESOURCE_LOCAL">
-        <class>org.apache.james.mailbox.jpa.mail.model.JPAMailbox</class>
-        <class>org.apache.james.mailbox.jpa.mail.model.JPAUserFlag</class>
-        <class>org.apache.james.mailbox.jpa.mail.model.openjpa.AbstractJPAMessage</class>
-        <class>org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMessage</class>
-        <class>org.apache.james.mailbox.jpa.mail.model.JPAProperty</class>
-        <class>org.apache.james.mailbox.jpa.user.model.JPASubscription</class>
-        <properties>
-            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
-            <property name="openjpa.jdbc.MappingDefaults" value="ForeignKeyDeleteAction=cascade, JoinForeignKeyDeleteAction=cascade"/>
-            <property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)"/>
-            <property name="openjpa.jdbc.QuerySQLCache" value="false"/>
-        </properties>
-
-    </persistence-unit>
-
-</persistence>
Index: jpa/src/main/resources/META-INF/spring/mailbox-jpa.xml
===================================================================
--- jpa/src/main/resources/META-INF/spring/mailbox-jpa.xml	(Revision 5814)
+++ jpa/src/main/resources/META-INF/spring/mailbox-jpa.xml	(Revision 5832)
@@ -29,13 +29,12 @@
           
     <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
 
-    <bean id="jpa-mailboxmanager" class="org.apache.james.mailbox.jpa.openjpa.OpenJPAMailboxManager" init-method="init">
+    <bean id="jpa-mailboxmanager" class="org.apache.james.mailbox.jpa.JPAMailboxManager" init-method="init">
         <constructor-arg index="0" ref="jpa-sessionMapperFactory"/>
         <constructor-arg index="1" ref="authenticator"/>
         <constructor-arg index="2" ref="jpa-locker"/>
-        <constructor-arg index="3" type="boolean" value="false"/>
-        <constructor-arg index="4" ref="aclResolver"/>
-        <constructor-arg index="5" ref="groupMembershipResolver"/>
+        <constructor-arg index="3" ref="aclResolver"/>
+        <constructor-arg index="4" ref="groupMembershipResolver"/>
     </bean>
     <bean id ="jpa-subscriptionManager" class="org.apache.james.mailbox.jpa.JPASubscriptionManager">
         <constructor-arg index="0" ref="jpa-sessionMapperFactory"/>
@@ -55,29 +54,5 @@
     </bean>
     <alias name="jvm-locker" alias="jpa-locker"/>
 
-    <!-- 
-       Database DataSource
-    -->
-          
-    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
-        <property name="ignoreUnresolvablePlaceholders" value="true"/>
-        <property name ="location" value="classpath:james-database.properties"/>
-    </bean>
-    <bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
-        <property name="driverClassName" value="${database.driverClassName}" />
-        <property name="url" value="${database.url}" />
-        <property name="username" value="${database.username}" />
-        <property name="password" value="${database.password}" />
-    </bean>
-    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
-        <property name="dataSource" ref="datasource"/>
-        <property name="jpaVendorAdapter" ref="vendorAdapter"/>
-        <property name="persistenceUnitName" value="James"/>
-    </bean>
-    <bean id="vendorAdapter" class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
-        <property name="database" value="${vendorAdapter.database}"/>
-        <!-- set this to true for debugging purposes -->
-        <property name="showSql" value="false"/>
-    </bean>
 
 </beans>
Index: jpa/pom.xml
===================================================================
--- jpa/pom.xml	(Revision 5814)
+++ jpa/pom.xml	(Revision 5832)
@@ -31,6 +31,15 @@
     <name>Apache James :: Mailbox :: JPA</name>
     <packaging>bundle</packaging>
 
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.1</version>
+            </plugin>
+        </plugins>
+    </build>
+
     <dependencies>
         <dependency>
             <groupId>org.apache.james</groupId>
@@ -41,89 +50,23 @@
             <artifactId>apache-james-mailbox-store</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.openjpa</groupId>
-            <artifactId>openjpa</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.geronimo.specs</groupId>
-            <artifactId>geronimo-jpa_2.0_spec</artifactId>
-        </dependency>
-        <dependency>
             <groupId>${javax.mail.groupId}</groupId>
             <artifactId>${javax.mail.artifactId}</artifactId>
         </dependency>
+        
+        <!-- JPA 2.1 API: -->
         <dependency>
-            <groupId>org.jasypt</groupId>
-            <artifactId>jasypt</artifactId>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>javax.persistence</artifactId>
+            <version>2.1.0</version>
         </dependency>
+        
+        <!-- generate static metamodel classes for JPA Criteria API: -->
         <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-jpamodelgen</artifactId>
+            <version>4.3.5.Final</version>
+            <scope>provided</scope>
         </dependency>
-        <dependency>
-            <groupId>org.apache.james</groupId>
-            <artifactId>apache-james-mailbox-api</artifactId>
-            <scope>test</scope>
-            <type>test-jar</type>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.james</groupId>
-            <artifactId>apache-james-mailbox-store</artifactId>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.h2database</groupId>
-            <artifactId>h2</artifactId>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-simple</artifactId>
-            <scope>test</scope>
-        </dependency>
     </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>openjpa-maven-plugin</artifactId>
-                <version>1.1</version>
-                <configuration>
-                    <includes>org/apache/james/mailbox/jpa/*/model/**/*.class</includes>
-                    <excludes>org/apache/james/mailbox/jpa/mail/model/openjpa/EncryptDecryptHelper.class</excludes>
-                    <addDefaultConstructor>true</addDefaultConstructor>
-                    <enforcePropertyRestrictions>true</enforcePropertyRestrictions>
-                    <toolProperties>
-                        <property>
-                            <name>log</name>
-                            <value>TOOL=TRACE</value>
-                        </property>
-                        <property>
-                            <name>metaDataFactory</name>
-                            <value>
-                                jpa(Types=org.apache.james.mailbox.jpa.mail.model.JPAUserFlag;org.apache.james.mailbox.jpa.mail.model.JPAMailbox;org.apache.james.mailbox.jpa.mail.model.openjpa.AbstractJPAMessage;org.apache.james.mailbox.jpa.mail.model.openjpa.JPAEncryptedMessage;org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMessage;org.apache.james.mailbox.jpa.mail.model.openjpa.JPAStreamingMessage;org.apache.james.mailbox.jpa.mail.model.JPAProperty;org.apache.james.mailbox.jpa.user.model.JPASubscription)
-                            </value>
-                        </property>
-                    </toolProperties>
-                </configuration>
-                <executions>
-                    <execution>
-                        <id>enhancer</id>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>enhance</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
 </project>

Eigenschaftsänderungen: jpa
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target



Eigenschaftsänderungen: lucene
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target



Eigenschaftsänderungen: tool
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target



Eigenschaftsänderungen: jcr
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target


Index: maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirMailboxManagerTest.java
===================================================================
--- maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirMailboxManagerTest.java	(Revision 5814)
+++ maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirMailboxManagerTest.java	(Revision 5832)
@@ -18,7 +18,7 @@
  ****************************************************************/
 package org.apache.james.mailbox.maildir;
 
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 
 import java.io.File;
 import java.io.IOException;
@@ -30,7 +30,6 @@
 import org.apache.james.mailbox.acl.MailboxACLResolver;
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
-import org.apache.james.mailbox.exception.BadCredentialsException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxExistsException;
 import org.apache.james.mailbox.store.JVMMailboxPathLocker;
@@ -53,11 +52,9 @@
      */
     @Before
     public void setup() throws Exception {
-        if (OsDetector.isWindows()) {
-            System.out.println("Maildir tests work only on non-windows systems. So skip the test");
-        } else {
-          deleteMaildirTestDirectory();
-        }
+        assertFalse("Maildir tests work only on non-windows systems. So skip the test",
+                OsDetector.isWindows());
+        createMailboxManager();
     }
     
     /**
@@ -68,142 +65,62 @@
     @After
     public void tearDown() throws IOException {
         if (OsDetector.isWindows()) {
-            System.out.println("Maildir tests work only on non-windows systems. So skip the test");
-        } else {
-          deleteMaildirTestDirectory();
+            return;
         }
+        deleteMaildirTestDirectory();
     }
 
     /**
-     * @see org.apache.james.mailbox.AbstractMailboxManagerTest#testList()
+     * TODO Tests fail with /%user configuration.
+     * @throws MailboxException
+     * @throws UnsupportedEncodingException
+     * @throws IOException
      */
-    @Test
-    @Override
-    public void testList() throws MailboxException, UnsupportedEncodingException {
-        
-        if (OsDetector.isWindows()) {
-            System.out.println("Maildir tests work only on non-windows systems. So skip the test");
-        } else {
-
-            doTestListWithMaildirStoreConfiguration("/%domain/%user");
-
-            // TODO Tests fail with /%user configuration
-            try {
-                doTestListWithMaildirStoreConfiguration("/%user");
-                fail();
-            } catch (MailboxExistsException e) {
-                // This is expected as the there are many users which have the same localpart
-            }
-            // TODO Tests fail with /%fulluser configuration
-            doTestListWithMaildirStoreConfiguration("/%fulluser");
-
-        }
-            
+    // This is expected as the there are many users which have the same localpart
+    @Test(expected = MailboxExistsException.class)
+    public void testListSimpleUserMaildirStoreConfig() throws MailboxException, UnsupportedEncodingException, IOException {
+        createMailboxManager("/%user");
+        super.testList();
     }
-    
+
     /**
-     * @see org.apache.james.mailbox.AbstractMailboxManagerTest#testBasicOperations()
+     * TODO Tests fail with /%fulluser configuration.
+     * @throws MailboxException
+     * @throws UnsupportedEncodingException
+     * @throws IOException
      */
     @Test
-    @Override
-    public void testBasicOperations() throws BadCredentialsException, MailboxException, UnsupportedEncodingException {
-        
-        if (OsDetector.isWindows()) {
-            System.out.println("Maildir tests work only on non-windows systems. So skip the test");
-        } else {
-
-            MaildirStore store = new MaildirStore(MAILDIR_HOME + "/%domain/%user", new JVMMailboxPathLocker());
-            MaildirMailboxSessionMapperFactory mf = new MaildirMailboxSessionMapperFactory(store);
-            
-            MailboxACLResolver aclResolver = new UnionMailboxACLResolver();
-            GroupMembershipResolver groupMembershipResolver = new SimpleGroupMembershipResolver();
-
-            StoreMailboxManager<Integer> manager = new StoreMailboxManager<Integer>(mf, null, new JVMMailboxPathLocker(), aclResolver, groupMembershipResolver);
-            manager.init();
-            setMailboxManager(manager);
-            try {
-                super.testBasicOperations();
-            } finally {
-                try {
-                    deleteMaildirTestDirectory();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-       
-        }
-
+    public void testListFulluserMaildirStoreConfig() throws MailboxException, UnsupportedEncodingException, IOException {
+        createMailboxManager("/%fulluser");
+        super.testList();
     }
 
     /**
-     * @see org.apache.james.mailbox.AbstractMailboxManagerTest#testCreateSubFolderDirectly()
+     * @throws org.apache.james.mailbox.exception.MailboxException
+     * @see org.apache.james.mailbox.MailboxManagerTest#createMailboxManager()
      */
-    @Test
     @Override
-    public void testCreateSubFolderDirectly() throws BadCredentialsException, MailboxException { 
+    protected void createMailboxManager() throws MailboxException {
+        createMailboxManager("/%domain/%user");
+    }
 
-        if (OsDetector.isWindows()) {
-            System.out.println("Maildir tests work only on non-windows systems. So skip the test");
-        } else {
-
-            MaildirStore store = new MaildirStore(MAILDIR_HOME + "/%domain/%user", new JVMMailboxPathLocker());
-            MaildirMailboxSessionMapperFactory mf = new MaildirMailboxSessionMapperFactory(store);
-            MailboxACLResolver aclResolver = new UnionMailboxACLResolver();
-            GroupMembershipResolver groupMembershipResolver = new SimpleGroupMembershipResolver();
-
-            StoreMailboxManager<Integer> manager = new StoreMailboxManager<Integer>(mf, null, new JVMMailboxPathLocker(), aclResolver, groupMembershipResolver);
-            manager.init();
-            setMailboxManager(manager);
-            try {
-                super.testCreateSubFolderDirectly();
-            } finally {
-                try {
-                    deleteMaildirTestDirectory();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-       
-    
+    private void createMailboxManager(String maildirStoreConfiguration) throws MailboxException {
+        try {
+            deleteMaildirTestDirectory();
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
         }
 
-    }
-
-    /**
-     * Create the maildirStore with the provided configuration and executes the list() tests.
-     * Cleans the generated artifacts.
-     * 
-     * @param maildirStoreConfiguration
-     * @throws MailboxException
-     * @throws UnsupportedEncodingException
-     */
-    private void doTestListWithMaildirStoreConfiguration(String maildirStoreConfiguration) throws MailboxException, UnsupportedEncodingException {
         MaildirStore store = new MaildirStore(MAILDIR_HOME + maildirStoreConfiguration, new JVMMailboxPathLocker());
         MaildirMailboxSessionMapperFactory mf = new MaildirMailboxSessionMapperFactory(store);
+
         MailboxACLResolver aclResolver = new UnionMailboxACLResolver();
         GroupMembershipResolver groupMembershipResolver = new SimpleGroupMembershipResolver();
 
         StoreMailboxManager<Integer> manager = new StoreMailboxManager<Integer>(mf, null, new JVMMailboxPathLocker(), aclResolver, groupMembershipResolver);
         manager.init();
         setMailboxManager(manager);
-        try {
-            super.testList();
-        } finally {
-            try {
-                deleteMaildirTestDirectory();
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
     }
-
-    /**
-     * @see org.apache.james.mailbox.MailboxManagerTest#createMailboxManager()
-     */
-    @Override
-    protected void createMailboxManager() {
-        // Do nothing, the maildir mailboxManager is created in the test method.
-    }
    
     /**
      * Utility method to delete the test Maildir Directory.

Eigenschaftsänderungen: maildir
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target



Eigenschaftsänderungen: hbase
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target



Eigenschaftsänderungen: zoo-seq-provider
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target


Index: pom.xml
===================================================================
--- pom.xml	(Revision 5814)
+++ pom.xml	(Revision 5832)
@@ -54,6 +54,7 @@
         <module>hbase</module>
         <module>jcr</module>
         <module>jpa</module>
+        <module>openjpa</module>
         <module>lucene</module>
         <module>maildir</module>
         <module>memory</module>
@@ -93,11 +94,12 @@
         <javax.mail.version>1.4.1</javax.mail.version>
         <activation.version>1.1.1</activation.version>
         <jmock.version>2.5.1</jmock.version>
-        <hbase.version>0.92.0</hbase.version>
-        <hadoop.version>1.0.1</hadoop.version>
-        <spring.version>3.1.2.RELEASE</spring.version>
+        <hbase.version>0.92.2</hbase.version>
+        <hadoop.version>1.1.1</hadoop.version>
+        <spring.version>4.0.3.RELEASE</spring.version>
         <commons-io.version>2.4</commons-io.version>
         <commons-lang.version>2.6</commons-lang.version>
+        <commons-codec.version>1.7</commons-codec.version>
         <commons-pool.version>1.6</commons-pool.version>
         <commons-dbcp.version>1.4</commons-dbcp.version>
         <commons-configuration.version>1.9</commons-configuration.version>
@@ -117,7 +119,9 @@
         <slf4j.version>1.7.2</slf4j.version>
         <junit.version>4.11</junit.version>
         <jasypt.version>1.9.0</jasypt.version>
-        <guava.version>13.0</guava.version>
+        <guava.version>13.0.1</guava.version>
+        <log4j.version>1.2.17</log4j.version>
+        <jackson.version>1.9.13</jackson.version>
     </properties>
 
     <dependencyManagement>
@@ -173,6 +177,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.james</groupId>
+                <artifactId>apache-james-mailbox-openjpa</artifactId>
+                <version>${project.version}</version>
+            </dependency>            
+            <dependency>
+                <groupId>org.apache.james</groupId>
                 <artifactId>apache-james-mailbox-jcr</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -536,12 +545,118 @@
             <!--
                 END HBASE/HADOOP
             -->
+            
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>org.hamcrest</groupId>
+                <artifactId>hamcrest-core</artifactId>
+                <version>1.3</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>commons-httpclient</groupId>
+                <artifactId>commons-httpclient</artifactId>
+                <version>3.1</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>org.apache.mina</groupId>
+                <artifactId>mina-core</artifactId>
+                <version>2.0.7</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpclient</artifactId>
+                <version>4.3.3</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpmime</artifactId>
+                <version>4.3.3</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpcore</artifactId>
+                <version>4.3.2</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>org.codehaus.jackson</groupId>
+                <artifactId>jackson-mapper-asl</artifactId>
+                <version>${jackson.version}</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>org.codehaus.jackson</groupId>
+                <artifactId>jackson-core-asl</artifactId>
+                <version>${jackson.version}</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>org.codehaus.jackson</groupId>
+                <artifactId>jackson-xc</artifactId>
+                <version>${jackson.version}</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>org.codehaus.jackson</groupId>
+                <artifactId>jackson-jaxrs</artifactId>
+                <version>${jackson.version}</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>javax.xml.bind</groupId>
+                <artifactId>jaxb-api</artifactId>
+                <version>2.2.11</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>commons-codec</groupId>
+                <artifactId>commons-codec</artifactId>
+                <version>${commons-codec.version}</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>org.jboss.netty</groupId>
+                <artifactId>netty</artifactId>
+                <version>3.2.10.Final</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>log4j</groupId>
+                <artifactId>log4j</artifactId>
+                <version>${log4j.version}</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>org.apache.ftpserver</groupId>
+                <artifactId>ftpserver-core</artifactId>
+                <version>1.0.0</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>org.apache.ftpserver</groupId>
+                <artifactId>ftplet-api</artifactId>
+                <version>1.0.0</version>
+            </dependency>
+            <!-- dependency convergence fix: -->
+            <dependency>
+                <groupId>asm</groupId>
+                <artifactId>asm</artifactId>
+                <version>3.3.1</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
     <build>
         <plugins>
             <plugin>
+                <artifactId>maven-enforcer-plugin</artifactId>
+            </plugin>
+            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-assembly-plugin</artifactId>
                 <configuration>
@@ -556,7 +671,54 @@
                 <artifactId>maven-bundle-plugin</artifactId>
                 <extensions>true</extensions>
             </plugin>
+            <plugin>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <!-- avoid race with bundle plugin manifest (known bug): -->
+                    <useDefaultManifestFile>true</useDefaultManifestFile>
+                </configuration>
+            </plugin>
         </plugins>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <version>2.8</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-jar-plugin</artifactId>
+                    <version>2.4</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.felix</groupId>
+                    <artifactId>maven-bundle-plugin</artifactId>
+                    <version>2.4.0</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-enforcer-plugin</artifactId>
+                    <version>1.3.1</version>
+                    <executions>
+                        <execution>
+                            <id>enforce-sane-versions</id>
+                            <goals>
+                                <goal>enforce</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                    <configuration>
+                        <rules>
+                            <requirePluginVersions />
+                            <dependencyConvergence />
+                            <requireUpperBoundDeps />
+                            <requireReleaseDeps>
+                                <message>No Snapshots Allowed!</message>
+                                <onlyWhenRelease>true</onlyWhenRelease>
+                            </requireReleaseDeps>
+                        </rules>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
     </build>
 
     <profiles>
Index: openjpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
===================================================================
--- openjpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java	(Revision 0)
+++ openjpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java	(Revision 5832)
@@ -0,0 +1,85 @@
+/****************************************************************
+ * 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.mailbox.jpa.openjpa;
+
+import java.util.Date;
+
+import javax.mail.Flags;
+import javax.mail.internet.SharedInputStream;
+
+import org.apache.james.mailbox.MailboxPathLocker;
+import org.apache.james.mailbox.acl.GroupMembershipResolver;
+import org.apache.james.mailbox.acl.MailboxACLResolver;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.jpa.JPAMessageManager;
+import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
+import org.apache.james.mailbox.jpa.mail.model.JPAEncryptedMessage;
+import org.apache.james.mailbox.jpa.mail.model.JPAStreamingMessage;
+import org.apache.james.mailbox.store.MailboxEventDispatcher;
+import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.Message;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+import org.apache.james.mailbox.store.search.MessageSearchIndex;
+
+/**
+ * OpenJPA implementation of Mailbox
+ */
+public class OpenJPAMessageManager extends JPAMessageManager {
+
+    private final AdvancedFeature feature;
+
+    public static enum AdvancedFeature {
+        None,
+        Streaming,
+        Encryption
+    }
+    
+    public OpenJPAMessageManager(MailboxSessionMapperFactory<Long> mapperFactory, MessageSearchIndex<Long> index,
+            MailboxEventDispatcher<Long> dispatcher, MailboxPathLocker locker, Mailbox<Long> mailbox, MailboxACLResolver aclResolver, GroupMembershipResolver groupMembershipResolver) throws MailboxException {
+        this(mapperFactory, index, dispatcher, locker,  mailbox, AdvancedFeature.None, aclResolver, groupMembershipResolver);
+    }
+
+    public OpenJPAMessageManager(MailboxSessionMapperFactory<Long> mapperFactory, MessageSearchIndex<Long> index, 
+            MailboxEventDispatcher<Long> dispatcher, MailboxPathLocker locker, Mailbox<Long> mailbox, final AdvancedFeature f, MailboxACLResolver aclResolver, GroupMembershipResolver groupMembershipResolver) throws MailboxException {
+        super(mapperFactory,  index, dispatcher, locker, mailbox, aclResolver, groupMembershipResolver);
+        this.feature = f;
+    }
+
+    @Override
+    protected Message<Long> createMessage(Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder) throws MailboxException {
+        int headerEnd = bodyStartOctet -2;
+        if (headerEnd < 0) {
+            headerEnd = 0;
+        }
+        switch (feature) {
+        case Streaming:
+            return new JPAStreamingMessage((JPAMailbox) getMailboxEntity(), internalDate, size, flags, content, bodyStartOctet, propertyBuilder);
+        case Encryption:
+            return new JPAEncryptedMessage((JPAMailbox) getMailboxEntity(), internalDate, size, flags, content, bodyStartOctet, propertyBuilder);
+        default:
+            return super.createMessage(internalDate, size, bodyStartOctet, content, flags,  propertyBuilder);
+        }
+       
+    }
+
+    
+
+}
Index: openjpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
===================================================================
--- openjpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java	(Revision 0)
+++ openjpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java	(Revision 5832)
@@ -0,0 +1,73 @@
+/****************************************************************
+ * 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.mailbox.jpa.openjpa;
+
+
+import org.apache.james.mailbox.MailboxPathLocker;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.acl.GroupMembershipResolver;
+import org.apache.james.mailbox.acl.MailboxACLResolver;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.jpa.JPAMailboxManager;
+import org.apache.james.mailbox.jpa.JPAMailboxSessionMapperFactory;
+import org.apache.james.mailbox.jpa.mail.model.EncryptDecryptHelper;
+import org.apache.james.mailbox.jpa.openjpa.OpenJPAMessageManager.AdvancedFeature;
+import org.apache.james.mailbox.store.Authenticator;
+import org.apache.james.mailbox.store.JVMMailboxPathLocker;
+import org.apache.james.mailbox.store.StoreMessageManager;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+
+/**
+ * OpenJPA implementation of MailboxManager
+ *
+ */
+public class OpenJPAMailboxManager extends JPAMailboxManager {
+
+    private AdvancedFeature feature;
+
+    public OpenJPAMailboxManager(JPAMailboxSessionMapperFactory mapperFactory, Authenticator authenticator, MailboxPathLocker locker, boolean useStreaming, MailboxACLResolver aclResolver, GroupMembershipResolver groupMembershipResolver) {
+        super(mapperFactory, authenticator,  locker, aclResolver, groupMembershipResolver);
+        if (useStreaming) {
+            feature = AdvancedFeature.Streaming;
+        } else {
+            feature = AdvancedFeature.None;
+        }
+    }
+
+    public OpenJPAMailboxManager(JPAMailboxSessionMapperFactory mapperFactory, Authenticator authenticator, MailboxPathLocker locker,  String encryptPass, MailboxACLResolver aclResolver, GroupMembershipResolver groupMembershipResolver) {
+        super(mapperFactory, authenticator,  locker, aclResolver, groupMembershipResolver);
+        if (encryptPass != null) {
+            EncryptDecryptHelper.init(encryptPass);
+            feature = AdvancedFeature.Encryption;
+        } else {
+            feature = AdvancedFeature.None;
+        }
+    }
+    
+    public OpenJPAMailboxManager(JPAMailboxSessionMapperFactory mapperFactory, Authenticator authenticator, MailboxACLResolver aclResolver, GroupMembershipResolver groupMembershipResolver) {
+        this(mapperFactory, authenticator, new JVMMailboxPathLocker(), false, aclResolver, groupMembershipResolver);
+    }
+
+    @Override
+    protected StoreMessageManager<Long> createMessageManager(Mailbox<Long> mailboxRow, MailboxSession session) throws MailboxException {
+        StoreMessageManager<Long> result =  new OpenJPAMessageManager(getMapperFactory(), getMessageSearchIndex(), getEventDispatcher(), getLocker(), mailboxRow, feature, getAclResolver(), getGroupMembershipResolver());
+        return result;
+    }
+}
Index: openjpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageMapper.java
===================================================================
--- openjpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageMapper.java	(Revision 0)
+++ openjpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageMapper.java	(Revision 5832)
@@ -0,0 +1,62 @@
+/****************************************************************
+ * 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.mailbox.jpa.openjpa;
+
+import javax.persistence.EntityManagerFactory;
+
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.jpa.mail.JPAMessageMapper;
+import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
+import org.apache.james.mailbox.jpa.mail.model.JPAEncryptedMessage;
+import org.apache.james.mailbox.jpa.mail.model.JPAMessage;
+import org.apache.james.mailbox.jpa.mail.model.JPAStreamingMessage;
+import org.apache.james.mailbox.model.MessageMetaData;
+import org.apache.james.mailbox.store.mail.MessageMapper;
+import org.apache.james.mailbox.store.mail.ModSeqProvider;
+import org.apache.james.mailbox.store.mail.UidProvider;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.Message;
+
+
+public class OpenJPAMessageMapper extends JPAMessageMapper implements MessageMapper<Long> {
+
+    public OpenJPAMessageMapper(MailboxSession session, UidProvider<Long> uidProvider, ModSeqProvider<Long> modSeqProvider, EntityManagerFactory entityManagerFactory) {
+        super(session, uidProvider, modSeqProvider, entityManagerFactory);
+    }
+    /**
+     * @return
+     * @see org.apache.james.mailbox.store.mail.AbstractMessageMapper#copy(Mailbox,
+     *      long, long, Message)
+     */
+    @Override
+    protected MessageMetaData copy(Mailbox<Long> mailbox, long uid, long modSeq, Message<Long> original)
+            throws MailboxException {
+        Message<Long> copy;
+        if (original instanceof JPAStreamingMessage) {
+            copy = new JPAStreamingMessage((JPAMailbox) mailbox, uid, modSeq, original);
+        } else if (original instanceof JPAEncryptedMessage) {
+            copy = new JPAEncryptedMessage((JPAMailbox) mailbox, uid, modSeq, original);
+        } else {
+            copy = new JPAMessage((JPAMailbox) mailbox, uid, modSeq, original);
+        }
+        return save(mailbox, copy);
+    }
+
+}
Index: openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAStreamingMessage.java
===================================================================
--- openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAStreamingMessage.java	(Revision 0)
+++ openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAStreamingMessage.java	(Revision 5832)
@@ -0,0 +1,120 @@
+/****************************************************************
+ * 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.mailbox.jpa.mail.model;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+
+import javax.mail.Flags;
+import javax.mail.internet.SharedInputStream;
+import javax.mail.util.SharedByteArrayInputStream;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Table;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
+import org.apache.james.mailbox.jpa.mail.model.AbstractJPAMessage;
+import org.apache.james.mailbox.store.mail.model.Message;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+import org.apache.openjpa.persistence.Persistent;
+
+/**
+ * JPA implementation of {@link AbstractJPAMessage} which use openjpas {@link Persistent} type to
+ * be able to stream the message content without loading it into the memory at all. 
+ * 
+ * This is not supported for all DB's yet. See <a href="http://openjpa.apache.org/builds/latest/docs/manual/ref_guide_mapping_jpa.html">Additional JPA Mappings</a>
+ * 
+ * If your DB is not supported by this, use {@link JPAMessage} 
+ *
+ * TODO: Fix me!
+ */
+@Entity(name="Message")
+@Table(name="JAMES_MAIL")
+public class JPAStreamingMessage extends AbstractJPAMessage {
+
+    @SuppressWarnings("unused")
+    @Persistent(optional = false, fetch = FetchType.LAZY)
+    @Column(name = "MAIL_BYTES", length = 1048576000, nullable = false)
+    private InputStream body;
+
+    @SuppressWarnings("unused")
+    @Persistent(optional = false, fetch = FetchType.LAZY)
+    @Column(name = "HEADER_BYTES", length = 10485760, nullable = false)
+    private InputStream header;
+
+    private SharedInputStream content;
+
+    @Deprecated
+    public JPAStreamingMessage() {}
+
+    public JPAStreamingMessage(JPAMailbox mailbox, Date internalDate, int size, Flags flags, SharedInputStream content, int bodyStartOctet,final PropertyBuilder propertyBuilder) throws MailboxException {
+        super(mailbox, internalDate, flags, size ,bodyStartOctet, propertyBuilder);
+        this.content = content;
+
+        try {
+            this.header = getHeaderContent();
+            this.body = getBodyContent();
+
+        } catch (IOException e) {
+            throw new MailboxException("Unable to parse message",e);
+        }
+    }
+
+    /**
+     * Create a copy of the given message
+     * 
+     * @param message
+     * @throws IOException 
+     */
+    public JPAStreamingMessage(JPAMailbox mailbox, long uid, long modSeq, Message<?> message) throws MailboxException {
+        super(mailbox, uid, modSeq, message);
+        try {
+            this.content = new SharedByteArrayInputStream(IOUtils.toByteArray(message.getFullContent()));
+            this.header = getHeaderContent();
+            this.body = getBodyContent();
+        } catch (IOException e) {
+            throw new MailboxException("Unable to parse message",e);
+        }
+    }
+
+    
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getBodyContent()
+     */
+    public InputStream getBodyContent() throws IOException {
+        return content.newStream(getBodyStartOctet(), -1);
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getHeaderContent()
+     */
+    public InputStream getHeaderContent() throws IOException {
+        int headerEnd = getBodyStartOctet() -2;
+        if (headerEnd < 0) {
+            headerEnd = 0;
+        }
+        return content.newStream(0, headerEnd);
+    }
+
+}
Index: openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAEncryptedMessage.java
===================================================================
--- openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAEncryptedMessage.java	(Revision 0)
+++ openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAEncryptedMessage.java	(Revision 5832)
@@ -0,0 +1,111 @@
+/****************************************************************
+ * 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.mailbox.jpa.mail.model;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+import javax.mail.Flags;
+import javax.mail.internet.SharedInputStream;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Lob;
+import javax.persistence.Table;
+import org.apache.commons.io.IOUtils;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.mail.model.Message;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+import org.apache.openjpa.persistence.Externalizer;
+import org.apache.openjpa.persistence.Factory;
+
+@Entity(name="Message")
+@Table(name="JAMES_MAIL")
+public class JPAEncryptedMessage extends AbstractJPAMessage {
+
+        /** The value for the body field. Lazy loaded */
+        /** We use a max length to represent 1gb data. Thats prolly overkill, but who knows */
+        @Basic(optional = false, fetch = FetchType.LAZY)
+        @Column(name = "MAIL_BYTES", length = 1048576000, nullable = false)
+        @Externalizer("EncryptDecryptHelper.getEncrypted")
+        @Factory("EncryptDecryptHelper.getDecrypted")
+        @Lob private byte[] body;
+
+
+        /** The value for the header field. Lazy loaded */
+        /** We use a max length to represent 1gb data. Thats prolly overkill, but who knows */
+        @Basic(optional = false, fetch = FetchType.LAZY)
+        @Column(name = "HEADER_BYTES", length = 10485760, nullable = false)
+        @Externalizer("EncryptDecryptHelper.getEncrypted")
+        @Factory("EncryptDecryptHelper.getDecrypted")
+        @Lob private byte[] header;
+        
+        @Deprecated
+        public JPAEncryptedMessage() {}
+
+        public JPAEncryptedMessage(JPAMailbox mailbox,Date internalDate, int size, Flags flags, SharedInputStream content, int bodyStartOctet, final PropertyBuilder propertyBuilder) throws MailboxException {
+            super(mailbox, internalDate, flags, size ,bodyStartOctet, propertyBuilder);
+            try {
+                int headerEnd = bodyStartOctet;
+                if (headerEnd < 0) {
+                    headerEnd = 0;
+                }
+                this.header = IOUtils.toByteArray(content.newStream(0, headerEnd));
+                this.body = IOUtils.toByteArray(content.newStream(getBodyStartOctet(), -1));
+
+            } catch (IOException e) {
+                throw new MailboxException("Unable to parse message",e);
+            }
+        }
+
+        /**
+         * Create a copy of the given message
+         * 
+         * @param message
+         * @throws MailboxException 
+         */
+        public JPAEncryptedMessage(JPAMailbox mailbox, long uid, long modSeq, Message<?> message) throws MailboxException{
+            super(mailbox, uid, modSeq, message);
+            try {
+                this.body = IOUtils.toByteArray(message.getBodyContent());
+                this.header = IOUtils.toByteArray(message.getHeaderContent());
+            } catch (IOException e) {
+                throw new MailboxException("Unable to parse message",e);
+            }
+        }
+
+
+        /**
+         * @see org.apache.james.mailbox.store.mail.model.Message#getBodyContent()
+         */
+        public InputStream getBodyContent() throws IOException {
+            return new ByteArrayInputStream(body);
+        }
+
+        /**
+         * @see org.apache.james.mailbox.store.mail.model.Message#getHeaderContent()
+         */
+        public InputStream getHeaderContent() throws IOException {
+            return new ByteArrayInputStream(header);
+        }
+
+}
Index: openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/EncryptDecryptHelper.java
===================================================================
--- openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/EncryptDecryptHelper.java	(Revision 0)
+++ openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/EncryptDecryptHelper.java	(Revision 5832)
@@ -0,0 +1,67 @@
+/****************************************************************
+ * 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.mailbox.jpa.mail.model;
+
+import org.jasypt.encryption.pbe.StandardPBEByteEncryptor;
+
+/**
+ * Helper class for encrypt and de-crypt data
+ * 
+ *
+ */
+public class EncryptDecryptHelper {    
+
+    // Use one static instance as it is thread safe
+    private static StandardPBEByteEncryptor encryptor = new StandardPBEByteEncryptor();
+    
+    
+    /**
+     * Set the password for encrypt / de-crypt. This MUST be done before
+     * the usage of {@link #getDecrypted(byte[])} and {@link #getEncrypted(byte[])}.
+     * 
+     * So to be safe its the best to call this in a constructor
+     * 
+     * @param pass
+     */
+    public static void init(String pass) {
+        encryptor.setPassword(pass);
+    }
+
+    /**
+     * Encrypt the given array and return the encrypted one
+     * 
+     * @param array
+     * @return enc-array
+     */
+    public static byte[] getEncrypted(byte[] array) {
+        return encryptor.encrypt(array);
+    }
+
+    /**
+     * Decrypt the given array and return the de-crypted one
+     * 
+     * @param array
+     * @return dec-array
+     */
+    public static byte[] getDecrypted(byte[] array) {
+        return encryptor.decrypt(array);
+    }
+
+}
Index: openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMessage.java
===================================================================
--- openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMessage.java	(Revision 0)
+++ openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAMessage.java	(Revision 5832)
@@ -0,0 +1,109 @@
+/****************************************************************
+ * 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.mailbox.jpa.mail.model;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+import javax.mail.Flags;
+import javax.mail.internet.SharedInputStream;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Lob;
+import javax.persistence.Table;
+import org.apache.commons.io.IOUtils;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.mail.model.Message;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+
+@Entity(name="Message")
+@Table(name="JAMES_MAIL")
+public class JPAMessage extends AbstractJPAMessage {
+
+    /** The value for the body field. Lazy loaded */
+    /** We use a max length to represent 1gb data. Thats prolly overkill, but who knows */
+    @Basic(optional = false, fetch = FetchType.LAZY)
+    @Column(name = "MAIL_BYTES", length = 1048576000, nullable = false)
+    @Lob private byte[] body;
+
+
+    /** The value for the header field. Lazy loaded */
+    /** We use a max length to represent 10mb data. Thats prolly overkill, but who knows */
+    @Basic(optional = false, fetch = FetchType.LAZY)
+    @Column(name = "HEADER_BYTES", length = 10485760, nullable = false)
+    @Lob private byte[] header;
+    
+    @Deprecated
+    public JPAMessage() {}
+
+    public JPAMessage(JPAMailbox mailbox,Date internalDate, int size, Flags flags, SharedInputStream content, int bodyStartOctet, final PropertyBuilder propertyBuilder) throws MailboxException {
+        super(mailbox, internalDate, flags, size ,bodyStartOctet, propertyBuilder);
+        try {
+            int headerEnd = bodyStartOctet;
+            if (headerEnd < 0) {
+                headerEnd = 0;
+            }
+            this.header = IOUtils.toByteArray(content.newStream(0, headerEnd));
+            this.body = IOUtils.toByteArray(content.newStream(getBodyStartOctet(), -1));
+
+        } catch (IOException e) {
+            throw new MailboxException("Unable to parse message",e);
+        }
+    }
+
+    /**
+     * Create a copy of the given message
+     * 
+     * @param message
+     * @throws MailboxException 
+     */
+    public JPAMessage(JPAMailbox mailbox, long uid, long modSeq, Message<?> message) throws MailboxException{
+        super(mailbox, uid, modSeq, message);
+        try {
+            this.body = IOUtils.toByteArray(message.getBodyContent());
+            this.header = IOUtils.toByteArray(message.getHeaderContent());
+        } catch (IOException e) {
+            throw new MailboxException("Unable to parse message",e);
+        }
+    }
+
+
+    /**
+     * @throws java.io.IOException
+     * @see org.apache.james.mailbox.store.mail.model.Message#getBodyContent()
+     */
+    @Override
+    public InputStream getBodyContent() throws IOException {
+        return new ByteArrayInputStream(body);
+    }
+
+    /**
+     * @throws java.io.IOException
+     * @see org.apache.james.mailbox.store.mail.model.Message#getHeaderContent()
+     */
+    @Override
+    public InputStream getHeaderContent() throws IOException {
+        return new ByteArrayInputStream(header);
+    }
+
+}
Index: openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAProperty.java
===================================================================
--- openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAProperty.java	(Revision 0)
+++ openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/JPAProperty.java	(Revision 5832)
@@ -0,0 +1,183 @@
+/****************************************************************
+ * 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.mailbox.jpa.mail.model;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import org.apache.james.mailbox.store.mail.model.Property;
+import org.apache.openjpa.persistence.jdbc.Index;
+
+@Entity(name = "Property")
+@Table(name = "JAMES_MAIL_PROPERTY")
+public class JPAProperty implements Property {
+
+    /**
+     * The system unique key
+     */
+    @Id
+    @GeneratedValue
+    @Column(name = "PROPERTY_ID", nullable = true)
+    // TODO The columnNames are not interpreted, see OPENJPA-223 to fix
+    // MAILBOX-186
+    // -- maybe some participant thinks it is unnecessary to create an index
+    //    on a foreign key constraint?
+    @Index(name = "INDEX_PROPERTY_MSG_ID", columnNames = {"MAILBOX_ID", "MAIL_UID"})
+    private long id;
+
+    /** Order within the list of properties */
+    @Basic(optional = false)
+    @Column(name = "PROPERTY_LINE_NUMBER", nullable = false)
+    @Index(name = "INDEX_PROPERTY_LINE_NUMBER")
+    private int line;
+
+    /** Local part of the name of this property */
+    @Basic(optional = false)
+    @Column(name = "PROPERTY_LOCAL_NAME", nullable = false, length = 500)
+    private String localName;
+
+    /** Namespace part of the name of this property */
+    @Basic(optional = false)
+    @Column(name = "PROPERTY_NAME_SPACE", nullable = false, length = 500)
+    private String namespace;
+
+    /** Value of this property */
+    @Basic(optional = false)
+    @Column(name = "PROPERTY_VALUE", nullable = false, length = 1024)
+    private String value;
+
+    /**
+     * @deprecated enhancement only
+     */
+    @Deprecated
+    public JPAProperty() {
+    }
+
+    /**
+     * Constructs a property.
+     * 
+     * @param localName
+     *            not null
+     * @param namespace
+     *            not null
+     * @param value
+     *            not null
+     */
+    public JPAProperty(String namespace, String localName, String value, int order) {
+        super();
+        this.localName = localName;
+        this.namespace = namespace;
+        this.value = value;
+        this.line = order;
+    }
+
+    /**
+     * Constructs a property cloned from the given.
+     * 
+     * @param property
+     *            not null
+     */
+    public JPAProperty(Property property, int order) {
+        this(property.getNamespace(), property.getLocalName(), property.getValue(), order);
+    }
+
+    /**
+     * Create a copy of the give JPAProperty
+     * 
+     * @param property
+     */
+    public JPAProperty(JPAProperty property) {
+        this(property.getNamespace(), property.getLocalName(), property.getValue(), property.getOrder());
+    }
+
+    /**
+     * Gets the order of this property.
+     * 
+     * @return order of this property
+     */
+    public int getOrder() {
+        return line;
+    }
+
+    /**
+     * Gets the local part of the name of the property.
+     * 
+     * @return not null
+     */
+    public String getLocalName() {
+        return localName;
+    }
+
+    /**
+     * Gets the namespace for the name.
+     * 
+     * @return not null
+     */
+    public String getNamespace() {
+        return namespace;
+    }
+
+    /**
+     * Gets the value for this property.
+     * 
+     * @return not null
+     */
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public int hashCode() {
+        final int PRIME = 31;
+        int result = 1;
+        result = PRIME * result + (int) (id ^ (id >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final JPAProperty other = (JPAProperty) obj;
+        if (id != other.id)
+            return false;
+        return true;
+    }
+
+    /**
+     * Constructs a <code>String</code> with all attributes in name = value
+     * format.
+     * 
+     * @return a <code>String</code> representation of this object.
+     */
+    public String toString() {
+        final String result = "JPAProperty ( " + "id = " + this.id + " " + "localName = " + this.localName + " "
+                + "namespace = " + this.namespace + " " + "value = " + this.value + " )";
+
+        return result;
+    }
+
+}
Index: openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/AbstractJPAMessage.java
===================================================================
--- openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/AbstractJPAMessage.java	(Revision 0)
+++ openjpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/AbstractJPAMessage.java	(Revision 5832)
@@ -0,0 +1,564 @@
+/****************************************************************
+ * 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.mailbox.jpa.mail.model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import javax.mail.Flags;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.ManyToOne;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.OrderBy;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
+import org.apache.james.mailbox.jpa.mail.model.JPAProperty;
+import org.apache.james.mailbox.jpa.mail.model.JPAUserFlag;
+import org.apache.james.mailbox.store.mail.model.AbstractMessage;
+import org.apache.james.mailbox.store.mail.model.Message;
+import org.apache.james.mailbox.store.mail.model.Property;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+import org.apache.openjpa.persistence.jdbc.ElementJoinColumn;
+import org.apache.openjpa.persistence.jdbc.ElementJoinColumns;
+import org.apache.openjpa.persistence.jdbc.Index;
+
+/**
+ * Abstract base class for JPA based implementations of {@link AbstractMessage}
+ */
+@IdClass(AbstractJPAMessage.MailboxIdUidKey.class)
+@NamedQueries({
+    @NamedQuery(name="findRecentMessageUidsInMailbox",
+            query="SELECT message.uid FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.recent = TRUE"),
+    @NamedQuery(name="findUnseenMessagesInMailboxOrderByUid",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.seen = FALSE ORDER BY message.uid ASC"),
+    @NamedQuery(name="findMessagesInMailbox",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam"),
+    @NamedQuery(name="findMessagesInMailboxBetweenUIDs",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid BETWEEN :fromParam AND :toParam"),        
+    @NamedQuery(name="findMessagesInMailboxWithUID",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid=:uidParam"),                    
+    @NamedQuery(name="findMessagesInMailboxAfterUID",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid>=:uidParam"),                    
+    @NamedQuery(name="findDeletedMessagesInMailbox",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.deleted=TRUE"),        
+    @NamedQuery(name="findDeletedMessagesInMailboxBetweenUIDs",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid BETWEEN :fromParam AND :toParam AND message.deleted=TRUE"),        
+    @NamedQuery(name="findDeletedMessagesInMailboxWithUID",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid=:uidParam AND message.deleted=TRUE"),                    
+    @NamedQuery(name="findDeletedMessagesInMailboxAfterUID",
+            query="SELECT message FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid>=:uidParam AND message.deleted=TRUE"),          
+
+    @NamedQuery(name="deleteDeletedMessagesInMailbox",
+            query="DELETE FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.deleted=TRUE"),        
+    @NamedQuery(name="deleteDeletedMessagesInMailboxBetweenUIDs",
+            query="DELETE FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid BETWEEN :fromParam AND :toParam AND message.deleted=TRUE"),        
+    @NamedQuery(name="deleteDeletedMessagesInMailboxWithUID",
+            query="DELETE FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid=:uidParam AND message.deleted=TRUE"),                    
+    @NamedQuery(name="deleteDeletedMessagesInMailboxAfterUID",
+            query="DELETE FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.uid>=:uidParam AND message.deleted=TRUE"),  
+                    
+    @NamedQuery(name="countUnseenMessagesInMailbox",
+            query="SELECT COUNT(message) FROM Message message WHERE message.mailbox.mailboxId = :idParam AND message.seen=FALSE"),                     
+    @NamedQuery(name="countMessagesInMailbox",
+            query="SELECT COUNT(message) FROM Message message WHERE message.mailbox.mailboxId = :idParam"),                    
+    @NamedQuery(name="deleteMessages",
+            query="DELETE FROM Message message WHERE message.mailbox.mailboxId = :idParam"),
+    @NamedQuery(name="findLastUidInMailbox",
+            query="SELECT message.uid FROM Message message WHERE message.mailbox.mailboxId = :idParam ORDER BY message.uid DESC"),
+    @NamedQuery(name="findHighestModSeqInMailbox",
+            query="SELECT message.modSeq FROM Message message WHERE message.mailbox.mailboxId = :idParam ORDER BY message.modSeq DESC"),
+    @NamedQuery(name="deleteAllMemberships",
+            query="DELETE FROM Message message")
+})
+@MappedSuperclass
+public abstract class AbstractJPAMessage extends AbstractMessage<Long> {
+
+
+
+    private static final String TOSTRING_SEPARATOR = " ";
+
+    /** Identifies composite key */
+    public static class MailboxIdUidKey implements Serializable {
+
+        private static final long serialVersionUID = 7847632032426660997L;
+
+        public MailboxIdUidKey() {}
+
+        /** The value for the mailbox field */
+        public long mailbox;
+        
+        /** The value for the uid field */
+        public long uid;
+
+        @Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + (int) (mailbox ^ (mailbox >>> 32));
+            result = PRIME * result + (int) (uid ^ (uid >>> 32));
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final MailboxIdUidKey other = (MailboxIdUidKey) obj;
+            if (mailbox != other.mailbox)
+                return false;
+            if (uid != other.uid)
+                return false;
+            return true;
+        }
+
+    }
+
+    /** The value for the mailboxId field */
+    @Id
+    @ManyToOne(
+            cascade = {
+                    CascadeType.PERSIST, 
+                    CascadeType.REFRESH, 
+                    CascadeType.MERGE}, 
+            fetch=FetchType.LAZY)
+    @Column(name = "MAILBOX_ID", nullable = true)
+    private JPAMailbox mailbox;
+
+    /** The value for the uid field */
+    @Id
+    @Column(name = "MAIL_UID")
+    private long uid;
+
+    /** The value for the modSeq field */
+    @Index
+    @Column(name = "MAIL_MODSEQ")
+    private long modSeq;
+
+    /** The value for the internalDate field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_DATE")
+    private Date internalDate;
+
+    /** The value for the answered field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_IS_ANSWERED", nullable = false)
+    private boolean answered = false;
+
+    /** The value for the deleted field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_IS_DELETED", nullable = false)
+    @Index
+    private boolean deleted = false;
+
+    /** The value for the draft field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_IS_DRAFT", nullable = false)
+    private boolean draft = false;
+
+    /** The value for the flagged field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_IS_FLAGGED", nullable = false)
+    private boolean flagged = false;
+
+    /** The value for the recent field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_IS_RECENT", nullable = false)
+    @Index
+    private boolean recent = false;
+
+    /** The value for the seen field */
+    @Basic(optional = false)
+    @Column(name = "MAIL_IS_SEEN", nullable = false)
+    @Index
+    private boolean seen = false;
+
+    
+    /** The first body octet */
+    @Basic(optional = false)
+    @Column(name = "MAIL_BODY_START_OCTET", nullable = false)
+    private int bodyStartOctet;
+    
+    /** Number of octets in the full document content */
+    @Basic(optional = false)
+    @Column(name = "MAIL_CONTENT_OCTETS_COUNT", nullable = false)
+    private long contentOctets;
+    
+    /** MIME media type */
+    @Basic(optional = true)
+    @Column(name = "MAIL_MIME_TYPE", nullable = true, length = 200)
+    private String mediaType;
+    
+    /** MIME sub type */
+    @Basic(optional = true)
+    @Column(name = "MAIL_MIME_SUBTYPE", nullable = true, length = 200)
+    private String subType;
+    
+    /** THE CRFL count when this document is textual, null otherwise */
+    @Basic(optional = true)
+    @Column(name = "MAIL_TEXTUAL_LINE_COUNT", nullable = true)
+    private Long textualLineCount;
+    
+    /** Meta data for this message */
+    @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY)
+    @OrderBy("line")
+    @ElementJoinColumns({@ElementJoinColumn(name="MAILBOX_ID", referencedColumnName="MAILBOX_ID"),
+                @ElementJoinColumn(name="MAIL_UID", referencedColumnName="MAIL_UID")})
+    private List<JPAProperty> properties;
+
+    @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY)
+    @OrderBy("id")
+    @ElementJoinColumns({@ElementJoinColumn(name="MAILBOX_ID", referencedColumnName="MAILBOX_ID"),
+    @ElementJoinColumn(name="MAIL_UID", referencedColumnName="MAIL_UID")})
+    private List<JPAUserFlag> userFlags;
+    
+    @Deprecated
+    public AbstractJPAMessage() {}
+
+    public AbstractJPAMessage(JPAMailbox mailbox, Date internalDate, Flags flags, final long contentOctets, final int bodyStartOctet, final PropertyBuilder propertyBuilder) {
+        super();
+        this.mailbox = mailbox;
+        this.internalDate = internalDate;
+        userFlags = new ArrayList<JPAUserFlag>();
+
+        setFlags(flags);        
+        this.contentOctets = contentOctets;
+        this.bodyStartOctet = bodyStartOctet;
+        this.textualLineCount = propertyBuilder.getTextualLineCount();
+        this.mediaType = propertyBuilder.getMediaType();
+        this.subType = propertyBuilder.getSubType();
+        final List<Property> properties = propertyBuilder.toProperties();
+        this.properties = new ArrayList<JPAProperty>(properties.size());
+        int order = 0;
+        for (final Property property:properties) {
+            this.properties.add(new JPAProperty(property, order++));
+        }
+        
+    }
+
+    /**
+     * Constructs a copy of the given message.
+     * All properties are cloned except mailbox and UID.
+     * @param mailbox new mailbox
+     * @param uid new UID
+     * @param modSeq new modSeq
+     * @param original message to be copied, not null
+     * @throws IOException 
+     */
+    public AbstractJPAMessage(JPAMailbox mailbox, long uid, long modSeq,  Message<?> original) throws MailboxException {
+        super();
+        this.mailbox = mailbox;
+        this.uid = uid;
+        this.modSeq = modSeq;
+        this.userFlags = new ArrayList<JPAUserFlag>();
+        setFlags(original.createFlags());
+        
+        // A copy of a message is recent 
+        // See MAILBOX-85
+        this.recent = true;
+
+        this.contentOctets = original.getFullContentOctets();
+        this.bodyStartOctet = (int) (original.getFullContentOctets() - original.getBodyOctets());
+        this.internalDate = original.getInternalDate();
+
+
+        PropertyBuilder pBuilder = new PropertyBuilder(original.getProperties());
+        this.textualLineCount = original.getTextualLineCount();
+        this.mediaType = original.getMediaType();
+        this.subType = original.getSubType();
+        final List<Property> properties = pBuilder.toProperties();
+        this.properties = new ArrayList<JPAProperty>(properties.size());
+        int order = 0;
+        for (final Property property:properties) {
+            this.properties.add(new JPAProperty(property, order++));
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        final int PRIME = 31;
+        int result = 1;
+        result = PRIME * result + (int) (getMailboxId() ^ (getMailboxId() >>> 32));
+        result = PRIME * result + (int) (uid ^ (uid >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final AbstractJPAMessage other = (AbstractJPAMessage) obj;
+        if (getMailboxId() != null) {
+            if (!getMailboxId().equals(other.getMailboxId()))
+            return false;
+        } else {
+            if (other.getMailboxId() != null)
+            return false;
+        }
+        if (uid != other.uid)
+            return false;
+        return true;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getModSeq()
+     */
+    public long getModSeq() {
+        return modSeq;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#setModSeq(long)
+     */
+    public void setModSeq(long modSeq) {
+        this.modSeq = modSeq;
+    }
+    
+    /**
+     * Gets the top level MIME content media type.
+     * 
+     * @return top level MIME content media type, or null if default
+     */
+    public String getMediaType() {
+        return mediaType;
+    }
+    
+    /**
+     * Gets the MIME content subtype.
+     * 
+     * @return the MIME content subtype, or null if default
+     */
+    public String getSubType() {
+        return subType;
+    }
+
+    /**
+     * Gets a read-only list of meta-data properties.
+     * For properties with multiple values, this list will contain
+     * several enteries with the same namespace and local name.
+     * @return unmodifiable list of meta-data, not null
+     */
+    public List<Property> getProperties() {
+        return new ArrayList<Property>(properties);
+    }
+    
+    /**
+     * Gets the number of CRLF in a textual document.
+     * @return CRLF count when document is textual,
+     * null otherwise
+     */
+    public Long getTextualLineCount() {
+        return textualLineCount;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getFullContentOctets()
+     */
+    public long getFullContentOctets() {
+        return contentOctets;
+    }
+
+    @Override
+    protected int getBodyStartOctet() {
+        return bodyStartOctet;
+    }
+    
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getInternalDate()
+     */
+    public Date getInternalDate() {
+        return internalDate;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getMailboxId()
+     */
+    public Long getMailboxId() {
+        return getMailbox().getMailboxId();
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#getUid()
+     */
+    public long getUid() {
+        return uid;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#isAnswered()
+     */
+    public boolean isAnswered() {
+        return answered;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#isDeleted()
+     */
+    public boolean isDeleted() {
+        return deleted;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#isDraft()
+     */
+    public boolean isDraft() {
+        return draft;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#isFlagged()
+     */
+    public boolean isFlagged() {
+        return flagged;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#isRecent()
+     */
+    public boolean isRecent() {
+        return recent;
+    }
+
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#isSeen()
+     */
+    public boolean isSeen() {
+        return seen;
+    }
+    
+    public void setUid(long uid) {
+        this.uid = uid;
+    }
+
+//    public long getVersion() {
+//        return version;
+//    }
+//
+//    public void setVersion(long _version) {
+//        version = _version;
+//    }
+    
+    /**
+     * @see org.apache.james.mailbox.store.mail.model.Message#setFlags(javax.mail.Flags)
+     */
+    public void setFlags(Flags flags) {
+        answered = flags.contains(Flags.Flag.ANSWERED);
+        deleted = flags.contains(Flags.Flag.DELETED);
+        draft = flags.contains(Flags.Flag.DRAFT);
+        flagged = flags.contains(Flags.Flag.FLAGGED);
+        recent = flags.contains(Flags.Flag.RECENT);
+        seen = flags.contains(Flags.Flag.SEEN);
+        
+        /*
+        // Loop over the user flags and check which of them needs to get added / removed
+        List<String> uFlags = Arrays.asList(flags.getUserFlags());
+        for (int i = 0; i < userFlags.size(); i++) {
+            JPAUserFlag f = userFlags.get(i);
+            if (uFlags.contains(f.getName()) == false) {
+                userFlags.remove(f);
+                i++;
+            }
+        }
+        for (int i = 0; i < uFlags.size(); i++) {
+            boolean found = false;
+            String uFlag = uFlags.get(i);
+            for (int a = 0; a < userFlags.size(); a++) {
+                String userFlag = userFlags.get(a).getName();
+                if (userFlag.equals(uFlag)) {
+                    found = true;
+                    break;
+                }
+            }
+            if (found == false) {
+                userFlags.add(new JPAUserFlag(uFlag));
+            }
+            
+            
+        }
+        */
+        String[] userflags =  flags.getUserFlags();
+        userFlags.clear();
+        for (int i = 0 ; i< userflags.length; i++) {
+            userFlags.add(new JPAUserFlag(userflags[i]));
+        }
+    }
+
+    /**
+     * Utility getter on Mailbox.
+     */
+    public JPAMailbox getMailbox() {
+        return mailbox;
+    }
+
+    /**
+     * This implementation supports user flags
+     * 
+     * 
+     */
+    @Override
+    protected String[] createUserFlags() {
+        String[] flags = new String[userFlags.size()];
+        for (int i = 0; i < userFlags.size(); i++) {
+            flags[i] = userFlags.get(i).getName();
+        }
+        return flags;
+    }
+
+    /**
+     * Utility setter on Mailbox.
+     */
+    public void setMailbox(JPAMailbox mailbox) {
+        this.mailbox = mailbox;
+    }
+
+    public String toString() {
+        final String retValue = 
+            "message("
+            + "mailboxId = " + this.getMailboxId() + TOSTRING_SEPARATOR
+            + "uid = " + this.uid + TOSTRING_SEPARATOR
+            + "internalDate = " + this.internalDate + TOSTRING_SEPARATOR
+            + "answered = " + this.answered + TOSTRING_SEPARATOR
+            + "deleted = " + this.deleted + TOSTRING_SEPARATOR
+            + "draft = " + this.draft + TOSTRING_SEPARATOR
+            + "flagged = " + this.flagged + TOSTRING_SEPARATOR
+            + "recent = " + this.recent + TOSTRING_SEPARATOR
+            + "seen = " + this.seen + TOSTRING_SEPARATOR
+            + " )";
+        return retValue;
+    }
+    
+
+}
Index: openjpa/src/main/resources/james-database.properties
===================================================================
--- openjpa/src/main/resources/james-database.properties	(Revision 0)
+++ openjpa/src/main/resources/james-database.properties	(Revision 5832)
@@ -0,0 +1,26 @@
+#  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.
+#
+
+# See http://james.apache.org/server/3/config.html for usage
+
+database.driverClassName=org.apache.derby.jdbc.EmbeddedDriver
+database.url=jdbc:derby:target/var/store/derby;create=true
+database.username=app
+database.password=app
+vendorAdapter.database=DERBY
+openjpa.streaming=false
Index: openjpa/src/main/resources/META-INF/spring/mailbox-jpa.xml
===================================================================
--- openjpa/src/main/resources/META-INF/spring/mailbox-jpa.xml	(Revision 0)
+++ openjpa/src/main/resources/META-INF/spring/mailbox-jpa.xml	(Revision 5832)
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.    
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans" 
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+    <!-- 
+      Mailbox JPA
+     -->
+          
+    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
+
+    <bean id="jpa-mailboxmanager" class="org.apache.james.mailbox.jpa.openjpa.OpenJPAMailboxManager" init-method="init">
+        <constructor-arg index="0" ref="jpa-sessionMapperFactory"/>
+        <constructor-arg index="1" ref="authenticator"/>
+        <constructor-arg index="2" ref="jpa-locker"/>
+        <constructor-arg index="3" type="boolean" value="false"/>
+        <constructor-arg index="4" ref="aclResolver"/>
+        <constructor-arg index="5" ref="groupMembershipResolver"/>
+    </bean>
+    <bean id ="jpa-subscriptionManager" class="org.apache.james.mailbox.jpa.JPASubscriptionManager">
+        <constructor-arg index="0" ref="jpa-sessionMapperFactory"/>
+    </bean>
+    <bean id="jpa-sessionMapperFactory" class="org.apache.james.mailbox.jpa.JPAMailboxSessionMapperFactory">
+        <constructor-arg index="0" ref="entityManagerFactory"/>
+        <constructor-arg index="1" ref="jpa-uidProvider"/>
+        <constructor-arg index="2" ref="jpa-modSeqProvider"/>
+    </bean>
+    <bean id="jpa-uidProvider" class="org.apache.james.mailbox.jpa.mail.JPAUidProvider">
+        <constructor-arg index="0" ref="jpa-locker"/>
+        <constructor-arg index="1" ref="entityManagerFactory"/>
+    </bean>
+    <bean id="jpa-modSeqProvider" class="org.apache.james.mailbox.jpa.mail.JPAModSeqProvider">
+        <constructor-arg index="0" ref="jpa-locker"/>
+        <constructor-arg index="1" ref="entityManagerFactory"/>
+    </bean>
+    <alias name="jvm-locker" alias="jpa-locker"/>
+
+    <!-- 
+       Database DataSource
+    -->
+          
+    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+        <property name="ignoreUnresolvablePlaceholders" value="true"/>
+        <property name ="location" value="classpath:james-database.properties"/>
+    </bean>
+    <bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
+        <property name="driverClassName" value="${database.driverClassName}" />
+        <property name="url" value="${database.url}" />
+        <property name="username" value="${database.username}" />
+        <property name="password" value="${database.password}" />
+    </bean>
+    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
+        <property name="dataSource" ref="datasource"/>
+        <property name="jpaVendorAdapter" ref="vendorAdapter"/>
+        <property name="persistenceUnitName" value="James"/>
+    </bean>
+    <bean id="vendorAdapter" class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
+        <property name="database" value="${vendorAdapter.database}"/>
+        <!-- set this to true for debugging purposes -->
+        <property name="showSql" value="false"/>
+    </bean>
+
+</beans>
Index: openjpa/src/main/resources/META-INF/persistence.xml
===================================================================
--- openjpa/src/main/resources/META-INF/persistence.xml	(Revision 0)
+++ openjpa/src/main/resources/META-INF/persistence.xml	(Revision 5832)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.    
+-->
+<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
+  <persistence-unit name="James" transaction-type="RESOURCE_LOCAL">
+    <class>org.apache.james.mailbox.jpa.mail.model.JPAMailbox</class>
+    <class>org.apache.james.mailbox.jpa.mail.model.JPAUserFlag</class>
+    <class>org.apache.james.mailbox.jpa.mail.model.JPAProperty</class>
+    <class>org.apache.james.mailbox.jpa.user.model.JPASubscription</class>
+    <class>org.apache.james.mailbox.jpa.mail.model.JPAMessage</class>
+    <properties>
+      <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
+      <property name="openjpa.jdbc.MappingDefaults" value="ForeignKeyDeleteAction=cascade, JoinForeignKeyDeleteAction=cascade"/>
+      <property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)"/>
+      <property name="openjpa.jdbc.QuerySQLCache" value="false"/>
+    </properties>
+  </persistence-unit>
+</persistence>
Index: openjpa/src/reporting-site/site.xml
===================================================================
--- openjpa/src/reporting-site/site.xml	(Revision 0)
+++ openjpa/src/reporting-site/site.xml	(Revision 5832)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    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.    
+-->
+<project name="${project.name}">
+
+    <body>
+
+        <menu ref="parent" />
+        <menu ref="reports" />
+
+    </body>
+
+</project>
Index: openjpa/src/test/java/org/apache/james/mailbox/openjpa/OpenJPASubscriptionManagerTest.java
===================================================================
--- openjpa/src/test/java/org/apache/james/mailbox/openjpa/OpenJPASubscriptionManagerTest.java	(Revision 0)
+++ openjpa/src/test/java/org/apache/james/mailbox/openjpa/OpenJPASubscriptionManagerTest.java	(Revision 5832)
@@ -0,0 +1,82 @@
+/****************************************************************
+ * 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.mailbox.openjpa;
+
+import java.util.HashMap;
+
+import org.apache.james.mailbox.AbstractSubscriptionManagerTest;
+import org.apache.james.mailbox.SubscriptionManager;
+import org.apache.james.mailbox.jpa.JPAMailboxSessionMapperFactory;
+import org.apache.james.mailbox.jpa.JPAMailboxSessionMapperFactory;
+import org.apache.james.mailbox.jpa.JPASubscriptionManager;
+import org.apache.james.mailbox.jpa.JPASubscriptionManager;
+import org.apache.james.mailbox.jpa.mail.JPAModSeqProvider;
+import org.apache.james.mailbox.jpa.mail.JPAUidProvider;
+import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
+import org.apache.james.mailbox.jpa.mail.model.JPAProperty;
+import org.apache.james.mailbox.jpa.mail.model.JPAUserFlag;
+import org.apache.james.mailbox.jpa.mail.model.AbstractJPAMessage;
+import org.apache.james.mailbox.jpa.mail.model.JPAMessage;
+import org.apache.james.mailbox.jpa.user.model.JPASubscription;
+import org.apache.james.mailbox.store.JVMMailboxPathLocker;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.junit.After;
+import org.junit.Before;
+
+public class OpenJPASubscriptionManagerTest extends AbstractSubscriptionManagerTest{
+
+    private OpenJPAEntityManagerFactory entityManagerFactory;
+
+    @Before
+    public void setUp() {
+
+        HashMap<String, String> properties = new HashMap<String, String>();
+        properties.put("openjpa.ConnectionDriverName", "org.h2.Driver");
+        properties.put("openjpa.ConnectionURL", "jdbc:h2:mem:imap;DB_CLOSE_DELAY=-1");
+        properties.put("openjpa.Log", "JDBC=WARN, SQL=WARN, Runtime=WARN");
+        properties.put("openjpa.ConnectionFactoryProperties", "PrettyPrint=true, PrettyPrintLineLength=72");
+        properties.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");
+        properties.put("openjpa.MetaDataFactory", "jpa(Types=" +
+                JPAMailbox.class.getName() + ";" +
+                AbstractJPAMessage.class.getName() + ";" +
+                JPAMessage.class.getName() + ";" +
+                JPAProperty.class.getName() + ";" +
+                JPAUserFlag.class.getName() + ";" +
+                JPASubscription.class.getName() + ")");
+       
+        entityManagerFactory = OpenJPAPersistence.getEntityManagerFactory(properties);
+    }
+    
+    @Override
+    public SubscriptionManager createSubscriptionManager() {
+        JVMMailboxPathLocker locker = new JVMMailboxPathLocker();
+
+        JPAMailboxSessionMapperFactory mf = new JPAMailboxSessionMapperFactory(entityManagerFactory, new JPAUidProvider(locker, entityManagerFactory), new JPAModSeqProvider(locker, entityManagerFactory));
+
+        JPASubscriptionManager sm = new JPASubscriptionManager(mf);
+        
+        return sm;
+    }
+
+    @After
+    public void tearDown() {
+        entityManagerFactory.close();
+    }
+}
Index: openjpa/src/test/java/org/apache/james/mailbox/openjpa/OpenJPAStressTest.java
===================================================================
--- openjpa/src/test/java/org/apache/james/mailbox/openjpa/OpenJPAStressTest.java	(Revision 0)
+++ openjpa/src/test/java/org/apache/james/mailbox/openjpa/OpenJPAStressTest.java	(Revision 5832)
@@ -0,0 +1,120 @@
+/****************************************************************
+ * 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.mailbox.openjpa;
+
+import java.util.HashMap;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+import org.apache.james.mailbox.AbstractStressTest;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.acl.GroupMembershipResolver;
+import org.apache.james.mailbox.acl.MailboxACLResolver;
+import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
+import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.jpa.JPAMailboxSessionMapperFactory;
+import org.apache.james.mailbox.jpa.JPAMailboxSessionMapperFactory;
+import org.apache.james.mailbox.jpa.mail.JPAModSeqProvider;
+import org.apache.james.mailbox.jpa.mail.JPAUidProvider;
+import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
+import org.apache.james.mailbox.jpa.mail.model.JPAProperty;
+import org.apache.james.mailbox.jpa.mail.model.JPAUserFlag;
+import org.apache.james.mailbox.jpa.mail.model.AbstractJPAMessage;
+import org.apache.james.mailbox.jpa.mail.model.JPAMessage;
+import org.apache.james.mailbox.jpa.openjpa.OpenJPAMailboxManager;
+import org.apache.james.mailbox.jpa.user.model.JPASubscription;
+import org.apache.james.mailbox.store.JVMMailboxPathLocker;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.junit.After;
+import org.junit.Before;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Proof of bug https://issues.apache.org/jira/browse/IMAP-137
+ */
+public class OpenJPAStressTest extends AbstractStressTest {
+    
+    private OpenJPAMailboxManager mailboxManager;
+    
+    private long locktimeout = 60000;
+    
+    private EntityManagerFactory entityManagerFactory;
+    
+    @Before
+    public void setUp() throws MailboxException {
+        
+        HashMap<String, String> properties = new HashMap<String, String>();
+        properties.put("openjpa.ConnectionDriverName", org.h2.Driver.class.getName());
+        properties.put("openjpa.ConnectionURL", "jdbc:h2:mem:mailboxintegrationstress;DB_CLOSE_DELAY=-1");
+        properties.put("openjpa.Log", "JDBC=WARN, SQL=WARN, Runtime=WARN");
+        properties.put("openjpa.ConnectionFactoryProperties", "PrettyPrint=true, PrettyPrintLineLength=72");
+        properties.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");
+        properties.put("openjpa.MetaDataFactory", "jpa(Types=" +
+                JPAMailbox.class.getName() + ";" +
+                AbstractJPAMessage.class.getName() + ";" +
+                JPAMessage.class.getName() + ";" +
+                JPAProperty.class.getName() + ";" +
+                JPAUserFlag.class.getName() + ";" +
+                JPASubscription.class.getName() + ")");
+        properties.put("openjpa.LockTimeout", locktimeout + "");
+       
+        entityManagerFactory = OpenJPAPersistence.getEntityManagerFactory(properties);
+        JVMMailboxPathLocker locker = new JVMMailboxPathLocker();
+        JPAMailboxSessionMapperFactory mf = new JPAMailboxSessionMapperFactory(entityManagerFactory, new JPAUidProvider(locker, entityManagerFactory), new JPAModSeqProvider(locker, entityManagerFactory));
+
+        MailboxACLResolver aclResolver = new UnionMailboxACLResolver();
+        GroupMembershipResolver groupMembershipResolver = new SimpleGroupMembershipResolver();
+
+        mailboxManager = new OpenJPAMailboxManager(mf, null, aclResolver, groupMembershipResolver);
+        mailboxManager.init();
+
+        // Set the lock timeout via SQL because of a bug in openJPA
+        // https://issues.apache.org/jira/browse/OPENJPA-1656
+        setH2LockTimeout();
+    
+    }
+    
+    private void setH2LockTimeout() {
+        EntityManager manager = entityManagerFactory.createEntityManager();
+        manager.getTransaction().begin();
+        manager.createNativeQuery("SET DEFAULT_LOCK_TIMEOUT " + locktimeout).executeUpdate();
+        manager.getTransaction().commit();
+        manager.close();
+    }
+    
+    @After
+    public void tearDown() {
+        MailboxSession session = mailboxManager.createSystemSession("test", LoggerFactory.getLogger("Test"));
+        try {
+            mailboxManager.deleteEverything(session);
+        } catch (MailboxException e) {
+            e.printStackTrace();
+        }
+        session.close();
+    }
+
+    @Override
+    protected MailboxManager getMailboxManager() {
+        return mailboxManager;
+    }
+
+}
Index: openjpa/src/test/java/org/apache/james/mailbox/openjpa/OpenJPAMailboxManagerTest.java
===================================================================
--- openjpa/src/test/java/org/apache/james/mailbox/openjpa/OpenJPAMailboxManagerTest.java	(Revision 0)
+++ openjpa/src/test/java/org/apache/james/mailbox/openjpa/OpenJPAMailboxManagerTest.java	(Revision 5832)
@@ -0,0 +1,130 @@
+/****************************************************************
+ * 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.mailbox.openjpa;
+
+import java.util.HashMap;
+
+import javax.persistence.EntityManagerFactory;
+
+import org.apache.james.mailbox.AbstractMailboxManagerTest;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.acl.GroupMembershipResolver;
+import org.apache.james.mailbox.acl.MailboxACLResolver;
+import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
+import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
+import org.apache.james.mailbox.exception.BadCredentialsException;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.jpa.JPAMailboxManager;
+import org.apache.james.mailbox.jpa.JPAMailboxSessionMapperFactory;
+import org.apache.james.mailbox.jpa.mail.JPAModSeqProvider;
+import org.apache.james.mailbox.jpa.mail.JPAUidProvider;
+import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
+import org.apache.james.mailbox.jpa.mail.model.JPAProperty;
+import org.apache.james.mailbox.jpa.mail.model.JPAUserFlag;
+import org.apache.james.mailbox.jpa.mail.model.AbstractJPAMessage;
+import org.apache.james.mailbox.jpa.mail.model.JPAMessage;
+import org.apache.james.mailbox.jpa.openjpa.OpenJPAMailboxManager;
+import org.apache.james.mailbox.jpa.user.model.JPASubscription;
+import org.apache.james.mailbox.store.JVMMailboxPathLocker;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.junit.After;
+import org.junit.Before;
+import org.slf4j.LoggerFactory;
+
+/**
+ * OpenJPAMailboxManagerTest that extends the StoreMailboxManagerTest.
+ */
+public class OpenJPAMailboxManagerTest extends AbstractMailboxManagerTest {
+    
+    /**
+     * The entity manager factory.
+     */
+    private static EntityManagerFactory entityManagerFactory;
+    
+    /**
+     * Setup the mailboxManager.
+     * 
+     * @throws Exception
+     */
+    @Before
+    public void setup() throws Exception {
+        createMailboxManager();
+    }
+    
+    /**
+     * Close the system session and entityManagerFactory
+     * 
+     * @throws MailboxException 
+     * @throws BadCredentialsException 
+     */
+    @After
+    public void tearDown() throws BadCredentialsException, MailboxException {
+        deleteAllMailboxes();
+        MailboxSession session = getMailboxManager().createSystemSession("test", LoggerFactory.getLogger("Test"));
+        session.close();
+        entityManagerFactory.close();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.james.mailbox.MailboxManagerTest#createMailboxManager()
+     */
+    @Override
+    protected void createMailboxManager() throws MailboxException {
+        
+        HashMap<String, String> properties = new HashMap<String, String>();
+        properties.put("openjpa.ConnectionDriverName", "org.h2.Driver");
+        properties.put("openjpa.ConnectionURL", "jdbc:h2:mem:imap;DB_CLOSE_DELAY=-1");
+        properties.put("openjpa.Log", "JDBC=WARN, SQL=WARN, Runtime=WARN");
+        properties.put("openjpa.ConnectionFactoryProperties", "PrettyPrint=true, PrettyPrintLineLength=72");
+        properties.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");
+        properties.put("openjpa.MetaDataFactory", "jpa(Types=" +
+                JPAMailbox.class.getName() + ";" +
+                AbstractJPAMessage.class.getName() + ";" +
+                JPAMessage.class.getName() + ";" +
+                JPAProperty.class.getName() + ";" +
+                JPAUserFlag.class.getName() + ";" +
+                JPASubscription.class.getName() + ")");
+       
+        entityManagerFactory = OpenJPAPersistence.getEntityManagerFactory(properties);
+        JVMMailboxPathLocker locker = new JVMMailboxPathLocker();
+        JPAMailboxSessionMapperFactory mf = new JPAMailboxSessionMapperFactory(entityManagerFactory, new JPAUidProvider(locker, entityManagerFactory), new JPAModSeqProvider(locker, entityManagerFactory));
+
+        MailboxACLResolver aclResolver = new UnionMailboxACLResolver();
+        GroupMembershipResolver groupMembershipResolver = new SimpleGroupMembershipResolver();
+
+        JPAMailboxManager mailboxManager = new OpenJPAMailboxManager(mf, null, aclResolver, groupMembershipResolver);
+        mailboxManager.init();
+
+        setMailboxManager(mailboxManager);
+        
+        deleteAllMailboxes();
+        
+    }
+    
+    private void deleteAllMailboxes() throws BadCredentialsException, MailboxException {
+        MailboxSession session = getMailboxManager().createSystemSession("test", LoggerFactory.getLogger("Test"));
+        try {
+            ((OpenJPAMailboxManager) mailboxManager).deleteEverything(session);
+        } catch (MailboxException e) {
+            e.printStackTrace();
+        }
+        session.close();
+    }
+
+}
Index: openjpa/pom.xml
===================================================================
--- openjpa/pom.xml	(Revision 0)
+++ openjpa/pom.xml	(Revision 5832)
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>apache-james-mailbox</artifactId>
+        <groupId>org.apache.james</groupId>
+        <version>0.6-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>apache-james-mailbox-openjpa</artifactId>
+    <name>Apache James :: Mailbox :: OpenJPA</name>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+        </dependency>
+        <!-- required for IDEs only (we copy and enhance the generic JPA classes!): -->
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-mailbox-jpa</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-mailbox-store</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.openjpa</groupId>
+            <artifactId>openjpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jpa_2.0_spec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${javax.mail.groupId}</groupId>
+            <artifactId>${javax.mail.artifactId}</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jasypt</groupId>
+            <artifactId>jasypt</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+            <scope>test</scope>
+            <type>test-jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-mailbox-store</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <!-- include jpa-implementation-shared entity classes for openjpa enhancement: -->
+            <plugin>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>unpack</goal>
+                        </goals>
+                        <configuration>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>org.apache.james</groupId>
+                                    <artifactId>apache-james-mailbox-jpa</artifactId>
+                                    <version>${project.version}</version>
+                                    <type>jar</type>
+                                </artifactItem>
+                            </artifactItems>
+                            <outputDirectory>${project.build.directory}/classes</outputDirectory>
+                            <excludes>
+                                **/JPAMessage.class,
+                                **/AbstractJPAMessage.class,
+                                **/JPAProperty.class,
+                                **/*_.class
+                            </excludes>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>openjpa-maven-plugin</artifactId>
+                <version>1.2</version>
+                <configuration>
+                    <includes>org/apache/james/mailbox/jpa/*/model/**/*.class</includes>
+                    <excludes>
+                        org/apache/james/mailbox/jpa/mail/model/EncryptDecryptHelper.class,
+                        org/apache/james/mailbox/jpa/mail/model/AbstractJPAMessage$MailboxIdUidKey.class,
+                        **/*_.class
+                    </excludes>
+                    <addDefaultConstructor>true</addDefaultConstructor>
+                    <enforcePropertyRestrictions>true</enforcePropertyRestrictions>
+                    <toolProperties>
+                        <property>
+                            <name>log</name>
+                            <value>TOOL=TRACE</value>
+                        </property>
+                        <property>
+                            <name>metaDataFactory</name>
+                            <value>
+                                jpa(Types=org.apache.james.mailbox.jpa.mail.model.JPAUserFlag;org.apache.james.mailbox.jpa.mail.model.JPAMailbox;org.apache.james.mailbox.jpa.mail.model.JPAMessage;org.apache.james.mailbox.jpa.mail.model.AbstractJPAMessage;org.apache.james.mailbox.jpa.mail.model.JPAEncryptedMessage;org.apache.james.mailbox.jpa.mail.model.JPAMessage;org.apache.james.mailbox.jpa.mail.model.JPAStreamingMessage;org.apache.james.mailbox.jpa.mail.model.JPAProperty;org.apache.james.mailbox.jpa.user.model.JPASubscription)
+                            </value>
+                        </property>
+                    </toolProperties>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>enhancer</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>enhance</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>

Eigenschaftsänderungen: openjpa
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target



Eigenschaftsänderungen: caching
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target



Eigenschaftsänderungen: store
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target



Eigenschaftsänderungen: .
___________________________________________________________________
Hinzugefügt: svn:ignore
   + target
.pom.xml.swp


