JAMES-1710 implement SetMailboxesMethod base class to handle dispatch to 
Processors


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/fefc9c5c
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/fefc9c5c
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/fefc9c5c

Branch: refs/heads/master
Commit: fefc9c5c76deef0b8759a0add577e7458aa9bf52
Parents: e930dfe
Author: Matthieu Baechler <[email protected]>
Authored: Wed Mar 23 17:03:34 2016 +0100
Committer: Raphael Ouazana <[email protected]>
Committed: Tue Mar 29 14:22:38 2016 +0200

----------------------------------------------------------------------
 .../org/apache/james/jmap/MethodsModule.java    |  10 +-
 .../james/modules/data/MemoryDataModule.java    |  11 +-
 .../CassandraSetMailboxesMethodTest.java        |  54 +++++++
 .../integration/SetMailboxesMethodTest.java     | 103 ++++++++++++
 .../memory-jmap-integration-testing/pom.xml     |   5 +
 .../memory/MemorySetMailboxesMethodTest.java    |  47 ++++++
 .../src/test/resources/logback-test.xml         |  12 ++
 .../james/jmap/methods/GetMailboxesMethod.java  |   2 +-
 .../apache/james/jmap/methods/JmapResponse.java |  30 ++++
 .../methods/SetMailboxesCreationProcessor.java  |  38 +++++
 .../james/jmap/methods/SetMailboxesMethod.java  |  77 +++++++++
 .../jmap/methods/SetMailboxesProcessor.java     |  30 ++++
 .../james/jmap/model/MailboxCreationId.java     |  55 +++++++
 .../james/jmap/model/SetMailboxesRequest.java   |  92 +++++++++++
 .../james/jmap/model/SetMailboxesResponse.java  |  61 ++++++++
 .../james/jmap/model/mailbox/Mailbox.java       |  17 +-
 .../jmap/model/mailbox/MailboxRequest.java      | 156 +++++++++++++++++++
 .../james/jmap/model/mailbox/SortOrder.java     |  74 +++++++--
 .../jmap/methods/GetMailboxesMethodTest.java    |  23 +--
 .../jmap/methods/SetMailboxesMethodTest.java    | 115 ++++++++++++++
 .../jmap/model/SetMailboxesRequestTest.java     |  66 ++++++++
 .../jmap/model/mailbox/MailboxRequestTest.java  |  80 ++++++++++
 .../james/jmap/model/mailbox/MailboxTest.java   |  22 +--
 .../james/jmap/model/mailbox/SortOrderTest.java |  56 +++++++
 24 files changed, 1172 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/MethodsModule.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/MethodsModule.java
 
b/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/MethodsModule.java
index 897f4bf..449d468 100644
--- 
a/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/MethodsModule.java
+++ 
b/server/container/guice/guice-common/src/main/java/org/apache/james/jmap/MethodsModule.java
@@ -28,6 +28,9 @@ import org.apache.james.jmap.methods.JmapRequestParserImpl;
 import org.apache.james.jmap.methods.JmapResponseWriter;
 import org.apache.james.jmap.methods.JmapResponseWriterImpl;
 import org.apache.james.jmap.methods.Method;
+import org.apache.james.jmap.methods.SetMailboxesCreationProcessor;
+import org.apache.james.jmap.methods.SetMailboxesMethod;
+import org.apache.james.jmap.methods.SetMailboxesProcessor;
 import org.apache.james.jmap.methods.SetMessagesCreationProcessor;
 import org.apache.james.jmap.methods.SetMessagesDestructionProcessor;
 import org.apache.james.jmap.methods.SetMessagesMethod;
@@ -63,8 +66,13 @@ public class MethodsModule<Id extends MailboxId> extends 
AbstractModule {
         
methods.addBinding().to(guiceGenericType.newGenericType(GetMessageListMethod.class));
         
methods.addBinding().to(guiceGenericType.newGenericType(GetMessagesMethod.class));
         
methods.addBinding().to(guiceGenericType.newGenericType(SetMessagesMethod.class));
+        
methods.addBinding().to(guiceGenericType.newGenericType(SetMailboxesMethod.class));
 
-        Multibinder<SetMessagesProcessor<Id>> setMessagesProcessors = 
+        Multibinder<SetMailboxesProcessor<Id>> setMailboxesProcessor =
+            Multibinder.newSetBinder(binder(), 
guiceGenericType.newGenericType(SetMailboxesProcessor.class));
+        
setMailboxesProcessor.addBinding().to(guiceGenericType.newGenericType(SetMailboxesCreationProcessor.class));
+
+        Multibinder<SetMessagesProcessor<Id>> setMessagesProcessors =
                 Multibinder.newSetBinder(binder(), 
guiceGenericType.newGenericType(SetMessagesProcessor.class));
         
setMessagesProcessors.addBinding().to(guiceGenericType.newGenericType(SetMessagesUpdateProcessor.class));
         
setMessagesProcessors.addBinding().to(guiceGenericType.newGenericType(SetMessagesCreationProcessor.class));

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
 
b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
index 0b77388..ca11b1f 100644
--- 
a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
+++ 
b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
@@ -19,11 +19,6 @@
 
 package org.apache.james.modules.data;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
-import com.google.inject.Scopes;
-import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.domainlist.memory.MemoryDomainList;
 import org.apache.james.rrt.api.RecipientRewriteTable;
@@ -35,6 +30,12 @@ import org.apache.james.utils.ConfigurationProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+import com.google.inject.Scopes;
+import com.google.inject.Singleton;
+import com.google.inject.multibindings.Multibinder;
+
 public class MemoryDataModule extends AbstractModule {
 
     private static final Logger LOGGER = 
LoggerFactory.getLogger(MemoryDataModule.class);

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMailboxesMethodTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMailboxesMethodTest.java
 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMailboxesMethodTest.java
new file mode 100644
index 0000000..a57a21a
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMailboxesMethodTest.java
@@ -0,0 +1,54 @@
+/****************************************************************
+ * 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.jmap.cassandra;
+
+import org.apache.james.CassandraJamesServerMain;
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.backends.cassandra.EmbeddedCassandra;
+import org.apache.james.jmap.methods.integration.SetMailboxesMethodTest;
+import org.apache.james.jmap.servers.CassandraJmapServerModule;
+import org.apache.james.mailbox.elasticsearch.EmbeddedElasticSearch;
+import org.junit.Rule;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TemporaryFolder;
+
+public class CassandraSetMailboxesMethodTest extends SetMailboxesMethodTest {
+
+    private TemporaryFolder temporaryFolder = new TemporaryFolder();
+    private EmbeddedElasticSearch embeddedElasticSearch = new 
EmbeddedElasticSearch();
+    private EmbeddedCassandra cassandra = 
EmbeddedCassandra.createStartServer();
+
+    @Rule
+    public RuleChain chain = RuleChain
+        .outerRule(temporaryFolder)
+        .around(embeddedElasticSearch);
+
+    @Override
+    protected GuiceJamesServer<?> createJmapServer() {
+        return new GuiceJamesServer<>(CassandraJamesServerMain.cassandraId)
+                    
.combineWith(CassandraJamesServerMain.cassandraServerModule)
+                    .overrideWith(new 
CassandraJmapServerModule(temporaryFolder, embeddedElasticSearch, cassandra));
+    }
+    
+    @Override
+    protected void await() {
+        embeddedElasticSearch.awaitForElasticSearch();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMailboxesMethodTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMailboxesMethodTest.java
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMailboxesMethodTest.java
new file mode 100644
index 0000000..162bb6e
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMailboxesMethodTest.java
@@ -0,0 +1,103 @@
+/****************************************************************
+ * 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.jmap.methods.integration;
+
+import static com.jayway.restassured.RestAssured.given;
+import static com.jayway.restassured.config.EncoderConfig.encoderConfig;
+import static com.jayway.restassured.config.RestAssuredConfig.newConfig;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasKey;
+
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.jmap.JmapAuthentication;
+import org.apache.james.jmap.api.access.AccessToken;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.http.ContentType;
+
+public abstract class SetMailboxesMethodTest {
+
+    private static final String NAME = "[0][0]";
+    private static final String ARGUMENTS = "[0][1]";
+    private static final String USERS_DOMAIN = "domain.tld";
+
+    protected abstract GuiceJamesServer<?> createJmapServer();
+
+    protected abstract void await();
+
+    private AccessToken accessToken;
+    private String username;
+    private GuiceJamesServer<?> jmapServer;
+
+    @Before
+    public void setup() throws Throwable {
+        jmapServer = createJmapServer();
+        jmapServer.start();
+        RestAssured.port = jmapServer.getJmapPort();
+        RestAssured.config = 
newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8));
+
+        username = "username@" + USERS_DOMAIN;
+        String password = "password";
+        jmapServer.serverProbe().addDomain(USERS_DOMAIN);
+        jmapServer.serverProbe().addUser(username, password);
+        jmapServer.serverProbe().createMailbox("#private", username, "inbox");
+        accessToken = JmapAuthentication.authenticateJamesUser(username, 
password);
+
+        await();
+    }
+
+    @After
+    public void teardown() {
+        jmapServer.stop();
+    }
+    
+    @Test
+    public void setMailboxesShouldCreateMailbox() throws Exception {
+        String requestBody =
+            "[" +
+                "  [ \"setMailboxes\"," +
+                "    {" +
+                "      \"create\": {" +
+                "        \"create-id01\" : {" +
+                "          \"name\" : \"foo\"" +
+                "        }" +
+                "      }" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", this.accessToken.serialize())
+            .body(requestBody)
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxesSet"))
+            .body(ARGUMENTS + ".created", hasKey("create-id01"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/pom.xml
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/pom.xml
 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/pom.xml
index 6404f9c..fcd0d61 100644
--- 
a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/pom.xml
+++ 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/pom.xml
@@ -184,6 +184,11 @@
                 <dependency>
                     <groupId>org.hamcrest</groupId>
                     <artifactId>java-hamcrest</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-classic</artifactId>
+                    <version>1.1.6</version>
                     <scope>test</scope>
                 </dependency>
             </dependencies>

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMailboxesMethodTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMailboxesMethodTest.java
 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMailboxesMethodTest.java
new file mode 100644
index 0000000..5fadd9b
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMailboxesMethodTest.java
@@ -0,0 +1,47 @@
+/****************************************************************
+ * 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.jmap.memory;
+
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.MemoryJamesServerMain;
+import org.apache.james.jmap.methods.integration.SetMailboxesMethodTest;
+import org.apache.james.jmap.servers.MemoryJmapServerModule;
+import org.apache.james.mailbox.inmemory.InMemoryId;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+
+import com.google.inject.TypeLiteral;
+
+public class MemorySetMailboxesMethodTest extends SetMailboxesMethodTest {
+
+    @Rule
+    public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+    @Override
+    protected GuiceJamesServer<?> createJmapServer() {
+        return new GuiceJamesServer<>(new TypeLiteral<InMemoryId>(){})
+                    .combineWith(MemoryJamesServerMain.inMemoryServerModule)
+                    .overrideWith(new MemoryJmapServerModule(temporaryFolder));
+    }
+    
+    @Override
+    protected void await() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/logback-test.xml
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/logback-test.xml
 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..dd2d81e
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/logback-test.xml
@@ -0,0 +1,12 @@
+<configuration>
+
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%date %-5level [%thread] - [%logger]- %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <root level="WARN">
+        <appender-ref ref="STDOUT" />
+    </root>
+</configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMailboxesMethod.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMailboxesMethod.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMailboxesMethod.java
index 2285ff6..53a22e2 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMailboxesMethod.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMailboxesMethod.java
@@ -105,7 +105,7 @@ public class GetMailboxesMethod<Id extends MailboxId> 
implements Method {
                 .filter(Optional::isPresent)
                 .map(Optional::get)
                 .filter(filterMailboxesById(mailboxesRequest.getIds()))
-                .sorted((m1, m2) -> Integer.compare(m1.getSortOrder(), 
m2.getSortOrder()))
+                .sorted((m1, m2) -> 
m1.getSortOrder().compareTo(m2.getSortOrder()))
                 .forEach(mailbox -> builder.add(mailbox));
             return builder.build();
         } catch (MailboxException e) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponse.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponse.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponse.java
index db15434..dbfdee9 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponse.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponse.java
@@ -26,6 +26,7 @@ import org.apache.james.jmap.model.ClientId;
 import org.apache.james.jmap.model.Property;
 
 import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
+import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableSet;
 
 public class JmapResponse {
@@ -131,4 +132,33 @@ public class JmapResponse {
     public Optional<SimpleFilterProvider> getFilterProvider() {
         return filterProvider;
     }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(method, clientId, response, properties, 
filterProvider);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (object instanceof JmapResponse) {
+            JmapResponse that = (JmapResponse) object;
+            return Objects.equal(this.method, that.method)
+                    && Objects.equal(this.clientId, that.clientId)
+                    && Objects.equal(this.response, that.response)
+                    && Objects.equal(this.properties, that.properties)
+                    && Objects.equal(this.filterProvider, that.filterProvider);
+        }
+        return false;
+    }
+    
+    @Override
+    public String toString() {
+        return Objects.toStringHelper(getClass())
+                .add("method", method)
+                .add("response", response)
+                .add("clientId", clientId)
+                .add("properties", properties)
+                .add("filterProvider", filterProvider)
+                .toString();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
new file mode 100644
index 0000000..73426f5
--- /dev/null
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
@@ -0,0 +1,38 @@
+/****************************************************************
+ * 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.jmap.methods;
+
+import org.apache.james.jmap.model.SetMailboxesRequest;
+import org.apache.james.jmap.model.SetMailboxesResponse;
+import org.apache.james.jmap.model.mailbox.Mailbox;
+import org.apache.james.mailbox.store.mail.model.MailboxId;
+
+public class SetMailboxesCreationProcessor<Id extends MailboxId> implements 
SetMailboxesProcessor<Id> {
+
+    public SetMailboxesResponse process(SetMailboxesRequest request) {
+        SetMailboxesResponse.Builder builder = SetMailboxesResponse.builder();
+        request.getCreate().entrySet().stream()
+            .forEach(entry -> builder.creation(
+                entry.getKey(),
+                
Mailbox.builder().name(entry.getValue().getName()).id("serverId").build()));
+        return builder.build();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesMethod.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesMethod.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesMethod.java
new file mode 100644
index 0000000..70b6e90
--- /dev/null
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesMethod.java
@@ -0,0 +1,77 @@
+/****************************************************************
+ * 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.jmap.methods;
+
+import java.util.Set;
+import java.util.stream.Stream;
+
+import javax.inject.Inject;
+
+import org.apache.james.jmap.model.ClientId;
+import org.apache.james.jmap.model.SetMailboxesRequest;
+import org.apache.james.jmap.model.SetMailboxesResponse;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.store.mail.model.MailboxId;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+
+public class SetMailboxesMethod<Id extends MailboxId> implements Method {
+
+    private static final Request.Name METHOD_NAME = 
Request.name("setMailboxes");
+    @VisibleForTesting static final Response.Name RESPONSE_NAME = 
Response.name("mailboxesSet");
+
+    private final Set<SetMailboxesProcessor<Id>> processors;
+
+    @Inject
+    public SetMailboxesMethod(Set<SetMailboxesProcessor<Id>> processors) {
+        this.processors = processors;
+    }
+
+    @Override
+    public Request.Name requestHandled() {
+        return METHOD_NAME;
+    }
+
+    @Override
+    public Class<? extends JmapRequest> requestType() {
+        return SetMailboxesRequest.class;
+    }
+
+    @Override
+    public Stream<JmapResponse> process(JmapRequest request, ClientId 
clientId, MailboxSession mailboxSession) {
+        Preconditions.checkNotNull(request);
+        Preconditions.checkNotNull(clientId);
+        Preconditions.checkNotNull(mailboxSession);
+        Preconditions.checkArgument(request instanceof SetMailboxesRequest);
+        SetMailboxesRequest setMailboxesRequest = (SetMailboxesRequest) 
request;
+        return processors.stream()
+            .map(processor -> processor.process(setMailboxesRequest))
+            .map(response -> toJmapResponse(clientId, response));
+    }
+
+    private JmapResponse toJmapResponse(ClientId clientId, 
SetMailboxesResponse response) {
+        return JmapResponse.builder()
+                .clientId(clientId)
+                .responseName(RESPONSE_NAME)
+                .response(response)
+                .build();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesProcessor.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesProcessor.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesProcessor.java
new file mode 100644
index 0000000..c9b7ef7
--- /dev/null
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesProcessor.java
@@ -0,0 +1,30 @@
+/****************************************************************
+ * 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.jmap.methods;
+
+import org.apache.james.jmap.model.SetMailboxesRequest;
+import org.apache.james.jmap.model.SetMailboxesResponse;
+import org.apache.james.mailbox.store.mail.model.MailboxId;
+
+public interface SetMailboxesProcessor<Id extends MailboxId> {
+
+    SetMailboxesResponse process(SetMailboxesRequest request);
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxCreationId.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxCreationId.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxCreationId.java
new file mode 100644
index 0000000..4304ae8
--- /dev/null
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxCreationId.java
@@ -0,0 +1,55 @@
+/****************************************************************
+ * 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.jmap.model;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import java.util.Objects;
+
+public class MailboxCreationId {
+
+    public static MailboxCreationId of(String creationId) {
+        return new MailboxCreationId(creationId);
+    }
+
+    private final String creationId;
+
+    private MailboxCreationId(String creationId) {
+        this.creationId = creationId;
+    }
+
+    @JsonValue
+    public String getCreationId() {
+        return creationId;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof MailboxCreationId) {
+            return Objects.equals(creationId, ((MailboxCreationId) 
obj).creationId);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(creationId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMailboxesRequest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMailboxesRequest.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMailboxesRequest.java
new file mode 100644
index 0000000..a28549b
--- /dev/null
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMailboxesRequest.java
@@ -0,0 +1,92 @@
+/****************************************************************
+ * 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.jmap.model;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.james.jmap.methods.JmapRequest;
+import org.apache.james.jmap.model.mailbox.Mailbox;
+import org.apache.james.jmap.model.mailbox.MailboxRequest;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableMap;
+
+@JsonDeserialize(builder = SetMailboxesRequest.Builder.class)
+public class SetMailboxesRequest implements JmapRequest {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    @JsonPOJOBuilder(withPrefix = "")
+    public static class Builder {
+
+        private ImmutableMap.Builder<MailboxCreationId, MailboxRequest> create;
+
+        private Builder() {
+            create = ImmutableMap.builder();
+        }
+
+        public Builder create(Map<MailboxCreationId, MailboxRequest> requests) 
{
+            create.putAll(requests);
+            return this;
+        }
+
+        public Builder create(MailboxCreationId creationId, MailboxRequest 
mailbox) {
+            create.put(creationId, mailbox);
+            return this;
+        }
+        
+        public Builder accountId(String accountId) {
+            throw new NotImplementedException();
+        }
+        
+        public Builder ifInState(String state) {
+            throw new NotImplementedException();
+        }
+        
+        public Builder update(Map<String, Mailbox> updates) {
+            throw new NotImplementedException();
+        }
+        
+        public Builder destroy(List<String> deletions) {
+            throw new NotImplementedException();
+        }
+
+        public SetMailboxesRequest build() {
+            return new SetMailboxesRequest(create.build());
+        }
+    }
+
+    private final ImmutableMap<MailboxCreationId, MailboxRequest> create;
+
+    @VisibleForTesting
+    SetMailboxesRequest(ImmutableMap<MailboxCreationId, MailboxRequest> 
create) {
+        this.create = create;
+    }
+
+    public ImmutableMap<MailboxCreationId, MailboxRequest> getCreate() {
+        return create;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMailboxesResponse.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMailboxesResponse.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMailboxesResponse.java
new file mode 100644
index 0000000..4322328
--- /dev/null
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMailboxesResponse.java
@@ -0,0 +1,61 @@
+/****************************************************************
+ * 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.jmap.model;
+
+import org.apache.james.jmap.methods.Method;
+import org.apache.james.jmap.model.mailbox.Mailbox;
+
+import com.google.common.collect.ImmutableMap;
+
+public class SetMailboxesResponse implements Method.Response {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static class Builder {
+
+        private ImmutableMap.Builder<MailboxCreationId, Mailbox> created;
+
+        private Builder() {
+            created = ImmutableMap.builder();
+        }
+
+        public Builder creation(MailboxCreationId creationId, Mailbox mailbox) 
{
+            created.put(creationId, mailbox);
+            return this;
+        }
+
+        public SetMailboxesResponse build() {
+            return new SetMailboxesResponse(created.build());
+        }
+
+    }
+
+    private final ImmutableMap<MailboxCreationId, Mailbox> created;
+
+    private SetMailboxesResponse(ImmutableMap<MailboxCreationId, Mailbox> 
created) {
+        this.created = created;
+    }
+
+    public ImmutableMap<MailboxCreationId, Mailbox> getCreated() {
+        return created;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Mailbox.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Mailbox.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Mailbox.java
index 58f6ff7..a0b5d70 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Mailbox.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Mailbox.java
@@ -22,13 +22,14 @@ package org.apache.james.jmap.model.mailbox;
 import java.util.Objects;
 import java.util.Optional;
 
+import org.apache.james.jmap.methods.JmapResponseWriterImpl;
+
 import com.fasterxml.jackson.annotation.JsonFilter;
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
-import org.apache.james.jmap.methods.JmapResponseWriterImpl;
 
 @JsonDeserialize(builder = Mailbox.Builder.class)
 @JsonFilter(JmapResponseWriterImpl.PROPERTIES_FILTER)
@@ -41,13 +42,11 @@ public class Mailbox {
     @JsonPOJOBuilder(withPrefix = "")
     public static class Builder {
 
-        private final static int MAX_SORT_ORDER = Double.valueOf(Math.pow(2, 
31)).intValue();
-
         private String id;
         private String name;
         private String parentId;
         private Optional<Role> role;
-        private int sortOrder;
+        private SortOrder sortOrder;
         private boolean mustBeOnlyMailbox;
         private boolean mayReadItems;
         private boolean mayAddItems;
@@ -85,7 +84,7 @@ public class Mailbox {
             return this;
         }
 
-        public Builder sortOrder(int sortOrder) {
+        public Builder sortOrder(SortOrder sortOrder) {
             this.sortOrder = sortOrder;
             return this;
         }
@@ -148,8 +147,6 @@ public class Mailbox {
         public Mailbox build() {
             Preconditions.checkState(!Strings.isNullOrEmpty(name), "'name' is 
mandatory");
             Preconditions.checkState(!Strings.isNullOrEmpty(id), "'id' is 
mandatory");
-            Preconditions.checkState(sortOrder >= 0, "'sortOrder' must be 
positive");
-            Preconditions.checkState(sortOrder < MAX_SORT_ORDER, "'sortOrder' 
must be lesser than " + MAX_SORT_ORDER);
 
             return new Mailbox(id, name, Optional.ofNullable(parentId), role, 
sortOrder, mustBeOnlyMailbox, mayReadItems, mayAddItems, mayRemoveItems, 
mayCreateChild, mayRename, mayDelete,
                     totalMessages, unreadMessages, totalThreads, 
unreadThreads);
@@ -160,7 +157,7 @@ public class Mailbox {
     private final String name;
     private final Optional<String> parentId;
     private final Optional<Role> role;
-    private final int sortOrder;
+    private final SortOrder sortOrder;
     private final boolean mustBeOnlyMailbox;
     private final boolean mayReadItems;
     private final boolean mayAddItems;
@@ -173,7 +170,7 @@ public class Mailbox {
     private final long totalThreads;
     private final long unreadThreads;
 
-    @VisibleForTesting Mailbox(String id, String name, Optional<String> 
parentId, Optional<Role> role, int sortOrder, boolean mustBeOnlyMailbox, 
+    @VisibleForTesting Mailbox(String id, String name, Optional<String> 
parentId, Optional<Role> role, SortOrder sortOrder, boolean mustBeOnlyMailbox,
             boolean mayReadItems, boolean mayAddItems, boolean mayRemoveItems, 
boolean mayCreateChild, boolean mayRename, boolean mayDelete,
             long totalMessages, long unreadMessages, long totalThreads, long 
unreadThreads) {
 
@@ -211,7 +208,7 @@ public class Mailbox {
         return role;
     }
 
-    public int getSortOrder() {
+    public SortOrder getSortOrder() {
         return sortOrder;
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/MailboxRequest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/MailboxRequest.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/MailboxRequest.java
new file mode 100644
index 0000000..c625f7a
--- /dev/null
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/MailboxRequest.java
@@ -0,0 +1,156 @@
+/****************************************************************
+O * 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.jmap.model.mailbox;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import org.apache.commons.lang.NotImplementedException;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
+@JsonDeserialize(builder = MailboxRequest.Builder.class)
+public class MailboxRequest {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    @JsonPOJOBuilder(withPrefix = "")
+    public static class Builder {
+
+        private Optional<String> id;
+        private String name;
+        private Optional<String> parentId;
+        private Optional<Role> role;
+        private Optional<SortOrder> sortOrder;
+
+        private Builder() {
+            id = Optional.empty();
+            role = Optional.empty();
+            sortOrder = Optional.empty();
+            parentId = Optional.empty();
+        }
+
+        public Builder id(String id) {
+            Preconditions.checkNotNull(id);
+            this.id = Optional.of(id);
+            return this;
+        }
+
+        public Builder name(String name) {
+            Preconditions.checkNotNull(name);
+            this.name = name;
+            return this;
+        }
+
+        public Builder parentId(String parentId) {
+            Preconditions.checkNotNull(parentId);
+            this.parentId = Optional.of(parentId);
+            return this;
+        }
+
+        public Builder role(Role role) {
+            Preconditions.checkNotNull(role);
+            throw new NotImplementedException();
+        }
+
+        public Builder sortOrder(SortOrder sortOrder) {
+            Preconditions.checkNotNull(sortOrder);
+            throw new NotImplementedException();
+        }
+
+
+        public MailboxRequest build() {
+            Preconditions.checkState(!Strings.isNullOrEmpty(name), "'name' is 
mandatory");
+            return new MailboxRequest(id, name, parentId, role, sortOrder);
+        }
+    }
+
+    private final Optional<String> id;
+    private final String name;
+    private final Optional<String> parentId;
+    private final Optional<Role> role;
+    private final Optional<SortOrder> sortOrder;
+
+    @VisibleForTesting
+    MailboxRequest(Optional<String> id, String name, Optional<String> 
parentId, Optional<Role> role, Optional<SortOrder> sortOrder) {
+
+        this.id = id;
+        this.name = name;
+        this.parentId = parentId;
+        this.role = role;
+        this.sortOrder = sortOrder;
+    }
+
+    public Optional<String> getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Optional<String> getParentId() {
+        return parentId;
+    }
+
+    public Optional<Role> getRole() {
+        return role;
+    }
+
+    public Optional<SortOrder> getSortOrder() {
+        return sortOrder;
+    }
+
+
+    @Override
+    public final boolean equals(Object obj) {
+        if (obj instanceof MailboxRequest) {
+            MailboxRequest other = (MailboxRequest) obj;
+            return Objects.equals(this.id, other.id)
+                && Objects.equals(this.name, other.name)
+                && Objects.equals(this.parentId, other.parentId)
+                && Objects.equals(this.role, other.role)
+                && Objects.equals(this.sortOrder, other.sortOrder);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(id, name, parentId, role, sortOrder);
+    }
+
+    @Override
+    public String toString() {
+        return com.google.common.base.Objects.toStringHelper(getClass())
+                .add("id", id)
+                .add("name", name)
+                .add("parentId", parentId)
+                .add("role", role)
+                .add("sortOrder", sortOrder)
+                .toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/SortOrder.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/SortOrder.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/SortOrder.java
index 4fb2035..fe5fb0b 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/SortOrder.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/SortOrder.java
@@ -18,33 +18,75 @@
  ****************************************************************/
 package org.apache.james.jmap.model.mailbox;
 
+import java.util.Optional;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 
-import java.util.Optional;
+public class SortOrder implements Comparable<SortOrder> {
 
-public class SortOrder {
-
-    private static final int DEFAULT_SORT_ORDER = 1000;
-    private static final ImmutableMap<Role, Integer> defaultSortOrders =
-            ImmutableMap.<Role, Integer>builder()
-                .put(Role.INBOX, 10)
-                .put(Role.ARCHIVE, 20)
-                .put(Role.DRAFTS, 30)
-                .put(Role.OUTBOX, 40)
-                .put(Role.SENT, 50)
-                .put(Role.TRASH, 60)
-                .put(Role.SPAM, 70)
-                .put(Role.TEMPLATES, 80)
+    private static final SortOrder DEFAULT_SORT_ORDER = SortOrder.of(1000);
+    private static final ImmutableMap<Role, SortOrder> defaultSortOrders =
+            ImmutableMap.<Role, SortOrder>builder()
+                .put(Role.INBOX, SortOrder.of(10))
+                .put(Role.ARCHIVE, SortOrder.of(20))
+                .put(Role.DRAFTS, SortOrder.of(30))
+                .put(Role.OUTBOX, SortOrder.of(40))
+                .put(Role.SENT, SortOrder.of(50))
+                .put(Role.TRASH, SortOrder.of(60))
+                .put(Role.SPAM, SortOrder.of(70))
+                .put(Role.TEMPLATES, SortOrder.of(80))
                 .build();
 
-    private static Optional<Integer> getDefaultSortOrder(Role role) {
+    private static Optional<SortOrder> getDefaultSortOrder(Role role) {
         return Optional.ofNullable(defaultSortOrders.get(role));
     }
 
-    public static Integer getSortOrder(Optional<Role> role) {
+    public static SortOrder getSortOrder(Optional<Role> role) {
         return role
                 .map(SortOrder::getDefaultSortOrder)
                 .map(Optional::get)
                 .orElse(DEFAULT_SORT_ORDER);
     }
+
+    public static SortOrder of(int sortOrder) {
+        Preconditions.checkArgument(sortOrder >= 0, "'sortOrder' must be 
positive");
+        return new SortOrder(sortOrder);
+    }
+
+    private final int sortOrder;
+
+    private SortOrder(int sortOrder) {
+        this.sortOrder = sortOrder;
+    }
+
+    @JsonValue
+    public int getSortOrder() {
+        return sortOrder;
+    }
+
+    @Override
+    public int compareTo(SortOrder o) {
+        return Integer.compare(sortOrder, o.sortOrder);
+    }
+    
+    @Override
+    public String toString() {
+        return Objects.toStringHelper(getClass()).add("order", 
sortOrder).toString();
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof SortOrder) {
+            return sortOrder == ((SortOrder)obj).sortOrder;
+        }
+        return super.equals(obj);
+    }
+    
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(sortOrder);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMailboxesMethodTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMailboxesMethodTest.java
 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMailboxesMethodTest.java
index de12b71..08f8ef3 100644
--- 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMailboxesMethodTest.java
+++ 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMailboxesMethodTest.java
@@ -36,6 +36,7 @@ import org.apache.james.jmap.model.GetMailboxesRequest;
 import org.apache.james.jmap.model.GetMailboxesResponse;
 import org.apache.james.jmap.model.mailbox.Mailbox;
 import org.apache.james.jmap.model.mailbox.Role;
+import org.apache.james.jmap.model.mailbox.SortOrder;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
@@ -189,7 +190,7 @@ public class GetMailboxesMethodTest {
                 .extracting(GetMailboxesResponse.class::cast)
                 .flatExtracting(GetMailboxesResponse::getList)
                 .extracting(Mailbox::getSortOrder)
-                .containsOnly(10);
+                .containsOnly(SortOrder.of(10));
     }
 
     @Test
@@ -210,7 +211,7 @@ public class GetMailboxesMethodTest {
                 .extracting(GetMailboxesResponse.class::cast)
                 .flatExtracting(GetMailboxesResponse::getList)
                 .extracting(Mailbox::getSortOrder)
-                .containsOnly(1000);
+                .containsOnly(SortOrder.of(1000));
     }
 
     @Test
@@ -231,7 +232,7 @@ public class GetMailboxesMethodTest {
                 .extracting(GetMailboxesResponse.class::cast)
                 .flatExtracting(GetMailboxesResponse::getList)
                 .extracting(Mailbox::getSortOrder)
-                .containsOnly(10);
+                .containsOnly(SortOrder.of(10));
     }
 
     @Test
@@ -259,14 +260,14 @@ public class GetMailboxesMethodTest {
                 .flatExtracting(GetMailboxesResponse::getList)
                 .extracting(Mailbox::getName, Mailbox::getSortOrder)
                 .containsExactly(
-                        Tuple.tuple("INBOX", 10),
-                        Tuple.tuple("ARCHIVE", 20),
-                        Tuple.tuple("DRAFTS", 30),
-                        Tuple.tuple("OUTBOX", 40),
-                        Tuple.tuple("SENT", 50),
-                        Tuple.tuple("TRASH", 60),
-                        Tuple.tuple("SPAM", 70),
-                        Tuple.tuple("TEMPLATES", 80));
+                        Tuple.tuple("INBOX", SortOrder.of(10)),
+                        Tuple.tuple("ARCHIVE", SortOrder.of(20)),
+                        Tuple.tuple("DRAFTS", SortOrder.of(30)),
+                        Tuple.tuple("OUTBOX", SortOrder.of(40)),
+                        Tuple.tuple("SENT", SortOrder.of(50)),
+                        Tuple.tuple("TRASH", SortOrder.of(60)),
+                        Tuple.tuple("SPAM", SortOrder.of(70)),
+                        Tuple.tuple("TEMPLATES", SortOrder.of(80)));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMailboxesMethodTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMailboxesMethodTest.java
 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMailboxesMethodTest.java
new file mode 100644
index 0000000..af0d4a3
--- /dev/null
+++ 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMailboxesMethodTest.java
@@ -0,0 +1,115 @@
+/****************************************************************
+ * 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.jmap.methods;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.stream.Stream;
+
+import org.apache.james.jmap.model.ClientId;
+import org.apache.james.jmap.model.GetMailboxesRequest;
+import org.apache.james.jmap.model.MailboxCreationId;
+import org.apache.james.jmap.model.SetMailboxesRequest;
+import org.apache.james.jmap.model.SetMailboxesResponse;
+import org.apache.james.jmap.model.mailbox.Mailbox;
+import org.apache.james.jmap.model.mailbox.MailboxRequest;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.store.TestId;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+public class SetMailboxesMethodTest {
+
+    private static final ImmutableSet<SetMailboxesProcessor<TestId>> 
NO_PROCESSOR = ImmutableSet.of();
+
+    @Test
+    public void requestHandledShouldBeSetMailboxes() {
+        assertThat(new 
SetMailboxesMethod<>(NO_PROCESSOR).requestHandled().getName()).isEqualTo("setMailboxes");
+    }
+
+    @Test
+    public void requestTypeShouldBeSetMailboxes() {
+        assertThat(new 
SetMailboxesMethod<>(NO_PROCESSOR).requestType()).isEqualTo(SetMailboxesRequest.class);
+    }
+
+    @Test
+    public void processShouldThrowWhenNullJmapRequest() {
+        MailboxSession session = mock(MailboxSession.class);
+        JmapRequest nullJmapRequest = null;
+        assertThatThrownBy(() -> new 
SetMailboxesMethod<>(NO_PROCESSOR).process(nullJmapRequest, 
ClientId.of("clientId"), session))
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void processShouldThrowWhenNullClientId() {
+        MailboxSession session = mock(MailboxSession.class);
+        JmapRequest jmapRequest = mock(JmapRequest.class);
+        ClientId nullClientId = null;
+        assertThatThrownBy(() -> new 
SetMailboxesMethod<>(NO_PROCESSOR).process(jmapRequest, nullClientId, session))
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void processShouldThrowWhenNullMailboxSession() {
+        MailboxSession nullMailboxSession = null;
+        JmapRequest jmapRequest = mock(JmapRequest.class);
+        assertThatThrownBy(() -> new 
SetMailboxesMethod<>(NO_PROCESSOR).process(jmapRequest, 
ClientId.of("clientId"), nullMailboxSession))
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void processShouldThrowWhenJmapRequestTypeMismatch() {
+        MailboxSession session = mock(MailboxSession.class);
+        JmapRequest getMailboxesRequest = 
GetMailboxesRequest.builder().build();
+        assertThatThrownBy(() -> new 
SetMailboxesMethod<>(NO_PROCESSOR).process(getMailboxesRequest, 
ClientId.of("clientId"), session))
+            .isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void processShouldCallCreatorProcessorWhenCreationRequest() {
+        MailboxCreationId creationId = MailboxCreationId.of("create-id01");
+        MailboxRequest fooFolder = 
MailboxRequest.builder().name("fooFolder").build();
+        SetMailboxesRequest creationRequest = 
SetMailboxesRequest.builder().create(creationId, fooFolder).build();
+
+        Mailbox createdfooFolder = 
Mailbox.builder().name("fooFolder").id("fooId").build();
+        SetMailboxesResponse creationResponse = 
SetMailboxesResponse.builder().creation(creationId, createdfooFolder).build();
+        JmapResponse jmapResponse = JmapResponse.builder()
+            .response(creationResponse)
+            .clientId(ClientId.of("clientId"))
+            .responseName(SetMailboxesMethod.RESPONSE_NAME)
+            .build();
+
+        MailboxSession session = mock(MailboxSession.class);
+        @SuppressWarnings("unchecked")
+        SetMailboxesProcessor<TestId> creatorProcessor = 
mock(SetMailboxesProcessor.class);
+        
when(creatorProcessor.process(creationRequest)).thenReturn(creationResponse);
+
+        Stream<JmapResponse> actual =
+            new SetMailboxesMethod<>(ImmutableSet.of(creatorProcessor))
+                    .process(creationRequest, ClientId.of("clientId"), 
session);
+
+        assertThat(actual).contains(jmapResponse);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetMailboxesRequestTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetMailboxesRequestTest.java
 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetMailboxesRequestTest.java
new file mode 100644
index 0000000..808f558
--- /dev/null
+++ 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetMailboxesRequestTest.java
@@ -0,0 +1,66 @@
+/****************************************************************
+ * 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.jmap.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.james.jmap.model.mailbox.MailboxRequest;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class SetMailboxesRequestTest {
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenAccountId() {
+        SetMailboxesRequest.builder().accountId("1");
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenIfInState() {
+        SetMailboxesRequest.builder().ifInState("1");
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenUpdate() {
+        SetMailboxesRequest.builder().update(ImmutableMap.of());
+    }
+    
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenDestroy() {
+        SetMailboxesRequest.builder().destroy(ImmutableList.of());
+    }
+    
+    @Test
+    public void builderShouldWork() {
+        MailboxCreationId creationId = MailboxCreationId.of("creationId");
+        MailboxRequest mailboxRequest = MailboxRequest.builder()
+            .name("mailboxRequest")
+            .build();
+        SetMailboxesRequest expected = new 
SetMailboxesRequest(ImmutableMap.of(creationId, mailboxRequest));
+        
+        SetMailboxesRequest actual = SetMailboxesRequest.builder()
+            .create(creationId, mailboxRequest)
+            .build();
+        
+        assertThat(actual).isEqualToComparingFieldByField(expected);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxRequestTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxRequestTest.java
 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxRequestTest.java
new file mode 100644
index 0000000..e5265f3
--- /dev/null
+++ 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxRequestTest.java
@@ -0,0 +1,80 @@
+/****************************************************************
+ * 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.jmap.model.mailbox;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.junit.Test;
+
+public class MailboxRequestTest {
+
+    @Test
+    public void builderShouldThrowOnNullRole() {
+        assertThatThrownBy(() -> 
MailboxRequest.builder().role(null)).isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void builderShouldThrowWhenRoleDefine() {
+        assertThatThrownBy(() -> 
MailboxRequest.builder().role(Role.ARCHIVE)).isInstanceOf(NotImplementedException.class);
+    }
+
+    @Test
+    public void builderShouldThrowOnNullId() {
+        assertThatThrownBy(() -> 
MailboxRequest.builder().id(null)).isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void builderShouldThrowOnNullSortOrder() {
+        assertThatThrownBy(() -> 
MailboxRequest.builder().sortOrder(null)).isInstanceOf(NullPointerException.class);
+    }
+    
+    @Test
+    public void builderShouldThrowOnSortOrderDefine() {
+        assertThatThrownBy(() -> 
MailboxRequest.builder().sortOrder(SortOrder.of(123))).isInstanceOf(NotImplementedException.class);
+    }    
+
+    @Test
+    public void builderShouldThrowOnNullParentId() {
+        assertThatThrownBy(() -> 
MailboxRequest.builder().parentId(null)).isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void builderShouldThrowOnNullName() {
+        assertThatThrownBy(() -> 
MailboxRequest.builder().name(null)).isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void builderShouldRequireName() {
+        assertThatThrownBy(() -> MailboxRequest.builder().build())
+            .isInstanceOf(IllegalStateException.class)
+            .hasMessageContaining("name");
+    }
+
+    @Test
+    public void builderShouldBuildWhenName() {
+        MailboxRequest request = MailboxRequest.builder().name("foo").build();
+        assertThat(request.getName()).isEqualTo("foo");
+        assertThat(request.getId()).isEmpty();
+        assertThat(request.getParentId()).isEmpty();
+        assertThat(request.getSortOrder()).isEmpty();
+        assertThat(request.getRole()).isEmpty();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxTest.java
 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxTest.java
index 8791a12..6510ba4 100644
--- 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxTest.java
+++ 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxTest.java
@@ -68,27 +68,9 @@ public class MailboxTest {
             .build();
     }
 
-    @Test(expected=IllegalStateException.class)
-    public void buildShouldThrowWhenSortOrderIsNegative() {
-        Mailbox.builder()
-            .id("id")
-            .name("name")
-            .sortOrder(-1)
-            .build();
-    }
-
-    @Test(expected=IllegalStateException.class)
-    public void buildShouldThrowWhenSortOrderIsGreaterThanMax() {
-        Mailbox.builder()
-            .id("id")
-            .name("name")
-            .sortOrder(Double.valueOf(Math.pow(2, 31)).intValue())
-            .build();
-    }
-
     @Test
     public void buildShouldWork() {
-        Mailbox expectedMailbox = new Mailbox("id", "name", 
Optional.of("parentId"), Optional.of(Role.DRAFTS), 123,
+        Mailbox expectedMailbox = new Mailbox("id", "name", 
Optional.of("parentId"), Optional.of(Role.DRAFTS), SortOrder.of(123),
                 true, true, true, true, true, true, true, 456, 789, 741, 852);
 
         Mailbox mailbox = Mailbox.builder()
@@ -96,7 +78,7 @@ public class MailboxTest {
             .name("name")
             .parentId("parentId")
             .role(Optional.of(Role.DRAFTS))
-            .sortOrder(123)
+            .sortOrder(SortOrder.of(123))
             .mustBeOnlyMailbox(true)
             .mayReadItems(true)
             .mayAddItems(true)

http://git-wip-us.apache.org/repos/asf/james-project/blob/fefc9c5c/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/SortOrderTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/SortOrderTest.java
 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/SortOrderTest.java
new file mode 100644
index 0000000..2c42890
--- /dev/null
+++ 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/SortOrderTest.java
@@ -0,0 +1,56 @@
+/****************************************************************
+ * 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.jmap.model.mailbox;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.TreeSet;
+
+import org.junit.Test;
+
+public class SortOrderTest {
+
+    @Test
+    public void sortOrderShouldNotBeNegative() {
+        assertThatThrownBy(() -> 
SortOrder.of(-1)).isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void sortOrderShouldSupportZero() {
+        assertThat(SortOrder.of(0).getSortOrder()).isEqualTo(0);
+    }
+
+    @Test
+    public void sortOrderShouldSupportPositiveInteger() {
+        assertThat(SortOrder.of(4).getSortOrder()).isEqualTo(4);
+    }
+
+    @Test
+    public void sortOrderShouldBeComparable() {
+        TreeSet<SortOrder> sortedSet = new TreeSet<>();
+        SortOrder _66 = SortOrder.of(66);
+        SortOrder _4 = SortOrder.of(4);
+        SortOrder _5 = SortOrder.of(5);
+        sortedSet.add(_66);
+        sortedSet.add(_4);
+        sortedSet.add(_5);
+        assertThat(sortedSet).containsExactly(_4, _5, _66);
+    }
+}
\ No newline at end of file


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

Reply via email to