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 13e97a2d07bac2b63a1e44da5eb3d9f39a53ca71..8883fe32c3164f7cc75918febb61907ccbc0d3f9 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
@@ -1,9 +1,9 @@
 package de.unikoblenz.fgbks.base.utils.boundary;
 
+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.checker.BoundaryCheck;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType;
-import de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType;
-import de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombiner;
 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.impl.InvalidBoundary;
@@ -15,21 +15,25 @@ import org.apache.commons.lang3.Validate;
 public abstract class AbstractBoundary<T extends Comparable<? super T>> implements Boundary {
 
   private HashMap<BoundaryCheckType, BoundaryCheck> checkFunctions;
-  private HashMap<BoundaryCombineType, BoundaryCombiner> combineFunctions;
+  private HashMap<BoundaryBiCreaterType, BoundaryBiCreater> biCreaterFunctions;
   private HashMap<BoundaryCreaterType, BoundaryCreater> createrFunctions;
   private Class<T> type;
   private String text;
 
-  public AbstractBoundary(String text, Class<T> type) {
+  protected AbstractBoundary(String text, Class<T> type) {
     this.text = text;
     this.type = type;
     parse(text);
     validate();
     checkFunctions = new HashMap<>(getChecker());
-    combineFunctions = new HashMap<>(getCombiner());
+    biCreaterFunctions = new HashMap<>(getBiCreater());
     createrFunctions = new HashMap<>(getCreater());
   }
 
+  protected AbstractBoundary(Class<T> type) {
+    this("", type);
+  }
+
   @Override
   public String getText() {
     return text;
@@ -62,15 +66,15 @@ public abstract class AbstractBoundary<T extends Comparable<? super T>> implemen
   }
 
   @Override
-  public Optional<Boundary> combine(BoundaryCombineType combineType, Boundary other) {
+  public Optional<Boundary> createBi(BoundaryBiCreaterType combineType, Boundary other) {
     if (other instanceof InvalidBoundary) {
       return Optional.empty();
     }
-    BoundaryCombiner combiner = getCombineFunction(combineType);
-    if (combiner == null || !isValidOperation(combineType, other)) {
+    BoundaryBiCreater biCreater = getBiCreaterFunction(combineType);
+    if (biCreater == null || !isValidOperation(combineType, other)) {
       throw new BoundaryOperationNotSupportedException(); // TODO: add error text
     }
-    return combiner.combine(this, other); // TODO, remove RAW type
+    return biCreater.create(this, other); // TODO, remove RAW type
   }
 
   public boolean isValidOperation(BoundaryCheckType checkType, Boundary other) {
@@ -81,12 +85,12 @@ public abstract class AbstractBoundary<T extends Comparable<? super T>> implemen
     return checkFunctions.containsKey(Validate.notNull(checkType));
   }
 
-  public boolean isValidOperation(BoundaryCombineType combineType, Boundary other) {
+  public boolean isValidOperation(BoundaryBiCreaterType combineType, Boundary other) {
     return this.getTypeRef() == other.getTypeRef() && isValidOperation(combineType);
   }
 
-  public boolean isValidOperation(BoundaryCombineType combineTyp) {
-    return combineFunctions.containsKey(Validate.notNull(combineTyp));
+  public boolean isValidOperation(BoundaryBiCreaterType combineTyp) {
+    return biCreaterFunctions.containsKey(Validate.notNull(combineTyp));
   }
 
   public boolean isValidOperation(BoundaryCreaterType createrType) {
@@ -101,8 +105,8 @@ public abstract class AbstractBoundary<T extends Comparable<? super T>> implemen
     return createrFunctions.get(createrType);
   }
 
-  protected BoundaryCombiner getCombineFunction(BoundaryCombineType combineTypeType) {
-    return combineFunctions.get(combineTypeType);
+  protected BoundaryBiCreater getBiCreaterFunction(BoundaryBiCreaterType biCreaterTypeType) {
+    return biCreaterFunctions.get(biCreaterTypeType);
   }
 
   protected abstract void parse(String text);
@@ -111,7 +115,7 @@ public abstract class AbstractBoundary<T extends Comparable<? super T>> implemen
 
   protected abstract HashMap<BoundaryCheckType, BoundaryCheck> getChecker();
 
-  protected abstract HashMap<BoundaryCombineType, BoundaryCombiner> getCombiner();
+  protected abstract HashMap<BoundaryBiCreaterType, BoundaryBiCreater> getBiCreater();
 
   protected abstract HashMap<BoundaryCreaterType, BoundaryCreater> getCreater();
 
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 07c4709b72219242434420d0be263da487acac58..a64b10913eadf89eeb023d1cf57c59dee5378b69 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
@@ -1,21 +1,27 @@
 package de.unikoblenz.fgbks.base.utils.boundary;
 
 import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.INCLUSIVE;
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.APPEND;
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.BETWEEN;
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.COMBINE;
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.INTERSECTION;
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.LOWER_BOUNDS;
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.UPPER_BOUNDS;
 import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_EQUAL;
 import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_IN_CONTACT;
 import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_NOT_IN_CONTACT;
 import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_OVERLAPPING;
 import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_SUBSUMPTION;
 import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.SUBSUMES;
-import static de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType.APPEND;
-import static de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType.BETWEEN;
-import static de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType.COMBINE;
-import static de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType.INTERSECTION;
-import static de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType.LOWER_BOUNDS;
-import static de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType.UPPER_BOUNDS;
 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.utils.boundary.bicreater.BiCreaterAppend;
+import de.unikoblenz.fgbks.base.utils.boundary.bicreater.BiCreaterBetween;
+import de.unikoblenz.fgbks.base.utils.boundary.bicreater.BiCreaterCombine;
+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.CheckEqual;
@@ -24,12 +30,10 @@ import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckIsSubsumption;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckNotInContact;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckOverlap;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckSubsumes;
-import de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType;
-import de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombiner;
-import de.unikoblenz.fgbks.base.utils.boundary.combiner.EmptyCombiner;
 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.EmptyCreater;
+import de.unikoblenz.fgbks.base.utils.boundary.creater.CreaterLower;
+import de.unikoblenz.fgbks.base.utils.boundary.creater.CreaterUpper;
 import java.util.HashMap;
 import java.util.Objects;
 import org.apache.commons.lang3.Validate;
@@ -37,6 +41,27 @@ import org.apache.commons.lang3.Validate;
 public abstract class AbstractGrowingBoundary<T extends Comparable<? super T>>
     extends AbstractBoundary<T> {
 
+  private static HashMap<BoundaryCheckType, BoundaryCheck> checkerMap = new HashMap<>();
+  private static HashMap<BoundaryCreaterType, BoundaryCreater> createrMap = new HashMap<>();
+  private static HashMap<BoundaryBiCreaterType, BoundaryBiCreater> biCreaterMap = new HashMap<>();
+
+  static {
+    checkerMap.put(IS_EQUAL, CheckEqual.getInstance());
+    checkerMap.put(IS_IN_CONTACT, CheckInContact.getInstance());
+    checkerMap.put(IS_NOT_IN_CONTACT, CheckNotInContact.getInstance());
+    checkerMap.put(IS_OVERLAPPING, CheckOverlap.getInstance());
+    checkerMap.put(IS_SUBSUMPTION, CheckIsSubsumption.getInstance());
+    checkerMap.put(SUBSUMES, CheckSubsumes.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, BiCreaterBetween.getInstance());
+    biCreaterMap.put(APPEND, BiCreaterAppend.getInstance());
+    biCreaterMap.put(COMBINE, BiCreaterCombine.getInstance());
+  }
+
   protected T lowerBound;
   protected BoundType lowerBoundType;
   protected T upperBound;
@@ -58,10 +83,14 @@ public abstract class AbstractGrowingBoundary<T extends Comparable<? super T>>
     return upperBoundType;
   }
 
-  public AbstractGrowingBoundary(String text, Class<T> type) {
+  protected AbstractGrowingBoundary(String text, Class<T> type) {
     super(text, type);
   }
 
+  protected AbstractGrowingBoundary(Class<T> type) {
+    super(type);
+  }
+
   @Override
   protected void validate() {
     Validate.notNull(lowerBound);
@@ -87,34 +116,17 @@ public abstract class AbstractGrowingBoundary<T extends Comparable<? super T>>
 
   @Override
   protected HashMap<BoundaryCheckType, BoundaryCheck> getChecker() {
-    HashMap<BoundaryCheckType, BoundaryCheck> map = new HashMap<>();
-    map.put(IS_EQUAL, CheckEqual.getInstance());
-    map.put(IS_IN_CONTACT, CheckInContact.getInstance());
-    map.put(IS_NOT_IN_CONTACT, CheckNotInContact.getInstance());
-    map.put(IS_OVERLAPPING, CheckOverlap.getInstance());
-    map.put(IS_SUBSUMPTION, CheckIsSubsumption.getInstance());
-    map.put(SUBSUMES, CheckSubsumes.getInstance());
-    return map;
+    return checkerMap;
   }
 
   @Override
-  protected HashMap<BoundaryCombineType, BoundaryCombiner> getCombiner() {
-    HashMap<BoundaryCombineType, BoundaryCombiner> map = new HashMap<>();
-    map.put(INTERSECTION, EmptyCombiner.getInstance());
-    map.put(LOWER_BOUNDS, EmptyCombiner.getInstance());
-    map.put(UPPER_BOUNDS, EmptyCombiner.getInstance());
-    map.put(BETWEEN, EmptyCombiner.getInstance());
-    map.put(APPEND, EmptyCombiner.getInstance());
-    map.put(COMBINE, EmptyCombiner.getInstance());
-    return map;
+  protected HashMap<BoundaryBiCreaterType, BoundaryBiCreater> getBiCreater() {
+    return biCreaterMap;
   }
 
   @Override
   protected HashMap<BoundaryCreaterType, BoundaryCreater> getCreater() {
-    HashMap<BoundaryCreaterType, BoundaryCreater> map = new HashMap<>();
-    map.put(UPPER, EmptyCreater.getInstance());
-    map.put(LOWER, EmptyCreater.getInstance());
-    return map;
+    return createrMap;
   }
 
   @Override
@@ -171,9 +183,12 @@ public abstract class AbstractGrowingBoundary<T extends Comparable<? super T>>
     return upperBound.compareTo((T) o.upperBound);
   }
 
-  protected abstract T getMinValue();
+  public abstract T getMinValue();
+
+  public abstract T getMaxValue();
 
-  protected abstract T getMaxValue();
+  public abstract AbstractGrowingBoundary getCopy(
+      T lowerBound, T upperBound, BoundType lowerBoundType, BoundType upperBoundType);
 
   @Override
   protected String getParsedText() {
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/Boundary.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/Boundary.java
index fab3d6b148ff509c00bf1476b12b7a1280d80c47..7772b3d8b9c457eeb9a45fc23dfae144a093149c 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/Boundary.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/Boundary.java
@@ -1,7 +1,7 @@
 package de.unikoblenz.fgbks.base.utils.boundary;
 
+import de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType;
-import de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType;
 import de.unikoblenz.fgbks.base.utils.boundary.creater.BoundaryCreaterType;
 import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VTypeRef;
 import java.util.Optional;
@@ -16,5 +16,5 @@ public interface Boundary extends Comparable<Boundary> {
 
   Optional<Boundary> create(BoundaryCreaterType createType);
 
-  Optional<Boundary> combine(BoundaryCombineType combineType, Boundary other);
+  Optional<Boundary> createBi(BoundaryBiCreaterType combineType, Boundary other);
 }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/AbstractBoundaryBiCreater.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/AbstractBoundaryBiCreater.java
new file mode 100644
index 0000000000000000000000000000000000000000..85c0664c4a78af08c95723975641af7f0be1baee
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/AbstractBoundaryBiCreater.java
@@ -0,0 +1,6 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+import de.unikoblenz.fgbks.base.utils.boundary.Boundary;
+
+public abstract class AbstractBoundaryBiCreater<T extends Boundary>
+    implements BoundaryBiCreater<T> {}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterAppend.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterAppend.java
new file mode 100644
index 0000000000000000000000000000000000000000..1be74c3b79d7e25211a65dcdf32873dd348d79b6
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterAppend.java
@@ -0,0 +1,97 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.INCLUSIVE;
+import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_NOT_IN_CONTACT;
+
+import de.unikoblenz.fgbks.base.utils.boundary.AbstractGrowingBoundary;
+import de.unikoblenz.fgbks.base.utils.boundary.impl.BooleanBoundary;
+import de.unikoblenz.fgbks.base.utils.boundary.impl.IntegerBoundary;
+import de.unikoblenz.fgbks.base.utils.boundary.impl.LongBoundary;
+import java.util.Optional;
+
+public class BiCreaterAppend extends AbstractBoundaryBiCreater<AbstractGrowingBoundary> {
+
+  private static final BiCreaterAppend instance = new BiCreaterAppend();
+
+  private BiCreaterAppend() {
+    super();
+  }
+
+  public static BiCreaterAppend getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryBiCreaterType getType() {
+    return BoundaryBiCreaterType.APPEND;
+  }
+
+  @Override
+  public Optional<AbstractGrowingBoundary> create(
+      AbstractGrowingBoundary b1, AbstractGrowingBoundary b2) {
+    if (b1.checkWith(IS_NOT_IN_CONTACT, b2)) {
+      if (b1 instanceof BooleanBoundary) {
+        return createrBoolean((BooleanBoundary) b1, (BooleanBoundary) b2);
+      }
+      if (b1 instanceof IntegerBoundary || b1 instanceof LongBoundary) {
+        return createrLong(b1, b2);
+      }
+      if (b1.getUpperBound().equals(b2.getLowerBound())
+          && b1.getUpperBoundType() != b2.getLowerBoundType()) {
+        return Optional.of(
+            b1.getCopy(
+                b1.getLowerBound(),
+                b2.getUpperBound(),
+                b1.getLowerBoundType(),
+                b2.getUpperBoundType()));
+      } else if (b2.getUpperBound().equals(b1.getLowerBound())
+          && b2.getUpperBoundType() != b1.getLowerBoundType()) {
+        return Optional.of(
+            b1.getCopy(
+                b2.getLowerBound(),
+                b1.getUpperBound(),
+                b2.getLowerBoundType(),
+                b1.getUpperBoundType()));
+      }
+    }
+    return Optional.empty();
+  }
+
+  private Optional<AbstractGrowingBoundary> createrLong(
+      AbstractGrowingBoundary b1, AbstractGrowingBoundary b2) {
+    long b1L = (long) b1.getLowerBound();
+    long b1U = (long) b1.getUpperBound();
+    long b2L = (long) b1.getLowerBound();
+    long b2U = (long) b1.getUpperBound();
+    if (b1U + 1 == b2L
+        && b1.getUpperBoundType() == INCLUSIVE
+        && b2.getLowerBoundType() == INCLUSIVE) {
+      return Optional.of(
+          b1.getCopy(
+              b1.getLowerBound(),
+              b2.getUpperBound(),
+              b1.getLowerBoundType(),
+              b2.getUpperBoundType()));
+    } else if (b2U + 1 == b1L
+        && b2.getUpperBoundType() == INCLUSIVE
+        && b1.getLowerBoundType() == INCLUSIVE) {
+      return Optional.of(
+          b1.getCopy(
+              b2.getLowerBound(),
+              b1.getUpperBound(),
+              b2.getLowerBoundType(),
+              b1.getUpperBoundType()));
+    }
+    return Optional.empty();
+  }
+
+  private Optional<AbstractGrowingBoundary> createrBoolean(BooleanBoundary b1, BooleanBoundary b2) {
+    if ((b1.getLowerBound() == b1.getUpperBound())
+        && (b2.getLowerBound() == b2.getUpperBound())
+        && b1.getLowerBound() != b1.getLowerBound()) {
+      return Optional.of(new BooleanBoundary(""));
+    } else {
+      return Optional.empty();
+    }
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterBetween.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterBetween.java
new file mode 100644
index 0000000000000000000000000000000000000000..3c9f40a3320a49d17ee9c692a39b7089f78c423a
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterBetween.java
@@ -0,0 +1,72 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.INCLUSIVE;
+
+import de.unikoblenz.fgbks.base.utils.boundary.AbstractGrowingBoundary;
+import de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType;
+import de.unikoblenz.fgbks.base.utils.boundary.impl.BooleanBoundary;
+import de.unikoblenz.fgbks.base.utils.boundary.impl.DoubleBoundary;
+import de.unikoblenz.fgbks.base.utils.boundary.impl.IntegerBoundary;
+import java.util.Optional;
+
+public class BiCreaterBetween extends AbstractBoundaryBiCreater<AbstractGrowingBoundary> {
+
+  private static final BiCreaterBetween instance = new BiCreaterBetween();
+
+  private BiCreaterBetween() {
+    super();
+  }
+
+  public static BiCreaterBetween getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryBiCreaterType getType() {
+    return BoundaryBiCreaterType.BETWEEN;
+  }
+
+  @Override
+  public Optional<AbstractGrowingBoundary> create(
+      AbstractGrowingBoundary b1, AbstractGrowingBoundary b2) {
+    if (b1 instanceof BooleanBoundary || b1.checkWith(BoundaryCheckType.IS_IN_CONTACT, b2)) {
+      return Optional.empty();
+    }
+    // no space between the two bounds
+    if (b1.getUpperBound().equals(b2.getLowerBound())
+            && !b1.getUpperBound().equals(b2.getLowerBound())
+        || b2.getUpperBound().equals(b1.getLowerBound())
+            && !b2.getUpperBound().equals(b1.getLowerBound())) {
+      return Optional.empty();
+    }
+    if (b1 instanceof DoubleBoundary || b1 instanceof IntegerBoundary) {
+      long b1L = (long) b1.getLowerBound();
+      long b1U = (long) b1.getUpperBound();
+      long b2L = (long) b1.getLowerBound();
+      long b2U = (long) b1.getUpperBound();
+      if (b1U + 1 == b2L
+              && b1.getUpperBoundType() == INCLUSIVE
+              && b2.getLowerBoundType() == INCLUSIVE
+          || b2U + 1 == b1L
+              && b2.getUpperBoundType() == INCLUSIVE
+              && b1.getLowerBoundType() == INCLUSIVE) {
+        return Optional.empty();
+      }
+    }
+    if (b1.getLowerBound().compareTo(b2.getUpperBound()) < 0) {
+      return Optional.of(
+          b1.getCopy(
+              b1.getLowerBound(),
+              b2.getLowerBound(),
+              b1.getUpperBoundType().getOp(),
+              b2.getLowerBoundType().getOp()));
+    } else {
+      return Optional.of(
+          b1.getCopy(
+              b2.getLowerBound(),
+              b1.getLowerBound(),
+              b2.getUpperBoundType().getOp(),
+              b1.getLowerBoundType().getOp()));
+    }
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterCombine.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterCombine.java
new file mode 100644
index 0000000000000000000000000000000000000000..303e7e8ec104582cc2f81571dc80403ecb2784a2
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterCombine.java
@@ -0,0 +1,51 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.EXCLUSIVE;
+import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.INCLUSIVE;
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.APPEND;
+import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_NOT_IN_CONTACT;
+
+import de.unikoblenz.fgbks.base.utils.boundary.AbstractGrowingBoundary;
+import java.util.Optional;
+
+public class BiCreaterCombine extends AbstractBoundaryBiCreater<AbstractGrowingBoundary> {
+
+  private static final BiCreaterCombine instance = new BiCreaterCombine();
+
+  private BiCreaterCombine() {
+    super();
+  }
+
+  public static BiCreaterCombine getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryBiCreaterType getType() {
+    return APPEND;
+  }
+
+  @Override
+  public Optional<AbstractGrowingBoundary> create(
+      AbstractGrowingBoundary b1, AbstractGrowingBoundary b2) {
+    if (b1.checkWith(IS_NOT_IN_CONTACT, b2)) {
+      return b1.createBi(APPEND, b2);
+    }
+    int lC = b1.getLowerBound().compareTo(b2.getLowerBound());
+    int uC = b1.getUpperBound().compareTo(b2.getUpperBound());
+    return Optional.of(
+        b1.getCopy(
+            lC < 0 ? b1.getLowerBound() : b2.getLowerBound(),
+            uC > 0 ? b1.getUpperBound() : b2.getUpperBound(),
+            lC == 0
+                ? (b1.getLowerBoundType() == INCLUSIVE || b2.getLowerBoundType() == INCLUSIVE)
+                    ? INCLUSIVE
+                    : EXCLUSIVE
+                : lC < 0 ? b1.getLowerBoundType() : b2.getLowerBoundType(),
+            uC == 0
+                ? (b1.getUpperBoundType() == INCLUSIVE || b2.getUpperBoundType() == INCLUSIVE)
+                    ? INCLUSIVE
+                    : EXCLUSIVE
+                : lC > 0 ? b1.getUpperBoundType() : b2.getUpperBoundType()));
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BoundaryBiCreater.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BoundaryBiCreater.java
new file mode 100644
index 0000000000000000000000000000000000000000..0a70608094ba2ce3c596d7f7fb50c69afd6ab537
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BoundaryBiCreater.java
@@ -0,0 +1,11 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+import de.unikoblenz.fgbks.base.utils.boundary.Boundary;
+import java.util.Optional;
+
+public interface BoundaryBiCreater<T extends Boundary> {
+
+  BoundaryBiCreaterType getType();
+
+  Optional<T> create(T b1, T b2);
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BoundaryBiCreaterType.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BoundaryBiCreaterType.java
new file mode 100644
index 0000000000000000000000000000000000000000..60289a0e48596474a7177a6f9f578cb0f6fbe53a
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BoundaryBiCreaterType.java
@@ -0,0 +1,10 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+public enum BoundaryBiCreaterType {
+  INTERSECTION,
+  LOWER_BOUNDS,
+  UPPER_BOUNDS,
+  BETWEEN,
+  APPEND,
+  COMBINE;
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/EmptyBiCreater.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/EmptyBiCreater.java
new file mode 100644
index 0000000000000000000000000000000000000000..e3251828d1bcc378014d1b719b5aafd40c5f820b
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/EmptyBiCreater.java
@@ -0,0 +1,27 @@
+package de.unikoblenz.fgbks.base.utils.boundary.bicreater;
+
+import de.unikoblenz.fgbks.base.utils.boundary.Boundary;
+import java.util.Optional;
+
+public class EmptyBiCreater extends AbstractBoundaryBiCreater<Boundary> {
+
+  private static final EmptyBiCreater instance = new EmptyBiCreater();
+
+  private EmptyBiCreater() {
+    super();
+  }
+
+  public static EmptyBiCreater getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryBiCreaterType getType() {
+    return null;
+  }
+
+  @Override
+  public Optional<Boundary> create(Boundary b1, Boundary b2) {
+    return Optional.empty();
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/combiner/AbstractBoundaryCombiner.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/combiner/AbstractBoundaryCombiner.java
deleted file mode 100644
index ed0cf6cb6e3639ad6d5c820b0f22e9bbe224efdc..0000000000000000000000000000000000000000
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/combiner/AbstractBoundaryCombiner.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package de.unikoblenz.fgbks.base.utils.boundary.combiner;
-
-import de.unikoblenz.fgbks.base.utils.boundary.Boundary;
-
-public abstract class AbstractBoundaryCombiner<T extends Boundary> implements BoundaryCombiner<T> {}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/combiner/BoundaryCombineType.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/combiner/BoundaryCombineType.java
deleted file mode 100644
index bcfcb494b9dd9c31d0cc47d81160e98cfbc49772..0000000000000000000000000000000000000000
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/combiner/BoundaryCombineType.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package de.unikoblenz.fgbks.base.utils.boundary.combiner;
-
-public enum BoundaryCombineType {
-  INTERSECTION,
-  LOWER_BOUNDS,
-  UPPER_BOUNDS,
-  BETWEEN,
-  APPEND,
-  COMBINE;
-}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/combiner/BoundaryCombiner.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/combiner/BoundaryCombiner.java
deleted file mode 100644
index 10ce58c733d9f0eb51addd0db1c798edae79152a..0000000000000000000000000000000000000000
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/combiner/BoundaryCombiner.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package de.unikoblenz.fgbks.base.utils.boundary.combiner;
-
-import de.unikoblenz.fgbks.base.utils.boundary.Boundary;
-import java.util.Optional;
-
-public interface BoundaryCombiner<T extends Boundary> {
-
-  BoundaryCombineType getType();
-
-  Optional<T> combine(T b1, T b2);
-}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/combiner/EmptyCombiner.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/combiner/EmptyCombiner.java
deleted file mode 100644
index 7bea8da77f8edc010a63b9dc829857eac6798f11..0000000000000000000000000000000000000000
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/combiner/EmptyCombiner.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package de.unikoblenz.fgbks.base.utils.boundary.combiner;
-
-import de.unikoblenz.fgbks.base.utils.boundary.Boundary;
-import java.util.Optional;
-
-public class EmptyCombiner extends AbstractBoundaryCombiner<Boundary> {
-
-  private static final EmptyCombiner instance = new EmptyCombiner();
-
-  private EmptyCombiner() {
-    super();
-  }
-
-  public static EmptyCombiner getInstance() {
-    return instance;
-  }
-
-  @Override
-  public BoundaryCombineType getType() {
-    return null;
-  }
-
-  @Override
-  public Optional<Boundary> combine(Boundary b1, Boundary b2) {
-    return Optional.empty();
-  }
-}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterLower.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterLower.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce669e9f43cdf4c0c9c3b39c6e7120e942173768
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterLower.java
@@ -0,0 +1,36 @@
+package de.unikoblenz.fgbks.base.utils.boundary.creater;
+
+import de.unikoblenz.fgbks.base.utils.boundary.AbstractGrowingBoundary;
+import de.unikoblenz.fgbks.base.utils.boundary.BoundType;
+import java.util.Optional;
+
+public class CreaterLower extends AbstractBoundaryCreater<AbstractGrowingBoundary> {
+
+  private static final CreaterLower instance = new CreaterLower();
+
+  private CreaterLower() {
+    super();
+  }
+
+  public static CreaterLower getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryCreaterType getType() {
+    return BoundaryCreaterType.LOWER;
+  }
+
+  @Override
+  public Optional<AbstractGrowingBoundary> create(AbstractGrowingBoundary b) {
+    if (b.getLowerBound().equals(b.getMinValue())) {
+      return Optional.empty();
+    }
+    return Optional.of(
+        b.getCopy(
+            b.getMinValue(),
+            b.getLowerBound(),
+            BoundType.INCLUSIVE,
+            b.getLowerBoundType().getOp()));
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterUpper.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterUpper.java
new file mode 100644
index 0000000000000000000000000000000000000000..8fe0b3cacda630eb6b593acd03a3e8b08ad106ca
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/creater/CreaterUpper.java
@@ -0,0 +1,36 @@
+package de.unikoblenz.fgbks.base.utils.boundary.creater;
+
+import de.unikoblenz.fgbks.base.utils.boundary.AbstractGrowingBoundary;
+import de.unikoblenz.fgbks.base.utils.boundary.BoundType;
+import java.util.Optional;
+
+public class CreaterUpper extends AbstractBoundaryCreater<AbstractGrowingBoundary> {
+
+  private static final CreaterUpper instance = new CreaterUpper();
+
+  private CreaterUpper() {
+    super();
+  }
+
+  public static CreaterUpper getInstance() {
+    return instance;
+  }
+
+  @Override
+  public BoundaryCreaterType getType() {
+    return BoundaryCreaterType.UPPER;
+  }
+
+  @Override
+  public Optional<AbstractGrowingBoundary> create(AbstractGrowingBoundary b) {
+    if (b.getUpperBound().equals(b.getMaxValue())) {
+      return Optional.empty();
+    }
+    return Optional.of(
+        b.getCopy(
+            b.getUpperBound(),
+            b.getMaxValue(),
+            b.getUpperBoundType().getOp(),
+            BoundType.INCLUSIVE));
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/BooleanBoundary.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/BooleanBoundary.java
index b8ba1308f5adfa4634dc6e9ba24b9cf9847db777..9d07669239d1be5099d7665770fb9cb7bb59ed40 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/BooleanBoundary.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/BooleanBoundary.java
@@ -3,6 +3,7 @@ package de.unikoblenz.fgbks.base.utils.boundary.impl;
 import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.INCLUSIVE;
 
 import de.unikoblenz.fgbks.base.utils.boundary.AbstractGrowingBoundary;
+import de.unikoblenz.fgbks.base.utils.boundary.BoundType;
 import de.unikoblenz.fgbks.base.utils.boundary.BoundaryParseException;
 
 public class BooleanBoundary extends AbstractGrowingBoundary<Boolean> {
@@ -14,16 +15,32 @@ public class BooleanBoundary extends AbstractGrowingBoundary<Boolean> {
     super(text, Boolean.TYPE);
   }
 
+  private BooleanBoundary() {
+    super(Boolean.TYPE);
+  }
+
   @Override
-  protected Boolean getMinValue() {
+  public Boolean getMinValue() {
     return false;
   }
 
   @Override
-  protected Boolean getMaxValue() {
+  public Boolean getMaxValue() {
     return true;
   }
 
+  @Override
+  public AbstractGrowingBoundary getCopy(
+      Boolean lowerBound, Boolean upperBound, BoundType lowerBoundType, BoundType upperBoundType) {
+    BooleanBoundary v = new BooleanBoundary();
+    v.lowerBound = lowerBound;
+    v.upperBound = upperBound;
+    v.lowerBoundType = lowerBoundType;
+    v.upperBoundType = upperBoundType;
+    v.validate();
+    return v;
+  }
+
   @Override
   protected void parse(String text) {
     upperBoundType = INCLUSIVE;
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/DateBoundary.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/DateBoundary.java
index 3ffd379c1201b0e0ee08b18d202ee444bf731f26..ef5b28d9fabb7931ff69170a18db201b89ecd9d2 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/DateBoundary.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/DateBoundary.java
@@ -4,6 +4,7 @@ import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.EXCLUSIVE;
 import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.INCLUSIVE;
 
 import de.unikoblenz.fgbks.base.utils.boundary.AbstractGrowingBoundary;
+import de.unikoblenz.fgbks.base.utils.boundary.BoundType;
 import de.unikoblenz.fgbks.base.utils.boundary.BoundaryParseException;
 import java.time.LocalDateTime;
 import java.util.regex.Matcher;
@@ -23,13 +24,32 @@ public class DateBoundary extends AbstractGrowingBoundary<LocalDateTime> {
     super(text, LocalDateTime.class);
   }
 
+  private DateBoundary() {
+    super(LocalDateTime.class);
+  }
+
+  @Override
+  public AbstractGrowingBoundary getCopy(
+      LocalDateTime lowerBound,
+      LocalDateTime upperBound,
+      BoundType lowerBoundType,
+      BoundType upperBoundType) {
+    DateBoundary v = new DateBoundary();
+    v.lowerBound = lowerBound;
+    v.upperBound = upperBound;
+    v.lowerBoundType = lowerBoundType;
+    v.upperBoundType = upperBoundType;
+    v.validate();
+    return v;
+  }
+
   @Override
-  protected LocalDateTime getMinValue() {
+  public LocalDateTime getMinValue() {
     return LocalDateTime.MAX;
   }
 
   @Override
-  protected LocalDateTime getMaxValue() {
+  public LocalDateTime getMaxValue() {
     return LocalDateTime.MIN;
   }
 
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/DoubleBoundary.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/DoubleBoundary.java
index 3d1acde6ee8464482951d0c812ec5c93868faeaf..6dd524516b15a82e1b473c735bee305cc8801627 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/DoubleBoundary.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/DoubleBoundary.java
@@ -4,6 +4,7 @@ import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.EXCLUSIVE;
 import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.INCLUSIVE;
 
 import de.unikoblenz.fgbks.base.utils.boundary.AbstractGrowingBoundary;
+import de.unikoblenz.fgbks.base.utils.boundary.BoundType;
 import de.unikoblenz.fgbks.base.utils.boundary.BoundaryParseException;
 import org.apache.commons.lang3.Validate;
 
@@ -13,13 +14,29 @@ public class DoubleBoundary extends AbstractGrowingBoundary<Double> {
     super(text, Double.TYPE);
   }
 
+  private DoubleBoundary() {
+    super(Double.TYPE);
+  }
+
+  @Override
+  public AbstractGrowingBoundary getCopy(
+      Double lowerBound, Double upperBound, BoundType lowerBoundType, BoundType upperBoundType) {
+    DoubleBoundary v = new DoubleBoundary();
+    v.lowerBound = lowerBound;
+    v.upperBound = upperBound;
+    v.lowerBoundType = lowerBoundType;
+    v.upperBoundType = upperBoundType;
+    v.validate();
+    return v;
+  }
+
   @Override
-  protected Double getMinValue() {
+  public Double getMinValue() {
     return Double.NEGATIVE_INFINITY;
   }
 
   @Override
-  protected Double getMaxValue() {
+  public Double getMaxValue() {
     return Double.POSITIVE_INFINITY;
   }
 
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/IntegerBoundary.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/IntegerBoundary.java
index b2d5a7905edaa1c587a4bce5b64c09e8bd4c0963..79c53c5036bd3c448ed7e8fec720f3d2356351d0 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/IntegerBoundary.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/IntegerBoundary.java
@@ -4,6 +4,7 @@ import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.EXCLUSIVE;
 import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.INCLUSIVE;
 
 import de.unikoblenz.fgbks.base.utils.boundary.AbstractGrowingBoundary;
+import de.unikoblenz.fgbks.base.utils.boundary.BoundType;
 import de.unikoblenz.fgbks.base.utils.boundary.BoundaryParseException;
 import org.apache.commons.lang3.Validate;
 
@@ -13,13 +14,30 @@ public class IntegerBoundary extends AbstractGrowingBoundary<Integer> {
     super(text, Integer.TYPE);
   }
 
+  private IntegerBoundary() {
+    super(Integer.TYPE);
+  }
+
+  @Override
+  public AbstractGrowingBoundary getCopy(
+      Integer lowerBound, Integer upperBound, BoundType lowerBoundType, BoundType upperBoundType) {
+    IntegerBoundary v = new IntegerBoundary();
+    v.lowerBound = lowerBound;
+    v.upperBound = upperBound;
+    v.lowerBoundType = lowerBoundType;
+    v.upperBoundType = upperBoundType;
+    v.simplifyBound();
+    v.validate();
+    return v;
+  }
+
   @Override
-  protected Integer getMinValue() {
+  public Integer getMinValue() {
     return Integer.MIN_VALUE;
   }
 
   @Override
-  protected Integer getMaxValue() {
+  public Integer getMaxValue() {
     return Integer.MAX_VALUE;
   }
 
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/InvalidBoundary.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/InvalidBoundary.java
index 61b30aef1da066173cf39c4e5a8e48e29171da19..2523efd075d9fd122c34e545218f2423f8443768 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/InvalidBoundary.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/InvalidBoundary.java
@@ -1,8 +1,8 @@
 package de.unikoblenz.fgbks.base.utils.boundary.impl;
 
 import de.unikoblenz.fgbks.base.utils.boundary.Boundary;
+import de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType;
-import de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType;
 import de.unikoblenz.fgbks.base.utils.boundary.creater.BoundaryCreaterType;
 import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VTypeRef;
 import java.util.Optional;
@@ -38,7 +38,7 @@ public class InvalidBoundary implements Boundary {
   }
 
   @Override
-  public Optional<Boundary> combine(BoundaryCombineType combineType, Boundary other) {
+  public Optional<Boundary> createBi(BoundaryBiCreaterType combineType, Boundary other) {
     return Optional.empty();
   }
 
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/LongBoundary.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/LongBoundary.java
index 162c040494c46f934649e15bcb15ec3619374152..06e316d3b3b2d4192968b1b7006290591fb71388 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/LongBoundary.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/impl/LongBoundary.java
@@ -4,6 +4,7 @@ import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.EXCLUSIVE;
 import static de.unikoblenz.fgbks.base.utils.boundary.BoundType.INCLUSIVE;
 
 import de.unikoblenz.fgbks.base.utils.boundary.AbstractGrowingBoundary;
+import de.unikoblenz.fgbks.base.utils.boundary.BoundType;
 import de.unikoblenz.fgbks.base.utils.boundary.BoundaryParseException;
 import org.apache.commons.lang3.Validate;
 
@@ -13,13 +14,30 @@ public class LongBoundary extends AbstractGrowingBoundary<Long> {
     super(text, Long.TYPE);
   }
 
+  private LongBoundary() {
+    super(Long.TYPE);
+  }
+
+  @Override
+  public AbstractGrowingBoundary getCopy(
+      Long lowerBound, Long upperBound, BoundType lowerBoundType, BoundType upperBoundType) {
+    LongBoundary v = new LongBoundary();
+    v.lowerBound = lowerBound;
+    v.upperBound = upperBound;
+    v.lowerBoundType = lowerBoundType;
+    v.upperBoundType = upperBoundType;
+    v.simplifyBound();
+    v.validate();
+    return v;
+  }
+
   @Override
-  protected Long getMinValue() {
+  public Long getMinValue() {
     return Long.MIN_VALUE;
   }
 
   @Override
-  protected Long getMaxValue() {
+  public Long getMaxValue() {
     return Long.MAX_VALUE;
   }
 
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 d1eef32e6ddbf481e2da551b8f782851581f23d2..3f4540aaedd21dd618248b3346adaf2c677ec384 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
@@ -1,17 +1,26 @@
 package de.unikoblenz.fgbks.base.utils.boundary.impl;
 
-import static de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType.APPEND;
-import static de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType.BETWEEN;
-import static de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType.COMBINE;
-import static de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType.INTERSECTION;
-import static de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType.LOWER_BOUNDS;
-import static de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombineType.UPPER_BOUNDS;
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.APPEND;
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.BETWEEN;
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.COMBINE;
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.INTERSECTION;
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.LOWER_BOUNDS;
+import static de.unikoblenz.fgbks.base.utils.boundary.bicreater.BoundaryBiCreaterType.UPPER_BOUNDS;
+import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_EQUAL;
+import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_IN_CONTACT;
+import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_NOT_IN_CONTACT;
+import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_OVERLAPPING;
+import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.IS_SUBSUMPTION;
+import static de.unikoblenz.fgbks.base.utils.boundary.checker.BoundaryCheckType.SUBSUMES;
 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.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.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;
@@ -20,12 +29,10 @@ import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckStringNotInContact;
 import de.unikoblenz.fgbks.base.utils.boundary.checker.CheckStringOverlap;
 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.combiner.BoundaryCombineType;
-import de.unikoblenz.fgbks.base.utils.boundary.combiner.BoundaryCombiner;
-import de.unikoblenz.fgbks.base.utils.boundary.combiner.EmptyCombiner;
 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.EmptyCreater;
+import de.unikoblenz.fgbks.base.utils.boundary.creater.CreaterLower;
+import de.unikoblenz.fgbks.base.utils.boundary.creater.CreaterUpper;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Objects;
@@ -33,6 +40,27 @@ import org.apache.commons.lang3.Validate;
 
 public class StringBoundary extends AbstractBoundary<String> {
 
+  private static HashMap<BoundaryCheckType, BoundaryCheck> checkerMap = new HashMap<>();
+  private static HashMap<BoundaryCreaterType, BoundaryCreater> createrMap = new HashMap<>();
+  private static HashMap<BoundaryBiCreaterType, BoundaryBiCreater> combinerMap = new HashMap<>();
+
+  static {
+    checkerMap.put(IS_EQUAL, CheckStringEqual.getInstance());
+    checkerMap.put(IS_IN_CONTACT, CheckStringInContact.getInstance());
+    checkerMap.put(IS_NOT_IN_CONTACT, CheckStringNotInContact.getInstance());
+    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());
+    combinerMap.put(INTERSECTION, EmptyBiCreater.getInstance());
+    combinerMap.put(LOWER_BOUNDS, EmptyBiCreater.getInstance());
+    combinerMap.put(UPPER_BOUNDS, EmptyBiCreater.getInstance());
+    combinerMap.put(BETWEEN, EmptyBiCreater.getInstance());
+    combinerMap.put(APPEND, EmptyBiCreater.getInstance());
+    combinerMap.put(COMBINE, EmptyBiCreater.getInstance());
+  }
+
   private boolean matchNoneOfValues;
   private boolean matchAny;
   private String[] values;
@@ -104,34 +132,17 @@ public class StringBoundary extends AbstractBoundary<String> {
 
   @Override
   protected HashMap<BoundaryCheckType, BoundaryCheck> getChecker() {
-    HashMap<BoundaryCheckType, BoundaryCheck> map = new HashMap<>();
-    map.put(BoundaryCheckType.IS_EQUAL, CheckStringEqual.getInstance());
-    map.put(BoundaryCheckType.IS_IN_CONTACT, CheckStringInContact.getInstance());
-    map.put(BoundaryCheckType.IS_NOT_IN_CONTACT, CheckStringNotInContact.getInstance());
-    map.put(BoundaryCheckType.IS_OVERLAPPING, CheckStringOverlap.getInstance());
-    map.put(BoundaryCheckType.IS_SUBSUMPTION, CheckStringSubsumption.getInstance());
-    map.put(BoundaryCheckType.SUBSUMES, CheckStringSubsumes.getInstance());
-    return map;
+    return checkerMap;
   }
 
   @Override
-  protected HashMap<BoundaryCombineType, BoundaryCombiner> getCombiner() {
-    HashMap<BoundaryCombineType, BoundaryCombiner> map = new HashMap<>();
-    map.put(INTERSECTION, EmptyCombiner.getInstance());
-    map.put(LOWER_BOUNDS, EmptyCombiner.getInstance());
-    map.put(UPPER_BOUNDS, EmptyCombiner.getInstance());
-    map.put(BETWEEN, EmptyCombiner.getInstance());
-    map.put(APPEND, EmptyCombiner.getInstance());
-    map.put(COMBINE, EmptyCombiner.getInstance());
-    return map;
+  protected HashMap<BoundaryBiCreaterType, BoundaryBiCreater> getBiCreater() {
+    return combinerMap;
   }
 
   @Override
   protected HashMap<BoundaryCreaterType, BoundaryCreater> getCreater() {
-    HashMap<BoundaryCreaterType, BoundaryCreater> map = new HashMap<>();
-    map.put(UPPER, EmptyCreater.getInstance());
-    map.put(LOWER, EmptyCreater.getInstance());
-    return map;
+    return createrMap;
   }
 
   @Override