diff --git a/dmnverifierapi/README.md b/dmnverifierapi/README.md
index 204bbb750e4e03dd2e8d8a28f2b9bf3775cfe116..2e33d412497bedc95e34e3f25422b47dcb681bed 100644
--- a/dmnverifierapi/README.md
+++ b/dmnverifierapi/README.md
@@ -8,5 +8,5 @@ This project contains all source files of the implementation, created for the ma
 
 ## Backend
 Based on
-- [Quarkus](https://quarkus.io/guides/maven-tooling)
+- [Quarkus](https://quarkus.io/)
 - [Camunda DMN](https://github.com/bpmn-io/dmn-js)
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/AbstractBoundary.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/AbstractBoundary.java
index 868e621d9e0b06db428e56fd57f59c1fe42d9759..7e95f7012406985fec9e440fd78420e1aef6709b 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/AbstractBoundary.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/AbstractBoundary.java
@@ -9,6 +9,7 @@ import de.unikoblenz.fgbks.base.utils.boundary.creater.BoundaryCreaterType;
 import de.unikoblenz.fgbks.base.utils.boundary.impl.InvalidBoundary;
 import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VTypeRef;
 import java.util.HashMap;
+import java.util.Map;
 import java.util.Optional;
 import org.apache.commons.lang3.Validate;
 
@@ -18,7 +19,7 @@ public abstract class AbstractBoundary<T extends Comparable<? super T>> implemen
   private HashMap<BoundaryBiCreaterType, BoundaryBiCreater> biCreaterFunctions;
   private HashMap<BoundaryCreaterType, BoundaryCreater> createrFunctions;
   private Class<T> type;
-  private String text;
+  protected String text;
 
   protected AbstractBoundary(String text, Class<T> type) {
     this.text = text;
@@ -113,11 +114,11 @@ public abstract class AbstractBoundary<T extends Comparable<? super T>> implemen
 
   protected abstract void validate();
 
-  protected abstract HashMap<BoundaryCheckType, BoundaryCheck> getChecker();
+  protected abstract Map<BoundaryCheckType, BoundaryCheck> getChecker();
 
-  protected abstract HashMap<BoundaryBiCreaterType, BoundaryBiCreater> getBiCreater();
+  protected abstract Map<BoundaryBiCreaterType, BoundaryBiCreater> getBiCreater();
 
-  protected abstract HashMap<BoundaryCreaterType, BoundaryCreater> getCreater();
+  protected abstract Map<BoundaryCreaterType, BoundaryCreater> getCreater();
 
   @Override
   public String toString() {
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/AbstractGrowingBoundary.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/AbstractGrowingBoundary.java
index 8298ef97d650f85672cc8ed11d23529534b40c51..1672df6b515e3a1ae3ec9d7f4c1d1520699ad4d4 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/AbstractGrowingBoundary.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/AbstractGrowingBoundary.java
@@ -36,7 +36,9 @@ import de.unikoblenz.fgbks.base.utils.boundary.creater.BoundaryCreater;
 import de.unikoblenz.fgbks.base.utils.boundary.creater.BoundaryCreaterType;
 import de.unikoblenz.fgbks.base.utils.boundary.creater.CreaterLower;
 import de.unikoblenz.fgbks.base.utils.boundary.creater.CreaterUpper;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.Map;
 import java.util.Objects;
 import org.apache.commons.lang3.Validate;
 
@@ -117,18 +119,18 @@ public abstract class AbstractGrowingBoundary<T extends Comparable<? super T>>
   }
 
   @Override
-  protected HashMap<BoundaryCheckType, BoundaryCheck> getChecker() {
-    return checkerMap;
+  protected Map<BoundaryCheckType, BoundaryCheck> getChecker() {
+    return Collections.unmodifiableMap(checkerMap);
   }
 
   @Override
-  protected HashMap<BoundaryBiCreaterType, BoundaryBiCreater> getBiCreater() {
-    return biCreaterMap;
+  protected Map<BoundaryBiCreaterType, BoundaryBiCreater> getBiCreater() {
+    return Collections.unmodifiableMap(biCreaterMap);
   }
 
   @Override
-  protected HashMap<BoundaryCreaterType, BoundaryCreater> getCreater() {
-    return createrMap;
+  protected Map<BoundaryCreaterType, BoundaryCreater> getCreater() {
+    return Collections.unmodifiableMap(createrMap);
   }
 
   @Override
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringAppend.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringAppend.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b2d6e2a7538a1155a092e050d9306ace69db28c
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringAppend.java
@@ -0,0 +1,27 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+import java.util.Optional;
+
+public class BiCreaterStringAppend extends AbstractBoundaryBiCreater<StringBoundary> {
+
+  private static final BiCreaterStringAppend instance = new BiCreaterStringAppend();
+
+  private BiCreaterStringAppend() {
+    super();
+  }
+
+  public static BiCreaterStringAppend getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryBiCreaterType getType() {
+    return BoundaryBiCreaterType.APPEND;
+  }
+
+  @Override
+  public Optional<StringBoundary> create(StringBoundary b1, StringBoundary b2) {
+    return Optional.empty();
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringBetween.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringBetween.java
new file mode 100644
index 0000000000000000000000000000000000000000..3b6f10a5d2e84ad44110dada1df648f5dbb8c175
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringBetween.java
@@ -0,0 +1,27 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+import java.util.Optional;
+
+public class BiCreaterStringBetween extends AbstractBoundaryBiCreater<StringBoundary> {
+
+  private static final BiCreaterStringBetween instance = new BiCreaterStringBetween();
+
+  private BiCreaterStringBetween() {
+    super();
+  }
+
+  public static BiCreaterStringBetween getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryBiCreaterType getType() {
+    return BoundaryBiCreaterType.BETWEEN;
+  }
+
+  @Override
+  public Optional<StringBoundary> create(StringBoundary b1, StringBoundary b2) {
+    return Optional.empty();
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringCombine.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringCombine.java
new file mode 100644
index 0000000000000000000000000000000000000000..a537cd73ee481a295ed723701b8b58bb3f1d8ada
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringCombine.java
@@ -0,0 +1,70 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+
+public class BiCreaterStringCombine extends AbstractBoundaryBiCreater<StringBoundary> {
+
+  private static final BiCreaterStringCombine instance = new BiCreaterStringCombine();
+
+  private BiCreaterStringCombine() {
+    super();
+  }
+
+  public static BiCreaterStringCombine getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryBiCreaterType getType() {
+    return BoundaryBiCreaterType.COMBINE;
+  }
+
+  @Override
+  public Optional<StringBoundary> create(StringBoundary b1, StringBoundary b2) {
+    if (b1.isMatchAny() || b2.isMatchAny()) {
+      return Optional.of(StringBoundary.getBuilder().isMatchAny(true).build());
+    }
+    if (!b1.matchesNoneOfValues() && !b2.matchesNoneOfValues()) {
+      return Optional.of(
+          StringBoundary.getBuilder().addValues(b1.getValues()).addValues(b2.getValues()).build());
+    }
+    Set<String> values = new HashSet<>();
+    if (b1.matchesNoneOfValues() && b2.matchesNoneOfValues()) {
+      values = intersection(b1.getValues(), b2.getValues());
+    } else if (b1.matchesNoneOfValues()) {
+      values = leftInter(b1.getValues(), b2.getValues());
+    } else if (b2.matchesNoneOfValues()) {
+      values = leftInter(b2.getValues(), b1.getValues());
+    }
+    return Optional.of(
+        StringBoundary.getBuilder()
+            .isMatchNoneOfValues(true)
+            .addValues(values)
+            .isMatchAny(values.size() == 0)
+            .build());
+  }
+
+  private Set<String> leftInter(String[] values1, String[] values2) {
+    Set<String> vals = new HashSet<>(Arrays.asList(values1));
+    for (String v : values2) {
+      vals.removeIf(x -> x.equals(v));
+    }
+    return vals;
+  }
+
+  private Set<String> intersection(String[] values1, String[] values2) {
+    Set<String> vals = new HashSet<>();
+    for (String v1 : values1) {
+      for (String v2 : values2) {
+        if (v1.equals(v2)) {
+          vals.add(v1);
+        }
+      }
+    }
+    return vals;
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringIntersection.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringIntersection.java
new file mode 100644
index 0000000000000000000000000000000000000000..016fcb0c02e89d5a02092405b91f95cc3d679c0a
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringIntersection.java
@@ -0,0 +1,27 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+import java.util.Optional;
+
+public class BiCreaterStringIntersection extends AbstractBoundaryBiCreater<StringBoundary> {
+
+  private static final BiCreaterStringIntersection instance = new BiCreaterStringIntersection();
+
+  private BiCreaterStringIntersection() {
+    super();
+  }
+
+  public static BiCreaterStringIntersection getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryBiCreaterType getType() {
+    return BoundaryBiCreaterType.INTERSECTION;
+  }
+
+  @Override
+  public Optional<StringBoundary> create(StringBoundary b1, StringBoundary b2) {
+    return Optional.empty();
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringLowerBounds.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringLowerBounds.java
new file mode 100644
index 0000000000000000000000000000000000000000..741c406a9ace324fa0885d0c75151e5b1a6be86e
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringLowerBounds.java
@@ -0,0 +1,27 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+import java.util.Optional;
+
+public class BiCreaterStringLowerBounds extends AbstractBoundaryBiCreater<StringBoundary> {
+
+  private static final BiCreaterStringLowerBounds instance = new BiCreaterStringLowerBounds();
+
+  private BiCreaterStringLowerBounds() {
+    super();
+  }
+
+  public static BiCreaterStringLowerBounds getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryBiCreaterType getType() {
+    return BoundaryBiCreaterType.LOWER_BOUNDS;
+  }
+
+  @Override
+  public Optional<StringBoundary> create(StringBoundary b1, StringBoundary b2) {
+    return Optional.empty();
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringUpperBounds.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringUpperBounds.java
new file mode 100644
index 0000000000000000000000000000000000000000..27f0124244ed1cdf62a7ad0c15c0462f68da3ad8
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringUpperBounds.java
@@ -0,0 +1,27 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+import java.util.Optional;
+
+public class BiCreaterStringUpperBounds extends AbstractBoundaryBiCreater<StringBoundary> {
+
+  private static final BiCreaterStringUpperBounds instance = new BiCreaterStringUpperBounds();
+
+  private BiCreaterStringUpperBounds() {
+    super();
+  }
+
+  public static BiCreaterStringUpperBounds getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryBiCreaterType getType() {
+    return BoundaryBiCreaterType.UPPER_BOUNDS;
+  }
+
+  @Override
+  public Optional<StringBoundary> create(StringBoundary b1, StringBoundary b2) {
+    return Optional.empty();
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterStringLower.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterStringLower.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b24bd5aa9b5084d7d9b2a4286c2188a1f1f0349
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterStringLower.java
@@ -0,0 +1,31 @@
+package de.unikoblenz.fgbks.base.utils.boundary.creater;
+
+import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+import java.util.Optional;
+
+public class CreaterStringLower extends AbstractBoundaryCreater<StringBoundary> {
+
+  private static final CreaterStringLower instance = new CreaterStringLower();
+
+  private CreaterStringLower() {
+    super();
+  }
+
+  public static CreaterStringLower getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryCreaterType getType() {
+    return BoundaryCreaterType.LOWER;
+  }
+
+  @Override
+  public Optional<StringBoundary> create(StringBoundary b) {
+    return Optional.of(StringBoundary.getBuilder()
+        .addValues(b.getValues())
+        .isMatchNoneOfValues(!b.matchesNoneOfValues())
+        .isMatchAny(b.getAmountOfElements() == 0)
+        .build());
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterStringUpper.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterStringUpper.java
new file mode 100644
index 0000000000000000000000000000000000000000..00e08a004bc68dcb6183ffcedfb2f7749e4f90f7
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterStringUpper.java
@@ -0,0 +1,29 @@
+package de.unikoblenz.fgbks.base.utils.boundary.creater;
+
+import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+import java.util.Optional;
+
+public class CreaterStringUpper extends AbstractBoundaryCreater<StringBoundary> {
+
+  private static final CreaterStringUpper instance = new CreaterStringUpper();
+
+  private CreaterStringUpper() {
+    super();
+  }
+
+  public static CreaterStringUpper getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryCreaterType getType() {
+    return BoundaryCreaterType.UPPER;
+  }
+
+  @Override
+  public Optional<StringBoundary> create(StringBoundary b) {
+    // is every time empty, because there is no "Upper", the result for "Upper" is
+    // inside the class CreaterStringLower
+    return Optional.empty();
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/StringBoundary.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/StringBoundary.java
index 6c67fca58a4b910352e2078fbddb17a4c7cebcae..12d091ebd65780538dc64ab8f52ae43204f45eb3 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/StringBoundary.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/StringBoundary.java
@@ -15,12 +15,18 @@ import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.
 import static de.unikoblenz.fgbks.base.utils.boundary.creater.BoundaryCreaterType.LOWER;
 import static de.unikoblenz.fgbks.base.utils.boundary.creater.BoundaryCreaterType.UPPER;
 
+import de.unikoblenz.fgbks.base.builder.DefaultBuilder;
 import de.unikoblenz.fgbks.base.utils.boundary.AbstractBoundary;
 import de.unikoblenz.fgbks.base.utils.boundary.Boundary;
 import de.unikoblenz.fgbks.base.utils.boundary.BoundaryParseException;
+import de.unikoblenz.fgbks.base.utils.boundary.bicreater.BiCreaterStringAppend;
+import de.unikoblenz.fgbks.base.utils.boundary.bicreater.BiCreaterStringBetween;
+import de.unikoblenz.fgbks.base.utils.boundary.bicreater.BiCreaterStringCombine;
+import de.unikoblenz.fgbks.base.utils.boundary.bicreater.BiCreaterStringIntersection;
+import de.unikoblenz.fgbks.base.utils.boundary.bicreater.BiCreaterStringLowerBounds;
+import de.unikoblenz.fgbks.base.utils.boundary.bicreater.BiCreaterStringUpperBounds;
 import de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreater;
 import de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType;
-import de.unikoblenz.fgbks.base.utils.boundary.bicreater.EmptyBiCreater;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheck;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckStringEqual;
@@ -31,10 +37,15 @@ import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckStringSubsumes;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckStringSubsumption;
 import de.unikoblenz.fgbks.base.utils.boundary.creater.BoundaryCreater;
 import de.unikoblenz.fgbks.base.utils.boundary.creater.BoundaryCreaterType;
-import de.unikoblenz.fgbks.base.utils.boundary.creater.CreaterLower;
-import de.unikoblenz.fgbks.base.utils.boundary.creater.CreaterUpper;
+import de.unikoblenz.fgbks.base.utils.boundary.creater.CreaterStringLower;
+import de.unikoblenz.fgbks.base.utils.boundary.creater.CreaterStringUpper;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.Validate;
@@ -52,14 +63,14 @@ public class StringBoundary extends AbstractBoundary<String> {
     checkerMap.put(IS_OVERLAPPING, CheckStringOverlap.getInstance());
     checkerMap.put(IS_SUBSUMPTION, CheckStringSubsumption.getInstance());
     checkerMap.put(SUBSUMES, CheckStringSubsumes.getInstance());
-    createrMap.put(UPPER, CreaterUpper.getInstance());
-    createrMap.put(LOWER, CreaterLower.getInstance());
-    biCreaterMap.put(INTERSECTION, EmptyBiCreater.getInstance());
-    biCreaterMap.put(LOWER_BOUNDS, EmptyBiCreater.getInstance());
-    biCreaterMap.put(UPPER_BOUNDS, EmptyBiCreater.getInstance());
-    biCreaterMap.put(BETWEEN, EmptyBiCreater.getInstance());
-    biCreaterMap.put(APPEND, EmptyBiCreater.getInstance());
-    biCreaterMap.put(COMBINE, EmptyBiCreater.getInstance());
+    createrMap.put(UPPER, CreaterStringUpper.getInstance());
+    createrMap.put(LOWER, CreaterStringLower.getInstance());
+    biCreaterMap.put(INTERSECTION, BiCreaterStringIntersection.getInstance());
+    biCreaterMap.put(LOWER_BOUNDS, BiCreaterStringLowerBounds.getInstance());
+    biCreaterMap.put(UPPER_BOUNDS, BiCreaterStringUpperBounds.getInstance());
+    biCreaterMap.put(BETWEEN, BiCreaterStringBetween.getInstance());
+    biCreaterMap.put(APPEND, BiCreaterStringAppend.getInstance());
+    biCreaterMap.put(COMBINE, BiCreaterStringCombine.getInstance());
   }
 
   private boolean matchNoneOfValues;
@@ -72,6 +83,10 @@ public class StringBoundary extends AbstractBoundary<String> {
     super(text, String.class);
   }
 
+  private StringBoundary() {
+    super(String.class);
+  }
+
   @Override
   public int compareTo(Boundary o) {
     return o.getText().compareTo(o.getText());
@@ -105,7 +120,6 @@ public class StringBoundary extends AbstractBoundary<String> {
       matchAny = Validate.notNull(text).isEmpty();
       if (matchAny) {
         values = new String[0];
-        valuesHashes = new int[0];
       } else {
         matchNoneOfValues = text.toLowerCase().startsWith("not");
         text = text.replace('(', '\0').replace(')', '\0').trim();
@@ -113,37 +127,41 @@ public class StringBoundary extends AbstractBoundary<String> {
           text = text.replaceFirst("not", "").trim();
         }
         values = text.split(",");
-        valuesHashes = new int[values.length];
-        for (int i = 0; i < values.length; i++) {
-          values[i] = values[i].replace('"', '\0').trim();
-          valuesHashes[i] = Objects.hashCode(values[i]);
-        }
       }
-      // Sort hashes for later comparisons
-      Arrays.sort(valuesHashes);
+      calcHashes();
     } catch (Exception e) {
       throw new BoundaryParseException("String value is not valid: " + this.getText());
     }
   }
 
+  private void calcHashes() {
+    valuesHashes = new int[values.length];
+    for (int i = 0; i < values.length; i++) {
+      values[i] = values[i].replace('"', '\0').trim();
+      valuesHashes[i] = Objects.hashCode(values[i]);
+    }
+    // Sort hashes for later comparisons
+    Arrays.sort(valuesHashes);
+  }
+
   @Override
   protected void validate() {
     Validate.noNullElements(values);
   }
 
   @Override
-  protected HashMap<BoundaryCheckType, BoundaryCheck> getChecker() {
-    return checkerMap;
+  protected Map<BoundaryCheckType, BoundaryCheck> getChecker() {
+    return Collections.unmodifiableMap(checkerMap);
   }
 
   @Override
-  protected HashMap<BoundaryBiCreaterType, BoundaryBiCreater> getBiCreater() {
-    return biCreaterMap;
+  protected Map<BoundaryBiCreaterType, BoundaryBiCreater> getBiCreater() {
+    return Collections.unmodifiableMap(biCreaterMap);
   }
 
   @Override
-  protected HashMap<BoundaryCreaterType, BoundaryCreater> getCreater() {
-    return createrMap;
+  protected Map<BoundaryCreaterType, BoundaryCreater> getCreater() {
+    return Collections.unmodifiableMap(createrMap);
   }
 
   @Override
@@ -152,4 +170,63 @@ public class StringBoundary extends AbstractBoundary<String> {
         + Arrays.stream(values).map(v -> '"' + v + '"').collect(Collectors.joining(","))
         + (matchNoneOfValues ? ")" : "");
   }
+
+  public static Builder getBuilder() {
+    return new StringBoundary().new Builder();
+  }
+
+  public class Builder extends DefaultBuilder<StringBoundary> {
+
+    private List<String> buildingValues;
+
+    private Builder() {
+      buildingValues = new ArrayList<>();
+      value.matchAny = false;
+      value.matchNoneOfValues = false;
+    }
+
+    public Builder isMatchNoneOfValues(boolean matchNoneOfValues) {
+      value.matchNoneOfValues = matchNoneOfValues;
+      return this;
+    }
+
+    public Builder isMatchAny(boolean matchAny) {
+      value.matchAny = matchAny;
+      return this;
+    }
+
+    public Builder addValue(String value) {
+      buildingValues.add(Validate.notNull(value));
+      return this;
+    }
+
+    public Builder addValues(Collection<String> values) {
+      buildingValues.addAll(Validate.noNullElements(values));
+      return this;
+    }
+
+    public Builder addValues(String[] values) {
+      return addValues(Validate.notNull(Arrays.asList(values)));
+    }
+
+    @Override
+    protected void validate() {
+      super.validate();
+      if (matchAny) {
+        // TODO exception
+      }
+    }
+
+    @Override
+    public StringBoundary build() {
+      value.values = buildingValues.toArray(new String[0]);
+      if (value.matchAny) {
+        value.matchNoneOfValues = false;
+        value.values = new String[0];
+      }
+      value.calcHashes();
+      value.text = value.getParsedText();
+      return super.build();
+    }
+  }
 }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/VerifierResult.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/VerifierResult.java
index 14c336d258babfe515d1814b0850d35526cbd15e..cf5d8399f4219118dec94a76b87949e3c9b2469f 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/VerifierResult.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/VerifierResult.java
@@ -12,6 +12,7 @@ import org.apache.commons.lang3.Validate;
 public class VerifierResult extends AbstractResultObject {
 
   private VerificationType verificationType;
+  private Long executionTime;
   private Set<VerificationResultEntry> verificationResultEntries;
 
   public VerifierResult() {
@@ -33,6 +34,15 @@ public class VerifierResult extends AbstractResultObject {
     return verificationResultEntries.size();
   }
 
+  @JsonbProperty("executionTime")
+  public Long getExecutionTime() {
+    return executionTime;
+  }
+
+  public void setExecutionTime(Long executionTime) {
+    this.executionTime = executionTime;
+  }
+
   public static Builder getBuilder() {
     return new VerifierResult().new Builder();
   }
@@ -49,6 +59,11 @@ public class VerifierResult extends AbstractResultObject {
       return this;
     }
 
+    public Builder withExecutionTime(Long executionTime) {
+      value.executionTime = executionTime;
+      return this;
+    }
+
     public Builder fromVerifier(AbstractVerifier verifier) {
       return withVerificationType(Validate.notNull(verifier).getVerificationType());
     }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/AbstractVerifier.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/AbstractVerifier.java
index 73e4bbc24616e3f98074dec7c03fe446c3c51fff..9a83e8d752c9ba5f3f4172e3ba696f3b39ab42ae 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/AbstractVerifier.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/AbstractVerifier.java
@@ -26,6 +26,8 @@ public abstract class AbstractVerifier implements Verifier {
   protected VerificationResultEntryFactory vreFactory;
   protected DmnObjectContainer dmnObjectContainer;
 
+  private long executionTime = -1;
+
   public VerificationType getVerificationType() {
     return verificationType;
   }
@@ -65,18 +67,28 @@ public abstract class AbstractVerifier implements Verifier {
     watch.start();
     doVerification();
     watch.stop();
+    executionTime = watch.getTime();
     LOGGER.info(
         "Verification "
             + getVerificationType().getName()
             + " finished. "
             + "Time Elapsed: "
-            + watch.getTime()
+            + executionTime
             + " ms");
-    return resultBuilder.build();
+    return resultBuilder.withExecutionTime(executionTime).build();
   }
 
   protected abstract void doVerification();
 
+  @Override
+  public long getExecutionTime() {
+    if (executionTime == -1) {
+      throw new IllegalStateException(
+          "Verifier must be executed before accessing the execution time!");
+    }
+    return executionTime;
+  }
+
   @Override
   public boolean equals(Object o) {
     if (this == o) {
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/Verifier.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/Verifier.java
index 695ab043fa08cbcd3c16e6fe6736b2f6256d4268..f91f7fc69c5d01ff406f778c605a6f9adae9f14d 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/Verifier.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/Verifier.java
@@ -7,4 +7,6 @@ import java.util.concurrent.Future;
 public interface Verifier {
 
   Future<VerifierResult> verify(ExecutorService executor);
+
+  long getExecutionTime();
 }
diff --git a/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringCombineTest.java b/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringCombineTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..259b9f6f448a52f3ce22af1c70fc7ca159a44bff
--- /dev/null
+++ b/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterStringCombineTest.java
@@ -0,0 +1,77 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.COMBINE;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+import io.quarkus.test.junit.QuarkusTest;
+import org.junit.jupiter.api.Test;
+
+@QuarkusTest
+class BiCreaterStringCombineTest {
+
+  StringBoundary sb1;
+  StringBoundary sb2;
+  StringBoundary sbR;
+
+  @Test
+  void testCreater() {
+    sb1 = StringBoundary.getBuilder().addValue("a").build();
+    sb2 = StringBoundary.getBuilder().addValue("b").build();
+    sbR = (StringBoundary) sb1.createBi(COMBINE, sb2).get();
+    assertArrayEquals(new String[]{"a", "b"}, sbR.getValues());
+    assertFalse(sbR.matchesNoneOfValues());
+    assertFalse(sbR.isMatchAny());
+
+    sb1 = StringBoundary.getBuilder().isMatchNoneOfValues(true).addValue("a").build();
+    sb2 = StringBoundary.getBuilder().addValue("b").build();
+    sbR = (StringBoundary) sb1.createBi(COMBINE, sb2).get();
+    assertArrayEquals(new String[]{"a"}, sbR.getValues());
+    assertTrue(sbR.matchesNoneOfValues());
+    assertFalse(sbR.isMatchAny());
+
+    sb1 = StringBoundary.getBuilder().isMatchNoneOfValues(true).addValue("a").addValue("b").build();
+    sb2 = StringBoundary.getBuilder().addValue("b").build();
+    sbR = (StringBoundary) sb1.createBi(COMBINE, sb2).get();
+    assertArrayEquals(new String[]{"a"}, sbR.getValues());
+    assertTrue(sbR.matchesNoneOfValues());
+    assertFalse(sbR.isMatchAny());
+
+    sb1 = StringBoundary.getBuilder().addValue("b").build();
+    sb2 = StringBoundary.getBuilder().isMatchNoneOfValues(true).addValue("a").addValue("b").build();
+    sbR = (StringBoundary) sb1.createBi(COMBINE, sb2).get();
+    assertArrayEquals(new String[]{"a"}, sbR.getValues());
+    assertTrue(sbR.matchesNoneOfValues());
+    assertFalse(sbR.isMatchAny());
+
+    sb1 = StringBoundary.getBuilder().isMatchNoneOfValues(true).addValue("a").build();
+    sb2 = StringBoundary.getBuilder().isMatchNoneOfValues(true).addValue("b").build();
+    sbR = (StringBoundary) sb1.createBi(COMBINE, sb2).get();
+    assertArrayEquals(new String[]{}, sbR.getValues());
+    assertFalse(sbR.matchesNoneOfValues());
+    assertTrue(sbR.isMatchAny());
+
+    sb1 = StringBoundary.getBuilder().isMatchNoneOfValues(true).addValue("a").build();
+    sb2 = StringBoundary.getBuilder().isMatchNoneOfValues(true).addValue("b").addValue("a").build();
+    sbR = (StringBoundary) sb1.createBi(COMBINE, sb2).get();
+    assertArrayEquals(new String[]{"a"}, sbR.getValues());
+    assertTrue(sbR.matchesNoneOfValues());
+    assertFalse(sbR.isMatchAny());
+
+    sb1 = StringBoundary.getBuilder().isMatchAny(true).build();
+    sb2 = StringBoundary.getBuilder().isMatchNoneOfValues(true).addValue("b").addValue("a").build();
+    sbR = (StringBoundary) sb1.createBi(COMBINE, sb2).get();
+    assertArrayEquals(new String[]{}, sbR.getValues());
+    assertFalse(sbR.matchesNoneOfValues());
+    assertTrue(sbR.isMatchAny());
+
+    sb1 = StringBoundary.getBuilder().isMatchAny(true).build();
+    sb2 = StringBoundary.getBuilder().isMatchAny(true).build();
+    sbR = (StringBoundary) sb1.createBi(COMBINE, sb2).get();
+    assertArrayEquals(new String[]{}, sbR.getValues());
+    assertFalse(sbR.matchesNoneOfValues());
+    assertTrue(sbR.isMatchAny());
+  }
+}
diff --git a/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterStringLowerTest.java b/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterStringLowerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a6635e9ad375c654487a09f079387200cd5b84a
--- /dev/null
+++ b/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterStringLowerTest.java
@@ -0,0 +1,28 @@
+package de.unikoblenz.fgbks.base.utils.boundary.creater;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import de.unikoblenz.fgbks.base.utils.boundary.impl.StringBoundary;
+import io.quarkus.test.junit.QuarkusTest;
+import org.junit.jupiter.api.Test;
+
+@QuarkusTest
+class CreaterStringLowerTest {
+
+  @Test
+  public void testStringLower() {
+    StringBoundary sb = StringBoundary.getBuilder().addValue("a").build();
+    assertEquals("a", sb.getValues()[0]);
+    assertFalse(sb.isMatchAny());
+    assertFalse(sb.matchesNoneOfValues());
+    assertEquals("\"a\"", sb.getText());
+
+    StringBoundary sb2 = (StringBoundary) sb.create(BoundaryCreaterType.LOWER).get();
+    assertArrayEquals(sb.getValues(), sb2.getValues());
+    assertTrue(sb2.matchesNoneOfValues());
+    assertFalse(sb.isMatchAny());
+  }
+}
diff --git a/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/impl/StringBoundaryTest.java b/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/impl/StringBoundaryTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5db876c0405b02304da009f8a6ec6510a95febbf
--- /dev/null
+++ b/dmnverifierapi/src/test/java/de/unikoblenz/fgbks/base/utils/boundary/impl/StringBoundaryTest.java
@@ -0,0 +1,24 @@
+package de.unikoblenz.fgbks.base.utils.boundary.impl;
+
+import io.quarkus.test.junit.QuarkusTest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+@QuarkusTest
+class StringBoundaryTest {
+
+  @Test
+  public void testBuilder() {
+    StringBoundary sb = StringBoundary.getBuilder().addValue("a").build();
+    Assertions.assertEquals("a", sb.getValues()[0]);
+    Assertions.assertFalse(sb.isMatchAny());
+    Assertions.assertFalse(sb.matchesNoneOfValues());
+    Assertions.assertEquals("\"a\"", sb.getText());
+
+    sb = StringBoundary.getBuilder().addValue("a").addValue("b").isMatchNoneOfValues(true).build();
+    Assertions.assertEquals("a", sb.getValues()[0]);
+    Assertions.assertFalse(sb.isMatchAny());
+    Assertions.assertTrue(sb.matchesNoneOfValues());
+    Assertions.assertEquals("not(\"a\",\"b\")", sb.getText());
+  }
+}