From bb949d84347e05146d255535b4a8a51a67788661 Mon Sep 17 00:00:00 2001
From: Jan-Eric Hellenberg <janeric.hellenberg@gmail.com>
Date: Fri, 3 Jan 2025 10:25:28 +0100
Subject: [PATCH 1/9] James-4099 Make mailbox path delimiter configurable

---
 .../servers/partials/configure/jvm.adoc       |  15 ++
 .../james/mailbox/model/MailboxConstants.java |  39 +++-
 .../james/mailbox/MailboxSessionUtil.java     |  11 +-
 .../mailbox/store/SessionProviderImpl.java    |   2 +-
 .../apache/james/imap/main/PathConverter.java |   2 +-
 .../imap/message/response/ListResponse.java   |   2 +-
 .../imap/main/DefaultPathConverterTest.java   |  47 ++--
 .../imap/main/PathConverterBasicContract.java | 210 ++++++++++--------
 .../docker-configuration/jvm.properties       |   6 +
 .../sample-configuration/jvm.properties       |   6 +
 .../docker-configuration/jvm.properties       |  12 +-
 .../sample-configuration/jvm.properties       |  10 +-
 .../docker-configuration/jvm.properties       |   6 +
 .../sample-configuration/jvm.properties       |   6 +
 .../sample-configuration/jvm.properties       |   6 +
 .../sample-configuration/jvm.properties       |   6 +
 .../sample-configuration/jvm.properties       |   6 +
 .../sample-configuration/jvm.properties       |   6 +
 18 files changed, 266 insertions(+), 132 deletions(-)

diff --git a/docs/modules/servers/partials/configure/jvm.adoc b/docs/modules/servers/partials/configure/jvm.adoc
index fdc71ef2059..11f22bc5a32 100644
--- a/docs/modules/servers/partials/configure/jvm.adoc
+++ b/docs/modules/servers/partials/configure/jvm.adoc
@@ -5,6 +5,21 @@ when a property affects very early JVM start behaviour.
 
 For testing purposes, you may specify a different file path via the command line option `-Dextra.props=/some/other/jvm.properties`.
 
+== Adjusting the Mailbox folder delimiter
+
+The delimiter used to separate parent/child folders.
+
+WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments will likely lead to failure of some system components, as occurrences of old the delimiter will still be present in the database/data store.
+
+Optional. String. Defaults to 'dot'
+
+Ex in `jvm.properties`
+----
+james.mailbox.folder.delimiter=dot
+----
+
+Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+
 == Control the threshold memory
 This governs the threshold MimeMessageInputStreamSource relies on for storing MimeMessage content on disk.
 
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxConstants.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxConstants.java
index 69bff299ded..3afd9f21c7f 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxConstants.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxConstants.java
@@ -19,28 +19,51 @@
 
 package org.apache.james.mailbox.model;
 
+import java.util.Optional;
+
 /**
  * Constants which are used within the mailbox api and implementations
  */
-public interface MailboxConstants {
+public class MailboxConstants {
 
     /**
      * The char which is used to prefix a namespace
      */
-    char NAMESPACE_PREFIX_CHAR = '#';
+    public static final char NAMESPACE_PREFIX_CHAR = '#';
 
     /** The namespace used for store user inboxes */
-    String USER_NAMESPACE = NAMESPACE_PREFIX_CHAR + "private";
+    public static final String USER_NAMESPACE = NAMESPACE_PREFIX_CHAR + "private";
+
+    /** The delimiter used to seperated parent/child folders */
+    public static char FOLDER_DELIMITER = Optional.ofNullable(System.getProperty("james.mailbox.folder.delimiter"))
+            .map(MailboxFolderDelimiter::parse).orElse(MailboxFolderDelimiter.DOT).value;
+
+    enum MailboxFolderDelimiter {
+        DOT('.'),
+        SLASH('/');
+
+        public final char value;
+
+        MailboxFolderDelimiter(char value) {
+            this.value = value;
+        }
 
-    /** The default delimiter used to seperated parent/child folders */
-    char DEFAULT_DELIMITER = '.';
+        static MailboxFolderDelimiter parse(String input) {
+            for (MailboxFolderDelimiter delimiter: values()) {
+                if (delimiter.name().equalsIgnoreCase(input)) {
+                    return delimiter;
+                }
+            }
+            throw new IllegalArgumentException(String.format("Invalid mailbox delimiter `%s`", input));
+        }
+    }
 
     /** The name of the INBOX */
-    String INBOX = "INBOX";
+    public static final String INBOX = "INBOX";
 
     /** The limitation of annotation data */
-    int DEFAULT_LIMIT_ANNOTATION_SIZE = 1024;
+    public static final int DEFAULT_LIMIT_ANNOTATION_SIZE = 1024;
 
     /** The maximum number of annotations on a mailbox */
-    int DEFAULT_LIMIT_ANNOTATIONS_ON_MAILBOX = 10;
+    public static final int DEFAULT_LIMIT_ANNOTATIONS_ON_MAILBOX = 10;
 }
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxSessionUtil.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxSessionUtil.java
index e2aa0130085..2d4ac34f7db 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxSessionUtil.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxSessionUtil.java
@@ -31,11 +31,16 @@
 
 public class MailboxSessionUtil {
     public static MailboxSession create(Username username) {
-        return create(username, MailboxSession.SessionId.of(ThreadLocalRandom.current().nextLong()));
+        return create(username, MailboxConstants.FOLDER_DELIMITER);
+    }
+
+    public static MailboxSession create(Username username, char folderDelimiter) {
+        return create(username, MailboxSession.SessionId.of(ThreadLocalRandom.current().nextLong()), folderDelimiter);
     }
 
     @VisibleForTesting
-    public static MailboxSession create(Username username, MailboxSession.SessionId sessionId) {
+    public static MailboxSession create(Username username, MailboxSession.SessionId sessionId,
+                                        char folderDelimiter) {
         ArrayList<Locale> locales = new ArrayList<>();
 
         return new MailboxSession(
@@ -43,7 +48,7 @@ public static MailboxSession create(Username username, MailboxSession.SessionId
             username,
             Optional.of(username),
             locales,
-            MailboxConstants.DEFAULT_DELIMITER,
+            folderDelimiter,
             MailboxSession.SessionType.User);
     }
 }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/SessionProviderImpl.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/SessionProviderImpl.java
index 5651c699c88..b0eea7c0a3a 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/SessionProviderImpl.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/SessionProviderImpl.java
@@ -127,7 +127,7 @@ public MailboxSession forMatchingUser(Predicate<Username> otherPredicate) throws
     }
 
     private MailboxSession createSession(Username userName, Optional<Username> loggedInUser, MailboxSession.SessionType type) {
-        return new MailboxSession(newSessionId(), userName, loggedInUser, new ArrayList<>(), MailboxConstants.DEFAULT_DELIMITER, type);
+        return new MailboxSession(newSessionId(), userName, loggedInUser, new ArrayList<>(), MailboxConstants.FOLDER_DELIMITER, type);
     }
 
     private MailboxSession.SessionId newSessionId() {
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/main/PathConverter.java b/protocols/imap/src/main/java/org/apache/james/imap/main/PathConverter.java
index 7d2d53281a5..f57cc3e3c1f 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/main/PathConverter.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/main/PathConverter.java
@@ -112,7 +112,7 @@ private MailboxPath asMailboxPath(List<String> mailboxPathParts, MailboxSession
                     return new MailboxPath(MailboxConstants.USER_NAMESPACE, null, sanitizeMailboxName(mailboxName));
                 }
                 String username = mailboxPathParts.get(USER);
-                String unescapedUsername = username.replace("__", ".")
+                String unescapedUsername = username.replace("__", String.valueOf(MailboxConstants.FOLDER_DELIMITER))
                     .replace("_-", "_");
                 Username user = Username.from(unescapedUsername, session.getUser().getDomainPart().map(Domain::asString));
                 String mailboxName = Joiner.on(session.getPathDelimiter()).join(Iterables.skip(mailboxPathParts, 2));
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/message/response/ListResponse.java b/protocols/imap/src/main/java/org/apache/james/imap/message/response/ListResponse.java
index ba8c6f785fe..77c13f095ab 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/message/response/ListResponse.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/message/response/ListResponse.java
@@ -106,7 +106,7 @@ public Builder nonExitingSubscribedMailbox(MailboxPath subscribedPath) {
             return name(subscribedPath.getName())
                 .children(MailboxMetaData.Children.CHILDREN_ALLOWED_BUT_UNKNOWN)
                 .selectability(MailboxMetaData.Selectability.NONE)
-                .hierarchyDelimiter(MailboxConstants.DEFAULT_DELIMITER)
+                .hierarchyDelimiter(MailboxConstants.FOLDER_DELIMITER)
                 .returnSubscribed(RETURN_SUBSCRIBED)
                 .returnNonExistent(RETURN_NON_EXISTENT)
                 .mailboxType(MailboxType.OTHER);
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/main/DefaultPathConverterTest.java b/protocols/imap/src/test/java/org/apache/james/imap/main/DefaultPathConverterTest.java
index 8a47746da48..95172d89285 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/main/DefaultPathConverterTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/main/DefaultPathConverterTest.java
@@ -19,36 +19,41 @@
 
 package org.apache.james.imap.main;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
 
-public class DefaultPathConverterTest implements PathConverterBasicContract {
-
-    private PathConverter pathConverter;
-
-    @BeforeEach
-    void setup() {
-        pathConverter = PathConverter.Factory.DEFAULT.forSession(mailboxSession);
-    }
-
-    @Override
-    public PathConverter pathConverter() {
-        return pathConverter;
+public class DefaultPathConverterTest {
+    @Nested
+    public class DotDelimiter extends TestBase {
+        @Override
+        public char pathDelimiter() {
+            return '.';
+        }
     }
 
     @Nested
-    class WithEmailTest implements PathConverterBasicContract.WithEmail {
-
-        private PathConverter pathConverter;
-
-        @BeforeEach
-        void setup() {
-            pathConverter = PathConverter.Factory.DEFAULT.forSession(mailboxSession);
+    public class SlashDelimiter extends TestBase {
+        @Override
+        public char pathDelimiter() {
+            return '/';
         }
+    }
+
+    public abstract static class TestBase extends PathConverterBasicContract {
+        private final PathConverter pathConverter = PathConverter.Factory.DEFAULT.forSession(mailboxSession);
 
         @Override
         public PathConverter pathConverter() {
             return pathConverter;
         }
+
+        @Nested
+        public class WithEmail extends PathConverterBasicContract.WithEmail {
+            private final PathConverter pathConverter = PathConverter.Factory.DEFAULT.forSession(mailboxWithEmailSession);
+
+            @Override
+            public PathConverter pathConverter() {
+                return pathConverter;
+            }
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/main/PathConverterBasicContract.java b/protocols/imap/src/test/java/org/apache/james/imap/main/PathConverterBasicContract.java
index 76ab0a6d36c..a6274627507 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/main/PathConverterBasicContract.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/main/PathConverterBasicContract.java
@@ -27,259 +27,285 @@
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 
-public interface PathConverterBasicContract {
+public abstract class PathConverterBasicContract {
+    public static final Username USERNAME = Username.of("username");
+    public static final Username USERNAME_WITH_DELIMITER = Username.of("username.with.delimiter");
+    public static final Username USERNAME_WITH_UNDERSCORE = Username.of("username_with_underscore");
+    public static final Username USERNAME2 = Username.of("username2");
 
-    Username USERNAME = Username.of("username");
-    Username USERNAME_WITH_DOT = Username.of("username.with.dot");
-    Username USERNAME_WITH_UNDERSCORE = Username.of("username_with_underscore");
-    Username USERNAME2 = Username.of("username2");
+    public static final Username USERNAME_WITH_MAIL = Username.of("username@apache.org");
+    public static final Username USERNAME2_WITH_MAIL = Username.of("username2@apache.org");
+    public static final boolean RELATIVE = true;
 
-    Username USERNAME_WITH_MAIL = Username.of("username@apache.org");
-    Username USERNAME2_WITH_MAIL = Username.of("username2@apache.org");
-    char PATH_DELIMITER = '.';
-    boolean RELATIVE = true;
+    public final MailboxSession mailboxSession = MailboxSessionUtil.create(USERNAME, pathDelimiter());
 
-    MailboxSession mailboxSession = MailboxSessionUtil.create(USERNAME);
+    abstract PathConverter pathConverter();
 
-    PathConverter pathConverter();
+    abstract char pathDelimiter();
+
+    static char initialPathDelimiter;
+
+    @BeforeEach
+    public void setUp() {
+        initialPathDelimiter = MailboxConstants.FOLDER_DELIMITER;
+        MailboxConstants.FOLDER_DELIMITER = pathDelimiter();
+    }
+
+    @AfterEach
+    public void tearDown() {
+        MailboxConstants.FOLDER_DELIMITER = initialPathDelimiter;
+    }
+
+    static String adjustToTestDelimiter(String valueWithDots) {
+        // Because the test setup will configure the desired delimiter to be used,
+        // we do not need to pass it in manually here.
+        return valueWithDots.replace('.', MailboxConstants.FOLDER_DELIMITER);
+    }
+
+    static Username adjustToTestDelimiter(Username username) {
+        return Username.of(adjustToTestDelimiter(username.asString()));
+    }
 
     @Test
-    default void buildFullPathShouldAcceptNull() {
+    public void buildFullPathShouldAcceptNull() {
         assertThat(pathConverter().buildFullPath(null))
             .isEqualTo(new MailboxPath("", USERNAME, ""));
     }
 
     @Test
-    default void buildPathShouldAcceptEmpty() {
+    public void buildPathShouldAcceptEmpty() {
         assertThat(pathConverter().buildFullPath(""))
             .isEqualTo(new MailboxPath("", USERNAME, ""));
     }
 
     @Test
-    default void buildPathShouldAcceptRelativeMailboxName() {
+    public void buildPathShouldAcceptRelativeMailboxName() {
         String mailboxName = "mailboxName";
         assertThat(pathConverter().buildFullPath(mailboxName))
             .isEqualTo(MailboxPath.forUser(USERNAME, mailboxName));
     }
 
     @Test
-    default void buildFullPathShouldAcceptUserNamespace() {
+    public void buildFullPathShouldAcceptUserNamespace() {
         assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE))
             .isEqualTo(MailboxPath.forUser(USERNAME, ""));
     }
 
     @Test
-    default void buildFullPathShouldAcceptUserNamespaceAndDelimiter() {
-        assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + PATH_DELIMITER))
+    public void buildFullPathShouldAcceptUserNamespaceAndDelimiter() {
+        assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + pathDelimiter()))
             .isEqualTo(MailboxPath.forUser(USERNAME, ""));
     }
 
     @Test
-    default void buildFullPathShouldAcceptFullAbsoluteUserPath() {
+    public void buildFullPathShouldAcceptFullAbsoluteUserPath() {
         String mailboxName = "mailboxName";
-        assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + PATH_DELIMITER + mailboxName))
-            .isEqualTo(MailboxPath.forUser(USERNAME, mailboxName));
+        assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + pathDelimiter() + mailboxName))
+                .isEqualTo(MailboxPath.forUser(USERNAME, mailboxName));
     }
 
     @Test
-    default void buildFullPathShouldAcceptRelativePathWithSubFolder() {
-        String mailboxName = "mailboxName" + PATH_DELIMITER + "subFolder";
+    public void buildFullPathShouldAcceptRelativePathWithSubFolder() {
+        String mailboxName = adjustToTestDelimiter("mailboxName.subFolder");
         assertThat(pathConverter().buildFullPath(mailboxName))
-            .isEqualTo(MailboxPath.forUser(USERNAME, mailboxName));
+                .isEqualTo(MailboxPath.forUser(USERNAME, mailboxName));
     }
 
     @Test
-    default void buildFullPathShouldAcceptAbsoluteUserPathWithSubFolder() {
-        String mailboxName = "mailboxName.subFolder";
-        assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + PATH_DELIMITER + mailboxName))
-            .isEqualTo(MailboxPath.forUser(USERNAME, mailboxName));
+    public void buildFullPathShouldAcceptAbsoluteUserPathWithSubFolder() {
+        String mailboxName = adjustToTestDelimiter("mailboxName.subFolder");
+        assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + pathDelimiter() + mailboxName))
+                .isEqualTo(MailboxPath.forUser(USERNAME, mailboxName));
     }
 
     @Test
-    default void buildFullPathShouldAcceptAbsoluteOtherUserPath() {
-        assertThat(pathConverter().buildFullPath("#user.username2.abc"))
+    public void buildFullPathShouldAcceptAbsoluteOtherUserPath() {
+        assertThat(pathConverter().buildFullPath(adjustToTestDelimiter("#user.username2.abc")))
             .isEqualTo(MailboxPath.forUser(USERNAME2, "abc"));
     }
 
     @Test
-    default void buildFullPathShouldAcceptAbsoluteOtherUserPathWithDot() {
-        assertThat(pathConverter().buildFullPath("#user.username__with__dot.abc"))
-            .isEqualTo(MailboxPath.forUser(USERNAME_WITH_DOT, "abc"));
+    public void buildFullPathShouldAcceptAbsoluteOtherUserPathWithDelimiter() {
+        assertThat(pathConverter().buildFullPath(adjustToTestDelimiter("#user.username__with__delimiter.abc")))
+            .isEqualTo(MailboxPath.forUser(adjustToTestDelimiter(USERNAME_WITH_DELIMITER), "abc"));
     }
 
     @Test
-    default void buildFullPathShouldAcceptAbsoluteOtherUserPathWithUnderscore() {
-        assertThat(pathConverter().buildFullPath("#user.username_-with_-underscore.abc"))
+    public void buildFullPathShouldAcceptAbsoluteOtherUserPathWithUnderscore() {
+        assertThat(pathConverter().buildFullPath(adjustToTestDelimiter("#user.username_-with_-underscore.abc")))
             .isEqualTo(MailboxPath.forUser(USERNAME_WITH_UNDERSCORE, "abc"));
     }
 
     @Test
-    default void buildFullPathShouldAcceptAbsoluteOtherUserPathWithSubfolder() {
-        assertThat(pathConverter().buildFullPath("#user.username2.abc.def"))
-            .isEqualTo(MailboxPath.forUser(USERNAME2, "abc.def"));
+    public void buildFullPathShouldAcceptAbsoluteOtherUserPathWithSubfolder() {
+        assertThat(pathConverter().buildFullPath(adjustToTestDelimiter("#user.username2.abc.def")))
+            .isEqualTo(MailboxPath.forUser(USERNAME2, adjustToTestDelimiter("abc.def")));
     }
 
     @Test
-    default void buildFullPathShouldDenyMailboxPathNotBelongingToTheUser() {
+    public void buildFullPathShouldDenyMailboxPathNotBelongingToTheUser() {
         assertThatThrownBy(() -> pathConverter().buildFullPath("#any"))
             .isInstanceOf(DeniedAccessOnSharedMailboxException.class);
     }
 
     @Test
-    default void mailboxNameShouldReturnNameOnlyWhenRelativeAndUserMailbox() {
+    public void mailboxNameShouldReturnNameOnlyWhenRelativeAndUserMailbox() {
         assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(USERNAME, "abc"), mailboxSession))
             .contains("abc");
     }
 
     @Test
-    default void mailboxNameShouldReturnFQDNWhenRelativeAndOtherUserMailbox() {
+    public void mailboxNameShouldReturnFQDNWhenRelativeAndOtherUserMailbox() {
         assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(USERNAME2, "abc"), mailboxSession))
-            .contains("#user.username2.abc");
+            .contains(adjustToTestDelimiter("#user.username2.abc"));
     }
 
     @Test
-    default void mailboxNameShouldEscapeDotInUsername() {
-        assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(USERNAME_WITH_DOT, "abc"), mailboxSession))
-            .contains("#user.username__with__dot.abc");
+    public void mailboxNameShouldEscapeDelimiterInUsername() {
+        assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(adjustToTestDelimiter(USERNAME_WITH_DELIMITER), "abc"), mailboxSession))
+            .contains(adjustToTestDelimiter("#user.username__with__delimiter.abc"));
     }
 
     @Test
-    default void mailboxNameShouldEscapeUnderscoreInUsername() {
+    public void mailboxNameShouldEscapeUnderscoreInUsername() {
         assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(USERNAME_WITH_UNDERSCORE, "abc"), mailboxSession))
-            .contains("#user.username_-with_-underscore.abc");
+            .contains(adjustToTestDelimiter("#user.username_-with_-underscore.abc"));
     }
 
     @Test
-    default void mailboxNameShouldReturnFQDNWhenRelativeAndSharedMailbox() {
+    public void mailboxNameShouldReturnFQDNWhenRelativeAndSharedMailbox() {
         assertThat(pathConverter().mailboxName(RELATIVE, new MailboxPath("#Shared", Username.of("marketing"), "abc"), mailboxSession))
-            .contains("#Shared.marketing.abc");
+            .contains(adjustToTestDelimiter("#Shared.marketing.abc"));
     }
 
     @Test
-    default void mailboxNameShouldReturnFQDNWhenNotRelativeAndUserMailbox() {
+    public void mailboxNameShouldReturnFQDNWhenNotRelativeAndUserMailbox() {
+        String mailboxName = adjustToTestDelimiter("#private.abc");
         assertThat(pathConverter().mailboxName(!RELATIVE, MailboxPath.forUser(USERNAME, "abc"), mailboxSession))
-            .contains("#private.abc");
+            .contains(mailboxName);
     }
 
     @Test
-    default void mailboxNameShouldReturnFQDNWhenNotRelativeAndOtherUserMailbox() {
+    public void mailboxNameShouldReturnFQDNWhenNotRelativeAndOtherUserMailbox() {
         assertThat(pathConverter().mailboxName(!RELATIVE, MailboxPath.forUser(USERNAME2, "abc"), mailboxSession))
-            .contains("#user.username2.abc");
+            .contains(adjustToTestDelimiter("#user.username2.abc"));
     }
 
     @Test
-    default void mailboxNameShouldReturnFQDNWhenNotRelativeAndSharedMailbox() {
+    public void mailboxNameShouldReturnFQDNWhenNotRelativeAndSharedMailbox() {
         assertThat(pathConverter().mailboxName(!RELATIVE, new MailboxPath("#Shared", Username.of("marketing"), "abc"), mailboxSession))
-            .contains("#Shared.marketing.abc");
+            .contains(adjustToTestDelimiter("#Shared.marketing.abc"));
     }
     
     @Nested
-    interface WithEmail {
-        MailboxSession mailboxSession = MailboxSessionUtil.create(USERNAME_WITH_MAIL);
+    public abstract class WithEmail {
+        public final MailboxSession mailboxWithEmailSession = MailboxSessionUtil.create(USERNAME_WITH_MAIL, pathDelimiter());
 
-        PathConverter pathConverter();
+        public abstract PathConverter pathConverter();
 
         @Test
-        default void buildFullPathShouldAcceptNull() {
+        public void buildFullPathShouldAcceptNull() {
             assertThat(pathConverter().buildFullPath(null))
                 .isEqualTo(new MailboxPath("", USERNAME_WITH_MAIL, ""));
         }
 
         @Test
-        default void buildPathShouldAcceptEmpty() {
+        public void buildPathShouldAcceptEmpty() {
             assertThat(pathConverter().buildFullPath(""))
                 .isEqualTo(new MailboxPath("", USERNAME_WITH_MAIL, ""));
         }
 
         @Test
-        default void buildPathShouldAcceptRelativeMailboxName() {
+        public void buildPathShouldAcceptRelativeMailboxName() {
             String mailboxName = "mailboxName";
             assertThat(pathConverter().buildFullPath(mailboxName))
                 .isEqualTo(MailboxPath.forUser(USERNAME_WITH_MAIL, mailboxName));
         }
 
         @Test
-        default void buildFullPathShouldAcceptUserNamespace() {
+        public void buildFullPathShouldAcceptUserNamespace() {
             assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE))
                 .isEqualTo(MailboxPath.forUser(USERNAME_WITH_MAIL, ""));
         }
 
         @Test
-        default void buildFullPathShouldAcceptUserNamespaceAndDelimiter() {
-            assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + PATH_DELIMITER))
+        public void buildFullPathShouldAcceptUserNamespaceAndDelimiter() {
+            assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + pathDelimiter()))
                 .isEqualTo(MailboxPath.forUser(USERNAME_WITH_MAIL, ""));
         }
 
         @Test
-        default void buildFullPathShouldAcceptFullAbsoluteUserPath() {
+        public void buildFullPathShouldAcceptFullAbsoluteUserPath() {
             String mailboxName = "mailboxName";
-            assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + PATH_DELIMITER + mailboxName))
+            assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + pathDelimiter() + mailboxName))
                 .isEqualTo(MailboxPath.forUser(USERNAME_WITH_MAIL, mailboxName));
         }
 
         @Test
-        default void buildFullPathShouldAcceptRelativePathWithSubFolder() {
-            String mailboxName = "mailboxName" + PATH_DELIMITER + "subFolder";
+        public void buildFullPathShouldAcceptRelativePathWithSubFolder() {
+            String mailboxName = "mailboxName" + pathDelimiter() + "subFolder";
             assertThat(pathConverter().buildFullPath(mailboxName))
                 .isEqualTo(MailboxPath.forUser(USERNAME_WITH_MAIL, mailboxName));
         }
 
         @Test
-        default void buildFullPathShouldAcceptAbsoluteUserPathWithSubFolder() {
-            String mailboxName = "mailboxName.subFolder";
-            assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + PATH_DELIMITER + mailboxName))
+        public void buildFullPathShouldAcceptAbsoluteUserPathWithSubFolder() {
+            String mailboxName = adjustToTestDelimiter("mailboxName.subFolder");
+            assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + pathDelimiter() + mailboxName))
                 .isEqualTo(MailboxPath.forUser(USERNAME_WITH_MAIL, mailboxName));
         }
 
         @Test
-        default void buildFullPathShouldAcceptAbsoluteOtherUserPath() {
-            assertThat(pathConverter().buildFullPath("#user.username2.abc"))
+        public void buildFullPathShouldAcceptAbsoluteOtherUserPath() {
+            assertThat(pathConverter().buildFullPath(adjustToTestDelimiter("#user.username2.abc")))
                 .isEqualTo(MailboxPath.forUser(USERNAME2_WITH_MAIL, "abc"));
         }
 
         @Test
-        default void buildFullPathShouldAcceptAbsoluteOtherUserPathWithSubfolder() {
-            assertThat(pathConverter().buildFullPath("#user.username2.abc.def"))
-                .isEqualTo(MailboxPath.forUser(USERNAME2_WITH_MAIL, "abc.def"));
+        public void buildFullPathShouldAcceptAbsoluteOtherUserPathWithSubfolder() {
+            assertThat(pathConverter().buildFullPath(adjustToTestDelimiter("#user.username2.abc.def")))
+                .isEqualTo(MailboxPath.forUser(USERNAME2_WITH_MAIL, adjustToTestDelimiter("abc.def")));
         }
 
         @Test
-        default void mailboxNameShouldReturnNameOnlyWhenRelativeAndUserMailbox() {
-            assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(USERNAME_WITH_MAIL, "abc"), mailboxSession))
+        public void mailboxNameShouldReturnNameOnlyWhenRelativeAndUserMailbox() {
+            assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(USERNAME_WITH_MAIL, "abc"), mailboxWithEmailSession))
                 .contains("abc");
         }
 
         @Test
-        default void mailboxNameShouldReturnFQDNWhenRelativeAndOtherUserMailbox() {
-            assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(USERNAME2_WITH_MAIL, "abc"), mailboxSession))
-                .contains("#user.username2.abc");
+        public void mailboxNameShouldReturnFQDNWhenRelativeAndOtherUserMailbox() {
+            assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(USERNAME2_WITH_MAIL, "abc"), mailboxWithEmailSession))
+                .contains(adjustToTestDelimiter("#user.username2.abc"));
         }
 
         @Test
-        default void mailboxNameShouldReturnFQDNWhenRelativeAndSharedMailbox() {
-            assertThat(pathConverter().mailboxName(RELATIVE, new MailboxPath("#Shared", Username.of("marketing@apache.org"), "abc"), mailboxSession))
-                .contains("#Shared.marketing.abc");
+        public void mailboxNameShouldReturnFQDNWhenRelativeAndSharedMailbox() {
+            assertThat(pathConverter().mailboxName(RELATIVE, new MailboxPath("#Shared", Username.of("marketing@apache.org"), "abc"), mailboxWithEmailSession))
+                .contains(adjustToTestDelimiter("#Shared.marketing.abc"));
         }
 
         @Test
-        default void mailboxNameShouldReturnFQDNWhenNotRelativeAndUserMailbox() {
-            assertThat(pathConverter().mailboxName(!RELATIVE, MailboxPath.forUser(USERNAME_WITH_MAIL, "abc"), mailboxSession))
-                .contains("#private.abc");
+        public void mailboxNameShouldReturnFQDNWhenNotRelativeAndUserMailbox() {
+            assertThat(pathConverter().mailboxName(!RELATIVE, MailboxPath.forUser(USERNAME_WITH_MAIL, "abc"), mailboxWithEmailSession))
+                .contains(adjustToTestDelimiter("#private.abc"));
         }
 
         @Test
-        default void mailboxNameShouldReturnFQDNWhenNotRelativeAndOtherUserMailbox() {
-            assertThat(pathConverter().mailboxName(!RELATIVE, MailboxPath.forUser(USERNAME2_WITH_MAIL, "abc"), mailboxSession))
-                .contains("#user.username2.abc");
+        public void mailboxNameShouldReturnFQDNWhenNotRelativeAndOtherUserMailbox() {
+            assertThat(pathConverter().mailboxName(!RELATIVE, MailboxPath.forUser(USERNAME2_WITH_MAIL, "abc"), mailboxWithEmailSession))
+                .contains(adjustToTestDelimiter("#user.username2.abc"));
         }
 
         @Test
-        default void mailboxNameShouldReturnFQDNWhenNotRelativeAndSharedMailbox() {
-            assertThat(pathConverter().mailboxName(!RELATIVE, new MailboxPath("#Shared", Username.of("marketing@apache.org"), "abc"), mailboxSession))
-                .contains("#Shared.marketing.abc");
+        public void mailboxNameShouldReturnFQDNWhenNotRelativeAndSharedMailbox() {
+            assertThat(pathConverter().mailboxName(!RELATIVE, new MailboxPath("#Shared", Username.of("marketing@apache.org"), "abc"), mailboxWithEmailSession))
+                .contains(adjustToTestDelimiter("#Shared.marketing.abc"));
         }
     }
 }
diff --git a/server/apps/cassandra-app/docker-configuration/jvm.properties b/server/apps/cassandra-app/docker-configuration/jvm.properties
index 85e932e7c9b..3c81157e45a 100644
--- a/server/apps/cassandra-app/docker-configuration/jvm.properties
+++ b/server/apps/cassandra-app/docker-configuration/jvm.properties
@@ -4,6 +4,12 @@
 # Example: If you need an option -Dmy.property=whatever, you can instead add it here as
 # my.property=whatever
 
+# The delimiter used to separate parent/child folders.
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
+# will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
+# james.mailbox.folder.delimiter=dot
+
 # Required to locate Cassandra driver configuration
 config.file=/root/conf/cassandra-driver.conf
 
diff --git a/server/apps/cassandra-app/sample-configuration/jvm.properties b/server/apps/cassandra-app/sample-configuration/jvm.properties
index 82ea594769f..d763daefa84 100644
--- a/server/apps/cassandra-app/sample-configuration/jvm.properties
+++ b/server/apps/cassandra-app/sample-configuration/jvm.properties
@@ -4,6 +4,12 @@
 # Example: If you need an option -Dmy.property=whatever, you can instead add it here as
 # my.property=whatever
 
+# The delimiter used to separate parent/child folders.
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
+# will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
+# james.mailbox.folder.delimiter=dot
+
 # Required to locate Cassandra driver configuration
 config.file=conf/cassandra-driver.conf
 
diff --git a/server/apps/distributed-app/docker-configuration/jvm.properties b/server/apps/distributed-app/docker-configuration/jvm.properties
index 573d064bccb..3c81157e45a 100644
--- a/server/apps/distributed-app/docker-configuration/jvm.properties
+++ b/server/apps/distributed-app/docker-configuration/jvm.properties
@@ -1,12 +1,18 @@
 # ============================================= Extra JVM System Properties ===========================================
 # To avoid clutter on the command line, any properties in this file will be added as system properties on server start.
 
-# Required to locate Cassandra driver configuration
-config.file=/root/conf/cassandra-driver.conf
-
 # Example: If you need an option -Dmy.property=whatever, you can instead add it here as
 # my.property=whatever
 
+# The delimiter used to separate parent/child folders.
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
+# will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
+# james.mailbox.folder.delimiter=dot
+
+# Required to locate Cassandra driver configuration
+config.file=/root/conf/cassandra-driver.conf
+
 # (Optional). String (size, integer + size units, example: `12 KIB`, supported units are bytes KIB MIB GIB TIB). Defaults to 100KIB.
 # This governs the threshold MimeMessageInputStreamSource relies on for storing MimeMessage content on disk.
 # Below, data is stored in memory. Above data is stored on disk.
diff --git a/server/apps/distributed-app/sample-configuration/jvm.properties b/server/apps/distributed-app/sample-configuration/jvm.properties
index a98626760d4..600d91b3294 100644
--- a/server/apps/distributed-app/sample-configuration/jvm.properties
+++ b/server/apps/distributed-app/sample-configuration/jvm.properties
@@ -1,11 +1,17 @@
 # ============================================= Extra JVM System Properties ===========================================
 # To avoid clutter on the command line, any properties in this file will be added as system properties on server start.
 
+# Example: If you need an option -Dmy.property=whatever, you can instead add it here as
+# my.property=whatever
+
 # Required to locate Cassandra driver configuration
 config.file=conf/cassandra-driver.conf
 
-# Example: If you need an option -Dmy.property=whatever, you can instead add it here as
-# my.property=whatever
+# The delimiter used to separate parent/child folders.
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
+# will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
+# james.mailbox.folder.delimiter=dot
 
 # (Optional). String (size, integer + size units, example: `12 KIB`, supported units are bytes KIB MIB GIB TIB). Defaults to 100KIB.
 # This governs the threshold MimeMessageInputStreamSource relies on for storing MimeMessage content on disk.
diff --git a/server/apps/distributed-pop3-app/docker-configuration/jvm.properties b/server/apps/distributed-pop3-app/docker-configuration/jvm.properties
index 85e932e7c9b..3c81157e45a 100644
--- a/server/apps/distributed-pop3-app/docker-configuration/jvm.properties
+++ b/server/apps/distributed-pop3-app/docker-configuration/jvm.properties
@@ -4,6 +4,12 @@
 # Example: If you need an option -Dmy.property=whatever, you can instead add it here as
 # my.property=whatever
 
+# The delimiter used to separate parent/child folders.
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
+# will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
+# james.mailbox.folder.delimiter=dot
+
 # Required to locate Cassandra driver configuration
 config.file=/root/conf/cassandra-driver.conf
 
diff --git a/server/apps/distributed-pop3-app/sample-configuration/jvm.properties b/server/apps/distributed-pop3-app/sample-configuration/jvm.properties
index 3901fdf50ca..37646e5cec2 100644
--- a/server/apps/distributed-pop3-app/sample-configuration/jvm.properties
+++ b/server/apps/distributed-pop3-app/sample-configuration/jvm.properties
@@ -4,6 +4,12 @@
 # Example: If you need an option -Dmy.property=whatever, you can instead add it here as
 # my.property=whatever
 
+# The delimiter used to separate parent/child folders.
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
+# will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
+# james.mailbox.folder.delimiter=dot
+
 # Required to locate Cassandra driver configuration
 config.file=conf/cassandra-driver.conf
 
diff --git a/server/apps/jpa-app/sample-configuration/jvm.properties b/server/apps/jpa-app/sample-configuration/jvm.properties
index d6d2e0ae4b4..8cf7dfb8614 100644
--- a/server/apps/jpa-app/sample-configuration/jvm.properties
+++ b/server/apps/jpa-app/sample-configuration/jvm.properties
@@ -4,6 +4,12 @@
 # Example: If you need an option -Dmy.property=whatever, you can instead add it here as
 # my.property=whatever
 
+# The delimiter used to separate parent/child folders.
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
+# will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
+# james.mailbox.folder.delimiter=dot
+
 # (Optional). String (size, integer + size units, example: `12 KIB`, supported units are bytes KIB MIB GIB TIB). Defaults to 100KIB.
 # This governs the threshold MimeMessageInputStreamSource relies on for storing MimeMessage content on disk.
 # Below, data is stored in memory. Above data is stored on disk.
diff --git a/server/apps/jpa-smtp-app/sample-configuration/jvm.properties b/server/apps/jpa-smtp-app/sample-configuration/jvm.properties
index 04cfad0b6ca..a90fd7a31f2 100644
--- a/server/apps/jpa-smtp-app/sample-configuration/jvm.properties
+++ b/server/apps/jpa-smtp-app/sample-configuration/jvm.properties
@@ -4,6 +4,12 @@
 # Example: If you need an option -Dmy.property=whatever, you can instead add it here as
 # my.property=whatever
 
+# The delimiter used to separate parent/child folders.
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
+# will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
+# james.mailbox.folder.delimiter=dot
+
 # (Optional). String (size, integer + size units, example: `12 KIB`, supported units are bytes KIB MIB GIB TIB). Defaults to 100KIB.
 # This governs the threshold MimeMessageInputStreamSource relies on for storing MimeMessage content on disk.
 # Below, data is stored in memory. Above data is stored on disk.
diff --git a/server/apps/memory-app/sample-configuration/jvm.properties b/server/apps/memory-app/sample-configuration/jvm.properties
index 317261dd038..c362f00894c 100644
--- a/server/apps/memory-app/sample-configuration/jvm.properties
+++ b/server/apps/memory-app/sample-configuration/jvm.properties
@@ -4,6 +4,12 @@
 # Example: If you need an option -Dmy.property=whatever, you can instead add it here as
 # my.property=whatever
 
+# The delimiter used to separate parent/child folders.
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
+# will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
+# james.mailbox.folder.delimiter=dot
+
 # (Optional). String (size, integer + size units, example: `12 KIB`, supported units are bytes KIB MIB GIB TIB). Defaults to 100KIB.
 # This governs the threshold MimeMessageInputStreamSource relies on for storing MimeMessage content on disk.
 # Below, data is stored in memory. Above data is stored on disk.
diff --git a/server/apps/scaling-pulsar-smtp/sample-configuration/jvm.properties b/server/apps/scaling-pulsar-smtp/sample-configuration/jvm.properties
index 579b688dcb9..886dec96f5b 100644
--- a/server/apps/scaling-pulsar-smtp/sample-configuration/jvm.properties
+++ b/server/apps/scaling-pulsar-smtp/sample-configuration/jvm.properties
@@ -4,6 +4,12 @@
 # Example: If you need an option -Dmy.property=whatever, you can instead add it here as
 # my.property=whatever
 
+# The delimiter used to separate parent/child folders.
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
+# will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
+# james.mailbox.folder.delimiter=dot
+
 # (Optional). String (size, integer + size units, example: `12 KIB`, supported units are bytes KIB MIB GIB TIB). Defaults to 100KIB.
 # This governs the threshold MimeMessageInputStreamSource relies on for storing MimeMessage content on disk.
 # Below, data is stored in memory. Above data is stored on disk.

From 01ee67f650ba512ee061901a025a0addeaad8fc1 Mon Sep 17 00:00:00 2001
From: Jan-Eric Hellenberg <janeric.hellenberg@gmail.com>
Date: Fri, 3 Jan 2025 11:40:17 +0100
Subject: [PATCH 2/9] James-4099 Introduce common superclass for mailbox path
 delimiter aware tests

---
 .../MailboxFolderDelimiterAwareTest.java      | 71 ++++++++++++++
 .../imap/main/DefaultPathConverterTest.java   |  4 +-
 .../imap/main/PathConverterBasicContract.java | 98 +++++++------------
 3 files changed, 109 insertions(+), 64 deletions(-)
 create mode 100644 mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxFolderDelimiterAwareTest.java

diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxFolderDelimiterAwareTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxFolderDelimiterAwareTest.java
new file mode 100644
index 00000000000..858c515de98
--- /dev/null
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxFolderDelimiterAwareTest.java
@@ -0,0 +1,71 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.model;
+
+import org.apache.james.core.Username;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+
+/**
+ * A base class for all tests that have to deal with the mailbox path delimiter.
+ * It will make sure to install the delimiter specified by the subclass during the test lifecycle and provides
+ * some utility methods for writing tests using the active delimiter.
+ * <p>
+ * NOTE: If you add a new folder delimiter, make sure to add tests for it in all classes extending this one!
+ */
+public abstract class MailboxFolderDelimiterAwareTest {
+    public abstract char folderDelimiter();
+
+    static char initialFolderDelimiter;
+
+    @BeforeEach
+    public void setUp() {
+        initialFolderDelimiter = MailboxConstants.FOLDER_DELIMITER;
+        MailboxConstants.FOLDER_DELIMITER = folderDelimiter();
+    }
+
+    @AfterEach
+    public void tearDown() {
+        MailboxConstants.FOLDER_DELIMITER = initialFolderDelimiter;
+    }
+
+    /**
+     * Adjust the given string assumed to contain path delimiter dots ('.') to an equivalent version for a different
+     * delimiter.
+     * For example, a string "folder.subfolder.subsubfolder" would be converted into "folder/subfolder/subsubfolder" when
+     * the active FOLDER_DELIMITER is '/'.
+     * This is used to test that all delimiters are handled correctly in a lot of different scenarios
+     * without having to manually assemble strings with the active path delimiter
+     * (like "folder" + MailboxConstants.FOLDER_DELIMITER + "subfolder" + MailboxConstants.FOLDER_DELIMITER + "subsubfolder")
+     * everywhere, which quickly becomes tedious.
+     */
+    public static String adjustToActiveFolderDelimiter(String valueWithDots) {
+        // Because the test setup will configure the desired delimiter to be used,
+        // we do not need to pass it in manually here.
+        return valueWithDots.replace('.', MailboxConstants.FOLDER_DELIMITER);
+    }
+
+    /**
+     * See {@link #adjustToActiveFolderDelimiter(String)}.
+     */
+    public static Username adjustToActiveFolderDelimiter(Username username) {
+        return Username.of(adjustToActiveFolderDelimiter(username.asString()));
+    }
+}
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/main/DefaultPathConverterTest.java b/protocols/imap/src/test/java/org/apache/james/imap/main/DefaultPathConverterTest.java
index 95172d89285..476d1c670ea 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/main/DefaultPathConverterTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/main/DefaultPathConverterTest.java
@@ -25,7 +25,7 @@ public class DefaultPathConverterTest {
     @Nested
     public class DotDelimiter extends TestBase {
         @Override
-        public char pathDelimiter() {
+        public char folderDelimiter() {
             return '.';
         }
     }
@@ -33,7 +33,7 @@ public char pathDelimiter() {
     @Nested
     public class SlashDelimiter extends TestBase {
         @Override
-        public char pathDelimiter() {
+        public char folderDelimiter() {
             return '/';
         }
     }
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/main/PathConverterBasicContract.java b/protocols/imap/src/test/java/org/apache/james/imap/main/PathConverterBasicContract.java
index a6274627507..d2d89d96484 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/main/PathConverterBasicContract.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/main/PathConverterBasicContract.java
@@ -26,13 +26,12 @@
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailbox.model.MailboxFolderDelimiterAwareTest;
 import org.apache.james.mailbox.model.MailboxPath;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 
-public abstract class PathConverterBasicContract {
+public abstract class PathConverterBasicContract extends MailboxFolderDelimiterAwareTest {
     public static final Username USERNAME = Username.of("username");
     public static final Username USERNAME_WITH_DELIMITER = Username.of("username.with.delimiter");
     public static final Username USERNAME_WITH_UNDERSCORE = Username.of("username_with_underscore");
@@ -42,35 +41,10 @@ public abstract class PathConverterBasicContract {
     public static final Username USERNAME2_WITH_MAIL = Username.of("username2@apache.org");
     public static final boolean RELATIVE = true;
 
-    public final MailboxSession mailboxSession = MailboxSessionUtil.create(USERNAME, pathDelimiter());
+    public final MailboxSession mailboxSession = MailboxSessionUtil.create(USERNAME, folderDelimiter());
 
     abstract PathConverter pathConverter();
 
-    abstract char pathDelimiter();
-
-    static char initialPathDelimiter;
-
-    @BeforeEach
-    public void setUp() {
-        initialPathDelimiter = MailboxConstants.FOLDER_DELIMITER;
-        MailboxConstants.FOLDER_DELIMITER = pathDelimiter();
-    }
-
-    @AfterEach
-    public void tearDown() {
-        MailboxConstants.FOLDER_DELIMITER = initialPathDelimiter;
-    }
-
-    static String adjustToTestDelimiter(String valueWithDots) {
-        // Because the test setup will configure the desired delimiter to be used,
-        // we do not need to pass it in manually here.
-        return valueWithDots.replace('.', MailboxConstants.FOLDER_DELIMITER);
-    }
-
-    static Username adjustToTestDelimiter(Username username) {
-        return Username.of(adjustToTestDelimiter(username.asString()));
-    }
-
     @Test
     public void buildFullPathShouldAcceptNull() {
         assertThat(pathConverter().buildFullPath(null))
@@ -98,53 +72,53 @@ public void buildFullPathShouldAcceptUserNamespace() {
 
     @Test
     public void buildFullPathShouldAcceptUserNamespaceAndDelimiter() {
-        assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + pathDelimiter()))
+        assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + folderDelimiter()))
             .isEqualTo(MailboxPath.forUser(USERNAME, ""));
     }
 
     @Test
     public void buildFullPathShouldAcceptFullAbsoluteUserPath() {
         String mailboxName = "mailboxName";
-        assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + pathDelimiter() + mailboxName))
+        assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + folderDelimiter() + mailboxName))
                 .isEqualTo(MailboxPath.forUser(USERNAME, mailboxName));
     }
 
     @Test
     public void buildFullPathShouldAcceptRelativePathWithSubFolder() {
-        String mailboxName = adjustToTestDelimiter("mailboxName.subFolder");
+        String mailboxName = adjustToActiveFolderDelimiter("mailboxName.subFolder");
         assertThat(pathConverter().buildFullPath(mailboxName))
                 .isEqualTo(MailboxPath.forUser(USERNAME, mailboxName));
     }
 
     @Test
     public void buildFullPathShouldAcceptAbsoluteUserPathWithSubFolder() {
-        String mailboxName = adjustToTestDelimiter("mailboxName.subFolder");
-        assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + pathDelimiter() + mailboxName))
+        String mailboxName = adjustToActiveFolderDelimiter("mailboxName.subFolder");
+        assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + folderDelimiter() + mailboxName))
                 .isEqualTo(MailboxPath.forUser(USERNAME, mailboxName));
     }
 
     @Test
     public void buildFullPathShouldAcceptAbsoluteOtherUserPath() {
-        assertThat(pathConverter().buildFullPath(adjustToTestDelimiter("#user.username2.abc")))
+        assertThat(pathConverter().buildFullPath(adjustToActiveFolderDelimiter("#user.username2.abc")))
             .isEqualTo(MailboxPath.forUser(USERNAME2, "abc"));
     }
 
     @Test
     public void buildFullPathShouldAcceptAbsoluteOtherUserPathWithDelimiter() {
-        assertThat(pathConverter().buildFullPath(adjustToTestDelimiter("#user.username__with__delimiter.abc")))
-            .isEqualTo(MailboxPath.forUser(adjustToTestDelimiter(USERNAME_WITH_DELIMITER), "abc"));
+        assertThat(pathConverter().buildFullPath(adjustToActiveFolderDelimiter("#user.username__with__delimiter.abc")))
+            .isEqualTo(MailboxPath.forUser(adjustToActiveFolderDelimiter(USERNAME_WITH_DELIMITER), "abc"));
     }
 
     @Test
     public void buildFullPathShouldAcceptAbsoluteOtherUserPathWithUnderscore() {
-        assertThat(pathConverter().buildFullPath(adjustToTestDelimiter("#user.username_-with_-underscore.abc")))
+        assertThat(pathConverter().buildFullPath(adjustToActiveFolderDelimiter("#user.username_-with_-underscore.abc")))
             .isEqualTo(MailboxPath.forUser(USERNAME_WITH_UNDERSCORE, "abc"));
     }
 
     @Test
     public void buildFullPathShouldAcceptAbsoluteOtherUserPathWithSubfolder() {
-        assertThat(pathConverter().buildFullPath(adjustToTestDelimiter("#user.username2.abc.def")))
-            .isEqualTo(MailboxPath.forUser(USERNAME2, adjustToTestDelimiter("abc.def")));
+        assertThat(pathConverter().buildFullPath(adjustToActiveFolderDelimiter("#user.username2.abc.def")))
+            .isEqualTo(MailboxPath.forUser(USERNAME2, adjustToActiveFolderDelimiter("abc.def")));
     }
 
     @Test
@@ -162,30 +136,30 @@ public void mailboxNameShouldReturnNameOnlyWhenRelativeAndUserMailbox() {
     @Test
     public void mailboxNameShouldReturnFQDNWhenRelativeAndOtherUserMailbox() {
         assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(USERNAME2, "abc"), mailboxSession))
-            .contains(adjustToTestDelimiter("#user.username2.abc"));
+            .contains(adjustToActiveFolderDelimiter("#user.username2.abc"));
     }
 
     @Test
     public void mailboxNameShouldEscapeDelimiterInUsername() {
-        assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(adjustToTestDelimiter(USERNAME_WITH_DELIMITER), "abc"), mailboxSession))
-            .contains(adjustToTestDelimiter("#user.username__with__delimiter.abc"));
+        assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(adjustToActiveFolderDelimiter(USERNAME_WITH_DELIMITER), "abc"), mailboxSession))
+            .contains(adjustToActiveFolderDelimiter("#user.username__with__delimiter.abc"));
     }
 
     @Test
     public void mailboxNameShouldEscapeUnderscoreInUsername() {
         assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(USERNAME_WITH_UNDERSCORE, "abc"), mailboxSession))
-            .contains(adjustToTestDelimiter("#user.username_-with_-underscore.abc"));
+            .contains(adjustToActiveFolderDelimiter("#user.username_-with_-underscore.abc"));
     }
 
     @Test
     public void mailboxNameShouldReturnFQDNWhenRelativeAndSharedMailbox() {
         assertThat(pathConverter().mailboxName(RELATIVE, new MailboxPath("#Shared", Username.of("marketing"), "abc"), mailboxSession))
-            .contains(adjustToTestDelimiter("#Shared.marketing.abc"));
+            .contains(adjustToActiveFolderDelimiter("#Shared.marketing.abc"));
     }
 
     @Test
     public void mailboxNameShouldReturnFQDNWhenNotRelativeAndUserMailbox() {
-        String mailboxName = adjustToTestDelimiter("#private.abc");
+        String mailboxName = adjustToActiveFolderDelimiter("#private.abc");
         assertThat(pathConverter().mailboxName(!RELATIVE, MailboxPath.forUser(USERNAME, "abc"), mailboxSession))
             .contains(mailboxName);
     }
@@ -193,18 +167,18 @@ public void mailboxNameShouldReturnFQDNWhenNotRelativeAndUserMailbox() {
     @Test
     public void mailboxNameShouldReturnFQDNWhenNotRelativeAndOtherUserMailbox() {
         assertThat(pathConverter().mailboxName(!RELATIVE, MailboxPath.forUser(USERNAME2, "abc"), mailboxSession))
-            .contains(adjustToTestDelimiter("#user.username2.abc"));
+            .contains(adjustToActiveFolderDelimiter("#user.username2.abc"));
     }
 
     @Test
     public void mailboxNameShouldReturnFQDNWhenNotRelativeAndSharedMailbox() {
         assertThat(pathConverter().mailboxName(!RELATIVE, new MailboxPath("#Shared", Username.of("marketing"), "abc"), mailboxSession))
-            .contains(adjustToTestDelimiter("#Shared.marketing.abc"));
+            .contains(adjustToActiveFolderDelimiter("#Shared.marketing.abc"));
     }
     
     @Nested
     public abstract class WithEmail {
-        public final MailboxSession mailboxWithEmailSession = MailboxSessionUtil.create(USERNAME_WITH_MAIL, pathDelimiter());
+        public final MailboxSession mailboxWithEmailSession = MailboxSessionUtil.create(USERNAME_WITH_MAIL, folderDelimiter());
 
         public abstract PathConverter pathConverter();
 
@@ -235,41 +209,41 @@ public void buildFullPathShouldAcceptUserNamespace() {
 
         @Test
         public void buildFullPathShouldAcceptUserNamespaceAndDelimiter() {
-            assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + pathDelimiter()))
+            assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + folderDelimiter()))
                 .isEqualTo(MailboxPath.forUser(USERNAME_WITH_MAIL, ""));
         }
 
         @Test
         public void buildFullPathShouldAcceptFullAbsoluteUserPath() {
             String mailboxName = "mailboxName";
-            assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + pathDelimiter() + mailboxName))
+            assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + folderDelimiter() + mailboxName))
                 .isEqualTo(MailboxPath.forUser(USERNAME_WITH_MAIL, mailboxName));
         }
 
         @Test
         public void buildFullPathShouldAcceptRelativePathWithSubFolder() {
-            String mailboxName = "mailboxName" + pathDelimiter() + "subFolder";
+            String mailboxName = "mailboxName" + folderDelimiter() + "subFolder";
             assertThat(pathConverter().buildFullPath(mailboxName))
                 .isEqualTo(MailboxPath.forUser(USERNAME_WITH_MAIL, mailboxName));
         }
 
         @Test
         public void buildFullPathShouldAcceptAbsoluteUserPathWithSubFolder() {
-            String mailboxName = adjustToTestDelimiter("mailboxName.subFolder");
-            assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + pathDelimiter() + mailboxName))
+            String mailboxName = adjustToActiveFolderDelimiter("mailboxName.subFolder");
+            assertThat(pathConverter().buildFullPath(MailboxConstants.USER_NAMESPACE + folderDelimiter() + mailboxName))
                 .isEqualTo(MailboxPath.forUser(USERNAME_WITH_MAIL, mailboxName));
         }
 
         @Test
         public void buildFullPathShouldAcceptAbsoluteOtherUserPath() {
-            assertThat(pathConverter().buildFullPath(adjustToTestDelimiter("#user.username2.abc")))
+            assertThat(pathConverter().buildFullPath(adjustToActiveFolderDelimiter("#user.username2.abc")))
                 .isEqualTo(MailboxPath.forUser(USERNAME2_WITH_MAIL, "abc"));
         }
 
         @Test
         public void buildFullPathShouldAcceptAbsoluteOtherUserPathWithSubfolder() {
-            assertThat(pathConverter().buildFullPath(adjustToTestDelimiter("#user.username2.abc.def")))
-                .isEqualTo(MailboxPath.forUser(USERNAME2_WITH_MAIL, adjustToTestDelimiter("abc.def")));
+            assertThat(pathConverter().buildFullPath(adjustToActiveFolderDelimiter("#user.username2.abc.def")))
+                .isEqualTo(MailboxPath.forUser(USERNAME2_WITH_MAIL, adjustToActiveFolderDelimiter("abc.def")));
         }
 
         @Test
@@ -281,31 +255,31 @@ public void mailboxNameShouldReturnNameOnlyWhenRelativeAndUserMailbox() {
         @Test
         public void mailboxNameShouldReturnFQDNWhenRelativeAndOtherUserMailbox() {
             assertThat(pathConverter().mailboxName(RELATIVE, MailboxPath.forUser(USERNAME2_WITH_MAIL, "abc"), mailboxWithEmailSession))
-                .contains(adjustToTestDelimiter("#user.username2.abc"));
+                .contains(adjustToActiveFolderDelimiter("#user.username2.abc"));
         }
 
         @Test
         public void mailboxNameShouldReturnFQDNWhenRelativeAndSharedMailbox() {
             assertThat(pathConverter().mailboxName(RELATIVE, new MailboxPath("#Shared", Username.of("marketing@apache.org"), "abc"), mailboxWithEmailSession))
-                .contains(adjustToTestDelimiter("#Shared.marketing.abc"));
+                .contains(adjustToActiveFolderDelimiter("#Shared.marketing.abc"));
         }
 
         @Test
         public void mailboxNameShouldReturnFQDNWhenNotRelativeAndUserMailbox() {
             assertThat(pathConverter().mailboxName(!RELATIVE, MailboxPath.forUser(USERNAME_WITH_MAIL, "abc"), mailboxWithEmailSession))
-                .contains(adjustToTestDelimiter("#private.abc"));
+                .contains(adjustToActiveFolderDelimiter("#private.abc"));
         }
 
         @Test
         public void mailboxNameShouldReturnFQDNWhenNotRelativeAndOtherUserMailbox() {
             assertThat(pathConverter().mailboxName(!RELATIVE, MailboxPath.forUser(USERNAME2_WITH_MAIL, "abc"), mailboxWithEmailSession))
-                .contains(adjustToTestDelimiter("#user.username2.abc"));
+                .contains(adjustToActiveFolderDelimiter("#user.username2.abc"));
         }
 
         @Test
         public void mailboxNameShouldReturnFQDNWhenNotRelativeAndSharedMailbox() {
             assertThat(pathConverter().mailboxName(!RELATIVE, new MailboxPath("#Shared", Username.of("marketing@apache.org"), "abc"), mailboxWithEmailSession))
-                .contains(adjustToTestDelimiter("#Shared.marketing.abc"));
+                .contains(adjustToActiveFolderDelimiter("#Shared.marketing.abc"));
         }
     }
 }

From 99e7c581468b43bc6ec3bec757cad82e251f3e49 Mon Sep 17 00:00:00 2001
From: Jan-Eric Hellenberg <janeric.hellenberg@gmail.com>
Date: Fri, 3 Jan 2025 11:41:01 +0100
Subject: [PATCH 3/9] James-4099 Ensure properly using the mailbox session path
 delimiter when escaping usernames

---
 .../org/apache/james/imap/main/PathConverter.java     | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/protocols/imap/src/main/java/org/apache/james/imap/main/PathConverter.java b/protocols/imap/src/main/java/org/apache/james/imap/main/PathConverter.java
index f57cc3e3c1f..2ed8adee7b9 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/main/PathConverter.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/main/PathConverter.java
@@ -63,15 +63,16 @@ public PathConverter forSession(MailboxSession session) {
     class Default implements PathConverter {
         private static final int NAMESPACE = 0;
         private static final int USER = 1;
-        public static final Escaper USERNAME_ESCAPER = Escapers.builder()
-            .addEscape('.', "__")
-            .addEscape('_', "_-")
-            .build();
 
         private final MailboxSession mailboxSession;
+        private final Escaper usernameEscaper;
 
         private Default(MailboxSession mailboxSession) {
             this.mailboxSession = mailboxSession;
+            this.usernameEscaper = Escapers.builder()
+                    .addEscape(mailboxSession.getPathDelimiter(), "__")
+                    .addEscape('_', "_-")
+                    .build();
         }
 
         public MailboxPath buildFullPath(String mailboxName) {
@@ -151,7 +152,7 @@ private String joinMailboxPath(MailboxPath mailboxPath, MailboxSession session)
                         sb.append(session.getPathDelimiter());
                     }
 
-                    sb.append(USERNAME_ESCAPER.escape(mailboxPath.getUser().getLocalPart()));
+                    sb.append(usernameEscaper.escape(mailboxPath.getUser().getLocalPart()));
                 }
             }
             if (mailboxPath.getName() != null && !mailboxPath.getName().isEmpty()) {

From 740b77f86828d53b0ecb4be48a90321d92d2571f Mon Sep 17 00:00:00 2001
From: Jan-Eric Hellenberg <janeric.hellenberg@gmail.com>
Date: Fri, 3 Jan 2025 13:57:27 +0100
Subject: [PATCH 4/9] James-4099 Refactor MailboxPath tests to work with
 different path delimiters

---
 .../james/mailbox/model/MailboxPath.java      |  13 +-
 .../james/mailbox/model/MailboxPathTest.java  | 377 ++++++++++--------
 2 files changed, 217 insertions(+), 173 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
index 24abfdad667..1140b327e82 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
@@ -35,6 +35,7 @@
 import org.apache.james.mailbox.exception.MailboxNameException;
 import org.apache.james.mailbox.exception.TooLongMailboxNameException;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.CharMatcher;
 import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
@@ -51,7 +52,8 @@ public class MailboxPath {
     private static final Joiner PARTS_JOINER = Joiner.on(':');
     private static final LookupTranslator USERNAME_ESCAPER = new LookupTranslator(Map.of(":", "/;", "/", "//"));
     private static final LookupTranslator USERNAME_UNESCAPER = new LookupTranslator(Map.of("/;", ":", "//", "/"));
-    private static final boolean RELAX_MAILBOX_NAME_VALIDATION = Boolean.parseBoolean(System.getProperty("james.relaxed.mailbox.name.validation", "false"));
+    @VisibleForTesting
+    static boolean RELAX_MAILBOX_NAME_VALIDATION = Boolean.parseBoolean(System.getProperty("james.relaxed.mailbox.name.validation", "false"));
 
     /**
      * Return a {@link MailboxPath} which represent the INBOX of the given
@@ -95,15 +97,18 @@ private static Username getUsername(List<String> parts) {
         return Username.of(USERNAME_UNESCAPER.translate(parts.get(1)));
     }
 
-    private static String evaluateInvalidChars() {
+    @VisibleForTesting
+    static String evaluateInvalidChars() {
         if (RELAX_MAILBOX_NAME_VALIDATION) {
             return "\r\n";
         }
         return "%*\r\n";
     }
 
-    private static final String INVALID_CHARS = evaluateInvalidChars();
-    private static final CharMatcher INVALID_CHARS_MATCHER = CharMatcher.anyOf(INVALID_CHARS);
+    @VisibleForTesting
+    static String INVALID_CHARS = evaluateInvalidChars();
+    @VisibleForTesting
+    static CharMatcher INVALID_CHARS_MATCHER = CharMatcher.anyOf(INVALID_CHARS);
     // This is the size that all mailbox backend should support
     public  static final int MAX_MAILBOX_NAME_LENGTH = 200;
 
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java
index 676db676bea..cadac1abe2d 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java
@@ -30,384 +30,420 @@
 import org.apache.james.mailbox.exception.HasEmptyMailboxNameInHierarchyException;
 import org.apache.james.mailbox.exception.MailboxNameException;
 import org.apache.james.mailbox.exception.TooLongMailboxNameException;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
+import com.google.common.base.CharMatcher;
 import com.google.common.base.Strings;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
 
 class MailboxPathTest {
+    @Nested
+    public class DotDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return '.';
+        }
+    }
+
+    @Nested
+    public class SlashDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return '/';
+        }
+    }
+
+    abstract static class TestBase extends MailboxFolderDelimiterAwareTest {
     private static final Username USER = Username.of("user");
     private static final Username BUGGY_USER = Username.of("buggy:bob");
 
     @Test
     void shouldMatchBeanContract() {
         EqualsVerifier.forClass(MailboxPath.class)
-            .withNonnullFields("namespace")
-            .verify();
+                .withNonnullFields("namespace")
+                .verify();
     }
 
     static Stream<Arguments> parseShouldYieldCorrectResults() {
         return Stream.of(
-            Arguments.of(MailboxPath.forUser(USER, "test")),
-            Arguments.of(MailboxPath.forUser(USER, "a:b")),
-            Arguments.of(MailboxPath.forUser(USER, "a;b")),
-            Arguments.of(MailboxPath.forUser(USER, "a;;b")),
-            Arguments.of(MailboxPath.forUser(USER, "a:b:c:")),
-            Arguments.of(MailboxPath.forUser(USER, "a:b:c:")),
-            Arguments.of(MailboxPath.forUser(USER, ":")),
-            Arguments.of(MailboxPath.forUser(USER, ";")),
-            Arguments.of(MailboxPath.forUser(USER, "")),
-            Arguments.of(MailboxPath.inbox(USER)),
-            Arguments.of(MailboxPath.inbox(Username.of("a;b"))),
-            Arguments.of(MailboxPath.inbox(Username.of(";"))),
-            Arguments.of(MailboxPath.inbox(Username.of(":"))),
-            Arguments.of(MailboxPath.inbox(Username.of("a;;a"))),
-            Arguments.of(MailboxPath.inbox(Username.of("a:::;:::;:;;;a"))),
-            Arguments.of(MailboxPath.inbox(Username.of("a::a"))),
-            Arguments.of(MailboxPath.inbox(Username.of("a/a"))),
-            Arguments.of(MailboxPath.inbox(Username.of("a//a"))),
-            Arguments.of(MailboxPath.inbox(Username.of("a/:a"))),
-            Arguments.of(MailboxPath.inbox(Username.of("a/;a"))),
-            Arguments.of(MailboxPath.inbox(Username.of("a/:::;;/:://:;//:/a"))),
-            Arguments.of(MailboxPath.inbox(BUGGY_USER)),
-            Arguments.of(new MailboxPath("#whatever", USER, "whatever")),
-            Arguments.of(new MailboxPath(null, USER, "whatever")));
+                Arguments.of(MailboxPath.forUser(USER, "test")),
+                Arguments.of(MailboxPath.forUser(USER, "a:b")),
+                Arguments.of(MailboxPath.forUser(USER, "a;b")),
+                Arguments.of(MailboxPath.forUser(USER, "a;;b")),
+                Arguments.of(MailboxPath.forUser(USER, "a:b:c:")),
+                Arguments.of(MailboxPath.forUser(USER, "a:b:c:")),
+                Arguments.of(MailboxPath.forUser(USER, ":")),
+                Arguments.of(MailboxPath.forUser(USER, ";")),
+                Arguments.of(MailboxPath.forUser(USER, "")),
+                Arguments.of(MailboxPath.inbox(USER)),
+                Arguments.of(MailboxPath.inbox(Username.of("a;b"))),
+                Arguments.of(MailboxPath.inbox(Username.of(";"))),
+                Arguments.of(MailboxPath.inbox(Username.of(":"))),
+                Arguments.of(MailboxPath.inbox(Username.of("a;;a"))),
+                Arguments.of(MailboxPath.inbox(Username.of("a:::;:::;:;;;a"))),
+                Arguments.of(MailboxPath.inbox(Username.of("a::a"))),
+                Arguments.of(MailboxPath.inbox(Username.of("a/a"))),
+                Arguments.of(MailboxPath.inbox(Username.of("a//a"))),
+                Arguments.of(MailboxPath.inbox(Username.of("a/:a"))),
+                Arguments.of(MailboxPath.inbox(Username.of("a/;a"))),
+                Arguments.of(MailboxPath.inbox(Username.of("a/:::;;/:://:;//:/a"))),
+                Arguments.of(MailboxPath.inbox(BUGGY_USER)),
+                Arguments.of(new MailboxPath("#whatever", USER, "whatever")),
+                Arguments.of(new MailboxPath(null, USER, "whatever")));
     }
 
     @ParameterizedTest
     @MethodSource
     void parseShouldYieldCorrectResults(MailboxPath mailboxPath) {
         assertThat(MailboxPath.parseEscaped(mailboxPath.asEscapedString()))
-            .contains(mailboxPath);
+                .contains(mailboxPath);
     }
 
     @Test
     void asStringShouldFormatUser() {
-        assertThat(MailboxPath.forUser(USER, "inbox.folder.subfolder").asString())
-            .isEqualTo("#private:user:inbox.folder.subfolder");
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder")).asString())
+                .isEqualTo(adjustToActiveFolderDelimiter("#private:user:inbox.folder.subfolder"));
     }
 
     @Test
     void getNameShouldReturnSubfolder() {
-        assertThat(MailboxPath.forUser(USER, "inbox.folder.subfolder").getName('.'))
-            .isEqualTo("subfolder");
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder")).getName(folderDelimiter()))
+                .isEqualTo("subfolder");
     }
 
     @Test
     void getNameShouldNoopWhenNoDelimiter() {
-        assertThat(MailboxPath.forUser(USER, "name").getName('.'))
-            .isEqualTo("name");
+        assertThat(MailboxPath.forUser(USER, "name").getName(folderDelimiter()))
+                .isEqualTo("name");
     }
 
     @Test
     void getNameShouldNoopWhenEmpty() {
-        assertThat(MailboxPath.forUser(USER, "").getName('.'))
-            .isEqualTo("");
+        assertThat(MailboxPath.forUser(USER, "").getName(folderDelimiter()))
+                .isEqualTo("");
     }
 
     @Test
     void getNameShouldNoopWhenBlank() {
-        assertThat(MailboxPath.forUser(USER, "  ").getName('.'))
-            .isEqualTo("  ");
+        assertThat(MailboxPath.forUser(USER, "  ").getName(folderDelimiter()))
+                .isEqualTo("  ");
     }
 
     @Test
     void getHierarchyLevelsShouldBeOrdered() {
-        assertThat(MailboxPath.forUser(USER, "inbox.folder.subfolder")
-            .getHierarchyLevels('.'))
-            .containsExactly(
-                MailboxPath.forUser(USER, "inbox"),
-                MailboxPath.forUser(USER, "inbox.folder"),
-                MailboxPath.forUser(USER, "inbox.folder.subfolder"));
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder"))
+                .getHierarchyLevels(folderDelimiter()))
+                .containsExactly(
+                        MailboxPath.forUser(USER, "inbox"),
+                        MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder")),
+                        MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder")));
     }
 
     @Test
-    void childShouldConcatenateChildNameWithParentForlder() {
+    void childShouldConcatenateChildNameWithParentFolder() {
         assertThat(MailboxPath.forUser(USER, "folder")
-            .child("toto", '.'))
-            .isEqualTo(MailboxPath.forUser(USER, "folder.toto"));
+                .child("toto", folderDelimiter()))
+                .isEqualTo(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("folder.toto")));
     }
 
     @Test
     void childShouldThrowWhenNull() {
         MailboxPath path = MailboxPath.forUser(USER, "folder");
-        assertThatThrownBy(() -> path.child(null, '.'))
-            .isInstanceOf(IllegalArgumentException.class);
+        assertThatThrownBy(() -> path.child(null, folderDelimiter()))
+                .isInstanceOf(IllegalArgumentException.class);
     }
 
     @Test
     void childShouldThrowWhenEmpty() {
         MailboxPath path = MailboxPath.forUser(USER, "folder");
-        assertThatThrownBy(() -> path.child("", '.'))
-            .isInstanceOf(IllegalArgumentException.class);
+        assertThatThrownBy(() -> path.child("", folderDelimiter()))
+                .isInstanceOf(IllegalArgumentException.class);
     }
 
     @Test
     void shouldThrowWhenLineBreak() {
-        assertThatThrownBy(() -> MailboxPath.forUser(USER, "a\r\n [ALERT] that's bad").assertAcceptable('.'))
-            .isInstanceOf(MailboxNameException.class);
+        assertThatThrownBy(() -> MailboxPath.forUser(USER, "a\r\n [ALERT] that's bad").assertAcceptable(folderDelimiter()))
+                .isInstanceOf(MailboxNameException.class);
     }
 
     @Test
     void childShouldThrowWhenBlank() {
         MailboxPath path = MailboxPath.forUser(USER, "folder");
-        assertThatThrownBy(() -> path.child(" ", '.'))
-            .isInstanceOf(IllegalArgumentException.class);
+        assertThatThrownBy(() -> path.child(" ", folderDelimiter()))
+                .isInstanceOf(IllegalArgumentException.class);
     }
 
     @Test
     void childShouldThrowWhenContainsDelimiter() {
         MailboxPath path = MailboxPath.forUser(USER, "folder");
-        assertThatThrownBy(() -> path.child("a.b", '.'))
-            .isInstanceOf(IllegalArgumentException.class);
+        assertThatThrownBy(() -> path.child(adjustToActiveFolderDelimiter("a.b"), folderDelimiter()))
+                .isInstanceOf(IllegalArgumentException.class);
     }
 
     @Test
     void getHierarchyLevelsShouldReturnPathWhenOneLevel() {
         assertThat(MailboxPath.forUser(USER, "inbox")
-            .getHierarchyLevels('.'))
-            .containsExactly(
-                MailboxPath.forUser(USER, "inbox"));
+                .getHierarchyLevels(folderDelimiter()))
+                .containsExactly(
+                        MailboxPath.forUser(USER, "inbox"));
     }
 
     @Test
     void getHierarchyLevelsShouldReturnPathWhenEmptyName() {
         assertThat(MailboxPath.forUser(USER, "")
-            .getHierarchyLevels('.'))
-            .containsExactly(
-                MailboxPath.forUser(USER, ""));
+                .getHierarchyLevels(folderDelimiter()))
+                .containsExactly(
+                        MailboxPath.forUser(USER, ""));
     }
 
     @Test
     void getHierarchyLevelsShouldReturnPathWhenBlankName() {
         assertThat(MailboxPath.forUser(USER, "  ")
-            .getHierarchyLevels('.'))
-            .containsExactly(
-                MailboxPath.forUser(USER, "  "));
+                .getHierarchyLevels(folderDelimiter()))
+                .containsExactly(
+                        MailboxPath.forUser(USER, "  "));
     }
 
     @Test
     void getHierarchyLevelsShouldReturnPathWhenNullName() {
         assertThat(MailboxPath.forUser(USER, null)
-            .getHierarchyLevels('.'))
-            .containsExactly(
-                MailboxPath.forUser(USER, null));
+                .getHierarchyLevels(folderDelimiter()))
+                .containsExactly(
+                        MailboxPath.forUser(USER, null));
     }
 
     @Test
     void sanitizeShouldNotThrowOnNullMailboxName() {
         assertThat(MailboxPath.forUser(USER, null)
-            .sanitize('.'))
-            .isEqualTo(
-                MailboxPath.forUser(USER, null));
+                .sanitize(folderDelimiter()))
+                .isEqualTo(
+                        MailboxPath.forUser(USER, null));
     }
 
     @Test
     void sanitizeShouldReturnEmptyWhenEmpty() {
         assertThat(MailboxPath.forUser(USER, "")
-            .sanitize('.'))
-            .isEqualTo(
-                MailboxPath.forUser(USER, ""));
+                .sanitize(folderDelimiter()))
+                .isEqualTo(
+                        MailboxPath.forUser(USER, ""));
     }
 
     @Test
     void sanitizeShouldRemoveMaximumOneTrailingDelimiterWhenAlone() {
-        assertThat(MailboxPath.forUser(USER, ".")
-            .sanitize('.'))
-            .isEqualTo(
-                MailboxPath.forUser(USER, ""));
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("."))
+                .sanitize(folderDelimiter()))
+                .isEqualTo(
+                        MailboxPath.forUser(USER, ""));
     }
 
     @Test
     void sanitizeShouldPreserveHeadingDelimiter() {
-        assertThat(MailboxPath.forUser(USER, ".a")
-            .sanitize('.'))
-            .isEqualTo(
-                MailboxPath.forUser(USER, ".a"));
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter(".a"))
+                .sanitize(folderDelimiter()))
+                .isEqualTo(
+                        MailboxPath.forUser(USER, adjustToActiveFolderDelimiter(".a")));
     }
 
     @Test
     void sanitizeShouldRemoveTrailingDelimiter() {
-        assertThat(MailboxPath.forUser(USER, "a.")
-            .sanitize('.'))
-            .isEqualTo(
-                MailboxPath.forUser(USER, "a"));
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a."))
+                .sanitize(folderDelimiter()))
+                .isEqualTo(
+                        MailboxPath.forUser(USER, "a"));
     }
 
     @Test
     void sanitizeShouldRemoveMaximumOneTrailingDelimiter() {
-        assertThat(MailboxPath.forUser(USER, "a..")
-            .sanitize('.'))
-            .isEqualTo(
-                MailboxPath.forUser(USER, "a."));
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.."))
+                .sanitize(folderDelimiter()))
+                .isEqualTo(
+                        MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.")));
     }
 
     @Test
     void sanitizeShouldPreserveRedundantDelimiters() {
-        assertThat(MailboxPath.forUser(USER, "a..a")
-            .sanitize('.'))
-            .isEqualTo(
-                MailboxPath.forUser(USER, "a..a"));
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a..a"))
+                .sanitize(folderDelimiter()))
+                .isEqualTo(
+                        MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a..a")));
     }
 
     @Test
     void hasEmptyNameInHierarchyShouldBeFalseIfSingleLevelPath() {
         assertThat(MailboxPath.forUser(USER, "a")
-            .hasEmptyNameInHierarchy('.'))
-            .isFalse();
+                .hasEmptyNameInHierarchy(folderDelimiter()))
+                .isFalse();
     }
 
     @Test
     void hasEmptyNameInHierarchyShouldBeFalseIfNestedLevelWithNonEmptyNames() {
-        assertThat(MailboxPath.forUser(USER, "a.b.c")
-            .hasEmptyNameInHierarchy('.'))
-            .isFalse();
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.b.c"))
+                .hasEmptyNameInHierarchy(folderDelimiter()))
+                .isFalse();
     }
 
     @Test
     void hasEmptyNameInHierarchyShouldBeTrueIfEmptyPath() {
         assertThat(MailboxPath.forUser(USER, "")
-            .hasEmptyNameInHierarchy('.'))
-            .isTrue();
+                .hasEmptyNameInHierarchy(folderDelimiter()))
+                .isTrue();
     }
 
     @Test
     void hasEmptyNameInHierarchyShouldBeTrueIfBlankPath() {
         assertThat(MailboxPath.forUser(USER, " ")
-            .hasEmptyNameInHierarchy('.'))
-            .isTrue();
+                .hasEmptyNameInHierarchy(folderDelimiter()))
+                .isTrue();
     }
 
     @Test
     void hasEmptyNameInHierarchyShouldBeTrueIfPathWithTwoEmptyNames() {
-        assertThat(MailboxPath.forUser(USER, ".")
-            .hasEmptyNameInHierarchy('.'))
-            .isTrue();
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("."))
+                .hasEmptyNameInHierarchy(folderDelimiter()))
+                .isTrue();
     }
 
     @Test
     void hasEmptyNameInHierarchyShouldBeTrueIfPathWithAnEmptyNameBetweenTwoNames() {
-        assertThat(MailboxPath.forUser(USER, "a..b")
-            .hasEmptyNameInHierarchy('.'))
-            .isTrue();
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a..b"))
+                .hasEmptyNameInHierarchy(folderDelimiter()))
+                .isTrue();
     }
 
     @Test
     void hasEmptyNameInHierarchyShouldBeTrueIfPathWithABlankNameBetweenTwoNames() {
-        assertThat(MailboxPath.forUser(USER, "a.   .b")
-            .hasEmptyNameInHierarchy('.'))
-            .isTrue();
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.   .b"))
+                .hasEmptyNameInHierarchy(folderDelimiter()))
+                .isTrue();
     }
 
     @Test
     void hasEmptyNameInHierarchyShouldBeTrueIfPathWithHeadingEmptyNames() {
-        assertThat(MailboxPath.forUser(USER, "..a")
-            .hasEmptyNameInHierarchy('.'))
-            .isTrue();
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("..a"))
+                .hasEmptyNameInHierarchy(folderDelimiter()))
+                .isTrue();
     }
 
     @Test
     void hasEmptyNameInHierarchyShouldBeTrueIfPathWithHeadingBlankName() {
-        assertThat(MailboxPath.forUser(USER, "  .a")
-            .hasEmptyNameInHierarchy('.'))
-            .isTrue();
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("  .a"))
+                .hasEmptyNameInHierarchy(folderDelimiter()))
+                .isTrue();
     }
 
     @Test
     void hasEmptyNameInHierarchyShouldBeTrueIfPathWithATrailingEmptyName() {
-        assertThat(MailboxPath.forUser(USER, "a.")
-            .hasEmptyNameInHierarchy('.'))
-            .isTrue();
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a."))
+                .hasEmptyNameInHierarchy(folderDelimiter()))
+                .isTrue();
     }
 
     @Test
     void hasEmptyNameInHierarchyShouldBeTrueIfPathWithATrailingBlankName() {
-        assertThat(MailboxPath.forUser(USER, "a.  ")
-            .hasEmptyNameInHierarchy('.'))
-            .isTrue();
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.  "))
+                .hasEmptyNameInHierarchy(folderDelimiter()))
+                .isTrue();
     }
 
     @Test
     void hasEmptyNameInHierarchyShouldBeTrueIfPathWithTrailingEmptyNames() {
-        assertThat(MailboxPath.forUser(USER, "a..")
-            .hasEmptyNameInHierarchy('.'))
-            .isTrue();
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.."))
+                .hasEmptyNameInHierarchy(folderDelimiter()))
+                .isTrue();
     }
 
     @Test
     void hasEmptyNameInHierarchyShouldBeTrueIfPathWithTrailingBlankNames() {
-        assertThat(MailboxPath.forUser(USER, "a. .  ")
-            .hasEmptyNameInHierarchy('.'))
-            .isTrue();
+        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a. .  "))
+                .hasEmptyNameInHierarchy(folderDelimiter()))
+                .isTrue();
     }
 
     @Test
     void assertAcceptableShouldThrowOnDoubleSeparator() {
-        assertThatThrownBy(() -> MailboxPath.forUser(USER, "a..b")
-            .assertAcceptable('.'))
-            .isInstanceOf(HasEmptyMailboxNameInHierarchyException.class);
+        assertThatThrownBy(() -> MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a..b"))
+                .assertAcceptable(folderDelimiter()))
+                .isInstanceOf(HasEmptyMailboxNameInHierarchyException.class);
     }
 
     @Test
     void assertAcceptableShouldThrowWhenStartsWithSharp() {
         assertThatThrownBy(() -> MailboxPath.forUser(USER, "#ab")
-            .assertAcceptable('.'))
-            .isInstanceOf(MailboxNameException.class);
+                .assertAcceptable(folderDelimiter()))
+                .isInstanceOf(MailboxNameException.class);
     }
 
     @Test
     void assertAcceptableShouldNotThrowWhenSharpInTheMiddle() {
         assertThatCode(() -> MailboxPath.forUser(USER, "mailbox #17")
-            .assertAcceptable('.'))
-            .doesNotThrowAnyException();
+                .assertAcceptable(folderDelimiter()))
+                .doesNotThrowAnyException();
     }
 
     @Test
     void assertAcceptableShouldThrowOnPercent() {
         assertThatThrownBy(() -> MailboxPath.forUser(USER, "a%b")
-            .assertAcceptable('.'))
-            .isInstanceOf(MailboxNameException.class);
-    }
-
-    @Test
-    void assertAcceptableShouldNotThrowOnPercentWhenRelaxMode() {
-        System.setProperty("james.relaxed.mailbox.name.validation", "true");
-
-        assertThatCode(() -> MailboxPath.forUser(USER, "a%b"))
-            .doesNotThrowAnyException();
+                .assertAcceptable(folderDelimiter()))
+                .isInstanceOf(MailboxNameException.class);
     }
 
     @Test
     void assertAcceptableShouldThrowOnWildcard() {
         assertThatThrownBy(() -> MailboxPath.forUser(USER, "a*b")
-            .assertAcceptable('.'))
-            .isInstanceOf(MailboxNameException.class);
-    }
-
-    @Test
-    void assertAcceptableShouldNotThrowOnWildcardWhenRelaxMode() {
-        System.setProperty("james.relaxed.mailbox.name.validation", "true");
-
-        assertThatCode(() -> MailboxPath.forUser(USER, "a*b"))
-            .doesNotThrowAnyException();
+                .assertAcceptable(folderDelimiter()))
+                .isInstanceOf(MailboxNameException.class);
+    }
+
+    @Nested
+    class WithMailboxNameValidationRelaxed {
+        @BeforeEach
+        void setUp() {
+            MailboxPath.RELAX_MAILBOX_NAME_VALIDATION = true;
+            MailboxPath.INVALID_CHARS = MailboxPath.evaluateInvalidChars();
+            MailboxPath.INVALID_CHARS_MATCHER = CharMatcher.anyOf(MailboxPath.INVALID_CHARS);
+        }
+
+        @AfterEach
+        void tearDown() {
+            MailboxPath.RELAX_MAILBOX_NAME_VALIDATION = false;
+            MailboxPath.INVALID_CHARS = MailboxPath.evaluateInvalidChars();
+            MailboxPath.INVALID_CHARS_MATCHER = CharMatcher.anyOf(MailboxPath.INVALID_CHARS);
+        }
+
+        @Test
+        void assertAcceptableShouldNotThrowOnPercentWhenRelaxMode() {
+            assertThatCode(() -> MailboxPath.forUser(USER, "a%b")
+                    .assertAcceptable(folderDelimiter()))
+                    .doesNotThrowAnyException();
+        }
+
+        @Test
+        void assertAcceptableShouldNotThrowOnWildcardWhenRelaxMode() {
+            assertThatCode(() -> MailboxPath.forUser(USER, "a*b")
+                    .assertAcceptable(folderDelimiter()))
+                    .doesNotThrowAnyException();
+        }
     }
 
     @Test
     void assertAcceptableShouldThrowOnTooLongMailboxName() {
         assertThatThrownBy(() -> MailboxPath.forUser(USER, Strings.repeat("a", 201))
-            .assertAcceptable('.'))
-            .isInstanceOf(TooLongMailboxNameException.class);
+                .assertAcceptable(folderDelimiter()))
+                .isInstanceOf(TooLongMailboxNameException.class);
     }
 
     @Test
     void assertAcceptableShouldNotThrowOnNotTooLongMailboxName() {
         assertThatCode(() -> MailboxPath.forUser(USER, Strings.repeat("a", 200))
-            .assertAcceptable('.'))
-            .doesNotThrowAnyException();
+                .assertAcceptable(folderDelimiter()))
+                .doesNotThrowAnyException();
     }
 
     @Test
@@ -430,27 +466,30 @@ void isInboxShouldReturnFalseWhenOtherThanInbox() {
 
     @Test
     void hasParentShouldReturnTrueWhenMailboxHasParent() {
-        MailboxPath mailboxPath = MailboxPath.forUser(USER, "inbox.folder.subfolder");
-        assertThat(mailboxPath.hasParent('.')).isTrue();
+        MailboxPath mailboxPath = MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder"));
+        assertThat(mailboxPath.hasParent(folderDelimiter())).isTrue();
     }
 
     @Test
     void hasParentShouldReturnFalseWhenNoParent() {
         MailboxPath mailboxPath = MailboxPath.forUser(USER, "inbox");
-        assertThat(mailboxPath.hasParent('.')).isFalse();
+        assertThat(mailboxPath.hasParent(folderDelimiter())).isFalse();
     }
 
     @Test
     void getParentShouldReturnParents() {
-        MailboxPath mailboxPath = MailboxPath.forUser(USER, "inbox.folder.subfolder");
-        assertThat(mailboxPath.getParents('.'))
-            .containsExactly(MailboxPath.forUser(USER, "inbox"), MailboxPath.forUser(USER, "inbox.folder"));
+        MailboxPath mailboxPath = MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder"));
+        assertThat(mailboxPath.getParents(folderDelimiter()))
+                .containsExactly(
+                        MailboxPath.forUser(USER, "inbox"),
+                        MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder")));
     }
 
     @Test
     void getParentShouldReturnEmptyWhenTopLevelMailbox() {
         MailboxPath mailboxPath = MailboxPath.forUser(USER, "inbox");
-        assertThat(mailboxPath.getParents('.'))
-            .isEmpty();
+        assertThat(mailboxPath.getParents(folderDelimiter()))
+                .isEmpty();
+    }
     }
 }

From 1d357e17c49650d9c3728c94c8e10140799c3986 Mon Sep 17 00:00:00 2001
From: Jan-Eric Hellenberg <janeric.hellenberg@gmail.com>
Date: Fri, 3 Jan 2025 14:56:22 +0100
Subject: [PATCH 5/9] James-4099 Properly indent MailboxPath tests

---
 .../james/mailbox/model/MailboxPathTest.java  | 734 +++++++++---------
 1 file changed, 367 insertions(+), 367 deletions(-)

diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java
index cadac1abe2d..25426515435 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java
@@ -61,435 +61,435 @@ public char folderDelimiter() {
     }
 
     abstract static class TestBase extends MailboxFolderDelimiterAwareTest {
-    private static final Username USER = Username.of("user");
-    private static final Username BUGGY_USER = Username.of("buggy:bob");
-
-    @Test
-    void shouldMatchBeanContract() {
-        EqualsVerifier.forClass(MailboxPath.class)
-                .withNonnullFields("namespace")
-                .verify();
-    }
+        private static final Username USER = Username.of("user");
+        private static final Username BUGGY_USER = Username.of("buggy:bob");
 
-    static Stream<Arguments> parseShouldYieldCorrectResults() {
-        return Stream.of(
-                Arguments.of(MailboxPath.forUser(USER, "test")),
-                Arguments.of(MailboxPath.forUser(USER, "a:b")),
-                Arguments.of(MailboxPath.forUser(USER, "a;b")),
-                Arguments.of(MailboxPath.forUser(USER, "a;;b")),
-                Arguments.of(MailboxPath.forUser(USER, "a:b:c:")),
-                Arguments.of(MailboxPath.forUser(USER, "a:b:c:")),
-                Arguments.of(MailboxPath.forUser(USER, ":")),
-                Arguments.of(MailboxPath.forUser(USER, ";")),
-                Arguments.of(MailboxPath.forUser(USER, "")),
-                Arguments.of(MailboxPath.inbox(USER)),
-                Arguments.of(MailboxPath.inbox(Username.of("a;b"))),
-                Arguments.of(MailboxPath.inbox(Username.of(";"))),
-                Arguments.of(MailboxPath.inbox(Username.of(":"))),
-                Arguments.of(MailboxPath.inbox(Username.of("a;;a"))),
-                Arguments.of(MailboxPath.inbox(Username.of("a:::;:::;:;;;a"))),
-                Arguments.of(MailboxPath.inbox(Username.of("a::a"))),
-                Arguments.of(MailboxPath.inbox(Username.of("a/a"))),
-                Arguments.of(MailboxPath.inbox(Username.of("a//a"))),
-                Arguments.of(MailboxPath.inbox(Username.of("a/:a"))),
-                Arguments.of(MailboxPath.inbox(Username.of("a/;a"))),
-                Arguments.of(MailboxPath.inbox(Username.of("a/:::;;/:://:;//:/a"))),
-                Arguments.of(MailboxPath.inbox(BUGGY_USER)),
-                Arguments.of(new MailboxPath("#whatever", USER, "whatever")),
-                Arguments.of(new MailboxPath(null, USER, "whatever")));
-    }
+        @Test
+        void shouldMatchBeanContract() {
+            EqualsVerifier.forClass(MailboxPath.class)
+                    .withNonnullFields("namespace")
+                    .verify();
+        }
 
-    @ParameterizedTest
-    @MethodSource
-    void parseShouldYieldCorrectResults(MailboxPath mailboxPath) {
-        assertThat(MailboxPath.parseEscaped(mailboxPath.asEscapedString()))
-                .contains(mailboxPath);
-    }
+        static Stream<Arguments> parseShouldYieldCorrectResults() {
+            return Stream.of(
+                    Arguments.of(MailboxPath.forUser(USER, "test")),
+                    Arguments.of(MailboxPath.forUser(USER, "a:b")),
+                    Arguments.of(MailboxPath.forUser(USER, "a;b")),
+                    Arguments.of(MailboxPath.forUser(USER, "a;;b")),
+                    Arguments.of(MailboxPath.forUser(USER, "a:b:c:")),
+                    Arguments.of(MailboxPath.forUser(USER, "a:b:c:")),
+                    Arguments.of(MailboxPath.forUser(USER, ":")),
+                    Arguments.of(MailboxPath.forUser(USER, ";")),
+                    Arguments.of(MailboxPath.forUser(USER, "")),
+                    Arguments.of(MailboxPath.inbox(USER)),
+                    Arguments.of(MailboxPath.inbox(Username.of("a;b"))),
+                    Arguments.of(MailboxPath.inbox(Username.of(";"))),
+                    Arguments.of(MailboxPath.inbox(Username.of(":"))),
+                    Arguments.of(MailboxPath.inbox(Username.of("a;;a"))),
+                    Arguments.of(MailboxPath.inbox(Username.of("a:::;:::;:;;;a"))),
+                    Arguments.of(MailboxPath.inbox(Username.of("a::a"))),
+                    Arguments.of(MailboxPath.inbox(Username.of("a/a"))),
+                    Arguments.of(MailboxPath.inbox(Username.of("a//a"))),
+                    Arguments.of(MailboxPath.inbox(Username.of("a/:a"))),
+                    Arguments.of(MailboxPath.inbox(Username.of("a/;a"))),
+                    Arguments.of(MailboxPath.inbox(Username.of("a/:::;;/:://:;//:/a"))),
+                    Arguments.of(MailboxPath.inbox(BUGGY_USER)),
+                    Arguments.of(new MailboxPath("#whatever", USER, "whatever")),
+                    Arguments.of(new MailboxPath(null, USER, "whatever")));
+        }
 
-    @Test
-    void asStringShouldFormatUser() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder")).asString())
-                .isEqualTo(adjustToActiveFolderDelimiter("#private:user:inbox.folder.subfolder"));
-    }
+        @ParameterizedTest
+        @MethodSource
+        void parseShouldYieldCorrectResults(MailboxPath mailboxPath) {
+            assertThat(MailboxPath.parseEscaped(mailboxPath.asEscapedString()))
+                    .contains(mailboxPath);
+        }
 
-    @Test
-    void getNameShouldReturnSubfolder() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder")).getName(folderDelimiter()))
-                .isEqualTo("subfolder");
-    }
+        @Test
+        void asStringShouldFormatUser() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder")).asString())
+                    .isEqualTo(adjustToActiveFolderDelimiter("#private:user:inbox.folder.subfolder"));
+        }
 
-    @Test
-    void getNameShouldNoopWhenNoDelimiter() {
-        assertThat(MailboxPath.forUser(USER, "name").getName(folderDelimiter()))
-                .isEqualTo("name");
-    }
+        @Test
+        void getNameShouldReturnSubfolder() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder")).getName(folderDelimiter()))
+                    .isEqualTo("subfolder");
+        }
 
-    @Test
-    void getNameShouldNoopWhenEmpty() {
-        assertThat(MailboxPath.forUser(USER, "").getName(folderDelimiter()))
-                .isEqualTo("");
-    }
+        @Test
+        void getNameShouldNoopWhenNoDelimiter() {
+            assertThat(MailboxPath.forUser(USER, "name").getName(folderDelimiter()))
+                    .isEqualTo("name");
+        }
 
-    @Test
-    void getNameShouldNoopWhenBlank() {
-        assertThat(MailboxPath.forUser(USER, "  ").getName(folderDelimiter()))
-                .isEqualTo("  ");
-    }
+        @Test
+        void getNameShouldNoopWhenEmpty() {
+            assertThat(MailboxPath.forUser(USER, "").getName(folderDelimiter()))
+                    .isEqualTo("");
+        }
 
-    @Test
-    void getHierarchyLevelsShouldBeOrdered() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder"))
-                .getHierarchyLevels(folderDelimiter()))
-                .containsExactly(
-                        MailboxPath.forUser(USER, "inbox"),
-                        MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder")),
-                        MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder")));
-    }
+        @Test
+        void getNameShouldNoopWhenBlank() {
+            assertThat(MailboxPath.forUser(USER, "  ").getName(folderDelimiter()))
+                    .isEqualTo("  ");
+        }
 
-    @Test
-    void childShouldConcatenateChildNameWithParentFolder() {
-        assertThat(MailboxPath.forUser(USER, "folder")
-                .child("toto", folderDelimiter()))
-                .isEqualTo(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("folder.toto")));
-    }
+        @Test
+        void getHierarchyLevelsShouldBeOrdered() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder"))
+                    .getHierarchyLevels(folderDelimiter()))
+                    .containsExactly(
+                            MailboxPath.forUser(USER, "inbox"),
+                            MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder")),
+                            MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder")));
+        }
 
-    @Test
-    void childShouldThrowWhenNull() {
-        MailboxPath path = MailboxPath.forUser(USER, "folder");
-        assertThatThrownBy(() -> path.child(null, folderDelimiter()))
-                .isInstanceOf(IllegalArgumentException.class);
-    }
+        @Test
+        void childShouldConcatenateChildNameWithParentFolder() {
+            assertThat(MailboxPath.forUser(USER, "folder")
+                    .child("toto", folderDelimiter()))
+                    .isEqualTo(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("folder.toto")));
+        }
 
-    @Test
-    void childShouldThrowWhenEmpty() {
-        MailboxPath path = MailboxPath.forUser(USER, "folder");
-        assertThatThrownBy(() -> path.child("", folderDelimiter()))
-                .isInstanceOf(IllegalArgumentException.class);
-    }
+        @Test
+        void childShouldThrowWhenNull() {
+            MailboxPath path = MailboxPath.forUser(USER, "folder");
+            assertThatThrownBy(() -> path.child(null, folderDelimiter()))
+                    .isInstanceOf(IllegalArgumentException.class);
+        }
 
-    @Test
-    void shouldThrowWhenLineBreak() {
-        assertThatThrownBy(() -> MailboxPath.forUser(USER, "a\r\n [ALERT] that's bad").assertAcceptable(folderDelimiter()))
-                .isInstanceOf(MailboxNameException.class);
-    }
+        @Test
+        void childShouldThrowWhenEmpty() {
+            MailboxPath path = MailboxPath.forUser(USER, "folder");
+            assertThatThrownBy(() -> path.child("", folderDelimiter()))
+                    .isInstanceOf(IllegalArgumentException.class);
+        }
 
-    @Test
-    void childShouldThrowWhenBlank() {
-        MailboxPath path = MailboxPath.forUser(USER, "folder");
-        assertThatThrownBy(() -> path.child(" ", folderDelimiter()))
-                .isInstanceOf(IllegalArgumentException.class);
-    }
+        @Test
+        void shouldThrowWhenLineBreak() {
+            assertThatThrownBy(() -> MailboxPath.forUser(USER, "a\r\n [ALERT] that's bad").assertAcceptable(folderDelimiter()))
+                    .isInstanceOf(MailboxNameException.class);
+        }
 
-    @Test
-    void childShouldThrowWhenContainsDelimiter() {
-        MailboxPath path = MailboxPath.forUser(USER, "folder");
-        assertThatThrownBy(() -> path.child(adjustToActiveFolderDelimiter("a.b"), folderDelimiter()))
-                .isInstanceOf(IllegalArgumentException.class);
-    }
+        @Test
+        void childShouldThrowWhenBlank() {
+            MailboxPath path = MailboxPath.forUser(USER, "folder");
+            assertThatThrownBy(() -> path.child(" ", folderDelimiter()))
+                    .isInstanceOf(IllegalArgumentException.class);
+        }
 
-    @Test
-    void getHierarchyLevelsShouldReturnPathWhenOneLevel() {
-        assertThat(MailboxPath.forUser(USER, "inbox")
-                .getHierarchyLevels(folderDelimiter()))
-                .containsExactly(
-                        MailboxPath.forUser(USER, "inbox"));
-    }
+        @Test
+        void childShouldThrowWhenContainsDelimiter() {
+            MailboxPath path = MailboxPath.forUser(USER, "folder");
+            assertThatThrownBy(() -> path.child(adjustToActiveFolderDelimiter("a.b"), folderDelimiter()))
+                    .isInstanceOf(IllegalArgumentException.class);
+        }
 
-    @Test
-    void getHierarchyLevelsShouldReturnPathWhenEmptyName() {
-        assertThat(MailboxPath.forUser(USER, "")
-                .getHierarchyLevels(folderDelimiter()))
-                .containsExactly(
-                        MailboxPath.forUser(USER, ""));
-    }
+        @Test
+        void getHierarchyLevelsShouldReturnPathWhenOneLevel() {
+            assertThat(MailboxPath.forUser(USER, "inbox")
+                    .getHierarchyLevels(folderDelimiter()))
+                    .containsExactly(
+                            MailboxPath.forUser(USER, "inbox"));
+        }
 
-    @Test
-    void getHierarchyLevelsShouldReturnPathWhenBlankName() {
-        assertThat(MailboxPath.forUser(USER, "  ")
-                .getHierarchyLevels(folderDelimiter()))
-                .containsExactly(
-                        MailboxPath.forUser(USER, "  "));
-    }
+        @Test
+        void getHierarchyLevelsShouldReturnPathWhenEmptyName() {
+            assertThat(MailboxPath.forUser(USER, "")
+                    .getHierarchyLevels(folderDelimiter()))
+                    .containsExactly(
+                            MailboxPath.forUser(USER, ""));
+        }
 
-    @Test
-    void getHierarchyLevelsShouldReturnPathWhenNullName() {
-        assertThat(MailboxPath.forUser(USER, null)
-                .getHierarchyLevels(folderDelimiter()))
-                .containsExactly(
-                        MailboxPath.forUser(USER, null));
-    }
+        @Test
+        void getHierarchyLevelsShouldReturnPathWhenBlankName() {
+            assertThat(MailboxPath.forUser(USER, "  ")
+                    .getHierarchyLevels(folderDelimiter()))
+                    .containsExactly(
+                            MailboxPath.forUser(USER, "  "));
+        }
 
-    @Test
-    void sanitizeShouldNotThrowOnNullMailboxName() {
-        assertThat(MailboxPath.forUser(USER, null)
-                .sanitize(folderDelimiter()))
-                .isEqualTo(
-                        MailboxPath.forUser(USER, null));
-    }
+        @Test
+        void getHierarchyLevelsShouldReturnPathWhenNullName() {
+            assertThat(MailboxPath.forUser(USER, null)
+                    .getHierarchyLevels(folderDelimiter()))
+                    .containsExactly(
+                            MailboxPath.forUser(USER, null));
+        }
 
-    @Test
-    void sanitizeShouldReturnEmptyWhenEmpty() {
-        assertThat(MailboxPath.forUser(USER, "")
-                .sanitize(folderDelimiter()))
-                .isEqualTo(
-                        MailboxPath.forUser(USER, ""));
-    }
+        @Test
+        void sanitizeShouldNotThrowOnNullMailboxName() {
+            assertThat(MailboxPath.forUser(USER, null)
+                    .sanitize(folderDelimiter()))
+                    .isEqualTo(
+                            MailboxPath.forUser(USER, null));
+        }
 
-    @Test
-    void sanitizeShouldRemoveMaximumOneTrailingDelimiterWhenAlone() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("."))
-                .sanitize(folderDelimiter()))
-                .isEqualTo(
-                        MailboxPath.forUser(USER, ""));
-    }
+        @Test
+        void sanitizeShouldReturnEmptyWhenEmpty() {
+            assertThat(MailboxPath.forUser(USER, "")
+                    .sanitize(folderDelimiter()))
+                    .isEqualTo(
+                            MailboxPath.forUser(USER, ""));
+        }
 
-    @Test
-    void sanitizeShouldPreserveHeadingDelimiter() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter(".a"))
-                .sanitize(folderDelimiter()))
-                .isEqualTo(
-                        MailboxPath.forUser(USER, adjustToActiveFolderDelimiter(".a")));
-    }
+        @Test
+        void sanitizeShouldRemoveMaximumOneTrailingDelimiterWhenAlone() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("."))
+                    .sanitize(folderDelimiter()))
+                    .isEqualTo(
+                            MailboxPath.forUser(USER, ""));
+        }
 
-    @Test
-    void sanitizeShouldRemoveTrailingDelimiter() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a."))
-                .sanitize(folderDelimiter()))
-                .isEqualTo(
-                        MailboxPath.forUser(USER, "a"));
-    }
+        @Test
+        void sanitizeShouldPreserveHeadingDelimiter() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter(".a"))
+                    .sanitize(folderDelimiter()))
+                    .isEqualTo(
+                            MailboxPath.forUser(USER, adjustToActiveFolderDelimiter(".a")));
+        }
 
-    @Test
-    void sanitizeShouldRemoveMaximumOneTrailingDelimiter() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.."))
-                .sanitize(folderDelimiter()))
-                .isEqualTo(
-                        MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.")));
-    }
+        @Test
+        void sanitizeShouldRemoveTrailingDelimiter() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a."))
+                    .sanitize(folderDelimiter()))
+                    .isEqualTo(
+                            MailboxPath.forUser(USER, "a"));
+        }
 
-    @Test
-    void sanitizeShouldPreserveRedundantDelimiters() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a..a"))
-                .sanitize(folderDelimiter()))
-                .isEqualTo(
-                        MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a..a")));
-    }
+        @Test
+        void sanitizeShouldRemoveMaximumOneTrailingDelimiter() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.."))
+                    .sanitize(folderDelimiter()))
+                    .isEqualTo(
+                            MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.")));
+        }
 
-    @Test
-    void hasEmptyNameInHierarchyShouldBeFalseIfSingleLevelPath() {
-        assertThat(MailboxPath.forUser(USER, "a")
-                .hasEmptyNameInHierarchy(folderDelimiter()))
-                .isFalse();
-    }
+        @Test
+        void sanitizeShouldPreserveRedundantDelimiters() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a..a"))
+                    .sanitize(folderDelimiter()))
+                    .isEqualTo(
+                            MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a..a")));
+        }
 
-    @Test
-    void hasEmptyNameInHierarchyShouldBeFalseIfNestedLevelWithNonEmptyNames() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.b.c"))
-                .hasEmptyNameInHierarchy(folderDelimiter()))
-                .isFalse();
-    }
+        @Test
+        void hasEmptyNameInHierarchyShouldBeFalseIfSingleLevelPath() {
+            assertThat(MailboxPath.forUser(USER, "a")
+                    .hasEmptyNameInHierarchy(folderDelimiter()))
+                    .isFalse();
+        }
 
-    @Test
-    void hasEmptyNameInHierarchyShouldBeTrueIfEmptyPath() {
-        assertThat(MailboxPath.forUser(USER, "")
-                .hasEmptyNameInHierarchy(folderDelimiter()))
-                .isTrue();
-    }
+        @Test
+        void hasEmptyNameInHierarchyShouldBeFalseIfNestedLevelWithNonEmptyNames() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.b.c"))
+                    .hasEmptyNameInHierarchy(folderDelimiter()))
+                    .isFalse();
+        }
 
-    @Test
-    void hasEmptyNameInHierarchyShouldBeTrueIfBlankPath() {
-        assertThat(MailboxPath.forUser(USER, " ")
-                .hasEmptyNameInHierarchy(folderDelimiter()))
-                .isTrue();
-    }
+        @Test
+        void hasEmptyNameInHierarchyShouldBeTrueIfEmptyPath() {
+            assertThat(MailboxPath.forUser(USER, "")
+                    .hasEmptyNameInHierarchy(folderDelimiter()))
+                    .isTrue();
+        }
 
-    @Test
-    void hasEmptyNameInHierarchyShouldBeTrueIfPathWithTwoEmptyNames() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("."))
-                .hasEmptyNameInHierarchy(folderDelimiter()))
-                .isTrue();
-    }
+        @Test
+        void hasEmptyNameInHierarchyShouldBeTrueIfBlankPath() {
+            assertThat(MailboxPath.forUser(USER, " ")
+                    .hasEmptyNameInHierarchy(folderDelimiter()))
+                    .isTrue();
+        }
 
-    @Test
-    void hasEmptyNameInHierarchyShouldBeTrueIfPathWithAnEmptyNameBetweenTwoNames() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a..b"))
-                .hasEmptyNameInHierarchy(folderDelimiter()))
-                .isTrue();
-    }
+        @Test
+        void hasEmptyNameInHierarchyShouldBeTrueIfPathWithTwoEmptyNames() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("."))
+                    .hasEmptyNameInHierarchy(folderDelimiter()))
+                    .isTrue();
+        }
 
-    @Test
-    void hasEmptyNameInHierarchyShouldBeTrueIfPathWithABlankNameBetweenTwoNames() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.   .b"))
-                .hasEmptyNameInHierarchy(folderDelimiter()))
-                .isTrue();
-    }
+        @Test
+        void hasEmptyNameInHierarchyShouldBeTrueIfPathWithAnEmptyNameBetweenTwoNames() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a..b"))
+                    .hasEmptyNameInHierarchy(folderDelimiter()))
+                    .isTrue();
+        }
 
-    @Test
-    void hasEmptyNameInHierarchyShouldBeTrueIfPathWithHeadingEmptyNames() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("..a"))
-                .hasEmptyNameInHierarchy(folderDelimiter()))
-                .isTrue();
-    }
+        @Test
+        void hasEmptyNameInHierarchyShouldBeTrueIfPathWithABlankNameBetweenTwoNames() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.   .b"))
+                    .hasEmptyNameInHierarchy(folderDelimiter()))
+                    .isTrue();
+        }
 
-    @Test
-    void hasEmptyNameInHierarchyShouldBeTrueIfPathWithHeadingBlankName() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("  .a"))
-                .hasEmptyNameInHierarchy(folderDelimiter()))
-                .isTrue();
-    }
+        @Test
+        void hasEmptyNameInHierarchyShouldBeTrueIfPathWithHeadingEmptyNames() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("..a"))
+                    .hasEmptyNameInHierarchy(folderDelimiter()))
+                    .isTrue();
+        }
 
-    @Test
-    void hasEmptyNameInHierarchyShouldBeTrueIfPathWithATrailingEmptyName() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a."))
-                .hasEmptyNameInHierarchy(folderDelimiter()))
-                .isTrue();
-    }
+        @Test
+        void hasEmptyNameInHierarchyShouldBeTrueIfPathWithHeadingBlankName() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("  .a"))
+                    .hasEmptyNameInHierarchy(folderDelimiter()))
+                    .isTrue();
+        }
 
-    @Test
-    void hasEmptyNameInHierarchyShouldBeTrueIfPathWithATrailingBlankName() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.  "))
-                .hasEmptyNameInHierarchy(folderDelimiter()))
-                .isTrue();
-    }
+        @Test
+        void hasEmptyNameInHierarchyShouldBeTrueIfPathWithATrailingEmptyName() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a."))
+                    .hasEmptyNameInHierarchy(folderDelimiter()))
+                    .isTrue();
+        }
 
-    @Test
-    void hasEmptyNameInHierarchyShouldBeTrueIfPathWithTrailingEmptyNames() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.."))
-                .hasEmptyNameInHierarchy(folderDelimiter()))
-                .isTrue();
-    }
+        @Test
+        void hasEmptyNameInHierarchyShouldBeTrueIfPathWithATrailingBlankName() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.  "))
+                    .hasEmptyNameInHierarchy(folderDelimiter()))
+                    .isTrue();
+        }
 
-    @Test
-    void hasEmptyNameInHierarchyShouldBeTrueIfPathWithTrailingBlankNames() {
-        assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a. .  "))
-                .hasEmptyNameInHierarchy(folderDelimiter()))
-                .isTrue();
-    }
+        @Test
+        void hasEmptyNameInHierarchyShouldBeTrueIfPathWithTrailingEmptyNames() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a.."))
+                    .hasEmptyNameInHierarchy(folderDelimiter()))
+                    .isTrue();
+        }
 
-    @Test
-    void assertAcceptableShouldThrowOnDoubleSeparator() {
-        assertThatThrownBy(() -> MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a..b"))
-                .assertAcceptable(folderDelimiter()))
-                .isInstanceOf(HasEmptyMailboxNameInHierarchyException.class);
-    }
+        @Test
+        void hasEmptyNameInHierarchyShouldBeTrueIfPathWithTrailingBlankNames() {
+            assertThat(MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a. .  "))
+                    .hasEmptyNameInHierarchy(folderDelimiter()))
+                    .isTrue();
+        }
 
-    @Test
-    void assertAcceptableShouldThrowWhenStartsWithSharp() {
-        assertThatThrownBy(() -> MailboxPath.forUser(USER, "#ab")
-                .assertAcceptable(folderDelimiter()))
-                .isInstanceOf(MailboxNameException.class);
-    }
+        @Test
+        void assertAcceptableShouldThrowOnDoubleSeparator() {
+            assertThatThrownBy(() -> MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("a..b"))
+                    .assertAcceptable(folderDelimiter()))
+                    .isInstanceOf(HasEmptyMailboxNameInHierarchyException.class);
+        }
 
-    @Test
-    void assertAcceptableShouldNotThrowWhenSharpInTheMiddle() {
-        assertThatCode(() -> MailboxPath.forUser(USER, "mailbox #17")
-                .assertAcceptable(folderDelimiter()))
-                .doesNotThrowAnyException();
-    }
+        @Test
+        void assertAcceptableShouldThrowWhenStartsWithSharp() {
+            assertThatThrownBy(() -> MailboxPath.forUser(USER, "#ab")
+                    .assertAcceptable(folderDelimiter()))
+                    .isInstanceOf(MailboxNameException.class);
+        }
 
-    @Test
-    void assertAcceptableShouldThrowOnPercent() {
-        assertThatThrownBy(() -> MailboxPath.forUser(USER, "a%b")
-                .assertAcceptable(folderDelimiter()))
-                .isInstanceOf(MailboxNameException.class);
-    }
+        @Test
+        void assertAcceptableShouldNotThrowWhenSharpInTheMiddle() {
+            assertThatCode(() -> MailboxPath.forUser(USER, "mailbox #17")
+                    .assertAcceptable(folderDelimiter()))
+                    .doesNotThrowAnyException();
+        }
 
-    @Test
-    void assertAcceptableShouldThrowOnWildcard() {
-        assertThatThrownBy(() -> MailboxPath.forUser(USER, "a*b")
-                .assertAcceptable(folderDelimiter()))
-                .isInstanceOf(MailboxNameException.class);
-    }
+        @Test
+        void assertAcceptableShouldThrowOnPercent() {
+            assertThatThrownBy(() -> MailboxPath.forUser(USER, "a%b")
+                    .assertAcceptable(folderDelimiter()))
+                    .isInstanceOf(MailboxNameException.class);
+        }
 
-    @Nested
-    class WithMailboxNameValidationRelaxed {
-        @BeforeEach
-        void setUp() {
-            MailboxPath.RELAX_MAILBOX_NAME_VALIDATION = true;
-            MailboxPath.INVALID_CHARS = MailboxPath.evaluateInvalidChars();
-            MailboxPath.INVALID_CHARS_MATCHER = CharMatcher.anyOf(MailboxPath.INVALID_CHARS);
+        @Test
+        void assertAcceptableShouldThrowOnWildcard() {
+            assertThatThrownBy(() -> MailboxPath.forUser(USER, "a*b")
+                    .assertAcceptable(folderDelimiter()))
+                    .isInstanceOf(MailboxNameException.class);
         }
 
-        @AfterEach
-        void tearDown() {
-            MailboxPath.RELAX_MAILBOX_NAME_VALIDATION = false;
-            MailboxPath.INVALID_CHARS = MailboxPath.evaluateInvalidChars();
-            MailboxPath.INVALID_CHARS_MATCHER = CharMatcher.anyOf(MailboxPath.INVALID_CHARS);
+        @Nested
+        class WithMailboxNameValidationRelaxed {
+            @BeforeEach
+            void setUp() {
+                MailboxPath.RELAX_MAILBOX_NAME_VALIDATION = true;
+                MailboxPath.INVALID_CHARS = MailboxPath.evaluateInvalidChars();
+                MailboxPath.INVALID_CHARS_MATCHER = CharMatcher.anyOf(MailboxPath.INVALID_CHARS);
+            }
+
+            @AfterEach
+            void tearDown() {
+                MailboxPath.RELAX_MAILBOX_NAME_VALIDATION = false;
+                MailboxPath.INVALID_CHARS = MailboxPath.evaluateInvalidChars();
+                MailboxPath.INVALID_CHARS_MATCHER = CharMatcher.anyOf(MailboxPath.INVALID_CHARS);
+            }
+
+            @Test
+            void assertAcceptableShouldNotThrowOnPercentWhenRelaxMode() {
+                assertThatCode(() -> MailboxPath.forUser(USER, "a%b")
+                        .assertAcceptable(folderDelimiter()))
+                        .doesNotThrowAnyException();
+            }
+
+            @Test
+            void assertAcceptableShouldNotThrowOnWildcardWhenRelaxMode() {
+                assertThatCode(() -> MailboxPath.forUser(USER, "a*b")
+                        .assertAcceptable(folderDelimiter()))
+                        .doesNotThrowAnyException();
+            }
         }
 
         @Test
-        void assertAcceptableShouldNotThrowOnPercentWhenRelaxMode() {
-            assertThatCode(() -> MailboxPath.forUser(USER, "a%b")
+        void assertAcceptableShouldThrowOnTooLongMailboxName() {
+            assertThatThrownBy(() -> MailboxPath.forUser(USER, Strings.repeat("a", 201))
                     .assertAcceptable(folderDelimiter()))
-                    .doesNotThrowAnyException();
+                    .isInstanceOf(TooLongMailboxNameException.class);
         }
 
         @Test
-        void assertAcceptableShouldNotThrowOnWildcardWhenRelaxMode() {
-            assertThatCode(() -> MailboxPath.forUser(USER, "a*b")
+        void assertAcceptableShouldNotThrowOnNotTooLongMailboxName() {
+            assertThatCode(() -> MailboxPath.forUser(USER, Strings.repeat("a", 200))
                     .assertAcceptable(folderDelimiter()))
                     .doesNotThrowAnyException();
         }
-    }
 
-    @Test
-    void assertAcceptableShouldThrowOnTooLongMailboxName() {
-        assertThatThrownBy(() -> MailboxPath.forUser(USER, Strings.repeat("a", 201))
-                .assertAcceptable(folderDelimiter()))
-                .isInstanceOf(TooLongMailboxNameException.class);
-    }
-
-    @Test
-    void assertAcceptableShouldNotThrowOnNotTooLongMailboxName() {
-        assertThatCode(() -> MailboxPath.forUser(USER, Strings.repeat("a", 200))
-                .assertAcceptable(folderDelimiter()))
-                .doesNotThrowAnyException();
-    }
-
-    @Test
-    void isInboxShouldReturnTrueWhenINBOX() {
-        MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, USER, DefaultMailboxes.INBOX);
-        assertThat(mailboxPath.isInbox()).isTrue();
-    }
+        @Test
+        void isInboxShouldReturnTrueWhenINBOX() {
+            MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, USER, DefaultMailboxes.INBOX);
+            assertThat(mailboxPath.isInbox()).isTrue();
+        }
 
-    @Test
-    void isInboxShouldReturnTrueWhenINBOXWithOtherCase() {
-        MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, USER, "InBoX");
-        assertThat(mailboxPath.isInbox()).isTrue();
-    }
+        @Test
+        void isInboxShouldReturnTrueWhenINBOXWithOtherCase() {
+            MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, USER, "InBoX");
+            assertThat(mailboxPath.isInbox()).isTrue();
+        }
 
-    @Test
-    void isInboxShouldReturnFalseWhenOtherThanInbox() {
-        MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, USER, DefaultMailboxes.ARCHIVE);
-        assertThat(mailboxPath.isInbox()).isFalse();
-    }
+        @Test
+        void isInboxShouldReturnFalseWhenOtherThanInbox() {
+            MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, USER, DefaultMailboxes.ARCHIVE);
+            assertThat(mailboxPath.isInbox()).isFalse();
+        }
 
-    @Test
-    void hasParentShouldReturnTrueWhenMailboxHasParent() {
-        MailboxPath mailboxPath = MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder"));
-        assertThat(mailboxPath.hasParent(folderDelimiter())).isTrue();
-    }
+        @Test
+        void hasParentShouldReturnTrueWhenMailboxHasParent() {
+            MailboxPath mailboxPath = MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder"));
+            assertThat(mailboxPath.hasParent(folderDelimiter())).isTrue();
+        }
 
-    @Test
-    void hasParentShouldReturnFalseWhenNoParent() {
-        MailboxPath mailboxPath = MailboxPath.forUser(USER, "inbox");
-        assertThat(mailboxPath.hasParent(folderDelimiter())).isFalse();
-    }
+        @Test
+        void hasParentShouldReturnFalseWhenNoParent() {
+            MailboxPath mailboxPath = MailboxPath.forUser(USER, "inbox");
+            assertThat(mailboxPath.hasParent(folderDelimiter())).isFalse();
+        }
 
-    @Test
-    void getParentShouldReturnParents() {
-        MailboxPath mailboxPath = MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder"));
-        assertThat(mailboxPath.getParents(folderDelimiter()))
-                .containsExactly(
-                        MailboxPath.forUser(USER, "inbox"),
-                        MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder")));
-    }
+        @Test
+        void getParentShouldReturnParents() {
+            MailboxPath mailboxPath = MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder.subfolder"));
+            assertThat(mailboxPath.getParents(folderDelimiter()))
+                    .containsExactly(
+                            MailboxPath.forUser(USER, "inbox"),
+                            MailboxPath.forUser(USER, adjustToActiveFolderDelimiter("inbox.folder")));
+        }
 
-    @Test
-    void getParentShouldReturnEmptyWhenTopLevelMailbox() {
-        MailboxPath mailboxPath = MailboxPath.forUser(USER, "inbox");
-        assertThat(mailboxPath.getParents(folderDelimiter()))
-                .isEmpty();
-    }
+        @Test
+        void getParentShouldReturnEmptyWhenTopLevelMailbox() {
+            MailboxPath mailboxPath = MailboxPath.forUser(USER, "inbox");
+            assertThat(mailboxPath.getParents(folderDelimiter()))
+                    .isEmpty();
+        }
     }
 }

From 8301b8e8094b577ee3e6fc90a74ecfc05015b216 Mon Sep 17 00:00:00 2001
From: Jan-Eric Hellenberg <janeric.hellenberg@gmail.com>
Date: Fri, 3 Jan 2025 14:25:41 +0100
Subject: [PATCH 6/9] James-4099 Refactor PrefixedRegex tests to work with
 different path delimiters

---
 .../model/search/PrefixedRegexTest.java       | 344 ++++++++++--------
 1 file changed, 183 insertions(+), 161 deletions(-)

diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java
index 03340f532f3..644bad44bed 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java
@@ -25,6 +25,8 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.james.mailbox.model.MailboxFolderDelimiterAwareTest;
+import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 
 import com.google.re2j.Pattern;
@@ -32,16 +34,32 @@
 import nl.jqno.equalsverifier.EqualsVerifier;
 
 class PrefixedRegexTest {
-    private static final char PATH_DELIMITER = '.';
+    @Nested
+    public class DotDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return '.';
+        }
+    }
+
+    @Nested
+    public class SlashDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return '/';
+        }
+    }
+
+    abstract static class TestBase extends MailboxFolderDelimiterAwareTest {
     private static final String PREFIX = "name";
     private static final String EMPTY_PREFIX = "";
 
     @Test
     public void shouldMatchBeanContract() {
         EqualsVerifier.forClass(PrefixedRegex.class)
-            .withIgnoredFields("pattern")
-            .withPrefabValues(Pattern.class, Pattern.compile("a"), Pattern.compile("b"))
-            .verify();
+                .withIgnoredFields("pattern")
+                .withPrefabValues(Pattern.class, Pattern.compile("a"), Pattern.compile("b"))
+                .verify();
     }
 
     @Test
@@ -50,7 +68,7 @@ void slowRegexShouldNotBeConstructedByFuzzing() throws Exception {
 
         try {
             executorService.submit(() -> {
-                PrefixedRegex prefixedRegex = new PrefixedRegex("", "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%a", PATH_DELIMITER);
+                PrefixedRegex prefixedRegex = new PrefixedRegex("", "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%a", folderDelimiter());
 
                 prefixedRegex.isExpressionMatch("aa%%%%%%%%%%%%%%%%");
             }).get(30, TimeUnit.SECONDS);
@@ -61,7 +79,7 @@ void slowRegexShouldNotBeConstructedByFuzzing() throws Exception {
 
     @Test
     void isWildShouldReturnTrueWhenOnlyFreeWildcard() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "*", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "*", folderDelimiter());
 
         boolean actual = prefixedRegex.isWild();
 
@@ -70,7 +88,7 @@ void isWildShouldReturnTrueWhenOnlyFreeWildcard() {
 
     @Test
     void isWildShouldReturnTrueWhenOnlyLocalWildcard() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "%", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "%", folderDelimiter());
 
         boolean actual = prefixedRegex.isWild();
 
@@ -79,7 +97,7 @@ void isWildShouldReturnTrueWhenOnlyLocalWildcard() {
 
     @Test
     void isWildShouldReturnTrueWhenFreeWildcardAtBeginning() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "*One", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "*One", folderDelimiter());
 
         boolean actual = prefixedRegex.isWild();
 
@@ -88,7 +106,7 @@ void isWildShouldReturnTrueWhenFreeWildcardAtBeginning() {
 
     @Test
     void isWildShouldReturnTrueWhenLocalWildcardAtBeginning() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "%One", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "%One", folderDelimiter());
 
         boolean actual = prefixedRegex.isWild();
 
@@ -97,7 +115,7 @@ void isWildShouldReturnTrueWhenLocalWildcardAtBeginning() {
 
     @Test
     void isWildShouldReturnTrueWhenFreeWildcardInMiddle() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "A*A", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "A*A", folderDelimiter());
 
         boolean actual = prefixedRegex.isWild();
 
@@ -106,7 +124,7 @@ void isWildShouldReturnTrueWhenFreeWildcardInMiddle() {
 
     @Test
     void isWildShouldReturnTrueWhenLocalWildcardInMiddle() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "A%A", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "A%A", folderDelimiter());
 
         boolean actual = prefixedRegex.isWild();
 
@@ -115,7 +133,7 @@ void isWildShouldReturnTrueWhenLocalWildcardInMiddle() {
 
     @Test
     void isWildShouldReturnTrueWhenFreeWildcardAtEnd() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "One*", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "One*", folderDelimiter());
 
         boolean actual = prefixedRegex.isWild();
 
@@ -124,7 +142,7 @@ void isWildShouldReturnTrueWhenFreeWildcardAtEnd() {
 
     @Test
     void isWildShouldReturnTrueWhenLocalWildcardAtEnd() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "One%", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "One%", folderDelimiter());
 
         boolean actual = prefixedRegex.isWild();
 
@@ -133,7 +151,7 @@ void isWildShouldReturnTrueWhenLocalWildcardAtEnd() {
 
     @Test
     void isWildShouldReturnFalseWhenEmptyExpression() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "", folderDelimiter());
 
         boolean actual = prefixedRegex.isWild();
 
@@ -142,7 +160,7 @@ void isWildShouldReturnFalseWhenEmptyExpression() {
 
     @Test
     void isWildShouldReturnFalseWhenNullExpression() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, null, PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, null, folderDelimiter());
 
         boolean actual = prefixedRegex.isWild();
 
@@ -151,7 +169,7 @@ void isWildShouldReturnFalseWhenNullExpression() {
 
     @Test
     void isWildShouldReturnFalseWhenNoWildcard() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "ONE", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "ONE", folderDelimiter());
 
         boolean actual = prefixedRegex.isWild();
 
@@ -160,16 +178,16 @@ void isWildShouldReturnFalseWhenNoWildcard() {
 
     @Test
     void getCombinedNameShouldWork() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "mailbox", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "mailbox", folderDelimiter());
 
         String actual = prefixedRegex.getCombinedName();
 
-        assertThat(actual).isEqualTo("name.mailbox");
+        assertThat(actual).isEqualTo(adjustToActiveFolderDelimiter("name.mailbox"));
     }
 
     @Test
     void getCombinedNameShouldWorkWhenEmptyExpression() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "", folderDelimiter());
 
         String actual = prefixedRegex.getCombinedName();
 
@@ -180,7 +198,7 @@ void getCombinedNameShouldWorkWhenEmptyExpression() {
     void getCombinedNameShouldReturnEmptyStringWhenNullMailboxPathAndExpression() {
         String prefix = null;
         String regex = null;
-        PrefixedRegex prefixedRegex = new PrefixedRegex(prefix, regex, PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(prefix, regex, folderDelimiter());
 
         String actual = prefixedRegex.getCombinedName();
 
@@ -189,25 +207,28 @@ void getCombinedNameShouldReturnEmptyStringWhenNullMailboxPathAndExpression() {
 
     @Test
     void getCombinedNameShouldIgnoreDelimiterWhenPresentAtBeginningOfExpression() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, ".mailbox", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, adjustToActiveFolderDelimiter(".mailbox"), folderDelimiter());
 
         String actual = prefixedRegex.getCombinedName();
 
-        assertThat(actual).isEqualTo("name.mailbox");
+        assertThat(actual).isEqualTo(adjustToActiveFolderDelimiter("name.mailbox"));
     }
 
     @Test
     void getCombinedNameShouldIgnoreDelimiterWhenPresentAtEndOfMailboxName() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX + ".", ".mailbox", PATH_DELIMITER);
+        PrefixedRegex prefixedRegex = new PrefixedRegex(
+                PREFIX + adjustToActiveFolderDelimiter("."),
+                adjustToActiveFolderDelimiter(".mailbox"),
+                folderDelimiter());
 
         String actual = prefixedRegex.getCombinedName();
 
-        assertThat(actual).isEqualTo("name.mailbox");
+        assertThat(actual).isEqualTo(adjustToActiveFolderDelimiter("name.mailbox"));
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenNullExpression() {
-        PrefixedRegex testee = new PrefixedRegex(PREFIX, null, PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(PREFIX, null, folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("folder");
 
@@ -216,7 +237,7 @@ void isExpressionMatchShouldReturnFalseWhenNullExpression() {
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailbox");
 
@@ -225,25 +246,25 @@ void isExpressionMatchShouldMatchFolderWhenMatching() {
 
     @Test
     void isExpressionMatchShouldReturnTrueWhenNameBeginsWithDelimiter() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(".mailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter(".mailbox"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenNameEndsWithDelimiter() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox.");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox."));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldNotMatchFolderWhenNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("sub");
 
@@ -252,7 +273,7 @@ void isExpressionMatchShouldNotMatchFolderWhenNoMatching() {
 
     @Test
     void isExpressionMatchShouldNotMatchFolderWithExpandedEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailbox123");
 
@@ -261,16 +282,16 @@ void isExpressionMatchShouldNotMatchFolderWithExpandedEndName() {
 
     @Test
     void isExpressionMatchShouldNotMatchSubFolder() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox.123");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.123"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldReturnTrueWhenEmptyNameAndExpression() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("");
 
@@ -279,16 +300,16 @@ void isExpressionMatchShouldReturnTrueWhenEmptyNameAndExpression() {
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenEmptyExpressionAndNameBeginsWithDelimiter() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(".123");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter(".123"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldNotMatchFolderWhenEmptyExpression() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("folder");
 
@@ -297,7 +318,7 @@ void isExpressionMatchShouldNotMatchFolderWhenEmptyExpression() {
 
     @Test
     void isExpressionMatchShouldReturnTrueWhenEmptyNameAndOnlyLocalWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("");
 
@@ -306,7 +327,7 @@ void isExpressionMatchShouldReturnTrueWhenEmptyNameAndOnlyLocalWildcard() {
 
     @Test
     void isExpressionMatchShouldReturnTrueWhenOnlyLocalWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("folder");
 
@@ -315,16 +336,16 @@ void isExpressionMatchShouldReturnTrueWhenOnlyLocalWildcard() {
 
     @Test
     void isExpressionMatchShouldNotMatchSubFolderWhenOnlyLocalWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox.sub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldReturnTrueWhenEmptyNameAndOnlyFreeWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("");
 
@@ -333,7 +354,7 @@ void isExpressionMatchShouldReturnTrueWhenEmptyNameAndOnlyFreeWildcard() {
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenOnlyFreeWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("sub");
 
@@ -342,16 +363,16 @@ void isExpressionMatchShouldMatchFolderWhenOnlyFreeWildcard() {
 
     @Test
     void isExpressionMatchShouldMatchSubFolderWhenOnlyFreeWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox.sub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalWildcardAtEnd() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("");
 
@@ -360,7 +381,7 @@ void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalWildcardAtEnd() {
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenLocalWildcardAtEndAndNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("sub");
 
@@ -369,7 +390,7 @@ void isExpressionMatchShouldReturnFalseWhenLocalWildcardAtEndAndNoMatching() {
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenLocalWildcardAtEndNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailbox");
 
@@ -378,7 +399,7 @@ void isExpressionMatchShouldMatchFolderWhenLocalWildcardAtEndNotUsed() {
 
     @Test
     void isExpressionMatchShouldReturnTrueWhenLocalWildcardAtEndUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailboxsub");
 
@@ -387,16 +408,16 @@ void isExpressionMatchShouldReturnTrueWhenLocalWildcardAtEndUsed() {
 
     @Test
     void isExpressionMatchShouldNotMatchSubFolderWhenLocalWildcardAtEnd() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox.sub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalWildcardAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("");
 
@@ -405,7 +426,7 @@ void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalWildcardAtBeginning(
 
     @Test
     void isExpressionMatchShouldNotMatchFolderWhenLocalWildcardAtBeginningAndNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("sub");
 
@@ -414,7 +435,7 @@ void isExpressionMatchShouldNotMatchFolderWhenLocalWildcardAtBeginningAndNoMatch
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenLocalWildcardAtBeginningNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailbox");
 
@@ -423,7 +444,7 @@ void isExpressionMatchShouldMatchFolderWhenLocalWildcardAtBeginningNotUsed() {
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenLocalWildcardAtBeginningUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("submailbox");
 
@@ -432,25 +453,25 @@ void isExpressionMatchShouldMatchFolderWhenLocalWildcardAtBeginningUsed() {
 
     @Test
     void isExpressionMatchShouldNotMatchSubFolderWhenLocalWildcardAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.mailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenLocalWildcardAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.mailbox.sub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox.sub"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("");
 
@@ -459,7 +480,7 @@ void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalWildcardInMiddle() {
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenLocalWildcardInMiddleAndMissingEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("sub");
 
@@ -468,7 +489,7 @@ void isExpressionMatchShouldReturnFalseWhenLocalWildcardInMiddleAndMissingEndNam
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenLocalWildcardInMiddleAndMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("submailbox");
 
@@ -477,7 +498,7 @@ void isExpressionMatchShouldMatchFolderWhenLocalWildcardInMiddleAndMatching() {
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("sub123mailbox");
 
@@ -486,25 +507,25 @@ void isExpressionMatchShouldMatchFolderWhenLocalWildcardInMiddle() {
 
     @Test
     void isExpressionMatchShouldNotMatchSubFolderWhenLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.mailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldNotMatchSubFolderWhenLocalWildcardInMiddleAndExpandedMiddleName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.123mailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.123mailbox"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenLocalWildcardInMiddleAndMissingBeginningName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailbox");
 
@@ -513,25 +534,25 @@ void isExpressionMatchShouldReturnFalseWhenLocalWildcardInMiddleAndMissingBeginn
 
     @Test
     void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("subw.hat.eve.rmailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldMatchSubFolderWhenFreeWildcardAtEnd() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox.sub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeWildcardAtEnd() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("");
 
@@ -540,7 +561,7 @@ void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeWildcardAtEnd() {
 
     @Test
     void isExpressionMatchShouldNotMatchFolderWhenFreeWildcardAtEndAndNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("sub");
 
@@ -549,7 +570,7 @@ void isExpressionMatchShouldNotMatchFolderWhenFreeWildcardAtEndAndNoMatching() {
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtEndNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailbox");
 
@@ -558,7 +579,7 @@ void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtEndNotUsed() {
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtEndUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailbox123");
 
@@ -567,7 +588,7 @@ void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtEndUsed() {
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeWildcardAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("");
 
@@ -576,7 +597,7 @@ void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeWildcardAtBeginning()
 
     @Test
     void isExpressionMatchShouldNotMatchFolderWhenFreeWildcardAtBeginningAndNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("sub");
 
@@ -585,7 +606,7 @@ void isExpressionMatchShouldNotMatchFolderWhenFreeWildcardAtBeginningAndNoMatchi
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtBeginningNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailbox");
 
@@ -594,7 +615,7 @@ void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtBeginningNotUsed() {
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtBeginningUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("submailbox");
 
@@ -603,16 +624,16 @@ void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtBeginningUsed() {
 
     @Test
     void isExpressionMatchShouldMatchSubFolderWhenFreeWildcardAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.mailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("");
 
@@ -621,7 +642,7 @@ void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeWildcardInMiddle() {
 
     @Test
     void isExpressionMatchShouldNotMatchFolderWhenFreeWildcardInMiddleAndMissingEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("sub");
 
@@ -630,7 +651,7 @@ void isExpressionMatchShouldNotMatchFolderWhenFreeWildcardInMiddleAndMissingEndN
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenFreeWildcardInMiddleNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("submailbox");
 
@@ -639,16 +660,16 @@ void isExpressionMatchShouldMatchFolderWhenFreeWildcardInMiddleNotUsed() {
 
     @Test
     void isExpressionMatchShouldMatchSubFolderWhenFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.mailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenFreeWildcardInMiddleNotUsedAndMissingBeginningName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailbox");
 
@@ -657,16 +678,16 @@ void isExpressionMatchShouldReturnFalseWhenFreeWildcardInMiddleNotUsedAndMissing
 
     @Test
     void isExpressionMatchShouldMatchDeeplyNestedFolderWhenFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("subw.hat.eve.rmailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenEmptyNameAndDoubleFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("");
 
@@ -675,7 +696,7 @@ void isExpressionMatchShouldReturnFalseWhenEmptyNameAndDoubleFreeWildcardInMiddl
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenDoubleFreeWildcardInMiddleAndMissingEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("sub");
 
@@ -684,7 +705,7 @@ void isExpressionMatchShouldReturnFalseWhenDoubleFreeWildcardInMiddleAndMissingE
 
     @Test
     void isExpressionMatchShouldReturnTrueWhenDoubleFreeWildcardInMiddleNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("submailbox");
 
@@ -693,16 +714,16 @@ void isExpressionMatchShouldReturnTrueWhenDoubleFreeWildcardInMiddleNotUsed() {
 
     @Test
     void isExpressionMatchShouldMatchSubFolderWhenDoubleFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.mailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenDoubleFreeWildcardInMiddleAndMissingBeginningName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailbox");
 
@@ -711,16 +732,16 @@ void isExpressionMatchShouldReturnFalseWhenDoubleFreeWildcardInMiddleAndMissingB
 
     @Test
     void isExpressionMatchShouldMatchDeeplyNestedFolderWhenDoubleFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("subw.hat.eve.rmailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("");
 
@@ -729,7 +750,7 @@ void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeLocalWildcardInMiddle
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenFreeLocalWildcardInMiddleAndMissingEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("sub");
 
@@ -738,7 +759,7 @@ void isExpressionMatchShouldReturnFalseWhenFreeLocalWildcardInMiddleAndMissingEn
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenFreeLocalWildcardInMiddleNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("submailbox");
 
@@ -747,16 +768,16 @@ void isExpressionMatchShouldMatchFolderWhenFreeLocalWildcardInMiddleNotUsed() {
 
     @Test
     void isExpressionMatchShouldMatchSubFolderWhenFreeLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.mailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenFreeLocalWildcardInMiddleAndMissingBeginningName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailbox");
 
@@ -765,16 +786,16 @@ void isExpressionMatchShouldReturnFalseWhenFreeLocalWildcardInMiddleAndMissingBe
 
     @Test
     void isExpressionMatchShouldMatchDeeplyNestedFolderWhenFreeLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("subw.hat.eve.rmailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("");
 
@@ -783,7 +804,7 @@ void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalFreeWildcardInMiddle
 
     @Test
     void isExpressionMatchShouldNotMatchFolderWhenLocalFreeWildcardInMiddleAndMissingEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("sub");
 
@@ -792,7 +813,7 @@ void isExpressionMatchShouldNotMatchFolderWhenLocalFreeWildcardInMiddleAndMissin
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenLocalFreewildcardInMiddleNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("submailbox");
 
@@ -801,16 +822,16 @@ void isExpressionMatchShouldMatchFolderWhenLocalFreewildcardInMiddleNotUsed() {
 
     @Test
     void isExpressionMatchShouldMatchSubFolderWhenLocalFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.mailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldNotMatchFolderWhenLocalFreeWildcardInMiddleAndMissingBeginningName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailbox");
 
@@ -819,16 +840,16 @@ void isExpressionMatchShouldNotMatchFolderWhenLocalFreeWildcardInMiddleAndMissin
 
     @Test
     void isExpressionMatchShouldMatchDeeplyNestedFolderWhenLocalFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("subw.hat.eve.rmailbox");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenMultipleFreeWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("submailboxsub");
 
@@ -837,52 +858,52 @@ void isExpressionMatchShouldMatchFolderWhenMultipleFreeWildcards() {
 
     @Test
     void isExpressionMatchShouldMatchDeeplyNestedFolderWhenMultipleFreeWildcardsNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.mailbox.sub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox.sub"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldMatchDeeplyNestedFolderWhenMultipleFreeWildcardsUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("subtosh.boshmailboxtosh.boshsubboshtosh");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subtosh.boshmailboxtosh.boshsubboshtosh"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenMultipleFreeWildcardsAndMissingMiddleName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.a.sub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.a.sub"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenMultipleFreeWildcardsAndMissingEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.a.submailbox.u");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.a.submailbox.u"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenMultipleFreeWildcardsAndMissingBeginningdName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("utosh.boshmailboxtosh.boshsubasubboshtoshmailboxu");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("utosh.boshmailboxtosh.boshsubasubboshtoshmailboxu"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenMixedLocalFreeWildcardsNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox*sub", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox*sub", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("submailboxsub");
 
@@ -891,16 +912,16 @@ void isExpressionMatchShouldMatchFolderWhenMixedLocalFreeWildcardsNotUsed() {
 
     @Test
     void isExpressionMatchShouldNotMatchSubFolderWhenMixedLocalFreeWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox*sub", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox*sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.mailboxsub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailboxsub"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenMixedFreeLocalWildcardsNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("submailboxsub");
 
@@ -909,25 +930,25 @@ void isExpressionMatchShouldMatchFolderWhenMixedFreeLocalWildcardsNotUsed() {
 
     @Test
     void isExpressionMatchShouldMatchSubFolderWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.mailboxsub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailboxsub"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldNotMatchSubFolderWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("submailbox.sub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("submailbox.sub"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldMatchFolderWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("submailboxwhateversub");
 
@@ -936,43 +957,43 @@ void isExpressionMatchShouldMatchFolderWhenMixedFreeLocalWildcards() {
 
     @Test
     void isExpressionMatchShouldNotMatchSubFolderEndingWithDelimiterWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("submailboxsub.Whatever.");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("submailboxsub.Whatever."));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.mailboxsub.sub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailboxsub.sub"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldMatchSubFoldeWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.mailboxsub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailboxsub"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldMatchDeeplyNestedFoldeWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub.whatever.mailbox123sub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.whatever.mailbox123sub"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldNotMatchFolderWhenTwoLocalPathDelimitedWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%.%", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("%.%"), folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("mailbox");
 
@@ -981,52 +1002,52 @@ void isExpressionMatchShouldNotMatchFolderWhenTwoLocalPathDelimitedWildcards() {
 
     @Test
     void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenTwoLocalPathDelimitedWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%.%", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("%.%"), folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox.sub.sub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub.sub"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldMatchSubFolderWhenTwoLocalPathDelimitedWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%.%", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("%.%"), folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox.sub");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldMatchSubFolderWhenFreeWildcardAndPathDelimiterAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*.test", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("*.test"), folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("blah.test");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("blah.test"));
 
         assertThat(actual).isTrue();
     }
 
     @Test
     void isExpressionMatchShouldNotMatchSubFolderWhenWhenFreeWildcardAndPathDelimiterAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*.test", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("*.test"), folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("blah.test3");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("blah.test3"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenFreeWildcardAndPathDelimiterAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*.test", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("*.test"), folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("blah.test.go");
+        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("blah.test.go"));
 
         assertThat(actual).isFalse();
     }
 
     @Test
     void isExpressionMatchShouldIgnoreRegexInjection() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "folder^$!)(%3", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "folder^$!)(%3", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("folder^$!)(123");
 
@@ -1035,7 +1056,7 @@ void isExpressionMatchShouldIgnoreRegexInjection() {
 
     @Test
     void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingEndOfQuoteAndNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Efo.", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Efo.", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("\\Efol");
 
@@ -1044,7 +1065,7 @@ void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingEndOfQuoteAndNoMatching
 
     @Test
     void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingEndOfQuoteAndMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Efo.", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Efo.", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("\\Efo.");
 
@@ -1053,7 +1074,7 @@ void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingEndOfQuoteAndMatching()
 
     @Test
     void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingBeginOfQuoteAndNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Qfo?", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Qfo?", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("\\Qfol");
 
@@ -1062,7 +1083,7 @@ void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingBeginOfQuoteAndNoMatchi
 
     @Test
     void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingBeginOfQuoteAndMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Qfo?", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Qfo?", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("\\Qfo?");
 
@@ -1071,7 +1092,7 @@ void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingBeginOfQuoteAndMatching
 
     @Test
     void isExpressionMatchShouldNotEscapeFreeWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "folder\\*", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "folder\\*", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("folder\\123");
 
@@ -1080,10 +1101,11 @@ void isExpressionMatchShouldNotEscapeFreeWildcard() {
 
     @Test
     void isExpressionMatchShouldNotEscapeLocalWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "folder\\%", PATH_DELIMITER);
+        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "folder\\%", folderDelimiter());
 
         boolean actual = testee.isExpressionMatch("folder\\123");
 
         assertThat(actual).isTrue();
     }
+    }
 }
\ No newline at end of file

From 58268754567c43d3f787930caedba59946ea4980 Mon Sep 17 00:00:00 2001
From: Jan-Eric Hellenberg <janeric.hellenberg@gmail.com>
Date: Fri, 3 Jan 2025 14:57:34 +0100
Subject: [PATCH 7/9] James-4099 Properly indent PrefixedRegex tests

---
 .../model/search/PrefixedRegexTest.java       | 1420 ++++++++---------
 1 file changed, 710 insertions(+), 710 deletions(-)

diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java
index 644bad44bed..d72becf65af 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java
@@ -51,1061 +51,1061 @@ public char folderDelimiter() {
     }
 
     abstract static class TestBase extends MailboxFolderDelimiterAwareTest {
-    private static final String PREFIX = "name";
-    private static final String EMPTY_PREFIX = "";
-
-    @Test
-    public void shouldMatchBeanContract() {
-        EqualsVerifier.forClass(PrefixedRegex.class)
-                .withIgnoredFields("pattern")
-                .withPrefabValues(Pattern.class, Pattern.compile("a"), Pattern.compile("b"))
-                .verify();
-    }
+        private static final String PREFIX = "name";
+        private static final String EMPTY_PREFIX = "";
+
+        @Test
+        public void shouldMatchBeanContract() {
+            EqualsVerifier.forClass(PrefixedRegex.class)
+                    .withIgnoredFields("pattern")
+                    .withPrefabValues(Pattern.class, Pattern.compile("a"), Pattern.compile("b"))
+                    .verify();
+        }
 
-    @Test
-    void slowRegexShouldNotBeConstructedByFuzzing() throws Exception {
-        ExecutorService executorService = Executors.newSingleThreadExecutor();
+        @Test
+        void slowRegexShouldNotBeConstructedByFuzzing() throws Exception {
+            ExecutorService executorService = Executors.newSingleThreadExecutor();
 
-        try {
-            executorService.submit(() -> {
-                PrefixedRegex prefixedRegex = new PrefixedRegex("", "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%a", folderDelimiter());
+            try {
+                executorService.submit(() -> {
+                    PrefixedRegex prefixedRegex = new PrefixedRegex("", "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%a", folderDelimiter());
 
-                prefixedRegex.isExpressionMatch("aa%%%%%%%%%%%%%%%%");
-            }).get(30, TimeUnit.SECONDS);
-        } finally {
-            executorService.shutdownNow();
+                    prefixedRegex.isExpressionMatch("aa%%%%%%%%%%%%%%%%");
+                }).get(30, TimeUnit.SECONDS);
+            } finally {
+                executorService.shutdownNow();
+            }
         }
-    }
 
-    @Test
-    void isWildShouldReturnTrueWhenOnlyFreeWildcard() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "*", folderDelimiter());
+        @Test
+        void isWildShouldReturnTrueWhenOnlyFreeWildcard() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "*", folderDelimiter());
 
-        boolean actual = prefixedRegex.isWild();
+            boolean actual = prefixedRegex.isWild();
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isWildShouldReturnTrueWhenOnlyLocalWildcard() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "%", folderDelimiter());
+        @Test
+        void isWildShouldReturnTrueWhenOnlyLocalWildcard() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "%", folderDelimiter());
 
-        boolean actual = prefixedRegex.isWild();
+            boolean actual = prefixedRegex.isWild();
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isWildShouldReturnTrueWhenFreeWildcardAtBeginning() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "*One", folderDelimiter());
+        @Test
+        void isWildShouldReturnTrueWhenFreeWildcardAtBeginning() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "*One", folderDelimiter());
 
-        boolean actual = prefixedRegex.isWild();
+            boolean actual = prefixedRegex.isWild();
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isWildShouldReturnTrueWhenLocalWildcardAtBeginning() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "%One", folderDelimiter());
+        @Test
+        void isWildShouldReturnTrueWhenLocalWildcardAtBeginning() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "%One", folderDelimiter());
 
-        boolean actual = prefixedRegex.isWild();
+            boolean actual = prefixedRegex.isWild();
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isWildShouldReturnTrueWhenFreeWildcardInMiddle() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "A*A", folderDelimiter());
+        @Test
+        void isWildShouldReturnTrueWhenFreeWildcardInMiddle() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "A*A", folderDelimiter());
 
-        boolean actual = prefixedRegex.isWild();
+            boolean actual = prefixedRegex.isWild();
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isWildShouldReturnTrueWhenLocalWildcardInMiddle() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "A%A", folderDelimiter());
+        @Test
+        void isWildShouldReturnTrueWhenLocalWildcardInMiddle() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "A%A", folderDelimiter());
 
-        boolean actual = prefixedRegex.isWild();
+            boolean actual = prefixedRegex.isWild();
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isWildShouldReturnTrueWhenFreeWildcardAtEnd() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "One*", folderDelimiter());
+        @Test
+        void isWildShouldReturnTrueWhenFreeWildcardAtEnd() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "One*", folderDelimiter());
 
-        boolean actual = prefixedRegex.isWild();
+            boolean actual = prefixedRegex.isWild();
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isWildShouldReturnTrueWhenLocalWildcardAtEnd() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "One%", folderDelimiter());
+        @Test
+        void isWildShouldReturnTrueWhenLocalWildcardAtEnd() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "One%", folderDelimiter());
 
-        boolean actual = prefixedRegex.isWild();
+            boolean actual = prefixedRegex.isWild();
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isWildShouldReturnFalseWhenEmptyExpression() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "", folderDelimiter());
+        @Test
+        void isWildShouldReturnFalseWhenEmptyExpression() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "", folderDelimiter());
 
-        boolean actual = prefixedRegex.isWild();
+            boolean actual = prefixedRegex.isWild();
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isWildShouldReturnFalseWhenNullExpression() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, null, folderDelimiter());
+        @Test
+        void isWildShouldReturnFalseWhenNullExpression() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, null, folderDelimiter());
 
-        boolean actual = prefixedRegex.isWild();
+            boolean actual = prefixedRegex.isWild();
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isWildShouldReturnFalseWhenNoWildcard() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "ONE", folderDelimiter());
+        @Test
+        void isWildShouldReturnFalseWhenNoWildcard() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "ONE", folderDelimiter());
 
-        boolean actual = prefixedRegex.isWild();
+            boolean actual = prefixedRegex.isWild();
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void getCombinedNameShouldWork() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "mailbox", folderDelimiter());
+        @Test
+        void getCombinedNameShouldWork() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "mailbox", folderDelimiter());
 
-        String actual = prefixedRegex.getCombinedName();
+            String actual = prefixedRegex.getCombinedName();
 
-        assertThat(actual).isEqualTo(adjustToActiveFolderDelimiter("name.mailbox"));
-    }
+            assertThat(actual).isEqualTo(adjustToActiveFolderDelimiter("name.mailbox"));
+        }
 
-    @Test
-    void getCombinedNameShouldWorkWhenEmptyExpression() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "", folderDelimiter());
+        @Test
+        void getCombinedNameShouldWorkWhenEmptyExpression() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, "", folderDelimiter());
 
-        String actual = prefixedRegex.getCombinedName();
+            String actual = prefixedRegex.getCombinedName();
 
-        assertThat(actual).isEqualTo("name");
-    }
+            assertThat(actual).isEqualTo("name");
+        }
 
-    @Test
-    void getCombinedNameShouldReturnEmptyStringWhenNullMailboxPathAndExpression() {
-        String prefix = null;
-        String regex = null;
-        PrefixedRegex prefixedRegex = new PrefixedRegex(prefix, regex, folderDelimiter());
+        @Test
+        void getCombinedNameShouldReturnEmptyStringWhenNullMailboxPathAndExpression() {
+            String prefix = null;
+            String regex = null;
+            PrefixedRegex prefixedRegex = new PrefixedRegex(prefix, regex, folderDelimiter());
 
-        String actual = prefixedRegex.getCombinedName();
+            String actual = prefixedRegex.getCombinedName();
 
-        assertThat(actual).isEmpty();
-    }
+            assertThat(actual).isEmpty();
+        }
 
-    @Test
-    void getCombinedNameShouldIgnoreDelimiterWhenPresentAtBeginningOfExpression() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, adjustToActiveFolderDelimiter(".mailbox"), folderDelimiter());
+        @Test
+        void getCombinedNameShouldIgnoreDelimiterWhenPresentAtBeginningOfExpression() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(PREFIX, adjustToActiveFolderDelimiter(".mailbox"), folderDelimiter());
 
-        String actual = prefixedRegex.getCombinedName();
+            String actual = prefixedRegex.getCombinedName();
 
-        assertThat(actual).isEqualTo(adjustToActiveFolderDelimiter("name.mailbox"));
-    }
+            assertThat(actual).isEqualTo(adjustToActiveFolderDelimiter("name.mailbox"));
+        }
 
-    @Test
-    void getCombinedNameShouldIgnoreDelimiterWhenPresentAtEndOfMailboxName() {
-        PrefixedRegex prefixedRegex = new PrefixedRegex(
-                PREFIX + adjustToActiveFolderDelimiter("."),
-                adjustToActiveFolderDelimiter(".mailbox"),
-                folderDelimiter());
+        @Test
+        void getCombinedNameShouldIgnoreDelimiterWhenPresentAtEndOfMailboxName() {
+            PrefixedRegex prefixedRegex = new PrefixedRegex(
+                    PREFIX + adjustToActiveFolderDelimiter("."),
+                    adjustToActiveFolderDelimiter(".mailbox"),
+                    folderDelimiter());
 
-        String actual = prefixedRegex.getCombinedName();
+            String actual = prefixedRegex.getCombinedName();
 
-        assertThat(actual).isEqualTo(adjustToActiveFolderDelimiter("name.mailbox"));
-    }
+            assertThat(actual).isEqualTo(adjustToActiveFolderDelimiter("name.mailbox"));
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenNullExpression() {
-        PrefixedRegex testee = new PrefixedRegex(PREFIX, null, folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenNullExpression() {
+            PrefixedRegex testee = new PrefixedRegex(PREFIX, null, folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("folder");
+            boolean actual = testee.isExpressionMatch("folder");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenMatching() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox");
+            boolean actual = testee.isExpressionMatch("mailbox");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnTrueWhenNameBeginsWithDelimiter() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnTrueWhenNameBeginsWithDelimiter() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter(".mailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter(".mailbox"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenNameEndsWithDelimiter() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenNameEndsWithDelimiter() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox."));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox."));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchFolderWhenNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchFolderWhenNoMatching() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub");
+            boolean actual = testee.isExpressionMatch("sub");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchFolderWithExpandedEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchFolderWithExpandedEndName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox123");
+            boolean actual = testee.isExpressionMatch("mailbox123");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchSubFolder() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchSubFolder() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.123"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.123"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnTrueWhenEmptyNameAndExpression() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnTrueWhenEmptyNameAndExpression() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("");
+            boolean actual = testee.isExpressionMatch("");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenEmptyExpressionAndNameBeginsWithDelimiter() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenEmptyExpressionAndNameBeginsWithDelimiter() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter(".123"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter(".123"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchFolderWhenEmptyExpression() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchFolderWhenEmptyExpression() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("folder");
+            boolean actual = testee.isExpressionMatch("folder");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnTrueWhenEmptyNameAndOnlyLocalWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnTrueWhenEmptyNameAndOnlyLocalWildcard() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("");
+            boolean actual = testee.isExpressionMatch("");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnTrueWhenOnlyLocalWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnTrueWhenOnlyLocalWildcard() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("folder");
+            boolean actual = testee.isExpressionMatch("folder");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchSubFolderWhenOnlyLocalWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchSubFolderWhenOnlyLocalWildcard() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnTrueWhenEmptyNameAndOnlyFreeWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnTrueWhenEmptyNameAndOnlyFreeWildcard() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("");
+            boolean actual = testee.isExpressionMatch("");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenOnlyFreeWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenOnlyFreeWildcard() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub");
+            boolean actual = testee.isExpressionMatch("sub");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchSubFolderWhenOnlyFreeWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchSubFolderWhenOnlyFreeWildcard() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalWildcardAtEnd() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalWildcardAtEnd() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("");
+            boolean actual = testee.isExpressionMatch("");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenLocalWildcardAtEndAndNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenLocalWildcardAtEndAndNoMatching() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub");
+            boolean actual = testee.isExpressionMatch("sub");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenLocalWildcardAtEndNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenLocalWildcardAtEndNotUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox");
+            boolean actual = testee.isExpressionMatch("mailbox");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnTrueWhenLocalWildcardAtEndUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnTrueWhenLocalWildcardAtEndUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailboxsub");
+            boolean actual = testee.isExpressionMatch("mailboxsub");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchSubFolderWhenLocalWildcardAtEnd() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchSubFolderWhenLocalWildcardAtEnd() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox%", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalWildcardAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalWildcardAtBeginning() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("");
+            boolean actual = testee.isExpressionMatch("");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchFolderWhenLocalWildcardAtBeginningAndNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchFolderWhenLocalWildcardAtBeginningAndNoMatching() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub");
+            boolean actual = testee.isExpressionMatch("sub");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenLocalWildcardAtBeginningNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenLocalWildcardAtBeginningNotUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox");
+            boolean actual = testee.isExpressionMatch("mailbox");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenLocalWildcardAtBeginningUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenLocalWildcardAtBeginningUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("submailbox");
+            boolean actual = testee.isExpressionMatch("submailbox");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchSubFolderWhenLocalWildcardAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchSubFolderWhenLocalWildcardAtBeginning() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenLocalWildcardAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenLocalWildcardAtBeginning() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox.sub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox.sub"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("");
+            boolean actual = testee.isExpressionMatch("");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenLocalWildcardInMiddleAndMissingEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenLocalWildcardInMiddleAndMissingEndName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub");
+            boolean actual = testee.isExpressionMatch("sub");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenLocalWildcardInMiddleAndMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenLocalWildcardInMiddleAndMatching() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("submailbox");
+            boolean actual = testee.isExpressionMatch("submailbox");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenLocalWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub123mailbox");
+            boolean actual = testee.isExpressionMatch("sub123mailbox");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchSubFolderWhenLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchSubFolderWhenLocalWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchSubFolderWhenLocalWildcardInMiddleAndExpandedMiddleName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchSubFolderWhenLocalWildcardInMiddleAndExpandedMiddleName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.123mailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.123mailbox"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenLocalWildcardInMiddleAndMissingBeginningName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenLocalWildcardInMiddleAndMissingBeginningName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox");
+            boolean actual = testee.isExpressionMatch("mailbox");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenLocalWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchSubFolderWhenFreeWildcardAtEnd() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchSubFolderWhenFreeWildcardAtEnd() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeWildcardAtEnd() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeWildcardAtEnd() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("");
+            boolean actual = testee.isExpressionMatch("");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchFolderWhenFreeWildcardAtEndAndNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchFolderWhenFreeWildcardAtEndAndNoMatching() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub");
+            boolean actual = testee.isExpressionMatch("sub");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtEndNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtEndNotUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox");
+            boolean actual = testee.isExpressionMatch("mailbox");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtEndUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtEndUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox*", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox123");
+            boolean actual = testee.isExpressionMatch("mailbox123");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeWildcardAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeWildcardAtBeginning() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("");
+            boolean actual = testee.isExpressionMatch("");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchFolderWhenFreeWildcardAtBeginningAndNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchFolderWhenFreeWildcardAtBeginningAndNoMatching() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub");
+            boolean actual = testee.isExpressionMatch("sub");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtBeginningNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtBeginningNotUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox");
+            boolean actual = testee.isExpressionMatch("mailbox");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtBeginningUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenFreeWildcardAtBeginningUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("submailbox");
+            boolean actual = testee.isExpressionMatch("submailbox");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchSubFolderWhenFreeWildcardAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchSubFolderWhenFreeWildcardAtBeginning() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("");
+            boolean actual = testee.isExpressionMatch("");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchFolderWhenFreeWildcardInMiddleAndMissingEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchFolderWhenFreeWildcardInMiddleAndMissingEndName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub");
+            boolean actual = testee.isExpressionMatch("sub");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenFreeWildcardInMiddleNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenFreeWildcardInMiddleNotUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("submailbox");
+            boolean actual = testee.isExpressionMatch("submailbox");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchSubFolderWhenFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchSubFolderWhenFreeWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenFreeWildcardInMiddleNotUsedAndMissingBeginningName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenFreeWildcardInMiddleNotUsedAndMissingBeginningName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox");
+            boolean actual = testee.isExpressionMatch("mailbox");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchDeeplyNestedFolderWhenFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchDeeplyNestedFolderWhenFreeWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenEmptyNameAndDoubleFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenEmptyNameAndDoubleFreeWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("");
+            boolean actual = testee.isExpressionMatch("");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenDoubleFreeWildcardInMiddleAndMissingEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenDoubleFreeWildcardInMiddleAndMissingEndName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub");
+            boolean actual = testee.isExpressionMatch("sub");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnTrueWhenDoubleFreeWildcardInMiddleNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnTrueWhenDoubleFreeWildcardInMiddleNotUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("submailbox");
+            boolean actual = testee.isExpressionMatch("submailbox");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchSubFolderWhenDoubleFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchSubFolderWhenDoubleFreeWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenDoubleFreeWildcardInMiddleAndMissingBeginningName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenDoubleFreeWildcardInMiddleAndMissingBeginningName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox");
+            boolean actual = testee.isExpressionMatch("mailbox");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchDeeplyNestedFolderWhenDoubleFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchDeeplyNestedFolderWhenDoubleFreeWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub**mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenEmptyNameAndFreeLocalWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("");
+            boolean actual = testee.isExpressionMatch("");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenFreeLocalWildcardInMiddleAndMissingEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenFreeLocalWildcardInMiddleAndMissingEndName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub");
+            boolean actual = testee.isExpressionMatch("sub");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenFreeLocalWildcardInMiddleNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenFreeLocalWildcardInMiddleNotUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("submailbox");
+            boolean actual = testee.isExpressionMatch("submailbox");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchSubFolderWhenFreeLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchSubFolderWhenFreeLocalWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenFreeLocalWildcardInMiddleAndMissingBeginningName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenFreeLocalWildcardInMiddleAndMissingBeginningName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox");
+            boolean actual = testee.isExpressionMatch("mailbox");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchDeeplyNestedFolderWhenFreeLocalWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchDeeplyNestedFolderWhenFreeLocalWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*%mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldReturnFalseWhenEmptyNameAndLocalFreeWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("");
+            boolean actual = testee.isExpressionMatch("");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchFolderWhenLocalFreeWildcardInMiddleAndMissingEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchFolderWhenLocalFreeWildcardInMiddleAndMissingEndName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("sub");
+            boolean actual = testee.isExpressionMatch("sub");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenLocalFreewildcardInMiddleNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenLocalFreewildcardInMiddleNotUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("submailbox");
+            boolean actual = testee.isExpressionMatch("submailbox");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchSubFolderWhenLocalFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchSubFolderWhenLocalFreeWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchFolderWhenLocalFreeWildcardInMiddleAndMissingBeginningName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchFolderWhenLocalFreeWildcardInMiddleAndMissingBeginningName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox");
+            boolean actual = testee.isExpressionMatch("mailbox");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchDeeplyNestedFolderWhenLocalFreeWildcardInMiddle() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchDeeplyNestedFolderWhenLocalFreeWildcardInMiddle() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%*mailbox", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subw.hat.eve.rmailbox"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenMultipleFreeWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenMultipleFreeWildcards() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("submailboxsub");
+            boolean actual = testee.isExpressionMatch("submailboxsub");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchDeeplyNestedFolderWhenMultipleFreeWildcardsNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchDeeplyNestedFolderWhenMultipleFreeWildcardsNotUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox.sub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailbox.sub"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchDeeplyNestedFolderWhenMultipleFreeWildcardsUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchDeeplyNestedFolderWhenMultipleFreeWildcardsUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subtosh.boshmailboxtosh.boshsubboshtosh"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("subtosh.boshmailboxtosh.boshsubboshtosh"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenMultipleFreeWildcardsAndMissingMiddleName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenMultipleFreeWildcardsAndMissingMiddleName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.a.sub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.a.sub"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenMultipleFreeWildcardsAndMissingEndName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenMultipleFreeWildcardsAndMissingEndName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.a.submailbox.u"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.a.submailbox.u"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenMultipleFreeWildcardsAndMissingBeginningdName() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenMultipleFreeWildcardsAndMissingBeginningdName() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox*sub**", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("utosh.boshmailboxtosh.boshsubasubboshtoshmailboxu"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("utosh.boshmailboxtosh.boshsubasubboshtoshmailboxu"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenMixedLocalFreeWildcardsNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox*sub", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenMixedLocalFreeWildcardsNotUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox*sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("submailboxsub");
+            boolean actual = testee.isExpressionMatch("submailboxsub");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchSubFolderWhenMixedLocalFreeWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox*sub", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchSubFolderWhenMixedLocalFreeWildcards() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub%mailbox*sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailboxsub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailboxsub"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenMixedFreeLocalWildcardsNotUsed() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenMixedFreeLocalWildcardsNotUsed() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("submailboxsub");
+            boolean actual = testee.isExpressionMatch("submailboxsub");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchSubFolderWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchSubFolderWhenMixedFreeLocalWildcards() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailboxsub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailboxsub"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchSubFolderWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchSubFolderWhenMixedFreeLocalWildcards() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("submailbox.sub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("submailbox.sub"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchFolderWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchFolderWhenMixedFreeLocalWildcards() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("submailboxwhateversub");
+            boolean actual = testee.isExpressionMatch("submailboxwhateversub");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchSubFolderEndingWithDelimiterWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchSubFolderEndingWithDelimiterWhenMixedFreeLocalWildcards() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("submailboxsub.Whatever."));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("submailboxsub.Whatever."));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenMixedFreeLocalWildcards() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailboxsub.sub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailboxsub.sub"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchSubFoldeWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchSubFoldeWhenMixedFreeLocalWildcards() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailboxsub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.mailboxsub"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchDeeplyNestedFoldeWhenMixedFreeLocalWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchDeeplyNestedFoldeWhenMixedFreeLocalWildcards() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "sub*mailbox%sub", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.whatever.mailbox123sub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("sub.whatever.mailbox123sub"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchFolderWhenTwoLocalPathDelimitedWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("%.%"), folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchFolderWhenTwoLocalPathDelimitedWildcards() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("%.%"), folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("mailbox");
+            boolean actual = testee.isExpressionMatch("mailbox");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenTwoLocalPathDelimitedWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("%.%"), folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenTwoLocalPathDelimitedWildcards() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("%.%"), folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub.sub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub.sub"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchSubFolderWhenTwoLocalPathDelimitedWildcards() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("%.%"), folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchSubFolderWhenTwoLocalPathDelimitedWildcards() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("%.%"), folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("mailbox.sub"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldMatchSubFolderWhenFreeWildcardAndPathDelimiterAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("*.test"), folderDelimiter());
+        @Test
+        void isExpressionMatchShouldMatchSubFolderWhenFreeWildcardAndPathDelimiterAtBeginning() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("*.test"), folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("blah.test"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("blah.test"));
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchSubFolderWhenWhenFreeWildcardAndPathDelimiterAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("*.test"), folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchSubFolderWhenWhenFreeWildcardAndPathDelimiterAtBeginning() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("*.test"), folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("blah.test3"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("blah.test3"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenFreeWildcardAndPathDelimiterAtBeginning() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("*.test"), folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotMatchDeeplyNestedFolderWhenFreeWildcardAndPathDelimiterAtBeginning() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, adjustToActiveFolderDelimiter("*.test"), folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("blah.test.go"));
+            boolean actual = testee.isExpressionMatch(adjustToActiveFolderDelimiter("blah.test.go"));
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldIgnoreRegexInjection() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "folder^$!)(%3", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldIgnoreRegexInjection() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "folder^$!)(%3", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("folder^$!)(123");
+            boolean actual = testee.isExpressionMatch("folder^$!)(123");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingEndOfQuoteAndNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Efo.", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingEndOfQuoteAndNoMatching() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Efo.", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("\\Efol");
+            boolean actual = testee.isExpressionMatch("\\Efol");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingEndOfQuoteAndMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Efo.", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingEndOfQuoteAndMatching() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Efo.", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("\\Efo.");
+            boolean actual = testee.isExpressionMatch("\\Efo.");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingBeginOfQuoteAndNoMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Qfo?", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingBeginOfQuoteAndNoMatching() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Qfo?", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("\\Qfol");
+            boolean actual = testee.isExpressionMatch("\\Qfol");
 
-        assertThat(actual).isFalse();
-    }
+            assertThat(actual).isFalse();
+        }
 
-    @Test
-    void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingBeginOfQuoteAndMatching() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Qfo?", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldIgnoreRegexInjectionWhenUsingBeginOfQuoteAndMatching() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "\\Qfo?", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("\\Qfo?");
+            boolean actual = testee.isExpressionMatch("\\Qfo?");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotEscapeFreeWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "folder\\*", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotEscapeFreeWildcard() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "folder\\*", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("folder\\123");
+            boolean actual = testee.isExpressionMatch("folder\\123");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
 
-    @Test
-    void isExpressionMatchShouldNotEscapeLocalWildcard() {
-        PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "folder\\%", folderDelimiter());
+        @Test
+        void isExpressionMatchShouldNotEscapeLocalWildcard() {
+            PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "folder\\%", folderDelimiter());
 
-        boolean actual = testee.isExpressionMatch("folder\\123");
+            boolean actual = testee.isExpressionMatch("folder\\123");
 
-        assertThat(actual).isTrue();
-    }
+            assertThat(actual).isTrue();
+        }
     }
 }
\ No newline at end of file

From 697869c72de294a26e28767ed99ec0843ce98191 Mon Sep 17 00:00:00 2001
From: Jan-Eric Hellenberg <janeric.hellenberg@gmail.com>
Date: Wed, 8 Jan 2025 10:26:43 +0100
Subject: [PATCH 8/9] James-4099 Allow more characters as path delimiter

---
 .../servers/partials/configure/jvm.adoc       |  2 +-
 .../james/mailbox/model/MailboxConstants.java | 14 ++++++-
 .../james/mailbox/model/MailboxPathTest.java  | 36 +++++++++++++++++-
 .../model/search/PrefixedRegexTest.java       | 37 ++++++++++++++++++-
 .../imap/main/DefaultPathConverterTest.java   | 37 ++++++++++++++++++-
 .../docker-configuration/jvm.properties       |  2 +-
 .../sample-configuration/jvm.properties       |  2 +-
 .../docker-configuration/jvm.properties       |  2 +-
 .../sample-configuration/jvm.properties       |  2 +-
 .../docker-configuration/jvm.properties       |  2 +-
 .../sample-configuration/jvm.properties       |  2 +-
 .../sample-configuration/jvm.properties       |  2 +-
 .../sample-configuration/jvm.properties       |  2 +-
 .../sample-configuration/jvm.properties       |  2 +-
 .../sample-configuration/jvm.properties       |  2 +-
 15 files changed, 127 insertions(+), 19 deletions(-)

diff --git a/docs/modules/servers/partials/configure/jvm.adoc b/docs/modules/servers/partials/configure/jvm.adoc
index 11f22bc5a32..0147537a8a0 100644
--- a/docs/modules/servers/partials/configure/jvm.adoc
+++ b/docs/modules/servers/partials/configure/jvm.adoc
@@ -18,7 +18,7 @@ Ex in `jvm.properties`
 james.mailbox.folder.delimiter=dot
 ----
 
-Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter), pipe ('|'), comma (','), colon (':'), semicolon (';').
 
 == Control the threshold memory
 This governs the threshold MimeMessageInputStreamSource relies on for storing MimeMessage content on disk.
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxConstants.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxConstants.java
index 3afd9f21c7f..6117e2b9e13 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxConstants.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxConstants.java
@@ -38,9 +38,19 @@ public class MailboxConstants {
     public static char FOLDER_DELIMITER = Optional.ofNullable(System.getProperty("james.mailbox.folder.delimiter"))
             .map(MailboxFolderDelimiter::parse).orElse(MailboxFolderDelimiter.DOT).value;
 
-    enum MailboxFolderDelimiter {
+    public enum MailboxFolderDelimiter {
+        // NOTE: When changing this list, make sure to adjust the MailboxFolderDelimiterAwareTests as well.
+        // Values currently left-out explicitly:
+        // hash sign '#' (Clashes with namespace prefix character)
+        // backslash '\\' (Anticipated some problems with the PrefixedRegex matching.
+        //                 Also, because it is the escaping character, it can generally be a bit more annoying
+        //                 to deal with in strings)
         DOT('.'),
-        SLASH('/');
+        SLASH('/'),
+        PIPE('|'),
+        COMMA(','),
+        COLON(':'),
+        SEMICOLON(';');
 
         public final char value;
 
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java
index 25426515435..01d11637fbe 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MailboxPathTest.java
@@ -48,7 +48,7 @@ class MailboxPathTest {
     public class DotDelimiter extends TestBase {
         @Override
         public char folderDelimiter() {
-            return '.';
+            return MailboxConstants.MailboxFolderDelimiter.DOT.value;
         }
     }
 
@@ -56,7 +56,39 @@ public char folderDelimiter() {
     public class SlashDelimiter extends TestBase {
         @Override
         public char folderDelimiter() {
-            return '/';
+            return MailboxConstants.MailboxFolderDelimiter.SLASH.value;
+        }
+    }
+
+    @Nested
+    public class PipeDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return MailboxConstants.MailboxFolderDelimiter.PIPE.value;
+        }
+    }
+
+    @Nested
+    public class CommaDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return MailboxConstants.MailboxFolderDelimiter.COMMA.value;
+        }
+    }
+
+    @Nested
+    public class ColonDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return MailboxConstants.MailboxFolderDelimiter.COLON.value;
+        }
+    }
+
+    @Nested
+    public class SemicolonDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return MailboxConstants.MailboxFolderDelimiter.SEMICOLON.value;
         }
     }
 
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java
index d72becf65af..e15ff3269fa 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java
@@ -25,6 +25,7 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxFolderDelimiterAwareTest;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
@@ -38,7 +39,7 @@ class PrefixedRegexTest {
     public class DotDelimiter extends TestBase {
         @Override
         public char folderDelimiter() {
-            return '.';
+            return MailboxConstants.MailboxFolderDelimiter.DOT.value;
         }
     }
 
@@ -46,7 +47,39 @@ public char folderDelimiter() {
     public class SlashDelimiter extends TestBase {
         @Override
         public char folderDelimiter() {
-            return '/';
+            return MailboxConstants.MailboxFolderDelimiter.SLASH.value;
+        }
+    }
+
+    @Nested
+    public class PipeDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return MailboxConstants.MailboxFolderDelimiter.PIPE.value;
+        }
+    }
+
+    @Nested
+    public class CommaDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return MailboxConstants.MailboxFolderDelimiter.COMMA.value;
+        }
+    }
+
+    @Nested
+    public class ColonDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return MailboxConstants.MailboxFolderDelimiter.COLON.value;
+        }
+    }
+
+    @Nested
+    public class SemicolonDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return MailboxConstants.MailboxFolderDelimiter.SEMICOLON.value;
         }
     }
 
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/main/DefaultPathConverterTest.java b/protocols/imap/src/test/java/org/apache/james/imap/main/DefaultPathConverterTest.java
index 476d1c670ea..29535c69ebf 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/main/DefaultPathConverterTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/main/DefaultPathConverterTest.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.imap.main;
 
+import org.apache.james.mailbox.model.MailboxConstants;
 import org.junit.jupiter.api.Nested;
 
 public class DefaultPathConverterTest {
@@ -26,7 +27,7 @@ public class DefaultPathConverterTest {
     public class DotDelimiter extends TestBase {
         @Override
         public char folderDelimiter() {
-            return '.';
+            return MailboxConstants.MailboxFolderDelimiter.DOT.value;
         }
     }
 
@@ -34,7 +35,39 @@ public char folderDelimiter() {
     public class SlashDelimiter extends TestBase {
         @Override
         public char folderDelimiter() {
-            return '/';
+            return MailboxConstants.MailboxFolderDelimiter.SLASH.value;
+        }
+    }
+
+    @Nested
+    public class PipeDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return MailboxConstants.MailboxFolderDelimiter.PIPE.value;
+        }
+    }
+
+    @Nested
+    public class CommaDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return MailboxConstants.MailboxFolderDelimiter.COMMA.value;
+        }
+    }
+
+    @Nested
+    public class ColonDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return MailboxConstants.MailboxFolderDelimiter.COLON.value;
+        }
+    }
+
+    @Nested
+    public class SemicolonDelimiter extends TestBase {
+        @Override
+        public char folderDelimiter() {
+            return MailboxConstants.MailboxFolderDelimiter.SEMICOLON.value;
         }
     }
 
diff --git a/server/apps/cassandra-app/docker-configuration/jvm.properties b/server/apps/cassandra-app/docker-configuration/jvm.properties
index 3c81157e45a..c4f1119578b 100644
--- a/server/apps/cassandra-app/docker-configuration/jvm.properties
+++ b/server/apps/cassandra-app/docker-configuration/jvm.properties
@@ -5,7 +5,7 @@
 # my.property=whatever
 
 # The delimiter used to separate parent/child folders.
-# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter), pipe ('|'), comma (','), colon (':'), semicolon (';').
 # WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
 # will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
 # james.mailbox.folder.delimiter=dot
diff --git a/server/apps/cassandra-app/sample-configuration/jvm.properties b/server/apps/cassandra-app/sample-configuration/jvm.properties
index d763daefa84..0fdbbe11721 100644
--- a/server/apps/cassandra-app/sample-configuration/jvm.properties
+++ b/server/apps/cassandra-app/sample-configuration/jvm.properties
@@ -5,7 +5,7 @@
 # my.property=whatever
 
 # The delimiter used to separate parent/child folders.
-# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter), pipe ('|'), comma (','), colon (':'), semicolon (';').
 # WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
 # will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
 # james.mailbox.folder.delimiter=dot
diff --git a/server/apps/distributed-app/docker-configuration/jvm.properties b/server/apps/distributed-app/docker-configuration/jvm.properties
index 3c81157e45a..c4f1119578b 100644
--- a/server/apps/distributed-app/docker-configuration/jvm.properties
+++ b/server/apps/distributed-app/docker-configuration/jvm.properties
@@ -5,7 +5,7 @@
 # my.property=whatever
 
 # The delimiter used to separate parent/child folders.
-# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter), pipe ('|'), comma (','), colon (':'), semicolon (';').
 # WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
 # will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
 # james.mailbox.folder.delimiter=dot
diff --git a/server/apps/distributed-app/sample-configuration/jvm.properties b/server/apps/distributed-app/sample-configuration/jvm.properties
index 600d91b3294..20b9d1c0673 100644
--- a/server/apps/distributed-app/sample-configuration/jvm.properties
+++ b/server/apps/distributed-app/sample-configuration/jvm.properties
@@ -8,7 +8,7 @@
 config.file=conf/cassandra-driver.conf
 
 # The delimiter used to separate parent/child folders.
-# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter), pipe ('|'), comma (','), colon (':'), semicolon (';').
 # WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
 # will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
 # james.mailbox.folder.delimiter=dot
diff --git a/server/apps/distributed-pop3-app/docker-configuration/jvm.properties b/server/apps/distributed-pop3-app/docker-configuration/jvm.properties
index 3c81157e45a..c4f1119578b 100644
--- a/server/apps/distributed-pop3-app/docker-configuration/jvm.properties
+++ b/server/apps/distributed-pop3-app/docker-configuration/jvm.properties
@@ -5,7 +5,7 @@
 # my.property=whatever
 
 # The delimiter used to separate parent/child folders.
-# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter), pipe ('|'), comma (','), colon (':'), semicolon (';').
 # WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
 # will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
 # james.mailbox.folder.delimiter=dot
diff --git a/server/apps/distributed-pop3-app/sample-configuration/jvm.properties b/server/apps/distributed-pop3-app/sample-configuration/jvm.properties
index 37646e5cec2..fb6e7bae9fc 100644
--- a/server/apps/distributed-pop3-app/sample-configuration/jvm.properties
+++ b/server/apps/distributed-pop3-app/sample-configuration/jvm.properties
@@ -5,7 +5,7 @@
 # my.property=whatever
 
 # The delimiter used to separate parent/child folders.
-# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter), pipe ('|'), comma (','), colon (':'), semicolon (';').
 # WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
 # will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
 # james.mailbox.folder.delimiter=dot
diff --git a/server/apps/jpa-app/sample-configuration/jvm.properties b/server/apps/jpa-app/sample-configuration/jvm.properties
index 8cf7dfb8614..6e5c37ba685 100644
--- a/server/apps/jpa-app/sample-configuration/jvm.properties
+++ b/server/apps/jpa-app/sample-configuration/jvm.properties
@@ -5,7 +5,7 @@
 # my.property=whatever
 
 # The delimiter used to separate parent/child folders.
-# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter), pipe ('|'), comma (','), colon (':'), semicolon (';').
 # WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
 # will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
 # james.mailbox.folder.delimiter=dot
diff --git a/server/apps/jpa-smtp-app/sample-configuration/jvm.properties b/server/apps/jpa-smtp-app/sample-configuration/jvm.properties
index a90fd7a31f2..e9d55bd1519 100644
--- a/server/apps/jpa-smtp-app/sample-configuration/jvm.properties
+++ b/server/apps/jpa-smtp-app/sample-configuration/jvm.properties
@@ -5,7 +5,7 @@
 # my.property=whatever
 
 # The delimiter used to separate parent/child folders.
-# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter), pipe ('|'), comma (','), colon (':'), semicolon (';').
 # WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
 # will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
 # james.mailbox.folder.delimiter=dot
diff --git a/server/apps/memory-app/sample-configuration/jvm.properties b/server/apps/memory-app/sample-configuration/jvm.properties
index c362f00894c..19fc9a33c0b 100644
--- a/server/apps/memory-app/sample-configuration/jvm.properties
+++ b/server/apps/memory-app/sample-configuration/jvm.properties
@@ -5,7 +5,7 @@
 # my.property=whatever
 
 # The delimiter used to separate parent/child folders.
-# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter), pipe ('|'), comma (','), colon (':'), semicolon (';').
 # WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
 # will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
 # james.mailbox.folder.delimiter=dot
diff --git a/server/apps/scaling-pulsar-smtp/sample-configuration/jvm.properties b/server/apps/scaling-pulsar-smtp/sample-configuration/jvm.properties
index 886dec96f5b..9e3220b277a 100644
--- a/server/apps/scaling-pulsar-smtp/sample-configuration/jvm.properties
+++ b/server/apps/scaling-pulsar-smtp/sample-configuration/jvm.properties
@@ -5,7 +5,7 @@
 # my.property=whatever
 
 # The delimiter used to separate parent/child folders.
-# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter).
+# Optional. Allowed values are: dot (will use '.' as delimiter), slash (will use '/' as delimiter), pipe ('|'), comma (','), colon (':'), semicolon (';').
 # WARNING: This value should only be changed when setting up a new deployment. Changing the parameter for an existing deployments
 # will likely lead to failure of some system components, as occurrences of old delimiter will still be present in the database/data store.
 # james.mailbox.folder.delimiter=dot

From 35471cd04be32daa6a6be293779c0772e3fe0c7c Mon Sep 17 00:00:00 2001
From: Jan-Eric Hellenberg <janeric.hellenberg@gmail.com>
Date: Wed, 8 Jan 2025 11:57:11 +0100
Subject: [PATCH 9/9] James-4099 Use configured mailbox folder delimiter in the
 FileIntoAction

---
 .../james/transport/mailets/jsieve/FileIntoAction.java   | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/FileIntoAction.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/FileIntoAction.java
index 72fd58d5b03..ea04381a2e8 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/FileIntoAction.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/FileIntoAction.java
@@ -20,6 +20,7 @@
 
 import jakarta.mail.MessagingException;
 
+import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.jsieve.mail.Action;
 import org.apache.jsieve.mail.ActionFileInto;
 import org.apache.mailet.Mail;
@@ -34,8 +35,6 @@
 public class FileIntoAction implements MailAction {
     private static final Logger LOGGER = LoggerFactory.getLogger(FileIntoAction.class);
 
-    private static final char HIERARCHY_DELIMITER = '.';
-
     @Override
     public void execute(Action action, Mail mail, ActionContext context) throws MessagingException {
         if (action instanceof ActionFileInto) {
@@ -68,7 +67,7 @@ public void execute(Action action, Mail mail, ActionContext context) throws Mess
      */
     public void execute(ActionFileInto anAction, Mail aMail, final ActionContext context) throws MessagingException {
         String destinationMailbox = getDestinationMailbox(anAction);
-        String mailbox = destinationMailbox.replace(HIERARCHY_DELIMITER, '/');
+        String mailbox = destinationMailbox.replace(MailboxConstants.FOLDER_DELIMITER, '/');
         String url = "mailbox://" + context.getRecipient().asString() + mailbox;
 
         context.post(url, aMail);
@@ -76,8 +75,8 @@ public void execute(ActionFileInto anAction, Mail aMail, final ActionContext con
     }
 
     private String getDestinationMailbox(ActionFileInto anAction) {
-        if (!(anAction.getDestination().length() > 0 && anAction.getDestination().charAt(0) == HIERARCHY_DELIMITER)) {
-            return HIERARCHY_DELIMITER + anAction.getDestination();
+        if (anAction.getDestination().isEmpty() || anAction.getDestination().charAt(0) != MailboxConstants.FOLDER_DELIMITER) {
+            return MailboxConstants.FOLDER_DELIMITER + anAction.getDestination();
         }
         return anAction.getDestination();
     }