http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
new file mode 100644
index 0000000..a90ae83
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
@@ -0,0 +1,1367 @@
+/****************************************************************
+ * 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.RestAssured.with;
+import static com.jayway.restassured.config.EncoderConfig.encoderConfig;
+import static com.jayway.restassured.config.RestAssuredConfig.newConfig;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.endsWith;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.isEmptyOrNullString;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.collection.IsMapWithSize.aMapWithSize;
+import static org.hamcrest.collection.IsMapWithSize.anEmptyMap;
+
+import java.io.ByteArrayInputStream;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import javax.mail.Flags;
+
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.jmap.JmapAuthentication;
+import org.apache.james.jmap.api.access.AccessToken;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.hamcrest.Matchers;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+import com.jayway.awaitility.Awaitility;
+import com.jayway.awaitility.Duration;
+import com.jayway.awaitility.core.ConditionFactory;
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.builder.ResponseSpecBuilder;
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.specification.ResponseSpecification;
+
+public abstract class SetMessagesMethodTest {
+
+    private static final String NAME = "[0][0]";
+    private static final String ARGUMENTS = "[0][1]";
+    private static final String SECOND_NAME = "[1][0]";
+    private static final String SECOND_ARGUMENTS = "[1][1]";
+    private static final String USERS_DOMAIN = "domain.tld";
+
+    private ConditionFactory calmlyAwait;
+
+    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);
+
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "outbox");
+        await();
+
+        Duration slowPacedPollInterval = Duration.FIVE_HUNDRED_MILLISECONDS;
+        calmlyAwait = 
Awaitility.with().pollInterval(slowPacedPollInterval).and().with().pollDelay(slowPacedPollInterval).await();
+    }
+
+    @After
+    public void teardown() {
+        jmapServer.stop();
+    }
+    
+    private String getOutboxId() {
+        // Find username's outbox (using getMailboxes command on /jmap 
endpoint)
+        return getAllMailboxesIds(accessToken).stream()
+                .filter(x -> x.get("role").equals("outbox"))
+                .map(x -> x.get("id"))
+                .findFirst().get();
+    }
+
+    private List<Map<String, String>> getAllMailboxesIds(AccessToken 
accessToken) {
+        return with()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body("[[\"getMailboxes\", {\"properties\": [\"role\", 
\"id\"]}, \"#0\"]]")
+        .post("/jmap")
+                .andReturn()
+                .body()
+                .jsonPath()
+                .getList(ARGUMENTS + ".list");
+    }
+
+    @Test
+    public void 
setMessagesShouldReturnErrorNotSupportedWhenRequestContainsNonNullAccountId() 
throws Exception {
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"accountId\": \"1\"}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("error"))
+            .body(ARGUMENTS + ".type", equalTo("Not yet implemented"));
+    }
+
+    @Test
+    public void 
setMessagesShouldReturnErrorNotSupportedWhenRequestContainsNonNullIfInState() 
throws Exception {
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"ifInState\": \"1\"}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("error"))
+            .body(ARGUMENTS + ".type", equalTo("Not yet implemented"));
+    }
+
+    @Test
+    public void setMessagesShouldReturnNotDestroyedWhenUnknownMailbox() throws 
Exception {
+
+        String unknownMailboxMessageId = username + "|unknown|12345";
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [\"" + 
unknownMailboxMessageId + "\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .log().ifValidationFails()
+            .statusCode(200)
+            .body(NAME, equalTo("messagesSet"))
+            .body(ARGUMENTS + ".destroyed", empty())
+            .body(ARGUMENTS + ".notDestroyed", 
hasEntry(equalTo(unknownMailboxMessageId), Matchers.allOf(
+                    hasEntry("type", "anErrorOccurred"),
+                    hasEntry("description", "An error occurred while deleting 
message " + unknownMailboxMessageId),
+                    hasEntry(equalTo("properties"), isEmptyOrNullString())))
+            );
+    }
+
+    @Test
+    public void setMessagesShouldReturnNotDestroyedWhenNoMatchingMessage() 
throws Exception {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        String messageId = username + "|mailbox|12345";
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [\"" + messageId + "\"]}, 
\"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .log().ifValidationFails()
+            .statusCode(200)
+            .body(NAME, equalTo("messagesSet"))
+            .body(ARGUMENTS + ".destroyed", empty())
+            .body(ARGUMENTS + ".notDestroyed", hasEntry(equalTo(messageId), 
Matchers.allOf(
+                    hasEntry("type", "notFound"),
+                    hasEntry("description", "The message " + messageId + " 
can't be found"),
+                    hasEntry(equalTo("properties"), isEmptyOrNullString())))
+            );
+    }
+
+    @Test
+    public void setMessagesShouldReturnDestroyedWhenMatchingMessage() throws 
Exception {
+        // Given
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        await();
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [\"" + username + 
"|mailbox|1\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("messagesSet"))
+            .body(ARGUMENTS + ".notDestroyed", anEmptyMap())
+            .body(ARGUMENTS + ".destroyed", hasSize(1))
+            .body(ARGUMENTS + ".destroyed", contains(username + "|mailbox|1"));
+    }
+
+    @Test
+    public void setMessagesShouldDeleteMessageWhenMatchingMessage() throws 
Exception {
+        // Given
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        await();
+
+        // When
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [\"" + username + 
"|mailbox|1\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        // Then
+        given()
+           .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessages\", {\"ids\": [\"" + username + 
"|mailbox|1\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("messages"))
+            .body(ARGUMENTS + ".list", empty());
+    }
+
+    @Test
+    public void setMessagesShouldReturnDestroyedNotDestroyWhenMixed() throws 
Exception {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test2\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test3\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        await();
+
+        String missingMessageId = username + "|mailbox|4";
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [\"" + username + 
"|mailbox|1\", \"" + missingMessageId + "\", \"" + username + "|mailbox|3\"]}, 
\"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("messagesSet"))
+            .body(ARGUMENTS + ".destroyed", hasSize(2))
+            .body(ARGUMENTS + ".notDestroyed", aMapWithSize(1))
+            .body(ARGUMENTS + ".destroyed", contains(username + "|mailbox|1", 
username + "|mailbox|3"))
+            .body(ARGUMENTS + ".notDestroyed", 
hasEntry(equalTo(missingMessageId), Matchers.allOf(
+                    hasEntry("type", "notFound"),
+                    hasEntry("description", "The message " + missingMessageId 
+ " can't be found")))
+            );
+    }
+
+    @Test
+    public void setMessagesShouldDeleteMatchingMessagesWhenMixed() throws 
Exception {
+        // Given
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test2\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test3\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        await();
+
+        // When
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [\"" + username + 
"|mailbox|1\", \"" + username + "|mailbox|4\", \"" + username + 
"|mailbox|3\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        // Then
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessages\", {\"ids\": [\"" + username + 
"|mailbox|1\", \"" + username + "|mailbox|2\", \"" + username + 
"|mailbox|3\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("messages"))
+            .body(ARGUMENTS + ".list", hasSize(1));
+    }
+
+    @Test
+    public void 
setMessagesShouldReturnUpdatedIdAndNoErrorWhenIsUnreadPassedToFalse() throws 
MailboxException {
+        // Given
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        await();
+
+        String presumedMessageId = username + "|mailbox|1";
+
+        // When
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { 
\"isUnread\" : false } } }, \"#0\"]]", presumedMessageId))
+        .when()
+            .post("/jmap")
+        // Then
+        .then()
+            .spec(getSetMessagesUpdateOKResponseAssertions(presumedMessageId))
+            .log().ifValidationFails();
+    }
+
+    private ResponseSpecification 
getSetMessagesUpdateOKResponseAssertions(String messageId) {
+        ResponseSpecBuilder builder = new ResponseSpecBuilder()
+                .expectStatusCode(200)
+                .expectBody(NAME, equalTo("messagesSet"))
+                .expectBody(ARGUMENTS + ".updated", hasSize(1))
+                .expectBody(ARGUMENTS + ".updated", contains(messageId))
+                .expectBody(ARGUMENTS + ".error", isEmptyOrNullString())
+                .expectBody(ARGUMENTS + ".notUpdated", not(hasKey(messageId)));
+        return builder.build();
+    }
+
+    @Test
+    public void setMessagesShouldMarkAsReadWhenIsUnreadPassedToFalse() throws 
MailboxException {
+        // Given
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        await();
+
+        String presumedMessageId = username + "|mailbox|1";
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : 
{ \"isUnread\" : false } } }, \"#0\"]]", presumedMessageId))
+        // When
+        .when()
+                .post("/jmap");
+        // Then
+        with()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body("[[\"getMessages\", {\"ids\": [\"" + presumedMessageId + 
"\"]}, \"#0\"]]")
+                .post("/jmap")
+        .then()
+                .statusCode(200)
+                .body(NAME, equalTo("messages"))
+                .body(ARGUMENTS + ".list", hasSize(1))
+                .body(ARGUMENTS + ".list[0].isUnread", equalTo(false))
+                .log().ifValidationFails();
+    }
+
+    @Test
+    public void setMessagesShouldReturnUpdatedIdAndNoErrorWhenIsUnreadPassed() 
throws MailboxException {
+        // Given
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new 
Flags(Flags.Flag.SEEN));
+        await();
+
+        String presumedMessageId = username + "|mailbox|1";
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : 
{ \"isUnread\" : true } } }, \"#0\"]]", presumedMessageId))
+        // When
+        .when()
+                .post("/jmap")
+        // Then
+        .then()
+                
.spec(getSetMessagesUpdateOKResponseAssertions(presumedMessageId))
+                .log().ifValidationFails();
+    }
+
+    @Test
+    public void setMessagesShouldMarkAsUnreadWhenIsUnreadPassed() throws 
MailboxException {
+        // Given
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new 
Flags(Flags.Flag.SEEN));
+        await();
+
+        String presumedMessageId = username + "|mailbox|1";
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : 
{ \"isUnread\" : true } } }, \"#0\"]]", presumedMessageId))
+        // When
+        .when()
+                .post("/jmap");
+        // Then
+        with()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body("[[\"getMessages\", {\"ids\": [\"" + presumedMessageId + 
"\"]}, \"#0\"]]")
+                .post("/jmap")
+        .then()
+                .body(NAME, equalTo("messages"))
+                .body(ARGUMENTS + ".list", hasSize(1))
+                .body(ARGUMENTS + ".list[0].isUnread", equalTo(true))
+                .log().ifValidationFails();
+    }
+
+
+    @Test
+    public void 
setMessagesShouldReturnUpdatedIdAndNoErrorWhenIsFlaggedPassed() throws 
MailboxException {
+        // Given
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        await();
+
+        String presumedMessageId = username + "|mailbox|1";
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : 
{ \"isFlagged\" : true } } }, \"#0\"]]", presumedMessageId))
+        // When
+        .when()
+                .post("/jmap")
+        // Then
+        .then()
+                
.spec(getSetMessagesUpdateOKResponseAssertions(presumedMessageId))
+                .log().ifValidationFails();
+    }
+
+    @Test
+    public void setMessagesShouldMarkAsFlaggedWhenIsFlaggedPassed() throws 
MailboxException {
+        // Given
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        await();
+
+        String presumedMessageId = username + "|mailbox|1";
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : 
{ \"isFlagged\" : true } } }, \"#0\"]]", presumedMessageId))
+        // When
+        .when()
+                .post("/jmap");
+        // Then
+        with()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body("[[\"getMessages\", {\"ids\": [\"" + presumedMessageId + 
"\"]}, \"#0\"]]")
+                .post("/jmap")
+        .then()
+                .body(NAME, equalTo("messages"))
+                .body(ARGUMENTS + ".list", hasSize(1))
+                .body(ARGUMENTS + ".list[0].isFlagged", equalTo(true))
+                .log().ifValidationFails();
+    }
+
+    @Test
+    public void setMessagesShouldRejectUpdateWhenPropertyHasWrongType() throws 
MailboxException {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+
+        await();
+
+        String messageId = username + "|mailbox|1";
+
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : 
{ \"isUnread\" : \"123\" } } }, \"#0\"]]", messageId))
+        .when()
+                .post("/jmap")
+        .then()
+                .log().ifValidationFails()
+                .statusCode(200)
+                .body(NAME, equalTo("messagesSet"))
+                .body(ARGUMENTS + ".notUpdated", hasKey(messageId))
+                .body(ARGUMENTS + ".notUpdated[\""+messageId+"\"].type", 
equalTo("invalidProperties"))
+                .body(ARGUMENTS + 
".notUpdated[\""+messageId+"\"].properties[0]", equalTo("isUnread"))
+                .body(ARGUMENTS + 
".notUpdated[\""+messageId+"\"].description", equalTo("isUnread: Can not 
construct instance of java.lang.Boolean from String value '123': only \"true\" 
or \"false\" recognized\n" +
+                        " at [Source: {\"isUnread\":\"123\"}; line: 1, column: 
2] (through reference chain: 
org.apache.james.jmap.model.Builder[\"isUnread\"])"))
+                .body(ARGUMENTS + ".updated", hasSize(0));
+    }
+
+    @Test
+    @Ignore("Jackson json deserializer stops after first error found")
+    public void setMessagesShouldRejectUpdateWhenPropertiesHaveWrongTypes() 
throws MailboxException {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+
+        await();
+
+        String messageId = username + "|mailbox|1";
+
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : 
{ \"isUnread\" : \"123\", \"isFlagged\" : 456 } } }, \"#0\"]]", messageId))
+        .when()
+                .post("/jmap")
+        .then()
+                .log().ifValidationFails()
+                .statusCode(200)
+                .body(NAME, equalTo("messagesSet"))
+                .body(ARGUMENTS + ".notUpdated", hasKey(messageId))
+                .body(ARGUMENTS + ".notUpdated[\""+messageId+"\"].type", 
equalTo("invalidProperties"))
+                .body(ARGUMENTS + ".notUpdated[\""+messageId+"\"].properties", 
hasSize(2))
+                .body(ARGUMENTS + 
".notUpdated[\""+messageId+"\"].properties[0]", equalTo("isUnread"))
+                .body(ARGUMENTS + 
".notUpdated[\""+messageId+"\"].properties[1]", equalTo("isFlagged"))
+                .body(ARGUMENTS + ".updated", hasSize(0));
+    }
+
+    @Test
+    public void setMessagesShouldMarkMessageAsAnsweredWhenIsAnsweredPassed() 
throws MailboxException {
+        // Given
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        await();
+
+        String presumedMessageId = username + "|mailbox|1";
+        // When
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : 
{ \"isAnswered\" : true } } }, \"#0\"]]", presumedMessageId))
+        .when()
+                .post("/jmap")
+        // Then
+        .then()
+                
.spec(getSetMessagesUpdateOKResponseAssertions(presumedMessageId))
+                .log().ifValidationFails();
+    }
+
+    @Test
+    public void setMessagesShouldMarkAsAnsweredWhenIsAnsweredPassed() throws 
MailboxException {
+        // Given
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        await();
+
+        String presumedMessageId = username + "|mailbox|1";
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : 
{ \"isAnswered\" : true } } }, \"#0\"]]", presumedMessageId))
+        // When
+        .when()
+                .post("/jmap");
+        // Then
+        with()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body("[[\"getMessages\", {\"ids\": [\"" + presumedMessageId + 
"\"]}, \"#0\"]]")
+                .post("/jmap")
+        .then()
+                .body(NAME, equalTo("messages"))
+                .body(ARGUMENTS + ".list", hasSize(1))
+                .body(ARGUMENTS + ".list[0].isAnswered", equalTo(true))
+                .log().ifValidationFails();
+    }
+
+    @Test
+    public void setMessageShouldReturnNotFoundWhenUpdateUnknownMessage() {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "mailbox");
+
+        String nonExistingMessageId = username + "|mailbox|12345";
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { 
\"isUnread\" : true } } }, \"#0\"]]", nonExistingMessageId))
+        .when()
+            .post("/jmap")
+        .then()
+            .log().ifValidationFails()
+            .statusCode(200)
+            .body(NAME, equalTo("messagesSet"))
+            .body(ARGUMENTS + ".notUpdated", hasKey(nonExistingMessageId))
+            .body(ARGUMENTS + 
".notUpdated[\""+nonExistingMessageId+"\"].type", equalTo("notFound"))
+            .body(ARGUMENTS + 
".notUpdated[\""+nonExistingMessageId+"\"].description", equalTo("message not 
found"))
+            .body(ARGUMENTS + ".updated", hasSize(0));
+    }
+
+    @Test
+    public void setMessageShouldReturnCreatedMessageWhenSendingMessage() {
+        String messageCreationId = "user|inbox|1";
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"name\": \"MAILER-DAEMON\", \"email\": 
\"postmas...@example.com\"}," +
+                "        \"to\": [{ \"name\": \"BOB\", \"email\": 
\"some...@example.com\"}]," +
+                "        \"subject\": \"Thank you for joining example.com!\"," 
+
+                "        \"textBody\": \"Hello someone, and thank you for 
joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + getOutboxId() + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(requestBody)
+        .when()
+                .post("/jmap")
+        .then()
+                .log().ifValidationFails()
+                .statusCode(200)
+                .body(NAME, equalTo("messagesSet"))
+                .body(ARGUMENTS + ".notCreated", aMapWithSize(0))
+                // note that assertions on result message had to be split 
between
+                // string-typed values and boolean-typed value assertions on 
the same .created entry
+                // make sure only one creation has been processed
+                .body(ARGUMENTS + ".created", aMapWithSize(1))
+                // assert server-set attributes are returned
+                .body(ARGUMENTS + ".created", 
hasEntry(equalTo(messageCreationId), Matchers.allOf(
+                        hasEntry(equalTo("id"), not(isEmptyOrNullString())),
+                        hasEntry(equalTo("blobId"), 
not(isEmptyOrNullString())),
+                        hasEntry(equalTo("threadId"), 
not(isEmptyOrNullString())),
+                        hasEntry(equalTo("size"), not(isEmptyOrNullString()))
+                )))
+                // assert that message flags are all unset
+                .body(ARGUMENTS + ".created", 
hasEntry(equalTo(messageCreationId), Matchers.allOf(
+                        hasEntry(equalTo("isDraft"), equalTo(false)),
+                        hasEntry(equalTo("isUnread"), equalTo(false)),
+                        hasEntry(equalTo("isFlagged"), equalTo(false)),
+                        hasEntry(equalTo("isAnswered"), equalTo(false))
+                )))
+                ;
+    }
+
+    @Test
+    public void setMessagesShouldCreateMessageInOutboxWhenSendingMessage() 
throws MailboxException {
+        // Given
+        String messageCreationId = "user|inbox|1";
+        String presumedMessageId = "usern...@domain.tld|outbox|1";
+        String messageSubject = "Thank you for joining example.com!";
+        String outboxId = getOutboxId();
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"name\": \"MAILER-DAEMON\", \"email\": 
\"postmas...@example.com\"}," +
+                "        \"to\": [{ \"name\": \"BOB\", \"email\": 
\"some...@example.com\"}]," +
+                "        \"subject\": \"" + messageSubject + "\"," +
+                "        \"textBody\": \"Hello someone, and thank you for 
joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + outboxId + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(requestBody)
+        // When
+        .when()
+                .post("/jmap");
+
+        // Then
+        with()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body("[[\"getMessages\", {\"ids\": [\"" + presumedMessageId + 
"\"]}, \"#0\"]]")
+        .post("/jmap")
+        .then()
+                .body(NAME, equalTo("messages"))
+                .body(ARGUMENTS + ".list", hasSize(1))
+                .body(ARGUMENTS + ".list[0].subject", equalTo(messageSubject))
+                .body(ARGUMENTS + ".list[0].mailboxIds", contains(outboxId))
+                ;
+    }
+
+    @Test
+    public void setMessagesShouldMoveMessageInSentWhenMessageIsSent() throws 
MailboxException {
+        // Given
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "sent");
+        String sentMailboxId = getAllMailboxesIds(accessToken).stream()
+                .filter(x -> x.get("role").equals("sent"))
+                .map(x -> x.get("id"))
+                .findFirst().get();
+
+        String messageCreationId = "user|inbox|1";
+        String messageSubject = "Thank you for joining example.com!";
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"name\": \"MAILER-DAEMON\", \"email\": 
\"postmas...@example.com\"}," +
+                "        \"to\": [{ \"name\": \"BOB\", \"email\": 
\"some...@example.com\"}]," +
+                "        \"subject\": \"" + messageSubject + "\"," +
+                "        \"textBody\": \"Hello someone, and thank you for 
joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + getOutboxId() + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(requestBody)
+        // When
+        .when()
+                .post("/jmap");
+
+        // Then
+        calmlyAwait.atMost(10, TimeUnit.SECONDS).until( () -> 
messageHasBeenMovedToSentBox(sentMailboxId));
+    }
+
+    private boolean messageHasBeenMovedToSentBox(String sentMailboxId) {
+        try {
+            with()
+                    .accept(ContentType.JSON)
+                    .contentType(ContentType.JSON)
+                    .header("Authorization", accessToken.serialize())
+                    .body("[[\"getMessageList\", {\"fetchMessages\":true, 
\"filter\":{\"inMailboxes\":[\"" + sentMailboxId + "\"]}}, \"#0\"]]")
+            .when()
+                    .post("/jmap")
+            .then()
+                    .statusCode(200)
+                    .body(SECOND_NAME, equalTo("messages"))
+                    .body(SECOND_ARGUMENTS + ".list", hasSize(1));
+            return true;
+        } catch(AssertionError e) {
+            return false;
+        }
+    }
+
+    @Test
+    public void setMessagesShouldRejectWhenSendingMessageHasNoValidAddress() {
+        String messageCreationId = "user|inbox|1";
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"name\": \"MAILER-DAEMON\", \"email\": 
\"postmas...@example.com\"}," +
+                "        \"to\": [{ \"name\": \"BOB\", \"email\": 
\"some...@example.com@example.com\"}]," +
+                "        \"cc\": [{ \"name\": \"ALICE\"}]," +
+                "        \"subject\": \"Thank you for joining example.com!\"," 
+
+                "        \"textBody\": \"Hello someone, and thank you for 
joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + getOutboxId() + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(requestBody)
+                .when()
+                .post("/jmap")
+                .then()
+                .log().ifValidationFails()
+                .statusCode(200)
+                .body(NAME, equalTo("messagesSet"))
+
+                .body(ARGUMENTS + ".notCreated", hasKey(messageCreationId))
+                .body(ARGUMENTS + 
".notCreated[\""+messageCreationId+"\"].type", equalTo("invalidProperties"))
+                .body(ARGUMENTS + 
".notCreated[\""+messageCreationId+"\"].description", endsWith("no recipient 
address set"))
+                .body(ARGUMENTS + ".created", aMapWithSize(0));
+    }
+
+    @Test
+    public void setMessagesShouldRejectWhenSendingMessageHasMissingFrom() {
+        String messageCreationId = "user|inbox|1";
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"to\": [{ \"name\": \"BOB\", \"email\": 
\"some...@example.com\"}]," +
+                "        \"cc\": [{ \"name\": \"ALICE\"}]," +
+                "        \"subject\": \"Thank you for joining example.com!\"," 
+
+                "        \"textBody\": \"Hello someone, and thank you for 
joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + getOutboxId() + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(requestBody)
+        .when()
+                .post("/jmap")
+        .then()
+                .log().ifValidationFails()
+                .statusCode(200)
+                .body(NAME, equalTo("messagesSet"))
+                .body(ARGUMENTS + ".notCreated", hasKey(messageCreationId))
+                .body(ARGUMENTS + 
".notCreated[\""+messageCreationId+"\"].type", equalTo("invalidProperties"))
+                .body(ARGUMENTS + 
".notCreated[\""+messageCreationId+"\"].description", endsWith("'from' address 
is mandatory"))
+                .body(ARGUMENTS + 
".notCreated[\""+messageCreationId+"\"].properties", hasSize(1))
+                .body(ARGUMENTS + 
".notCreated[\""+messageCreationId+"\"].properties", contains("from"))
+                .body(ARGUMENTS + ".created", aMapWithSize(0));
+    }
+
+    @Test
+    public void 
setMessagesShouldSucceedWhenSendingMessageWithOnlyFromAddress() {
+        String messageCreationId = "user|inbox|1";
+        String fromAddress = "postmas...@example.com";
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"email\": \"" + fromAddress + "\"}," +
+                "        \"to\": [{ \"name\": \"BOB\", \"email\": 
\"some...@example.com\"}]," +
+                "        \"cc\": [{ \"name\": \"ALICE\"}]," +
+                "        \"subject\": \"Thank you for joining example.com!\"," 
+
+                "        \"textBody\": \"Hello someone, and thank you for 
joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + getOutboxId() + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(requestBody)
+        .when()
+                .post("/jmap")
+        .then()
+                .log().ifValidationFails()
+                .statusCode(200)
+                .body(NAME, equalTo("messagesSet"))
+                .body(ARGUMENTS + ".created", aMapWithSize(1))
+                .body(ARGUMENTS + ".created", hasKey(messageCreationId))
+                .body(ARGUMENTS + 
".created[\""+messageCreationId+"\"].headers.from", equalTo(fromAddress))
+                .body(ARGUMENTS + 
".created[\""+messageCreationId+"\"].from.name", equalTo(fromAddress))
+                .body(ARGUMENTS + 
".created[\""+messageCreationId+"\"].from.email", equalTo(fromAddress));
+    }
+
+    @Test
+    public void setMessagesShouldSucceedWithHtmlBody() {
+        String messageCreationId = "user|inbox|1";
+        String fromAddress = "postmas...@example.com";
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"email\": \"" + fromAddress + "\"}," +
+                "        \"to\": [{ \"name\": \"BOB\", \"email\": 
\"some...@example.com\"}]," +
+                "        \"cc\": [{ \"name\": \"ALICE\"}]," +
+                "        \"subject\": \"Thank you for joining example.com!\"," 
+
+                "        \"htmlBody\": \"Hello <i>someone</i>, and thank 
<b>you</b> for joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + getOutboxId() + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(requestBody)
+        .when()
+                .post("/jmap")
+        .then()
+                .log().ifValidationFails()
+                .statusCode(200)
+                .body(NAME, equalTo("messagesSet"))
+                .body(ARGUMENTS + ".created", aMapWithSize(1))
+                .body(ARGUMENTS + ".created", hasKey(messageCreationId))
+                .body(ARGUMENTS + 
".created[\""+messageCreationId+"\"].headers.from", equalTo(fromAddress))
+                .body(ARGUMENTS + 
".created[\""+messageCreationId+"\"].from.name", equalTo(fromAddress))
+                .body(ARGUMENTS + 
".created[\""+messageCreationId+"\"].from.email", equalTo(fromAddress));
+    }
+
+    @Test
+    public void 
setMessagesShouldMoveToSentWhenSendingMessageWithOnlyFromAddress() {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "sent");
+        String sentMailboxId = getAllMailboxesIds(accessToken).stream()
+                .filter(x -> x.get("role").equals("sent"))
+                .map(x -> x.get("id"))
+                .findFirst().get();
+
+        String messageCreationId = "user|inbox|1";
+        String fromAddress = "postmas...@example.com";
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"email\": \"" + fromAddress + "\"}," +
+                "        \"to\": [{ \"name\": \"BOB\", \"email\": 
\"some...@example.com\"}]," +
+                "        \"cc\": [{ \"name\": \"ALICE\"}]," +
+                "        \"subject\": \"Thank you for joining example.com!\"," 
+
+                "        \"textBody\": \"Hello someone, and thank you for 
joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + getOutboxId() + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        // Given
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(requestBody)
+        // When
+        .when()
+                .post("/jmap");
+        // Then
+        calmlyAwait.atMost(10, TimeUnit.SECONDS).until( () -> 
messageHasBeenMovedToSentBox(sentMailboxId));
+    }
+
+
+    @Test
+    public void setMessagesShouldRejectWhenSendingMessageHasMissingSubject() {
+        String messageCreationId = "user|inbox|1";
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"name\": \"MAILER-DAEMON\", \"email\": 
\"postmas...@example.com\"}," +
+                "        \"to\": [{ \"name\": \"BOB\", \"email\": 
\"some...@example.com\"}]," +
+                "        \"cc\": [{ \"name\": \"ALICE\"}]," +
+                "        \"textBody\": \"Hello someone, and thank you for 
joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + getOutboxId() + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body(requestBody)
+        .when()
+                .post("/jmap")
+        .then()
+                .log().ifValidationFails()
+                .statusCode(200)
+                .body(NAME, equalTo("messagesSet"))
+                .body(ARGUMENTS + ".notCreated", hasKey(messageCreationId))
+                .body(ARGUMENTS + 
".notCreated[\""+messageCreationId+"\"].type", equalTo("invalidProperties"))
+                .body(ARGUMENTS + 
".notCreated[\""+messageCreationId+"\"].properties", hasSize(1))
+                .body(ARGUMENTS + 
".notCreated[\""+messageCreationId+"\"].properties", contains("subject"))
+                .body(ARGUMENTS + 
".notCreated[\""+messageCreationId+"\"].description", endsWith("'subject' is 
missing"))
+                .body(ARGUMENTS + ".created", aMapWithSize(0));
+    }
+
+    @Test
+    public void setMessagesShouldDeliverMessageToRecipient() throws Exception {
+        // Sender
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "sent");
+        // Recipient
+        String recipientAddress = "recipient" + "@" + USERS_DOMAIN;
+        String password = "password";
+        jmapServer.serverProbe().addUser(recipientAddress, password);
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
recipientAddress, "inbox");
+        await();
+        AccessToken recipientToken = 
JmapAuthentication.authenticateJamesUser(recipientAddress, password);
+
+        String messageCreationId = "user|inbox|1";
+        String fromAddress = username;
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"email\": \"" + fromAddress + "\"}," +
+                "        \"to\": [{ \"name\": \"BOB\", \"email\": \"" + 
recipientAddress + "\"}]," +
+                "        \"cc\": [{ \"name\": \"ALICE\"}]," +
+                "        \"subject\": \"Thank you for joining example.com!\"," 
+
+                "        \"textBody\": \"Hello someone, and thank you for 
joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + getOutboxId() + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        // Given
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", this.accessToken.serialize())
+                .body(requestBody)
+        // When
+        .when()
+                .post("/jmap");
+
+        // Then
+        calmlyAwait.atMost(10, TimeUnit.SECONDS).until( () -> 
isAnyMessageFoundInRecipientsMailboxes(recipientToken));
+    }
+
+    @Test
+    public void setMessagesShouldStripBccFromDeliveredEmail() throws Exception 
{
+        // Sender
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "sent");
+        // Recipient
+        String recipientAddress = "recipient" + "@" + USERS_DOMAIN;
+        String password = "password";
+        jmapServer.serverProbe().addUser(recipientAddress, password);
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
recipientAddress, "inbox");
+        await();
+        AccessToken recipientToken = 
JmapAuthentication.authenticateJamesUser(recipientAddress, password);
+
+        String messageCreationId = "user|inbox|1";
+        String fromAddress = username;
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"email\": \"" + fromAddress + "\"}," +
+                "        \"to\": [{ \"name\": \"recipient\", \"email\": \"" + 
recipientAddress + "\"}]," +
+                "        \"bcc\": [{ \"name\": \"BOB\", \"email\": \"bob@" + 
USERS_DOMAIN + "\"}]," +
+                "        \"cc\": [{ \"name\": \"ALICE\"}]," +
+                "        \"subject\": \"Thank you for joining example.com!\"," 
+
+                "        \"textBody\": \"Hello someone, and thank you for 
joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + getOutboxId() + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        // Given
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", this.accessToken.serialize())
+                .body(requestBody)
+        // When
+        .when()
+                .post("/jmap");
+
+        // Then
+        calmlyAwait.atMost(10, TimeUnit.SECONDS).until( () -> 
isAnyMessageFoundInRecipientsMailboxes(recipientToken));
+        with()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", recipientToken.serialize())
+            .body("[[\"getMessageList\", {\"fetchMessages\": true, 
\"fetchMessageProperties\": [\"bcc\"] }, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .log().ifValidationFails()
+            .statusCode(200)
+            .body(SECOND_NAME, equalTo("messages"))
+            .body(SECOND_ARGUMENTS + ".list", hasSize(1)) 
+            .body(SECOND_ARGUMENTS + ".list[0].bcc", empty());
+    }
+
+    @Test
+    public void setMessagesShouldKeepBccInSentMailbox() throws Exception {
+        // Sender
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "sent");
+        String sentMailboxId = getAllMailboxesIds(accessToken).stream()
+                .filter(x -> x.get("role").equals("sent"))
+                .map(x -> x.get("id"))
+                .findFirst().get();
+
+        // Recipient
+        String recipientAddress = "recipient" + "@" + USERS_DOMAIN;
+        String password = "password";
+        jmapServer.serverProbe().addUser(recipientAddress, password);
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
recipientAddress, "inbox");
+        await();
+
+        String messageCreationId = "user|inbox|1";
+        String fromAddress = username;
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"email\": \"" + fromAddress + "\"}," +
+                "        \"to\": [{ \"name\": \"recipient\", \"email\": \"" + 
recipientAddress + "\"}]," +
+                "        \"bcc\": [{ \"name\": \"BOB\", \"email\": \"bob@" + 
USERS_DOMAIN + "\" }]," +
+                "        \"cc\": [{ \"name\": \"ALICE\"}]," +
+                "        \"subject\": \"Thank you for joining example.com!\"," 
+
+                "        \"textBody\": \"Hello someone, and thank you for 
joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + getOutboxId() + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        // Given
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", this.accessToken.serialize())
+                .body(requestBody)
+        // When
+        .when()
+                .post("/jmap");
+
+        // Then
+        calmlyAwait.atMost(10, TimeUnit.SECONDS).until( () -> 
messageHasBeenMovedToSentBox(sentMailboxId));
+        with()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", this.accessToken.serialize())
+            .body("[[\"getMessageList\", {\"fetchMessages\":true, 
\"fetchMessageProperties\": [\"bcc\"], \"filter\":{\"inMailboxes\":[\"" + 
sentMailboxId + "\"]}}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .log().ifValidationFails()
+            .statusCode(200)
+            .body(SECOND_NAME, equalTo("messages"))
+            .body(SECOND_ARGUMENTS + ".list", hasSize(1)) 
+            .body(SECOND_ARGUMENTS + ".list[0].bcc", hasSize(1));
+    }
+
+    @Test
+    public void setMessagesShouldSendMessageToBcc() throws Exception {
+        // Sender
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "sent");
+
+        // Recipient
+        String recipientAddress = "recipient" + "@" + USERS_DOMAIN;
+        String password = "password";
+        jmapServer.serverProbe().addUser(recipientAddress, password);
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
recipientAddress, "inbox");
+
+        String bccAddress = "bob" + "@" + USERS_DOMAIN;
+        jmapServer.serverProbe().addUser(bccAddress, password);
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
bccAddress, "inbox");
+        await();
+        AccessToken bccToken = 
JmapAuthentication.authenticateJamesUser(bccAddress, password);
+
+        String messageCreationId = "user|inbox|1";
+        String fromAddress = username;
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"email\": \"" + fromAddress + "\"}," +
+                "        \"to\": [{ \"name\": \"recipient\", \"email\": \"" + 
recipientAddress + "\"}]," +
+                "        \"bcc\": [{ \"name\": \"BOB\", \"email\": \"" + 
bccAddress + "\" }]," +
+                "        \"cc\": [{ \"name\": \"ALICE\"}]," +
+                "        \"subject\": \"Thank you for joining example.com!\"," 
+
+                "        \"textBody\": \"Hello someone, and thank you for 
joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + getOutboxId() + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        // Given
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", this.accessToken.serialize())
+                .body(requestBody)
+        // When
+        .when()
+                .post("/jmap");
+
+        // Then
+        calmlyAwait.atMost(10, TimeUnit.SECONDS).until( () -> 
isAnyMessageFoundInRecipientsMailboxes(bccToken));
+        with()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", bccToken.serialize())
+            .body("[[\"getMessageList\", {\"fetchMessages\": true, 
\"fetchMessageProperties\": [\"bcc\"] }, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .log().ifValidationFails()
+            .statusCode(200)
+            .body(SECOND_NAME, equalTo("messages"))
+            .body(SECOND_ARGUMENTS + ".list", hasSize(1)) 
+            .body(SECOND_ARGUMENTS + ".list[0].bcc", empty());
+    }
+
+    private boolean isAnyMessageFoundInRecipientsMailboxes(AccessToken 
recipientToken) {
+        try {
+            with()
+                    .accept(ContentType.JSON)
+                    .contentType(ContentType.JSON)
+                    .header("Authorization", recipientToken.serialize())
+                    .body("[[\"getMessageList\", {}, \"#0\"]]")
+            .when()
+                    .post("/jmap")
+            .then()
+                    .statusCode(200)
+                    .body(NAME, equalTo("messageList"))
+                    .body(ARGUMENTS + ".messageIds", hasSize(1))
+            ;
+            return true;
+        } catch(AssertionError e) {
+            return false;
+        }
+    }
+
+
+    @Test
+    public void setMessagesShouldSendAReadableHtmlMessage() throws Exception {
+        // Sender
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "sent");
+        // Recipient
+        String recipientAddress = "recipient" + "@" + USERS_DOMAIN;
+        String password = "password";
+        jmapServer.serverProbe().addUser(recipientAddress, password);
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
recipientAddress, "inbox");
+        await();
+        AccessToken recipientToken = 
JmapAuthentication.authenticateJamesUser(recipientAddress, password);
+
+        String messageCreationId = "user|inbox|1";
+        String fromAddress = username;
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"email\": \"" + fromAddress + "\"}," +
+                "        \"to\": [{ \"name\": \"BOB\", \"email\": \"" + 
recipientAddress + "\"}]," +
+                "        \"subject\": \"Thank you for joining example.com!\"," 
+
+                "        \"htmlBody\": \"Hello <b>someone</b>, and thank you 
for joining example.com!\"," +
+                "        \"mailboxIds\": [\"" + getOutboxId() + "\"]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        // Given
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", this.accessToken.serialize())
+                .body(requestBody)
+        // When
+        .when()
+                .post("/jmap");
+
+        // Then
+        calmlyAwait.atMost(10, TimeUnit.SECONDS).until( () -> 
isHtmlMessageReceived(recipientToken));
+    }
+
+    private boolean isHtmlMessageReceived(AccessToken recipientToken) {
+        try {
+            with()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", recipientToken.serialize())
+                .body("[[\"getMessageList\", {\"fetchMessages\": true, 
\"fetchMessageProperties\": [\"htmlBody\"]}, \"#0\"]]")
+            .post("/jmap")
+            .then()
+                .statusCode(200)
+                .body(SECOND_NAME, equalTo("messages"))
+                .body(SECOND_ARGUMENTS + ".list", hasSize(1))
+                .body(SECOND_ARGUMENTS + ".list[0].htmlBody", equalTo("Hello 
<b>someone</b>, and thank you for joining example.com!"))
+            ;
+            return true;
+        } catch(AssertionError e) {
+            return false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/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
new file mode 100644
index 0000000..84fbdd9
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/pom.xml
@@ -0,0 +1,221 @@
+<?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>james-server</artifactId>
+        <groupId>org.apache.james</groupId>
+        <version>3.0.0-beta5-SNAPSHOT</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>memory-jmap-integration-testing</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Apache James :: Server :: JMAP :: Memory Integration testing</name>
+
+    <profiles>
+        <profile>
+            <id>noTest</id>
+            <activation>
+                <os>
+                    <family>windows</family>
+                </os>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <skipTests>true</skipTests>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>disable-build-for-older-jdk</id>
+            <activation>
+                <jdk>(,1.8)</jdk>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-jar-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>default-jar</id>
+                                <phase>none</phase>
+                            </execution>
+                            <execution>
+                                <id>jar</id>
+                                <phase>none</phase>
+                            </execution>
+                            <execution>
+                                <id>test-jar</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-compiler-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>default-compile</id>
+                                <phase>none</phase>
+                            </execution>
+                            <execution>
+                                <id>default-testCompile</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>default-test</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-source-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>attach-sources</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-install-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>default-install</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-resources-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>default-resources</id>
+                                <phase>none</phase>
+                            </execution>
+                            <execution>
+                                <id>default-testResources</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-site-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>attach-descriptor</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>build-for-jdk-8</id>
+            <activation>
+                <jdk>[1.8,)</jdk>
+            </activation>
+            <dependencies>
+                 <dependency>
+                    <groupId>${project.groupId}</groupId>
+                    <artifactId>james-server-guice-common</artifactId>
+                    <type>test-jar</type>
+                    <scope>test</scope>
+                 </dependency>
+                <dependency>
+                    <groupId>org.apache.james</groupId>
+                    
<artifactId>james-server-jmap-integration-testing</artifactId>
+                    <type>test-jar</type>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.james</groupId>
+                    <artifactId>james-server-memory-guice</artifactId>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
+                    <groupId>com.jayway.restassured</groupId>
+                    <artifactId>rest-assured</artifactId>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <configuration>
+                            <archive>
+                                <manifest>
+                                    
<mainClass>fully.qualified.MainClass</mainClass>
+                                </manifest>
+                            </archive>
+                            <descriptorRefs>
+                                
<descriptorRef>jar-with-dependencies</descriptorRef>
+                            </descriptorRefs>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-compiler-plugin</artifactId>
+                        <configuration>
+                            <source>1.8</source>
+                            <target>1.8</target>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>disable-animal-sniffer</id>
+            <activation>
+                <jdk>[1.6,)</jdk>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>animal-sniffer-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>check_java_6</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMailboxesMethodTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMailboxesMethodTest.java
 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMailboxesMethodTest.java
new file mode 100644
index 0000000..3680fb0
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMailboxesMethodTest.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.GetMailboxesMethodTest;
+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 MemoryGetMailboxesMethodTest extends GetMailboxesMethodTest {
+
+    @Rule
+    public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+    @Override
+    protected GuiceJamesServer<?> createJmapServer() {
+        return new GuiceJamesServer<>(new TypeLiteral<InMemoryId>(){})
+                .combineWith(MemoryJamesServerMain.inMemoryServerModule)
+                .overrideWith(new MemoryJmapServerModule(temporaryFolder));
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMessageListMethodTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMessageListMethodTest.java
 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMessageListMethodTest.java
new file mode 100644
index 0000000..aa95f37
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMessageListMethodTest.java
@@ -0,0 +1,48 @@
+/****************************************************************
+ * 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.GetMessageListMethodTest;
+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 MemoryGetMessageListMethodTest extends GetMessageListMethodTest {
+
+    @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/517a4cfe/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMessagesMethodTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMessagesMethodTest.java
 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMessagesMethodTest.java
new file mode 100644
index 0000000..cfbf467
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMessagesMethodTest.java
@@ -0,0 +1,48 @@
+/****************************************************************
+ * 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.GetMessagesMethodTest;
+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 MemoryGetMessagesMethodTest extends GetMessagesMethodTest {
+
+    @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/517a4cfe/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryJmapAuthenticationTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryJmapAuthenticationTest.java
 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryJmapAuthenticationTest.java
new file mode 100644
index 0000000..8b91003
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryJmapAuthenticationTest.java
@@ -0,0 +1,46 @@
+/****************************************************************
+ * 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.FixedDateZonedDateTimeProvider;
+import org.apache.james.jmap.JMAPAuthenticationTest;
+import org.apache.james.jmap.servers.MemoryJmapServerModule;
+import org.apache.james.jmap.utils.ZonedDateTimeProvider;
+import org.apache.james.mailbox.inmemory.InMemoryId;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+
+import com.google.inject.TypeLiteral;
+
+public class MemoryJmapAuthenticationTest extends JMAPAuthenticationTest {
+
+    @Rule
+    public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+    @Override
+    protected GuiceJamesServer<?> 
createJmapServer(FixedDateZonedDateTimeProvider zonedDateTimeProvider) {
+        return new GuiceJamesServer<>(new TypeLiteral<InMemoryId>(){})
+                .combineWith(MemoryJamesServerMain.inMemoryServerModule)
+                .overrideWith(new MemoryJmapServerModule(temporaryFolder),
+                             (binder) -> 
binder.bind(ZonedDateTimeProvider.class).toInstance(zonedDateTimeProvider));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMessagesMethodTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMessagesMethodTest.java
 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMessagesMethodTest.java
new file mode 100644
index 0000000..e4e65ff
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMessagesMethodTest.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.SetMessagesMethodTest;
+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 MemorySetMessagesMethodTest extends SetMessagesMethodTest {
+
+    @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() {
+    }
+}


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

Reply via email to