You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/12/12 02:18:48 UTC

[james-project] 04/15: [Refactoring] Strong typing for IMAP capabilities

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 7c5c8835fc5f4e057cd2f5c1219e89515c2b8e91
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Dec 11 09:39:48 2019 +0700

    [Refactoring] Strong typing for IMAP capabilities
---
 .../apache/james/imap/api/ImapConfiguration.java   | 10 ++--
 .../org/apache/james/imap/api/ImapConstants.java   | 42 +++++++++------
 .../message/Capability.java}                       | 62 +++++++++++++---------
 .../parser/AbstractSelectionCommandParser.java     |  7 +--
 .../imap/decode/parser/EnableCommandParser.java    | 10 ++--
 .../imap/encode/CapabilityResponseEncoder.java     |  5 +-
 .../james/imap/encode/EnableResponseEncoder.java   |  7 +--
 .../james/imap/message/request/EnableRequest.java  |  7 +--
 .../imap/message/response/CapabilityResponse.java  |  8 +--
 .../imap/message/response/EnableResponse.java      |  4 +-
 .../imap/processor/AbstractMailboxProcessor.java   |  3 +-
 .../imap/processor/AbstractSelectionProcessor.java | 13 ++---
 .../imap/processor/AuthenticateProcessor.java      |  9 ++--
 .../processor/CapabilityImplementingProcessor.java |  3 +-
 .../james/imap/processor/CapabilityProcessor.java  | 15 +++---
 .../james/imap/processor/CompressProcessor.java    |  5 +-
 .../james/imap/processor/DeleteACLProcessor.java   |  5 +-
 .../james/imap/processor/EnableProcessor.java      | 19 +++----
 .../james/imap/processor/ExpungeProcessor.java     |  7 ++-
 .../james/imap/processor/GetACLProcessor.java      |  5 +-
 .../imap/processor/GetAnnotationProcessor.java     |  3 +-
 .../james/imap/processor/GetQuotaProcessor.java    |  5 +-
 .../imap/processor/GetQuotaRootProcessor.java      |  5 +-
 .../apache/james/imap/processor/IdleProcessor.java |  5 +-
 .../james/imap/processor/ListRightsProcessor.java  |  5 +-
 .../james/imap/processor/LoginProcessor.java       |  5 +-
 .../apache/james/imap/processor/MoveProcessor.java |  5 +-
 .../james/imap/processor/MyRightsProcessor.java    |  5 +-
 .../james/imap/processor/NamespaceProcessor.java   | 10 ++--
 .../processor/PermitEnableCapabilityProcessor.java |  5 +-
 .../james/imap/processor/SearchProcessor.java      |  5 +-
 .../james/imap/processor/SetACLProcessor.java      |  8 +--
 .../imap/processor/SetAnnotationProcessor.java     |  3 +-
 .../james/imap/processor/SetQuotaProcessor.java    | 16 +++---
 .../james/imap/processor/StartTLSProcessor.java    |  5 +-
 .../james/imap/processor/StoreProcessor.java       |  3 +-
 .../james/imap/processor/UnselectProcessor.java    | 12 +++--
 .../james/imap/processor/XListProcessor.java       |  5 +-
 .../james/imap/api/ImapConfigurationTest.java      | 11 ++--
 .../james/imap/api/message/CapabilityTest.java}    | 46 +++++++++-------
 .../imap/processor/CapabilityProcessorTest.java    |  5 +-
 .../james/imap/processor/MoveProcessorTest.java    |  2 +-
 42 files changed, 244 insertions(+), 176 deletions(-)

diff --git a/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConfiguration.java b/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConfiguration.java
index 6b3e81e..2bd613e 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConfiguration.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConfiguration.java
@@ -23,6 +23,7 @@ import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.james.imap.api.message.Capability;
 
 import com.github.steveash.guavate.Guavate;
 import com.google.common.base.MoreObjects;
@@ -97,9 +98,10 @@ public class ImapConfiguration {
         }
 
         public ImapConfiguration build() {
-            ImmutableSet<String> normalizeDisableCaps = disabledCaps.stream()
+            ImmutableSet<Capability> normalizeDisableCaps = disabledCaps.stream()
                     .filter(Builder::noBlankString)
                     .map(StringUtils::normalizeSpace)
+                    .map(Capability::of)
                     .collect(Guavate.toImmutableSet());
             return new ImapConfiguration(
                     enableIdle.orElse(DEFAULT_ENABLE_IDLE),
@@ -112,11 +114,11 @@ public class ImapConfiguration {
 
     private final long idleTimeInterval;
     private final TimeUnit idleTimeIntervalUnit;
-    private final ImmutableSet<String> disabledCaps;
+    private final ImmutableSet<Capability> disabledCaps;
     private final boolean enableIdle;
     private final boolean isCondstoreEnable;
 
-    private ImapConfiguration(boolean enableIdle, long idleTimeInterval, TimeUnit idleTimeIntervalUnit, ImmutableSet<String> disabledCaps, boolean isCondstoreEnable) {
+    private ImapConfiguration(boolean enableIdle, long idleTimeInterval, TimeUnit idleTimeIntervalUnit, ImmutableSet<Capability> disabledCaps, boolean isCondstoreEnable) {
         this.enableIdle = enableIdle;
         this.idleTimeInterval = idleTimeInterval;
         this.idleTimeIntervalUnit = idleTimeIntervalUnit;
@@ -132,7 +134,7 @@ public class ImapConfiguration {
         return idleTimeIntervalUnit;
     }
 
-    public ImmutableSet<String> getDisabledCaps() {
+    public ImmutableSet<Capability> getDisabledCaps() {
         return disabledCaps;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConstants.java b/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConstants.java
index 0d9ef2f..17162f3 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConstants.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConstants.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.imap.api;
 
+import org.apache.james.imap.api.message.Capability;
+
 public interface ImapConstants {
     // Basic response types
     String OK = "OK";
@@ -81,33 +83,41 @@ public interface ImapConstants {
 
     String VERSION = "IMAP4rev1";
 
-    String SUPPORTS_LITERAL_PLUS = "LITERAL+";
+    Capability BASIC_CAPABILITIES = Capability.of(VERSION);
+
+    Capability SUPPORTS_LITERAL_PLUS = Capability.of("LITERAL+");
 
-    String SUPPORTS_RFC3348 = "CHILDREN";
+    Capability SUPPORTS_RFC3348 = Capability.of("CHILDREN");
 
     String UTF8 = "UTF-8";
-    
-    String SUPPORTS_I18NLEVEL_1 = "I18NLEVEL=1";
 
-    String SUPPORTS_NAMESPACES = "NAMESPACE";
+    Capability SUPPORTS_I18NLEVEL_1 = Capability.of("I18NLEVEL=1");
 
-    String SUPPORTS_STARTTLS = "STARTTLS";
+    Capability SUPPORTS_NAMESPACES = Capability.of("NAMESPACE");
 
-    String SUPPORTS_IDLE = "IDLE";
+    Capability SUPPORTS_STARTTLS = Capability.of("STARTTLS");
 
-    String SUPPORTS_XLIST = "XLIST";
+    Capability SUPPORTS_IDLE = Capability.of("IDLE");
 
-    String SUPPORTS_ENABLE = "ENABLE";
-    
-    String SUPPORTS_CONDSTORE = "CONDSTORE";
-    
-    String SUPPORTS_QRESYNC = "QRESYNC";
+    Capability SUPPORTS_XLIST = Capability.of("XLIST");
+
+    Capability SUPPORTS_ENABLE = Capability.of("ENABLE");
+
+    Capability SUPPORTS_CONDSTORE = Capability.of("CONDSTORE");
+
+    Capability SUPPORTS_UNSELECT = Capability.of("UNSELECT");
+
+    Capability SUPPORTS_QRESYNC = Capability.of("QRESYNC");
+
+    Capability SUPPORTS_ACL = Capability.of("ACL");
+
+    Capability SUPPORTS_QUOTA = Capability.of("QUOTA");
 
-    String SUPPORTS_ACL = "ACL";
+    Capability SUPPORTS_MOVE = Capability.of("MOVE");
 
-    String SUPPORTS_QUOTA = "QUOTA";
+    Capability SUPPORTS_UIDPLUS = Capability.of("UIDPLUS");
 
-    String SUPPORTS_ANNOTATION = "ANNOTATION";
+    Capability SUPPORTS_ANNOTATION = Capability.of("ANNOTATION");
     
     String INBOX_NAME = "INBOX";
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/encode/EnableResponseEncoder.java b/protocols/imap/src/main/java/org/apache/james/imap/api/message/Capability.java
similarity index 52%
copy from protocols/imap/src/main/java/org/apache/james/imap/encode/EnableResponseEncoder.java
copy to protocols/imap/src/main/java/org/apache/james/imap/api/message/Capability.java
index 09e52f8..0b10c02 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/encode/EnableResponseEncoder.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/api/message/Capability.java
@@ -16,40 +16,52 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
-package org.apache.james.imap.encode;
 
-import java.io.IOException;
-import java.util.Set;
+package org.apache.james.imap.api.message;
 
-import org.apache.james.imap.api.ImapMessage;
-import org.apache.james.imap.api.process.ImapSession;
-import org.apache.james.imap.encode.base.AbstractChainedImapEncoder;
-import org.apache.james.imap.message.response.EnableResponse;
+import java.util.Locale;
+import java.util.Objects;
 
-/**
- * Encodes <code>Enable</code> response.
- */
-public class EnableResponseEncoder extends AbstractChainedImapEncoder {
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
 
-    public EnableResponseEncoder(ImapEncoder next) {
-        super(next);
+public class Capability {
+    public static Capability of(String value) {
+        Preconditions.checkNotNull(value, "'value' can not be null");
+        Preconditions.checkArgument(!value.isEmpty(), "'value' can not be empty");
+
+        return new Capability(value.toUpperCase(Locale.US));
+    }
+
+    private final String value;
+
+    private Capability(String value) {
+        this.value = value;
+    }
+
+    public String asString() {
+        return value;
     }
 
     @Override
-    protected void doEncode(ImapMessage acceptableMessage, ImapResponseComposer composer, ImapSession session) throws IOException {
-        final EnableResponse response = (EnableResponse) acceptableMessage;
-        Set<String> capabilities = response.getCapabilities();
-        composer.untagged();
-        // Return ENABLED capabilities. See IMAP-323
-        composer.message("ENABLED");
-        for (String capability : capabilities) {
-            composer.message(capability);
+    public final boolean equals(Object o) {
+        if (o instanceof Capability) {
+            Capability that = (Capability) o;
+
+            return Objects.equals(this.value, that.value);
         }
-        composer.end();
+        return false;
     }
-    
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(value);
+    }
+
     @Override
-    protected boolean isAcceptable(ImapMessage message) {
-        return (message instanceof EnableResponse);
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("value", value)
+            .toString();
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/AbstractSelectionCommandParser.java b/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/AbstractSelectionCommandParser.java
index 4376179..4224e5a 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/AbstractSelectionCommandParser.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/AbstractSelectionCommandParser.java
@@ -34,16 +34,13 @@ import org.apache.james.imap.message.request.AbstractMailboxSelectionRequest;
 import org.apache.james.mailbox.MessageUid;
 
 public abstract class AbstractSelectionCommandParser extends AbstractImapCommandParser {
-    private static final byte[] CONDSTORE = ImapConstants.SUPPORTS_CONDSTORE.getBytes();
-    private static final byte[] QRESYNC = ImapConstants.SUPPORTS_QRESYNC.getBytes();
+    private static final byte[] CONDSTORE = ImapConstants.SUPPORTS_CONDSTORE.asString().getBytes();
+    private static final byte[] QRESYNC = ImapConstants.SUPPORTS_QRESYNC.asString().getBytes();
 
     public AbstractSelectionCommandParser(ImapCommand command) {
         super(command);
     }
     
-
-
-    
     @Override
     protected ImapMessage decode(ImapCommand command, ImapRequestLineReader request, Tag tag, ImapSession session) throws DecodingException {
         final String mailboxName = request.mailbox();
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/EnableCommandParser.java b/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/EnableCommandParser.java
index b4a9880..256713a 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/EnableCommandParser.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/EnableCommandParser.java
@@ -20,12 +20,12 @@ package org.apache.james.imap.decode.parser;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Locale;
 
 import org.apache.james.imap.api.ImapCommand;
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.Tag;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.decode.DecodingException;
 import org.apache.james.imap.decode.ImapRequestLineReader;
@@ -40,13 +40,11 @@ public class EnableCommandParser extends AbstractImapCommandParser {
 
     @Override
     protected ImapMessage decode(ImapCommand command, ImapRequestLineReader request, Tag tag, ImapSession session) throws DecodingException {
-        List<String> caps = new ArrayList<>();
-        String cap = request.astring();
-        caps.add(cap.toUpperCase(Locale.US));
+        List<Capability> caps = new ArrayList<>();
+        caps.add(Capability.of(request.astring()));
         while (request.nextChar() == ' ') {
             request.consume();
-            cap = request.astring();
-            caps.add(cap.toUpperCase(Locale.US));
+            caps.add(Capability.of(request.astring()));
         }
         request.eol();
         return new EnableRequest(tag, command, caps);
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/encode/CapabilityResponseEncoder.java b/protocols/imap/src/main/java/org/apache/james/imap/encode/CapabilityResponseEncoder.java
index df7f96c..90eee64 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/encode/CapabilityResponseEncoder.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/encode/CapabilityResponseEncoder.java
@@ -23,6 +23,7 @@ import java.util.Iterator;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.ImapMessage;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.encode.base.AbstractChainedImapEncoder;
 import org.apache.james.imap.message.response.CapabilityResponse;
@@ -41,11 +42,11 @@ public class CapabilityResponseEncoder extends AbstractChainedImapEncoder {
     @Override
     protected void doEncode(ImapMessage acceptableMessage, ImapResponseComposer composer, ImapSession session) throws IOException {
         final CapabilityResponse response = (CapabilityResponse) acceptableMessage;
-        Iterator<String> capabilities = response.getCapabilities().iterator();
+        Iterator<Capability> capabilities = response.getCapabilities().iterator();
         composer.untagged();
         composer.message(ImapConstants.CAPABILITY_COMMAND_NAME);
         while (capabilities.hasNext()) {
-            composer.message(capabilities.next());
+            composer.message(capabilities.next().asString());
         }
         composer.end();        
     }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/encode/EnableResponseEncoder.java b/protocols/imap/src/main/java/org/apache/james/imap/encode/EnableResponseEncoder.java
index 09e52f8..d9ca32f 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/encode/EnableResponseEncoder.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/encode/EnableResponseEncoder.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.util.Set;
 
 import org.apache.james.imap.api.ImapMessage;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.encode.base.AbstractChainedImapEncoder;
 import org.apache.james.imap.message.response.EnableResponse;
@@ -38,12 +39,12 @@ public class EnableResponseEncoder extends AbstractChainedImapEncoder {
     @Override
     protected void doEncode(ImapMessage acceptableMessage, ImapResponseComposer composer, ImapSession session) throws IOException {
         final EnableResponse response = (EnableResponse) acceptableMessage;
-        Set<String> capabilities = response.getCapabilities();
+        Set<Capability> capabilities = response.getCapabilities();
         composer.untagged();
         // Return ENABLED capabilities. See IMAP-323
         composer.message("ENABLED");
-        for (String capability : capabilities) {
-            composer.message(capability);
+        for (Capability capability : capabilities) {
+            composer.message(capability.asString());
         }
         composer.end();
     }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/message/request/EnableRequest.java b/protocols/imap/src/main/java/org/apache/james/imap/message/request/EnableRequest.java
index e285d27..d05be83 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/message/request/EnableRequest.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/message/request/EnableRequest.java
@@ -22,12 +22,13 @@ import java.util.List;
 
 import org.apache.james.imap.api.ImapCommand;
 import org.apache.james.imap.api.Tag;
+import org.apache.james.imap.api.message.Capability;
 
 public class EnableRequest extends AbstractImapRequest {
 
-    private final List<String> capabilities;
+    private final List<Capability> capabilities;
 
-    public EnableRequest(Tag tag, ImapCommand command, List<String> capabilities) {
+    public EnableRequest(Tag tag, ImapCommand command, List<Capability> capabilities) {
         super(tag, command);
         this.capabilities = capabilities;
     }
@@ -37,7 +38,7 @@ public class EnableRequest extends AbstractImapRequest {
      * 
      * @return caps
      */
-    public List<String> getCapabilities() {
+    public List<Capability> getCapabilities() {
         return capabilities;
     }
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/message/response/CapabilityResponse.java b/protocols/imap/src/main/java/org/apache/james/imap/message/response/CapabilityResponse.java
index cf933fa..3da1b76 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/message/response/CapabilityResponse.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/message/response/CapabilityResponse.java
@@ -20,6 +20,7 @@ package org.apache.james.imap.message.response;
 
 import java.util.Set;
 
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.ImapResponseMessage;
 
 /**
@@ -29,7 +30,7 @@ import org.apache.james.imap.api.message.response.ImapResponseMessage;
  */
 public class CapabilityResponse implements ImapResponseMessage {
 
-    private final Set<String> capabilities;
+    private final Set<Capability> capabilities;
 
     /**
      * Constructs a response based on the given capabilities.
@@ -37,8 +38,7 @@ public class CapabilityResponse implements ImapResponseMessage {
      * @param capabilities
      *            not null
      */
-    public CapabilityResponse(Set<String> capabilities) {
-        super();
+    public CapabilityResponse(Set<Capability> capabilities) {
         this.capabilities = capabilities;
     }
 
@@ -47,7 +47,7 @@ public class CapabilityResponse implements ImapResponseMessage {
      * 
      * @return not null
      */
-    public Set<String> getCapabilities() {
+    public Set<Capability> getCapabilities() {
         return capabilities;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/message/response/EnableResponse.java b/protocols/imap/src/main/java/org/apache/james/imap/message/response/EnableResponse.java
index d3dd4ac..ac0b715 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/message/response/EnableResponse.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/message/response/EnableResponse.java
@@ -20,9 +20,11 @@ package org.apache.james.imap.message.response;
 
 import java.util.Set;
 
+import org.apache.james.imap.api.message.Capability;
+
 public class EnableResponse extends CapabilityResponse {
 
-    public EnableResponse(Set<String> capabilities) {
+    public EnableResponse(Set<Capability> capabilities) {
         super(capabilities);
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractMailboxProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractMailboxProcessor.java
index 7eff975..5380767 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractMailboxProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractMailboxProcessor.java
@@ -30,6 +30,7 @@ import javax.mail.Flags;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.IdRange;
 import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.imap.api.message.request.ImapRequest;
@@ -278,7 +279,7 @@ public abstract class AbstractMailboxProcessor<R extends ImapRequest> extends Ab
     }
 
     protected void condstoreEnablingCommand(ImapSession session, Responder responder, MetaData metaData, boolean sendHighestModSeq) {
-        Set<String> enabled = EnableProcessor.getEnabledCapabilities(session);
+        Set<Capability> enabled = EnableProcessor.getEnabledCapabilities(session);
         if (!enabled.contains(ImapConstants.SUPPORTS_CONDSTORE)) {
             if (sendHighestModSeq) {
                 if (metaData.isModSeqPermanent()) {
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java
index a532b9e..e7a1184 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java
@@ -25,6 +25,7 @@ import java.util.List;
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.IdRange;
 import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.imap.api.message.request.ImapRequest;
@@ -61,7 +62,7 @@ import com.google.common.collect.ImmutableList;
 
 abstract class AbstractSelectionProcessor<R extends AbstractMailboxSelectionRequest> extends AbstractMailboxProcessor<R> implements PermitEnableCapabilityProcessor {
     private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSelectionProcessor.class);
-    private static final List<String> CAPS = ImmutableList.of(ImapConstants.SUPPORTS_QRESYNC, ImapConstants.SUPPORTS_CONDSTORE);
+    private static final List<Capability> CAPS = ImmutableList.of(ImapConstants.SUPPORTS_QRESYNC, ImapConstants.SUPPORTS_CONDSTORE);
 
     private final StatusResponseFactory statusResponseFactory;
     private final boolean openReadOnly;
@@ -418,17 +419,17 @@ abstract class AbstractSelectionProcessor<R extends AbstractMailboxSelectionRequ
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return CAPS;
     }
 
     @Override
-    public List<String> getPermitEnableCapabilities(ImapSession session) {
+    public List<Capability> getPermitEnableCapabilities(ImapSession session) {
         return CAPS;
     }
 
     @Override
-    public void enable(ImapMessage message, Responder responder, ImapSession session, String capability) throws EnableException {
+    public void enable(ImapMessage message, Responder responder, ImapSession session, Capability capability) throws EnableException {
 
         if (EnableProcessor.getEnabledCapabilities(session).contains(capability) == false) {
             SelectedMailbox sm = session.getSelected();
@@ -436,7 +437,7 @@ abstract class AbstractSelectionProcessor<R extends AbstractMailboxSelectionRequ
             // QRESYNC or CONDSTORE
             //
             // See http://www.dovecot.org/list/dovecot/2008-March/029561.html
-            if (capability.equalsIgnoreCase(ImapConstants.SUPPORTS_CONDSTORE) || capability.equalsIgnoreCase(ImapConstants.SUPPORTS_QRESYNC)) {
+            if (capability.equals(ImapConstants.SUPPORTS_CONDSTORE) || capability.equals(ImapConstants.SUPPORTS_QRESYNC)) {
                 try {
                     MetaData metaData  = null;
                     boolean send = false;
@@ -447,7 +448,7 @@ abstract class AbstractSelectionProcessor<R extends AbstractMailboxSelectionRequ
                     }
                     condstoreEnablingCommand(session, responder, metaData, send);
                 } catch (MailboxException e) {
-                    throw new EnableException("Unable to enable " + capability, e);
+                    throw new EnableException("Unable to enable " + capability.asString(), e);
                 }
             }
             
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java
index 6a92f7c..24620b9 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java
@@ -28,6 +28,7 @@ import java.util.StringTokenizer;
 
 import org.apache.james.core.Username;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.request.ImapRequest;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
@@ -134,15 +135,15 @@ public class AuthenticateProcessor extends AbstractAuthProcessor<AuthenticateReq
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
-        List<String> caps = new ArrayList<>();
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
+        List<Capability> caps = new ArrayList<>();
         // Only ounce AUTH=PLAIN if the session does allow plain auth or TLS is active.
         // See IMAP-304
         if (session.isPlainAuthDisallowed()  == false || session.isTLSActive()) {
-            caps.add("AUTH=PLAIN");
+            caps.add(Capability.of("AUTH=PLAIN"));
         }
         // Support for SASL-IR. See RFC4959
-        caps.add("SASL-IR");
+        caps.add(Capability.of("SASL-IR"));
         return ImmutableList.copyOf(caps);
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityImplementingProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityImplementingProcessor.java
index 042bf2f..a336a78 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityImplementingProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityImplementingProcessor.java
@@ -21,6 +21,7 @@ package org.apache.james.imap.processor;
 
 import java.util.List;
 
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
 
@@ -34,5 +35,5 @@ public interface CapabilityImplementingProcessor extends ImapProcessor {
      *
      * @return list not null
      */
-    List<String> getImplementedCapabilities(ImapSession session);
+    List<Capability> getImplementedCapabilities(ImapSession session);
 }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityProcessor.java
index d82f129..03f3a93 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/CapabilityProcessor.java
@@ -19,11 +19,11 @@
 
 package org.apache.james.imap.processor;
 
+import static org.apache.james.imap.api.ImapConstants.BASIC_CAPABILITIES;
 import static org.apache.james.imap.api.ImapConstants.SUPPORTS_CONDSTORE;
 import static org.apache.james.imap.api.ImapConstants.SUPPORTS_I18NLEVEL_1;
 import static org.apache.james.imap.api.ImapConstants.SUPPORTS_LITERAL_PLUS;
 import static org.apache.james.imap.api.ImapConstants.SUPPORTS_RFC3348;
-import static org.apache.james.imap.api.ImapConstants.VERSION;
 
 import java.io.Closeable;
 import java.util.ArrayList;
@@ -32,6 +32,7 @@ import java.util.List;
 import java.util.Set;
 
 import org.apache.james.imap.api.ImapConfiguration;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -45,15 +46,15 @@ import com.google.common.collect.ImmutableList;
 
 public class CapabilityProcessor extends AbstractMailboxProcessor<CapabilityRequest> implements CapabilityImplementingProcessor {
 
-    private static final List<String> CAPS = ImmutableList.of(
-            VERSION,
+    private static final List<Capability> CAPS = ImmutableList.of(
+            BASIC_CAPABILITIES,
             SUPPORTS_LITERAL_PLUS,
             SUPPORTS_RFC3348,
             SUPPORTS_I18NLEVEL_1,
             SUPPORTS_CONDSTORE);
 
     private final List<CapabilityImplementingProcessor> capabilities = new ArrayList<>();
-    private final Set<String> disabledCaps = new HashSet<>();
+    private final Set<Capability> disabledCaps = new HashSet<>();
 
     public CapabilityProcessor(ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory,
             MetricFactory metricFactory) {
@@ -96,7 +97,7 @@ public class CapabilityProcessor extends AbstractMailboxProcessor<CapabilityRequ
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return CAPS;
     }
     
@@ -106,8 +107,8 @@ public class CapabilityProcessor extends AbstractMailboxProcessor<CapabilityRequ
      * @param session
      * @return supported
      */
-    public Set<String> getSupportedCapabilities(ImapSession session) {
-        Set<String> caps = new HashSet<>();
+    public Set<Capability> getSupportedCapabilities(ImapSession session) {
+        Set<Capability> caps = new HashSet<>();
         for (CapabilityImplementingProcessor capability : capabilities) {
             caps.addAll(capability.getImplementedCapabilities(session));
         }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java
index c9331ae..5109058 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java
@@ -24,6 +24,7 @@ import java.util.List;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -35,7 +36,7 @@ import com.google.common.collect.ImmutableList;
 
 public class CompressProcessor extends AbstractChainedProcessor<CompressRequest> implements CapabilityImplementingProcessor {
     private static final String ALGO = "DEFLATE";
-    private static final List<String> CAPA = ImmutableList.of(ImapConstants.COMPRESS_COMMAND_NAME + "=" + ALGO);
+    private static final List<Capability> CAPA = ImmutableList.of(Capability.of(ImapConstants.COMPRESS_COMMAND_NAME + "=" + ALGO));
     private final StatusResponseFactory factory;
     private static final String COMPRESSED = "COMPRESSED";
 
@@ -67,7 +68,7 @@ public class CompressProcessor extends AbstractChainedProcessor<CompressRequest>
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         if (session.isCompressionSupported()) {
             return CAPA;
         }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteACLProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteACLProcessor.java
index 722eb09..0db8646 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteACLProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/DeleteACLProcessor.java
@@ -24,6 +24,7 @@ import java.util.List;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -50,7 +51,7 @@ import com.google.common.collect.ImmutableList;
 public class DeleteACLProcessor extends AbstractMailboxProcessor<DeleteACLRequest> implements CapabilityImplementingProcessor {
     private static final Logger LOGGER = LoggerFactory.getLogger(DeleteACLProcessor.class);
 
-    private static final List<String> CAPABILITIES = ImmutableList.of(ImapConstants.SUPPORTS_ACL);
+    private static final List<Capability> CAPABILITIES = ImmutableList.of(ImapConstants.SUPPORTS_ACL);
 
     public DeleteACLProcessor(ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory,
             MetricFactory metricFactory) {
@@ -134,7 +135,7 @@ public class DeleteACLProcessor extends AbstractMailboxProcessor<DeleteACLReques
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return CAPABILITIES;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/EnableProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/EnableProcessor.java
index 74b8982..33e650d 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/EnableProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/EnableProcessor.java
@@ -29,6 +29,7 @@ import java.util.List;
 import java.util.Set;
 
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.request.ImapRequest;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
@@ -49,7 +50,7 @@ public class EnableProcessor extends AbstractMailboxProcessor<EnableRequest> imp
 
     private static final List<PermitEnableCapabilityProcessor> capabilities = new ArrayList<>();
     public static final String ENABLED_CAPABILITIES = "ENABLED_CAPABILITIES";
-    private static final List<String> CAPS = ImmutableList.of(SUPPORTS_ENABLE);
+    private static final List<Capability> CAPS = ImmutableList.of(SUPPORTS_ENABLE);
     private final CapabilityProcessor capabilityProcessor;
 
     public EnableProcessor(ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory, List<PermitEnableCapabilityProcessor> capabilities,
@@ -70,8 +71,8 @@ public class EnableProcessor extends AbstractMailboxProcessor<EnableRequest> imp
     protected void processRequest(EnableRequest request, ImapSession session, Responder responder) {
         try {
 
-            List<String> caps = request.getCapabilities();
-            Set<String> enabledCaps = enable(request, responder, session, caps.iterator());
+            List<Capability> caps = request.getCapabilities();
+            Set<Capability> enabledCaps = enable(request, responder, session, caps.iterator());
             responder.respond(new EnableResponse(enabledCaps));
 
             unsolicitedResponses(session, responder, false);
@@ -82,10 +83,10 @@ public class EnableProcessor extends AbstractMailboxProcessor<EnableRequest> imp
         }
     }
    
-    public Set<String> enable(ImapRequest request, Responder responder, ImapSession session, Iterator<String> caps) throws EnableException {
-        Set<String> enabledCaps = new HashSet<>();
+    public Set<Capability> enable(ImapRequest request, Responder responder, ImapSession session, Iterator<Capability> caps) throws EnableException {
+        Set<Capability> enabledCaps = new HashSet<>();
         while (caps.hasNext()) {
-            String cap = caps.next();
+            Capability cap = caps.next();
             // Check if the CAPABILITY is supported at all
             if (capabilityProcessor.getSupportedCapabilities(session).contains(cap)) {
                 for (PermitEnableCapabilityProcessor enableProcessor : capabilities) {
@@ -111,8 +112,8 @@ public class EnableProcessor extends AbstractMailboxProcessor<EnableRequest> imp
      * Return all enabled <code>CAPABILITIES</code> for this {@link ImapSession}
      */
     @SuppressWarnings("unchecked")
-    public static Set<String> getEnabledCapabilities(ImapSession session) {
-        Set<String> caps = (Set<String>) session.getAttribute(ENABLED_CAPABILITIES);
+    public static Set<Capability> getEnabledCapabilities(ImapSession session) {
+        Set<Capability> caps = (Set<Capability>) session.getAttribute(ENABLED_CAPABILITIES);
         
         if (caps == null) {
             caps = new HashSet<>();
@@ -122,7 +123,7 @@ public class EnableProcessor extends AbstractMailboxProcessor<EnableRequest> imp
     }
     
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return CAPS;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/ExpungeProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/ExpungeProcessor.java
index 431aad7..fd45881 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/ExpungeProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/ExpungeProcessor.java
@@ -19,12 +19,15 @@
 
 package org.apache.james.imap.processor;
 
+import static org.apache.james.imap.api.ImapConstants.SUPPORTS_UIDPLUS;
+
 import java.io.Closeable;
 import java.util.Iterator;
 import java.util.List;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.IdRange;
 import org.apache.james.imap.api.message.response.StatusResponse.ResponseCode;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
@@ -51,7 +54,7 @@ import com.google.common.collect.ImmutableList;
 public class ExpungeProcessor extends AbstractMailboxProcessor<ExpungeRequest> implements CapabilityImplementingProcessor {
     private static final Logger LOGGER = LoggerFactory.getLogger(ExpungeProcessor.class);
 
-    private static final List<String> UIDPLUS = ImmutableList.of("UIDPLUS");
+    private static final List<Capability> UIDPLUS = ImmutableList.of(SUPPORTS_UIDPLUS);
 
     public ExpungeProcessor(ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory,
             MetricFactory metricFactory) {
@@ -121,7 +124,7 @@ public class ExpungeProcessor extends AbstractMailboxProcessor<ExpungeRequest> i
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return UIDPLUS;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java
index 06148c1..b17250b 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java
@@ -24,6 +24,7 @@ import java.util.List;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -52,7 +53,7 @@ import com.google.common.collect.ImmutableList;
 public class GetACLProcessor extends AbstractMailboxProcessor<GetACLRequest> implements CapabilityImplementingProcessor {
     private static final Logger LOGGER = LoggerFactory.getLogger(GetACLProcessor.class);
 
-    private static final List<String> CAPABILITIES = ImmutableList.of(ImapConstants.SUPPORTS_ACL);
+    private static final List<Capability> CAPABILITIES = ImmutableList.of(ImapConstants.SUPPORTS_ACL);
 
     public GetACLProcessor(ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory,
             MetricFactory metricFactory) {
@@ -109,7 +110,7 @@ public class GetACLProcessor extends AbstractMailboxProcessor<GetACLRequest> imp
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return CAPABILITIES;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetAnnotationProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetAnnotationProcessor.java
index 14f697e..8cd15c9 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetAnnotationProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetAnnotationProcessor.java
@@ -29,6 +29,7 @@ import java.util.function.Predicate;
 import org.apache.commons.lang3.NotImplementedException;
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.request.ImapRequest;
 import org.apache.james.imap.api.message.response.StatusResponse.ResponseCode;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
@@ -62,7 +63,7 @@ public class GetAnnotationProcessor extends AbstractMailboxProcessor<GetAnnotati
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return ImmutableList.of(ImapConstants.SUPPORTS_ANNOTATION);
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaProcessor.java
index 20976cf..1f9e2bf 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaProcessor.java
@@ -28,6 +28,7 @@ import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -52,7 +53,7 @@ import com.google.common.collect.ImmutableList;
  */
 public class GetQuotaProcessor extends AbstractMailboxProcessor<GetQuotaRequest> implements CapabilityImplementingProcessor {
 
-    private static final List<String> CAPABILITIES = ImmutableList.of(ImapConstants.SUPPORTS_QUOTA);
+    private static final List<Capability> CAPABILITIES = ImmutableList.of(ImapConstants.SUPPORTS_QUOTA);
 
     private final QuotaManager quotaManager;
     private final QuotaRootResolver quotaRootResolver;
@@ -65,7 +66,7 @@ public class GetQuotaProcessor extends AbstractMailboxProcessor<GetQuotaRequest>
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return CAPABILITIES;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaRootProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaRootProcessor.java
index c9a4db3..d794b03 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaRootProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/GetQuotaRootProcessor.java
@@ -28,6 +28,7 @@ import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaSizeUsage;
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -54,7 +55,7 @@ import com.google.common.collect.ImmutableList;
  */
 public class GetQuotaRootProcessor extends AbstractMailboxProcessor<GetQuotaRootRequest> implements CapabilityImplementingProcessor {
 
-    private static final List<String> CAPABILITIES = ImmutableList.of(ImapConstants.SUPPORTS_QUOTA);
+    private static final List<Capability> CAPABILITIES = ImmutableList.of(ImapConstants.SUPPORTS_QUOTA);
     private final QuotaRootResolver quotaRootResolver;
     private final QuotaManager quotaManager;
 
@@ -66,7 +67,7 @@ public class GetQuotaRootProcessor extends AbstractMailboxProcessor<GetQuotaRoot
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return CAPABILITIES;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
index f1dbe51..2af0936 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/IdleProcessor.java
@@ -33,6 +33,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.james.imap.api.ImapConfiguration;
 import org.apache.james.imap.api.ImapSessionState;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponse;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapLineHandler;
@@ -54,7 +55,7 @@ import org.apache.james.util.concurrent.NamedThreadFactory;
 import com.google.common.collect.ImmutableList;
 
 public class IdleProcessor extends AbstractMailboxProcessor<IdleRequest> implements CapabilityImplementingProcessor {
-    private static final List<String> CAPS = ImmutableList.of(SUPPORTS_IDLE);
+    private static final List<Capability> CAPS = ImmutableList.of(SUPPORTS_IDLE);
     public static final int DEFAULT_SCHEDULED_POOL_CORE_SIZE = 5;
     private static final String DONE = "DONE";
 
@@ -154,7 +155,7 @@ public class IdleProcessor extends AbstractMailboxProcessor<IdleRequest> impleme
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return CAPS;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/ListRightsProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/ListRightsProcessor.java
index 850d800..4c7a147 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/ListRightsProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/ListRightsProcessor.java
@@ -24,6 +24,7 @@ import java.util.List;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -51,7 +52,7 @@ import com.google.common.collect.ImmutableList;
 public class ListRightsProcessor extends AbstractMailboxProcessor<ListRightsRequest> implements CapabilityImplementingProcessor {
     private static final Logger LOGGER = LoggerFactory.getLogger(ListRightsProcessor.class);
 
-    private static final List<String> CAPABILITIES = ImmutableList.of(ImapConstants.SUPPORTS_ACL);
+    private static final List<Capability> CAPABILITIES = ImmutableList.of(ImapConstants.SUPPORTS_ACL);
 
     public ListRightsProcessor(ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory,
             MetricFactory metricFactory) {
@@ -123,7 +124,7 @@ public class ListRightsProcessor extends AbstractMailboxProcessor<ListRightsRequ
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return CAPABILITIES;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/LoginProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/LoginProcessor.java
index 3faa59f..568a245 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/LoginProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/LoginProcessor.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -39,7 +40,7 @@ import com.google.common.collect.ImmutableList;
  */
 public class LoginProcessor extends AbstractAuthProcessor<LoginRequest> implements CapabilityImplementingProcessor {
 
-    private static final List<String> LOGINDISABLED_CAPS = ImmutableList.of("LOGINDISABLED");
+    private static final List<Capability> LOGINDISABLED_CAPS = ImmutableList.of(Capability.of("LOGINDISABLED"));
     
     public LoginProcessor(ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory,
             MetricFactory metricFactory) {
@@ -58,7 +59,7 @@ public class LoginProcessor extends AbstractAuthProcessor<LoginRequest> implemen
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         // Announce LOGINDISABLED if plain auth / login is deactivated and the session is not using
         // TLS. See IMAP-304
         if (session.isPlainAuthDisallowed() && session.isTLSActive() == false) {
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/MoveProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/MoveProcessor.java
index 129251c..bbe1cc4 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/MoveProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/MoveProcessor.java
@@ -23,6 +23,7 @@ import java.io.Closeable;
 import java.util.List;
 
 import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.IdRange;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
@@ -61,9 +62,9 @@ public class MoveProcessor extends AbstractMessageRangeProcessor<MoveRequest> im
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         if (moveCapabilitySupported) {
-            return ImmutableList.of(ImapConstants.MOVE_COMMAND_NAME);
+            return ImmutableList.of(ImapConstants.SUPPORTS_MOVE);
         } else {
             return ImmutableList.of();
         }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/MyRightsProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/MyRightsProcessor.java
index 5e9ac7e..63f5138 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/MyRightsProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/MyRightsProcessor.java
@@ -25,6 +25,7 @@ import java.util.List;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -49,7 +50,7 @@ import org.slf4j.LoggerFactory;
 public class MyRightsProcessor extends AbstractMailboxProcessor<MyRightsRequest> implements CapabilityImplementingProcessor {
     private static final Logger LOGGER = LoggerFactory.getLogger(MyRightsProcessor.class);
 
-    private static final List<String> CAPABILITIES = Collections.singletonList(ImapConstants.SUPPORTS_ACL);
+    private static final List<Capability> CAPABILITIES = Collections.singletonList(ImapConstants.SUPPORTS_ACL);
 
     public MyRightsProcessor(ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory,
             MetricFactory metricFactory) {
@@ -106,7 +107,7 @@ public class MyRightsProcessor extends AbstractMailboxProcessor<MyRightsRequest>
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return CAPABILITIES;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/NamespaceProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/NamespaceProcessor.java
index afbd533..eb2e8c5 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/NamespaceProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/NamespaceProcessor.java
@@ -22,11 +22,10 @@ import static org.apache.james.imap.api.ImapConstants.SUPPORTS_NAMESPACES;
 
 import java.io.Closeable;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -37,12 +36,13 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.MDCBuilder;
 
+import com.google.common.collect.ImmutableList;
+
 /**
  * Processes a NAMESPACE command into a suitable set of responses.
  */
 public class NamespaceProcessor extends AbstractMailboxProcessor<NamespaceRequest> implements CapabilityImplementingProcessor {
-    private static final List<String> CAPS = Collections.unmodifiableList(Arrays.asList(SUPPORTS_NAMESPACES));
-    
+    private static final List<Capability> CAPS = ImmutableList.of(SUPPORTS_NAMESPACES);
     
     public NamespaceProcessor(ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory,
             MetricFactory metricFactory) {
@@ -103,7 +103,7 @@ public class NamespaceProcessor extends AbstractMailboxProcessor<NamespaceReques
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return CAPS;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/PermitEnableCapabilityProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/PermitEnableCapabilityProcessor.java
index 52e6242..8416e43 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/PermitEnableCapabilityProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/PermitEnableCapabilityProcessor.java
@@ -21,6 +21,7 @@ package org.apache.james.imap.processor;
 import java.util.List;
 
 import org.apache.james.imap.api.ImapMessage;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.process.ImapSession;
 
 /**
@@ -33,12 +34,12 @@ public interface PermitEnableCapabilityProcessor extends CapabilityImplementingP
      * 
      * Be sure that these are also returned by {@link #getImplementedCapabilities(ImapSession)}
      */
-    List<String> getPermitEnableCapabilities(ImapSession session);
+    List<Capability> getPermitEnableCapabilities(ImapSession session);
     
     /**
      * Callback which is used when a ENABLED command was used to enable on of the CAPABILITIES which is managed by this implementation
      */
-    void enable(ImapMessage message, Responder responder, ImapSession session, String capability) throws EnableException;
+    void enable(ImapMessage message, Responder responder, ImapSession session, Capability capability) throws EnableException;
 
     /**
      * Exception which should get thrown if for whatever reason its not possible to enable a capability
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/SearchProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
index c124234..b28216d 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
@@ -31,6 +31,7 @@ import javax.mail.Flags.Flag;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.IdRange;
 import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.imap.api.message.request.DayMonthYear;
@@ -73,7 +74,7 @@ public class SearchProcessor extends AbstractMailboxProcessor<SearchRequest> imp
     private static final Logger LOGGER = LoggerFactory.getLogger(SearchProcessor.class);
 
     protected static final String SEARCH_MODSEQ = "SEARCH_MODSEQ";
-    private static final List<String> CAPS = ImmutableList.of("WITHIN", "ESEARCH", "SEARCHRES");
+    private static final List<Capability> CAPS = ImmutableList.of(Capability.of("WITHIN"), Capability.of("ESEARCH"), Capability.of("SEARCHRES"));
     
     public SearchProcessor(ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory,
             MetricFactory metricFactory) {
@@ -498,7 +499,7 @@ public class SearchProcessor extends AbstractMailboxProcessor<SearchRequest> imp
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return CAPS;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetACLProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetACLProcessor.java
index 708ae15..afba088 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetACLProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetACLProcessor.java
@@ -20,11 +20,11 @@
 package org.apache.james.imap.processor;
 
 import java.io.Closeable;
-import java.util.Collections;
 import java.util.List;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -45,13 +45,15 @@ import org.apache.james.util.MDCBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableList;
+
 /**
  * SETACL Processor.
  */
 public class SetACLProcessor extends AbstractMailboxProcessor<SetACLRequest> implements CapabilityImplementingProcessor {
     private static final Logger LOGGER = LoggerFactory.getLogger(SetACLProcessor.class);
 
-    private static final List<String> CAPABILITIES = Collections.singletonList(ImapConstants.SUPPORTS_ACL);
+    private static final List<Capability> CAPABILITIES = ImmutableList.of(ImapConstants.SUPPORTS_ACL);
 
     public SetACLProcessor(ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory,
             MetricFactory metricFactory) {
@@ -151,7 +153,7 @@ public class SetACLProcessor extends AbstractMailboxProcessor<SetACLRequest> imp
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return CAPABILITIES;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetAnnotationProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetAnnotationProcessor.java
index 94e84e3..12209a0 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetAnnotationProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetAnnotationProcessor.java
@@ -24,6 +24,7 @@ import java.util.List;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponse;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
@@ -52,7 +53,7 @@ public class SetAnnotationProcessor extends AbstractMailboxProcessor<SetAnnotati
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return ImmutableList.of(ImapConstants.SUPPORTS_ANNOTATION);
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetQuotaProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetQuotaProcessor.java
index 3601b64..3f0e443 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetQuotaProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetQuotaProcessor.java
@@ -20,11 +20,11 @@
 package org.apache.james.imap.processor;
 
 import java.io.Closeable;
-import java.util.Collections;
 import java.util.List;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -33,16 +33,13 @@ import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.MDCBuilder;
 
+import com.google.common.collect.ImmutableList;
+
 /**
  * SETQUOTA processor
  */
 public class SetQuotaProcessor extends AbstractMailboxProcessor<SetQuotaRequest> implements CapabilityImplementingProcessor {
-    private static final List<String> CAPABILITIES = Collections.singletonList(ImapConstants.SUPPORTS_QUOTA);
-
-    @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
-        return CAPABILITIES;
-    }
+    private static final List<Capability> CAPABILITIES = ImmutableList.of(ImapConstants.SUPPORTS_QUOTA);
 
     public SetQuotaProcessor(ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory,
             MetricFactory metricFactory) {
@@ -50,6 +47,11 @@ public class SetQuotaProcessor extends AbstractMailboxProcessor<SetQuotaRequest>
     }
 
     @Override
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
+        return CAPABILITIES;
+    }
+
+    @Override
     protected void processRequest(SetQuotaRequest request, ImapSession session, Responder responder) {
         Object[] params = new Object[]{
             "Full admin rights",
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/StartTLSProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/StartTLSProcessor.java
index 60cb5e6..65977f9 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/StartTLSProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/StartTLSProcessor.java
@@ -24,6 +24,7 @@ import java.util.List;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -37,7 +38,7 @@ import com.google.common.collect.ImmutableList;
  * Processing STARTLS commands
  */
 public class StartTLSProcessor extends AbstractChainedProcessor<StartTLSRequest> implements CapabilityImplementingProcessor {
-    private static final List<String> STARTTLS_CAP = ImmutableList.of(ImapConstants.SUPPORTS_STARTTLS);
+    private static final List<Capability> STARTTLS_CAP = ImmutableList.of(ImapConstants.SUPPORTS_STARTTLS);
     private final StatusResponseFactory factory;
 
     public StartTLSProcessor(ImapProcessor next, StatusResponseFactory factory) {
@@ -58,7 +59,7 @@ public class StartTLSProcessor extends AbstractChainedProcessor<StartTLSRequest>
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         if (session.supportStartTLS()) {
             return STARTTLS_CAP;
         } else {
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/StoreProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/StoreProcessor.java
index 4f6695d..cbba9d4 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/StoreProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/StoreProcessor.java
@@ -32,6 +32,7 @@ import javax.mail.Flags;
 import org.apache.james.imap.api.ImapCommand;
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.IdRange;
 import org.apache.james.imap.api.message.UidRange;
 import org.apache.james.imap.api.message.response.StatusResponse;
@@ -247,7 +248,7 @@ public class StoreProcessor extends AbstractMailboxProcessor<StoreRequest> {
             selected.resetNewApplicableFlags();
         }
         
-        Set<String> enabled = EnableProcessor.getEnabledCapabilities(session);
+        Set<Capability> enabled = EnableProcessor.getEnabledCapabilities(session);
         boolean qresyncEnabled = enabled.contains(ImapConstants.SUPPORTS_QRESYNC);
         boolean condstoreEnabled = enabled.contains(ImapConstants.SUPPORTS_CONDSTORE);
         
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/UnselectProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/UnselectProcessor.java
index 5253f33..64176c1 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/UnselectProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/UnselectProcessor.java
@@ -18,12 +18,13 @@
  ****************************************************************/
 package org.apache.james.imap.processor;
 
+import static org.apache.james.imap.api.ImapConstants.SUPPORTS_UNSELECT;
+
 import java.io.Closeable;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 
 import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
@@ -32,14 +33,15 @@ import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.MDCBuilder;
 
+import com.google.common.collect.ImmutableList;
+
 /**
  * Processor which implements the UNSELECT extension.
  * 
  * See RFC3691
  */
 public class UnselectProcessor extends AbstractMailboxProcessor<UnselectRequest> implements CapabilityImplementingProcessor {
-
-    private static final List<String> UNSELECT = Collections.unmodifiableList(Arrays.asList("UNSELECT"));
+    private static final List<Capability> UNSELECT = ImmutableList.of(SUPPORTS_UNSELECT);
 
     public UnselectProcessor(ImapProcessor next, MailboxManager mailboxManager, StatusResponseFactory factory,
             MetricFactory metricFactory) {
@@ -58,7 +60,7 @@ public class UnselectProcessor extends AbstractMailboxProcessor<UnselectRequest>
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         return UNSELECT;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/XListProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/XListProcessor.java
index 381ae28..a7d4a6d 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/XListProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/XListProcessor.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.james.imap.api.ImapMessage;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.ImapResponseMessage;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
@@ -44,7 +45,7 @@ import com.google.common.collect.ImmutableList;
  */
 public class XListProcessor extends ListProcessor implements CapabilityImplementingProcessor {
 
-    private static final List<String> XLIST_CAPS = ImmutableList.of(SUPPORTS_XLIST);
+    private static final List<Capability> XLIST_CAPS = ImmutableList.of(SUPPORTS_XLIST);
     private final MailboxTyper mailboxTyper;
 
     // some interface
@@ -55,7 +56,7 @@ public class XListProcessor extends ListProcessor implements CapabilityImplement
     }
 
     @Override
-    public List<String> getImplementedCapabilities(ImapSession session) {
+    public List<Capability> getImplementedCapabilities(ImapSession session) {
         // if there's no mailboxTyper, do not annnoyce XLIST capability
         if (mailboxTyper == null) {
             return Collections.emptyList();
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/api/ImapConfigurationTest.java b/protocols/imap/src/test/java/org/apache/james/imap/api/ImapConfigurationTest.java
index b8697d7..ab589f2 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/api/ImapConfigurationTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/api/ImapConfigurationTest.java
@@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import java.util.concurrent.TimeUnit;
 
+import org.apache.james.imap.api.message.Capability;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -105,7 +106,7 @@ public class ImapConfigurationTest {
                 .disabledCaps(ImmutableSet.of("AnyValue"))
                 .build();
 
-        assertThat(imapConfiguration.getDisabledCaps()).containsExactly("AnyValue");
+        assertThat(imapConfiguration.getDisabledCaps()).containsExactly(Capability.of("AnyValue"));
     }
 
     @Test
@@ -114,7 +115,7 @@ public class ImapConfigurationTest {
                 .disabledCaps(ImmutableSet.of("AnyValue", "OtherValue"))
                 .build();
 
-        assertThat(imapConfiguration.getDisabledCaps()).containsExactly("AnyValue", "OtherValue");
+        assertThat(imapConfiguration.getDisabledCaps()).containsExactly(Capability.of("AnyValue"), Capability.of("OtherValue"));
     }
 
     @Test
@@ -123,7 +124,7 @@ public class ImapConfigurationTest {
                 .disabledCaps(ImmutableSet.of("   AnyValue   ", "  OtherValue   "))
                 .build();
 
-        assertThat(imapConfiguration.getDisabledCaps()).containsExactly("AnyValue", "OtherValue");
+        assertThat(imapConfiguration.getDisabledCaps()).containsExactly(Capability.of("AnyValue"), Capability.of("OtherValue"));
     }
 
     @Test
@@ -132,7 +133,7 @@ public class ImapConfigurationTest {
                 .disabledCaps("   AnyValue   ", "  OtherValue   ")
                 .build();
 
-        assertThat(imapConfiguration.getDisabledCaps()).containsExactly("AnyValue", "OtherValue");
+        assertThat(imapConfiguration.getDisabledCaps()).containsExactly(Capability.of("AnyValue"), Capability.of("OtherValue"));
     }
 
     @Test
@@ -141,7 +142,7 @@ public class ImapConfigurationTest {
                 .disabledCap("   AnyValue   ")
                 .build();
 
-        assertThat(imapConfiguration.getDisabledCaps()).containsExactly("AnyValue");
+        assertThat(imapConfiguration.getDisabledCaps()).containsExactly(Capability.of("AnyValue"));
     }
 
     @Test
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/message/request/EnableRequest.java b/protocols/imap/src/test/java/org/apache/james/imap/api/message/CapabilityTest.java
similarity index 58%
copy from protocols/imap/src/main/java/org/apache/james/imap/message/request/EnableRequest.java
copy to protocols/imap/src/test/java/org/apache/james/imap/api/message/CapabilityTest.java
index e285d27..f84a98a 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/message/request/EnableRequest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/api/message/CapabilityTest.java
@@ -16,28 +16,38 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
-package org.apache.james.imap.message.request;
 
-import java.util.List;
+package org.apache.james.imap.api.message;
 
-import org.apache.james.imap.api.ImapCommand;
-import org.apache.james.imap.api.Tag;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
-public class EnableRequest extends AbstractImapRequest {
+import org.junit.jupiter.api.Test;
 
-    private final List<String> capabilities;
+import nl.jqno.equalsverifier.EqualsVerifier;
 
-    public EnableRequest(Tag tag, ImapCommand command, List<String> capabilities) {
-        super(tag, command);
-        this.capabilities = capabilities;
+class CapabilityTest {
+    @Test
+    void shouldMatchBeanContract() {
+        EqualsVerifier.forClass(Capability.class)
+            .verify();
     }
-    
-    /**
-     * Return a List of <code>CAPABILITIES</code>. All these must be uppercase
-     * 
-     * @return caps
-     */
-    public List<String> getCapabilities() {
-        return capabilities;
+
+    @Test
+    void ofShouldThrowWhenNull() {
+        assertThatThrownBy(() -> Capability.of(null))
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    void ofShouldThrowWhenEmpty() {
+        assertThatThrownBy(() -> Capability.of(""))
+            .isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    void ofShouldNormalizeCase() {
+        assertThat(Capability.of("a"))
+            .isEqualTo(Capability.of("A"));
     }
-}
+}
\ No newline at end of file
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/processor/CapabilityProcessorTest.java b/protocols/imap/src/test/java/org/apache/james/imap/processor/CapabilityProcessorTest.java
index cfebddf..cefb8eb 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/processor/CapabilityProcessorTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/processor/CapabilityProcessorTest.java
@@ -24,6 +24,7 @@ import java.util.Set;
 
 import org.apache.james.imap.api.ImapConfiguration;
 import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.api.message.Capability;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.processor.base.UnknownRequestProcessor;
@@ -49,7 +50,7 @@ public class CapabilityProcessorTest {
     public void condstoreShouldBeSupportedWhenSelectedFor() {
         testee.configure(ImapConfiguration.builder().isCondstoreEnable(true).build());
 
-        Set<String> supportedCapabilities = testee.getSupportedCapabilities(null);
+        Set<Capability> supportedCapabilities = testee.getSupportedCapabilities(null);
         assertThat(supportedCapabilities).contains(ImapConstants.SUPPORTS_CONDSTORE);
     }
 
@@ -57,7 +58,7 @@ public class CapabilityProcessorTest {
     public void condstoreShouldBeNotSupportedByDefault() {
         testee.configure(ImapConfiguration.builder().build());
 
-        Set<String> supportedCapabilities = testee.getSupportedCapabilities(null);
+        Set<Capability> supportedCapabilities = testee.getSupportedCapabilities(null);
         assertThat(supportedCapabilities).doesNotContain(ImapConstants.SUPPORTS_CONDSTORE);
     }
 }
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/processor/MoveProcessorTest.java b/protocols/imap/src/test/java/org/apache/james/imap/processor/MoveProcessorTest.java
index 4bbbf83..6f2dd62 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/processor/MoveProcessorTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/processor/MoveProcessorTest.java
@@ -90,7 +90,7 @@ public class MoveProcessorTest {
 
     @Test
     public void getImplementedCapabilitiesShouldContainMoveWhenSupportedByMailboxManager() {
-        assertThat(testee.getImplementedCapabilities(null)).containsExactly(ImapConstants.MOVE_COMMAND_NAME);
+        assertThat(testee.getImplementedCapabilities(null)).containsExactly(ImapConstants.SUPPORTS_MOVE);
     }
 
     @Test


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