diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/builder/AbstractBuilder.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/builder/AbstractBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..8453085160f72847fee1f6f387335e653433543b
--- /dev/null
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/builder/AbstractBuilder.java
@@ -0,0 +1,45 @@
+package de.unikoblenz.fgbks.base.builder;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+
+public abstract class AbstractBuilder<E, B extends AbstractBuilder<E, B>> implements Serializable {
+  private static final String VALUE_FIELD_NAME = "value";
+
+  protected E value;
+
+  protected AbstractBuilder() {
+    value = newInstance();
+  }
+
+  protected AbstractBuilder(E v) {
+    value = v;
+  }
+
+  public static Field getAccessibleValueField() throws IllegalStateException {
+    try {
+      Field valueField = AbstractBuilder.class.getDeclaredField(VALUE_FIELD_NAME);
+      valueField.setAccessible(true);
+      return valueField;
+    } catch (NoSuchFieldException e) {
+      throw new IllegalStateException(
+          String.format(
+              "%s must have field with name '%s'",
+              AbstractBuilder.class.getSimpleName(), VALUE_FIELD_NAME),
+          e);
+    }
+  }
+
+  protected abstract B thisBuilder();
+
+  protected abstract E newInstance();
+
+  protected abstract void validate();
+
+  public E build() {
+    validate();
+    E result = value;
+    value = newInstance();
+    return result;
+  }
+}
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/builder/DefaultBuilder.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/builder/DefaultBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..c57b946c7b251f6c8c823d6e6e2a869a6374075b
--- /dev/null
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/builder/DefaultBuilder.java
@@ -0,0 +1,79 @@
+package de.unikoblenz.fgbks.base.builder;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+/** @param <E> The type of the object being constructed. */
+public class DefaultBuilder<E> extends AbstractBuilder<E, DefaultBuilder<E>> {
+
+  protected DefaultBuilder() {
+    super();
+  }
+
+  protected DefaultBuilder(E value) {
+    super(value);
+  }
+
+  /**
+   * Liefert E so zurück
+   *
+   * @return DefaultBuilder
+   */
+  @Override
+  protected DefaultBuilder<E> thisBuilder() {
+    return this;
+  }
+
+  @Override
+  protected void validate() {
+    // nothing to validate
+  }
+
+  /**
+   * @return <tt>new E()</tt>, where E is the type of the object being constructed which is the type
+   *     parameter of this class.
+   * @throws IllegalStateException
+   *     <ul>
+   *       <li>when the type parameter cannot be extracted or is no {@link Class}, but a generic
+   *           type
+   *       <li>or when no default-constructor can be found
+   *       <li>or when the constructor throws an exception other than {@link RuntimeException}
+   *     </ul>
+   */
+  @Override
+  protected E newInstance() {
+    Class<?> directSubclass = getClass();
+    while (directSubclass.getSuperclass() != DefaultBuilder.class) {
+      directSubclass = directSubclass.getSuperclass();
+    }
+    Type genericSuperclass = directSubclass.getGenericSuperclass();
+    if (!(genericSuperclass instanceof ParameterizedType)) {
+      throw new IllegalStateException(
+          "Generic type argument E missing for superclass " + DefaultBuilder.class.getSimpleName());
+    }
+    ParameterizedType parameterizedSuperclass = (ParameterizedType) genericSuperclass;
+    Type valueType = parameterizedSuperclass.getActualTypeArguments()[0];
+    if (!(valueType instanceof Class)) {
+      throw new IllegalStateException(
+          "No generics allowed for type argument, but found " + valueType);
+    }
+    Class<E> type = (Class<E>) valueType;
+    try {
+      Constructor<E> constructor = type.getDeclaredConstructor();
+      constructor.setAccessible(true);
+      return constructor.newInstance();
+    } catch (NoSuchMethodException e) {
+      throw new IllegalStateException("No default-constructor found for " + type.getName(), e);
+    } catch (InvocationTargetException e) {
+      if (e.getTargetException() instanceof RuntimeException) {
+        throw (RuntimeException) e.getTargetException();
+      } else {
+        throw new IllegalStateException(e.getTargetException());
+      }
+    } catch (ReflectiveOperationException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+}
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/api/APIExceptionInterceptor.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/utils/ExceptionInterceptor.java
similarity index 84%
rename from dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/api/APIExceptionInterceptor.java
rename to dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/utils/ExceptionInterceptor.java
index 05d07af4f351d383ba6e6699485a89cf2a4cc0fc..728db5531c4998f77376b237606779b158489620 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/api/APIExceptionInterceptor.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/utils/ExceptionInterceptor.java
@@ -1,10 +1,10 @@
-package de.unikoblenz.fgbks.dmn.api;
+package de.unikoblenz.fgbks.base.utils;
 
 import javax.interceptor.AroundInvoke;
 import javax.interceptor.InvocationContext;
 import javax.ws.rs.core.Response;
 
-public class APIExceptionInterceptor {
+public class ExceptionInterceptor {
 
   @AroundInvoke
   public Object value(InvocationContext context) {
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/utils/Performance.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/utils/Performance.java
new file mode 100644
index 0000000000000000000000000000000000000000..323ef5c0ac68ebd5fc3fe8145bbc13443b282794
--- /dev/null
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/utils/Performance.java
@@ -0,0 +1,14 @@
+package de.unikoblenz.fgbks.base.utils;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import javax.interceptor.InterceptorBinding;
+
+@InterceptorBinding
+@Target({METHOD, TYPE})
+@Retention(RUNTIME)
+public @interface Performance {}
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/utils/PerformanceInterceptor.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/utils/PerformanceInterceptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..c47d27d9d7677155c85ba4cddfc83e2850df263d
--- /dev/null
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/utils/PerformanceInterceptor.java
@@ -0,0 +1,26 @@
+package de.unikoblenz.fgbks.base.utils;
+
+import java.io.Serializable;
+import java.util.concurrent.TimeUnit;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Performance
+@Interceptor
+public class PerformanceInterceptor implements Serializable {
+
+  @AroundInvoke
+  public Object performance(InvocationContext ctx) throws Exception {
+    long start = System.nanoTime();
+    Object obj = ctx.proceed();
+    long end = System.nanoTime();
+    long durationInMs = TimeUnit.NANOSECONDS.toMillis(end - start);
+
+    Logger log = LoggerFactory.getLogger(ctx.getMethod().getDeclaringClass());
+    log.info(ctx.getMethod().getName() + " - " + durationInMs + " ms");
+    return obj;
+  }
+}
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/wordnet/WordnetService.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/wordnet/WordnetService.java
similarity index 93%
rename from dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/wordnet/WordnetService.java
rename to dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/wordnet/WordnetService.java
index bf327efba26ce01b84abf742bc66526ad8eaf4e4..915ce7c8816b5df8026d26b5e092972b960774a9 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/wordnet/WordnetService.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/wordnet/WordnetService.java
@@ -1,4 +1,4 @@
-package de.unikoblenz.fgbks.dmn.core.verifier.helper.wordnet;
+package de.unikoblenz.fgbks.base.wordnet;
 
 import edu.mit.jwi.Dictionary;
 import edu.mit.jwi.IDictionary;
@@ -85,4 +85,10 @@ public class WordnetService {
     }
     return false;
   }
+
+  public void close() {
+    if (dictionary != null && dictionary.isOpen()) {
+      dictionary.close();
+    }
+  }
 }
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/api/DmnApi.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/api/DmnApi.java
index e3aaac7cbaefd7bf6a8eb836d17451d80d7fe50c..fda7274d70ff07c3fa2899f9164f81fdaaefea3a 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/api/DmnApi.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/api/DmnApi.java
@@ -1,5 +1,7 @@
 package de.unikoblenz.fgbks.dmn.api;
 
+import de.unikoblenz.fgbks.base.utils.ExceptionInterceptor;
+import de.unikoblenz.fgbks.base.utils.PerformanceInterceptor;
 import de.unikoblenz.fgbks.dmn.beans.DmnBean;
 import de.unikoblenz.fgbks.dmn.core.DmnService;
 import de.unikoblenz.fgbks.dmn.core.models.VerifierType;
@@ -17,7 +19,7 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
 @Path("/dmn")
-@Interceptors(APIExceptionInterceptor.class)
+@Interceptors({ExceptionInterceptor.class, PerformanceInterceptor.class})
 public class DmnApi {
 
   private static final String NO_CURRENT_DMN_FOUND = "No current DMN found";
@@ -41,17 +43,6 @@ public class DmnApi {
     return Response.status(Status.OK).entity(dmnBean.getDmnXML()).build();
   }
 
-  @GET
-  @Produces({MediaType.APPLICATION_JSON})
-  @Path("/test")
-  public Response getTestDmnErrors() {
-    Optional<DmnService> dmnHandler = createDmnService();
-    if (dmnHandler.isPresent()) {
-      return Response.status(Status.OK).entity(dmnHandler.get().getTestValidationErrors()).build();
-    }
-    return Response.serverError().entity(NO_CURRENT_DMN_FOUND).build();
-  }
-
   @GET
   @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
   @Consumes({MediaType.TEXT_PLAIN})
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/beans/StartupListener.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/beans/StartupListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..aa53277f195014485742b06f9b9f98fda9221d4b
--- /dev/null
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/beans/StartupListener.java
@@ -0,0 +1,28 @@
+package de.unikoblenz.fgbks.dmn.beans;
+
+import de.unikoblenz.fgbks.base.wordnet.WordnetService;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.Destroyed;
+import javax.enterprise.context.Initialized;
+import javax.enterprise.event.Observes;
+import javax.servlet.ServletContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@ApplicationScoped
+public class StartupListener {
+
+  private static Logger LOGGER = LoggerFactory.getLogger(StartupListener.class.getSimpleName());
+
+  public void init(@Observes @Initialized(ApplicationScoped.class) ServletContext context) {
+    // init wordnet
+    LOGGER.info("init Wordnet");
+    WordnetService.getInstance();
+  }
+
+  public void destroy(@Observes @Destroyed(ApplicationScoped.class) ServletContext context) {
+    // close wordnet
+    LOGGER.info("close wordnet");
+    WordnetService.getInstance().close();
+  }
+}
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/DmnService.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/DmnService.java
index 71d4c9dfce16083e7a269025ac4931d082ac6350..cfca8a3e1b0311487335761090cdb6eb4c6b8fc5 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/DmnService.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/DmnService.java
@@ -1,10 +1,7 @@
 package de.unikoblenz.fgbks.dmn.core;
 
-import de.unikoblenz.fgbks.dmn.core.models.RuleIdentifier;
-import de.unikoblenz.fgbks.dmn.core.models.VerificationResult;
 import de.unikoblenz.fgbks.dmn.core.models.VerifierCollectionResult;
 import de.unikoblenz.fgbks.dmn.core.models.VerifierResult;
-import de.unikoblenz.fgbks.dmn.core.models.VerifierResult.Builder;
 import de.unikoblenz.fgbks.dmn.core.models.VerifierType;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -13,8 +10,6 @@ import java.util.Objects;
 import org.apache.commons.io.IOUtils;
 import org.camunda.bpm.dmn.engine.DmnDecision;
 import org.camunda.bpm.dmn.engine.DmnEngineConfiguration;
-import org.camunda.bpm.dmn.engine.impl.DmnDecisionTableImpl;
-import org.camunda.bpm.dmn.engine.impl.DmnDecisionTableRuleImpl;
 
 public class DmnService {
 
@@ -47,31 +42,6 @@ public class DmnService {
     return sb.toString();
   }
 
-  public VerifierResult getTestValidationErrors() {
-    Builder resultBuilder =
-        VerifierResult.getBuilder().withVerifierType(VerifierType.IdenticalRules);
-
-    for (DmnDecision d : dmnDecisions) {
-      if (d.isDecisionTable()) {
-        DmnDecisionTableImpl table = (DmnDecisionTableImpl) d.getDecisionLogic();
-        int counter = 0;
-        VerificationResult.Builder vBuilder =
-            VerificationResult.getBuilder().withMessage(d.getName() + " Verification!!!");
-        for (DmnDecisionTableRuleImpl rule : table.getRules()) {
-          vBuilder.addRule(
-              RuleIdentifier.getBuilder()
-                  .withDecisionKey(d.getKey())
-                  .withDecisionName(d.getName())
-                  .withRuleId(rule.getId())
-                  .withRowNumber(++counter)
-                  .build());
-        }
-        resultBuilder.addVerificationResult(vBuilder.build());
-      }
-    }
-    return resultBuilder.build();
-  }
-
   public VerifierResult getVerifierFromType(VerifierType verifierType) {
     return verifierType.getResult(dmnDecisions, null).orElse(null);
   }
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/RuleIdentifier.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/RuleIdentifier.java
index 828bb5924e30e09653e96165188bf613f887f692..92ae294f4ec732653ca2501b29c1a0a99ea36ae3 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/RuleIdentifier.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/RuleIdentifier.java
@@ -1,5 +1,6 @@
 package de.unikoblenz.fgbks.dmn.core.models;
 
+import de.unikoblenz.fgbks.base.builder.DefaultBuilder;
 import java.io.Serializable;
 import java.util.Objects;
 import javax.xml.bind.annotation.XmlElement;
@@ -95,56 +96,52 @@ public class RuleIdentifier implements Serializable {
     return Objects.hash(decisionKey, ruleId, conditionId);
   }
 
-  public class Builder {
+  public class Builder extends DefaultBuilder<RuleIdentifier> {
 
     private Builder() {}
 
     public Builder withDecision(DmnDecision d) {
-      setDecisionKey(d.getKey());
-      setDecisionName(d.getName());
+      value.setDecisionKey(d.getKey());
+      value.setDecisionName(d.getName());
       return this;
     }
 
     public Builder withDecisionKey(String decisionKey) {
-      setDecisionKey(decisionKey);
+      value.setDecisionKey(decisionKey);
       return this;
     }
 
     public Builder withDecisionName(String decisionName) {
-      setDecisionName(decisionName);
+      value.setDecisionName(decisionName);
       return this;
     }
 
     public Builder withRuleId(String ruleId) {
-      setRuleId(ruleId);
+      value.setRuleId(ruleId);
       return this;
     }
 
     public Builder withRowNumber(Integer rowNumber) {
-      setRowNumber(rowNumber);
+      value.setRowNumber(rowNumber);
       return this;
     }
 
     public Builder withConditionId(String conditionId) {
-      setConditionId(conditionId);
+      value.setConditionId(conditionId);
       return this;
     }
 
     public Builder withConditionName(String conditionName) {
-      setConditionName(conditionName);
+      value.setConditionName(conditionName);
       return this;
     }
 
-    private RuleIdentifier validate() {
-      Objects.requireNonNull(decisionKey);
-      Objects.requireNonNull(decisionName);
-      Objects.requireNonNull(ruleId);
-      Objects.requireNonNull(rowNumber);
-      return RuleIdentifier.this;
-    }
-
-    public RuleIdentifier build() {
-      return validate();
+    @Override
+    protected void validate() {
+      Objects.requireNonNull(value.decisionKey);
+      Objects.requireNonNull(value.decisionName);
+      Objects.requireNonNull(value.ruleId);
+      Objects.requireNonNull(value.rowNumber);
     }
   }
 }
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerificationResult.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerificationResult.java
index 4494dade082bce842cb990ebde468c566c5cac29..f1784f3af37d5eec3b0522fd9f79ff8a1311e5be 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerificationResult.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerificationResult.java
@@ -1,5 +1,6 @@
 package de.unikoblenz.fgbks.dmn.core.models;
 
+import de.unikoblenz.fgbks.base.builder.DefaultBuilder;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -43,37 +44,31 @@ public class VerificationResult implements Serializable {
     return new VerificationResult().new Builder();
   }
 
-  public class Builder {
-
-    private Builder() {}
+  public class Builder extends DefaultBuilder<VerificationResult> {
 
     public Builder addRule(RuleIdentifier ruleIdentifier) {
-      rules.add(ruleIdentifier);
+      value.rules.add(ruleIdentifier);
       return this;
     }
 
     public Builder addRules(Collection<RuleIdentifier> ruleIdentifier) {
-      rules.addAll(ruleIdentifier);
+      value.rules.addAll(ruleIdentifier);
       return this;
     }
 
     public Builder withMessage(String message, Object... args) {
-      setMessage(String.format(message, args));
+      value.setMessage(String.format(message, args));
       return this;
     }
 
     public Builder withMessage(String message) {
-      setMessage(message);
+      value.setMessage(message);
       return this;
     }
 
-    private VerificationResult validate() {
-      Objects.requireNonNull(message);
-      return VerificationResult.this;
-    }
-
-    public VerificationResult build() {
-      return validate();
+    @Override
+    protected void validate() {
+      Objects.requireNonNull(value.message);
     }
   }
 }
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierCollectionResult.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierCollectionResult.java
index f91403de454b465c02cf2a69965468685f50df44..b6a7c0e732cfaec9786d8a5396e2a3dd756ec05a 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierCollectionResult.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierCollectionResult.java
@@ -1,5 +1,6 @@
 package de.unikoblenz.fgbks.dmn.core.models;
 
+import de.unikoblenz.fgbks.base.builder.DefaultBuilder;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -24,21 +25,11 @@ public class VerifierCollectionResult {
     return new VerifierCollectionResult().new Builder();
   }
 
-  public class Builder {
-
-    private Builder() {}
+  public class Builder extends DefaultBuilder<VerifierCollectionResult> {
 
     public VerifierCollectionResult.Builder addVerification(VerifierResult verificationResult) {
-      verifierResults.add(Objects.requireNonNull(verificationResult));
+      value.verifierResults.add(Objects.requireNonNull(verificationResult));
       return this;
     }
-
-    private VerifierCollectionResult validate() {
-      return VerifierCollectionResult.this;
-    }
-
-    public VerifierCollectionResult build() {
-      return validate();
-    }
   }
 }
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierResult.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierResult.java
index de4e8db1d84177682ee1ecdef85b35da7c2c6485..1258472f8f3f2b06f3e8f38cc947f00a248005b4 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierResult.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierResult.java
@@ -1,5 +1,6 @@
 package de.unikoblenz.fgbks.dmn.core.models;
 
+import de.unikoblenz.fgbks.base.builder.DefaultBuilder;
 import java.io.Serializable;
 import java.util.HashSet;
 import java.util.Objects;
@@ -48,27 +49,21 @@ public class VerifierResult implements Serializable {
     return new VerifierResult().new Builder();
   }
 
-  public class Builder {
-
-    private Builder() {}
+  public class Builder extends DefaultBuilder<VerifierResult> {
 
     public Builder withVerifierType(VerifierType verifierType) {
-      setVerifierType(verifierType);
+      value.setVerifierType(verifierType);
       return this;
     }
 
     public Builder addVerificationResult(VerificationResult ruleIdentifier) {
-      verifications.add(ruleIdentifier);
+      value.verifications.add(ruleIdentifier);
       return this;
     }
 
-    private VerifierResult validate() {
-      Objects.requireNonNull(verifierType);
-      return VerifierResult.this;
-    }
-
-    public VerifierResult build() {
-      return validate();
+    @Override
+    protected void validate() {
+      Objects.requireNonNull(value.verifierType);
     }
   }
 }
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierType.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierType.java
index 1d7851120ab280f16f3e1c669a8f47d1fc1ffe87..0bb3657802f7d2e10b0577bb150ed543dff8ab47 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierType.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierType.java
@@ -1,24 +1,23 @@
 package de.unikoblenz.fgbks.dmn.core.models;
 
-import de.unikoblenz.fgbks.dmn.core.verifier.AbstractVerifier;
-import de.unikoblenz.fgbks.dmn.core.verifier.EquivalentRules;
-import de.unikoblenz.fgbks.dmn.core.verifier.IdenticalRules;
-import de.unikoblenz.fgbks.dmn.core.verifier.SubsumptionRules;
+import de.unikoblenz.fgbks.dmn.core.verifier.*;
 import de.unikoblenz.fgbks.dmn.core.verifier.helper.RuleMap;
 import java.util.List;
 import java.util.Optional;
 import org.camunda.bpm.dmn.engine.DmnDecision;
 
 public enum VerifierType {
-  IdenticalRules("Identical Business Rule", IdenticalRules.class),
+  Identical("Identical Business Rule", IdenticalRules.class),
   Subsumption("Business Rules, that are subsumption", SubsumptionRules.class),
-  Equivalent("Checking for synonyms in columns.", EquivalentRules.class);
+  Equivalent("Checking for synonyms in columns.", EquivalentRules.class),
+  Overlap("Checking for overlapping rules.", OverlappingRules.class),
+  Missing("Checking for missing rules", MissingRules.class);
   /*
   ,
   Overlap("", null),
   Contradictions("", null),
   SpecificPartialReduction("", null),
-  MissingRules("", null),
+  Missing("", null),
    */
   private final Class<? extends AbstractVerifier> verifierClass;
   private String description;
@@ -34,7 +33,7 @@ public enum VerifierType {
 
   public Optional<VerifierResult> getResult(List<DmnDecision> dmnDecisionList, RuleMap ruleMap) {
     if (ruleMap == null) {
-      ruleMap = RuleMap.createMapFromDMN(dmnDecisionList);
+      ruleMap = RuleMap.createMapFromDmn(dmnDecisionList);
     }
     try {
       return Optional.of(
@@ -45,7 +44,7 @@ public enum VerifierType {
   }
 
   public static VerifierCollectionResult getAllResults(List<DmnDecision> dmnDecisionList) {
-    RuleMap ruleMap = RuleMap.createMapFromDMN(dmnDecisionList);
+    RuleMap ruleMap = RuleMap.createMapFromDmn(dmnDecisionList);
     VerifierCollectionResult.Builder builder = VerifierCollectionResult.getBuilder();
     for (VerifierType verifierType : values()) {
       // TODO: make multi-thread
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/EquivalentRules.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/EquivalentRules.java
index b7b6bab2fcf51582d524bdc006b47479a251fd3e..93c049d2fe012b0800acbe30164beb89b1b83b8c 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/EquivalentRules.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/EquivalentRules.java
@@ -1,11 +1,11 @@
 package de.unikoblenz.fgbks.dmn.core.verifier;
 
+import de.unikoblenz.fgbks.base.wordnet.WordnetService;
 import de.unikoblenz.fgbks.dmn.core.models.VerificationResult;
 import de.unikoblenz.fgbks.dmn.core.models.VerifierType;
 import de.unikoblenz.fgbks.dmn.core.verifier.helper.DataType;
 import de.unikoblenz.fgbks.dmn.core.verifier.helper.Type;
 import de.unikoblenz.fgbks.dmn.core.verifier.helper.Value;
-import de.unikoblenz.fgbks.dmn.core.verifier.helper.wordnet.WordnetService;
 import java.util.List;
 import java.util.logging.Logger;
 import java.util.stream.Collectors;
@@ -50,7 +50,7 @@ public class EquivalentRules extends AbstractVerifier {
                     VerificationResult.getBuilder()
                         .addRule(values.get(i).getRuleIdentifier())
                         .addRule(values.get(u).getRuleIdentifier())
-                        .withMessage("%s and %s: equal meaning? are they synonyms.", val1, val2)
+                        .withMessage("%s and %s: equal meaning? Are they synonyms?", val1, val2)
                         .build());
               }
             }
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/IdenticalRules.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/IdenticalRules.java
index ff3ebed67bfb317c1eff8f628f554c727d295613..45ec8a484f71a0d4fc2cb0c0019f7045d47de33a 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/IdenticalRules.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/IdenticalRules.java
@@ -8,6 +8,7 @@ import de.unikoblenz.fgbks.dmn.core.verifier.helper.Value;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Set;
 import java.util.logging.Logger;
 import java.util.stream.Collectors;
 import org.camunda.bpm.dmn.engine.DmnDecision;
@@ -15,23 +16,26 @@ import org.camunda.bpm.dmn.engine.DmnDecision;
 public class IdenticalRules extends AbstractVerifier {
 
   private static final Logger LOGGER = Logger.getLogger(IdenticalRules.class.getSimpleName());
+  private Set<Set<String>> identicaldecicionTables;
 
   public IdenticalRules() {
-    super(VerifierType.IdenticalRules);
+    super(VerifierType.Identical);
   }
 
   @Override
-  protected void beforeVerifyDecision() {}
+  protected void beforeVerifyDecision() {
+    identicaldecicionTables = ruleMap.getIncludingInputDefinitions();
+  }
 
   @Override
   protected void verifyDecision(DmnDecision d) {
     if (d.isDecisionTable()) {
       List<Type> inputs = new ArrayList<>(ruleMap.getAllInputTypesFromDecisionKey(d.getKey()));
-      checkForEqualRules(inputs, 0, null);
+      checkForIdenticalRules(inputs, 0, null);
     }
   }
 
-  private void checkForEqualRules(
+  private void checkForIdenticalRules(
       List<Type> inputs, int i, List<RuleIdentifier> currentRuleIdentifiers) {
     if (i == inputs.size()) {
       VerificationResult.Builder vBuilder =
@@ -51,7 +55,7 @@ public class IdenticalRules extends AbstractVerifier {
           } else {
             if (currentBounds.size() > 0) {
               currentBounds.add(lastBound);
-              checkForEqualRules(
+              checkForIdenticalRules(
                   inputs,
                   i + 1,
                   currentBounds
@@ -66,7 +70,7 @@ public class IdenticalRules extends AbstractVerifier {
       }
       if (currentBounds.size() > 0) {
         currentBounds.add(lastBound);
-        checkForEqualRules(
+        checkForIdenticalRules(
             inputs,
             i + 1,
             currentBounds.stream().map(Value::getRuleIdentifier).collect(Collectors.toList()));
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/MissingRules.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/MissingRules.java
new file mode 100644
index 0000000000000000000000000000000000000000..c587154318141f50b7bafdfc8e3a0fca184bb8e7
--- /dev/null
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/MissingRules.java
@@ -0,0 +1,87 @@
+package de.unikoblenz.fgbks.dmn.core.verifier;
+
+import de.unikoblenz.fgbks.dmn.core.models.RuleIdentifier;
+import de.unikoblenz.fgbks.dmn.core.models.VerificationResult;
+import de.unikoblenz.fgbks.dmn.core.models.VerifierType;
+import de.unikoblenz.fgbks.dmn.core.verifier.helper.Boundary;
+import de.unikoblenz.fgbks.dmn.core.verifier.helper.Type;
+import de.unikoblenz.fgbks.dmn.core.verifier.helper.Value;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import org.camunda.bpm.dmn.engine.DmnDecision;
+
+public class MissingRules extends AbstractVerifier {
+
+  public MissingRules() {
+    super(VerifierType.Missing);
+  }
+
+  @Override
+  protected void beforeVerifyDecision() {}
+
+  @Override
+  protected void verifyDecision(DmnDecision d) {
+    if (d.isDecisionTable()) {
+      List<Type> inputs = new ArrayList<>(ruleMap.getAllInputTypesFromDecisionKey(d.getKey()));
+      checkForMissingRules(d, inputs, 0, null, new ArrayList<>());
+    }
+  }
+
+  private void checkForMissingRules(
+      DmnDecision d,
+      List<Type> inputs,
+      int i,
+      List<RuleIdentifier> currentRuleIdentifiers,
+      List<Boundary> missingIntervals) {
+
+    List<Value> sortedBounds =
+        new ArrayList<>(ruleMap.getValuesFromInputType(inputs.get(i), currentRuleIdentifiers));
+    sortedBounds.sort(Comparator.comparing(Value::getBoundary));
+
+    Value lastBound = null;
+    for (Value currentBound : sortedBounds) {
+      if (lastBound == null) {
+        if (currentBound.getBoundary().getLowerBound() != Double.MIN_VALUE) {
+          missingIntervals.add(currentBound.getBoundary().getNewBoundaryLower().get());
+        }
+      } else {
+        boolean contiguous =
+            lastBound.getBoundary().combineWith(currentBound.getBoundary()).isPresent();
+        if (!contiguous) {
+          Boundary newBound =
+              lastBound.getBoundary().getNewBoundaryBetween(currentBound.getBoundary()).get();
+          missingIntervals.add(newBound);
+        }
+      }
+      if (lastBound == null
+          || !lastBound
+              .getBoundary()
+              .isNumberInRange(
+                  currentBound.getBoundary().getUpperBound(),
+                  currentBound.getBoundary().getUpperBoundType())) {
+        lastBound = currentBound;
+      }
+    }
+    if (lastBound != null) {
+      if (lastBound.getBoundary().getUpperBound() != Double.MAX_VALUE) {
+        missingIntervals.add(lastBound.getBoundary().getNewBoundaryUpper().get());
+      }
+    }
+    for (Boundary b : missingIntervals) {
+      addVerification(
+          VerificationResult.getBuilder()
+              .addRule(
+                  RuleIdentifier.getBuilder()
+                      .withRowNumber(999)
+                      .withDecision(d)
+                      .withRuleId("a")
+                      .build())
+              .withMessage("Missing interval: %s", b.toString())
+              .build());
+    }
+  }
+
+  @Override
+  protected void afterVerifyDecision() {}
+}
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/OverlappingRules.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/OverlappingRules.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ebc9c1f8b4ed0ac7695ea5cce6a1eb370178806
--- /dev/null
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/OverlappingRules.java
@@ -0,0 +1,94 @@
+package de.unikoblenz.fgbks.dmn.core.verifier;
+
+import de.unikoblenz.fgbks.dmn.core.models.RuleIdentifier;
+import de.unikoblenz.fgbks.dmn.core.models.VerificationResult;
+import de.unikoblenz.fgbks.dmn.core.models.VerifierType;
+import de.unikoblenz.fgbks.dmn.core.verifier.helper.Type;
+import de.unikoblenz.fgbks.dmn.core.verifier.helper.Value;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.camunda.bpm.dmn.engine.DmnDecision;
+
+public class OverlappingRules extends AbstractVerifier {
+
+  public OverlappingRules() {
+    super(VerifierType.Overlap);
+  }
+
+  @Override
+  protected void beforeVerifyDecision() {}
+
+  @Override
+  protected void verifyDecision(DmnDecision d) {
+    if (d.isDecisionTable()) {
+      List<Type> inputs = new ArrayList<>(ruleMap.getAllInputTypesFromDecisionKey(d.getKey()));
+      checkForOverlappingRules(inputs, 0, null, false);
+    }
+  }
+
+  private void checkForOverlappingRules(
+      List<Type> inputs, int i, List<RuleIdentifier> currentRuleIdentifiers, boolean hasOverlap) {
+    if (i == inputs.size()) {
+      if (hasOverlap) {
+        VerificationResult.Builder vBuilder =
+            VerificationResult.getBuilder().withMessage(getMessageText(currentRuleIdentifiers));
+        vBuilder.addRules(currentRuleIdentifiers);
+        addVerification(vBuilder.build());
+      }
+    } else {
+      List<Value> currentBounds = new ArrayList<>();
+      List<Value> sortedBounds =
+          new ArrayList<>(ruleMap.getValuesFromInputType(inputs.get(i), currentRuleIdentifiers));
+      sortedBounds.sort(Comparator.comparing(Value::getBoundary));
+      Value lastBound = null;
+      boolean foundOverlap = false;
+      for (Value currentBound : sortedBounds) {
+        if (lastBound != null) {
+          boolean isOverlap =
+              currentBound.getBoundary().isBoundaryOverlapping(lastBound.getBoundary());
+          if (isOverlap || currentBound.getBoundary().isBoundaryEquals(lastBound.getBoundary())) {
+            currentBounds.add(lastBound);
+            if (isOverlap) {
+              foundOverlap = true;
+            }
+          } else {
+            if (currentBounds.size() > 0) {
+              currentBounds.add(lastBound);
+              checkForOverlappingRules(
+                  inputs,
+                  i + 1,
+                  currentBounds.stream().map(Value::getRuleIdentifier).collect(Collectors.toList()),
+                  foundOverlap || hasOverlap);
+            }
+            currentBounds.clear();
+          }
+        }
+        lastBound = currentBound;
+      }
+      if (currentBounds.size() > 0) {
+        currentBounds.add(lastBound);
+        checkForOverlappingRules(
+            inputs,
+            i + 1,
+            currentBounds.stream().map(Value::getRuleIdentifier).collect(Collectors.toList()),
+            foundOverlap || hasOverlap);
+      }
+    }
+  }
+
+  @Override
+  protected void afterVerifyDecision() {}
+
+  private String getMessageText(List<RuleIdentifier> currentRuleIdentifiers) {
+    StringBuilder sb = new StringBuilder("Rules ");
+    sb.append(
+        currentRuleIdentifiers
+            .stream()
+            .map(c -> c.getRowNumber().toString())
+            .collect(Collectors.joining(", ")));
+    sb.append(" are overlapping.");
+    return sb.toString();
+  }
+}
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/SubsumptionRules.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/SubsumptionRules.java
index 2e982a2e28c61a389b23bf90aa2b55b7db0cc974..1304fea522434927b50b6d3fb62a42663f7720d8 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/SubsumptionRules.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/SubsumptionRules.java
@@ -6,8 +6,10 @@ import de.unikoblenz.fgbks.dmn.core.models.VerifierType;
 import de.unikoblenz.fgbks.dmn.core.verifier.helper.Type;
 import de.unikoblenz.fgbks.dmn.core.verifier.helper.Value;
 import java.util.ArrayList;
-import java.util.Comparator;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.stream.Collectors;
 import org.camunda.bpm.dmn.engine.DmnDecision;
 
@@ -18,13 +20,14 @@ public class SubsumptionRules extends AbstractVerifier {
   }
 
   @Override
-  protected void beforeVerifyDecision() {}
+  protected void beforeVerifyDecision() {
+  }
 
   @Override
   protected void verifyDecision(DmnDecision d) {
     if (d.isDecisionTable()) {
       List<Type> inputs = new ArrayList<>(ruleMap.getAllInputTypesFromDecisionKey(d.getKey()));
-      checkForSubsumptionRules(inputs, 0, null, false);
+      checkForSubsumptionRules(inputs, 0, null, false, null);
     }
   }
 
@@ -32,7 +35,7 @@ public class SubsumptionRules extends AbstractVerifier {
       List<Type> inputs,
       int i,
       List<RuleIdentifier> currentRuleIdentifiers,
-      boolean hasSubsumption) {
+      boolean hasSubsumption, Value currentRootSubsumptionElement) {
     if (i == inputs.size()) {
       if (hasSubsumption) {
         VerificationResult.Builder vBuilder =
@@ -41,49 +44,79 @@ public class SubsumptionRules extends AbstractVerifier {
         addVerification(vBuilder.build());
       }
     } else {
-      List<Value> currentBounds = new ArrayList<>();
-      List<Value> sortedBounds =
+      List<Value> selectedBounds =
           new ArrayList<>(ruleMap.getValuesFromInputType(inputs.get(i), currentRuleIdentifiers));
-      sortedBounds.sort(Comparator.comparing(Value::getBoundary));
-      Value lastBound = null;
-      boolean foundSubsumption = false;
-      for (Value currentBound : sortedBounds) {
-        if (lastBound != null) {
-          boolean isSubsumption =
-              currentBound.getBoundary().isBoundarySubsumption(lastBound.getBoundary());
-          if (isSubsumption
-              || currentBound.getBoundary().isBoundaryEquals(lastBound.getBoundary())) {
-            currentBounds.add(lastBound);
-            if (isSubsumption) {
-              foundSubsumption = true;
+
+      List<Set<Value>> clusters = new ArrayList<>();
+      List<Boolean> subsumptions = new ArrayList<>();
+      List<Value> subsumptionValue = new ArrayList<>();
+      if (currentRootSubsumptionElement != null) {
+        Value nValue = ruleMap.getValuesFromInputType(inputs.get(i), Collections.singletonList(currentRootSubsumptionElement.getRuleIdentifier())).get(0);
+        Set<Value> c1 = new HashSet<>();
+        c1.add(nValue);
+        boolean foundSubsumption = false;
+        for (Value cb2 : selectedBounds) {
+          boolean fs = nValue.getBoundary().isBoundarySubsumptionOf(cb2.getBoundary());
+          foundSubsumption |= fs;
+          if (fs) {
+            c1.add(cb2);
+          }
+        }
+        if (c1.size() > 1) {
+          clusters.add(c1);
+          subsumptions.add(foundSubsumption);
+          subsumptionValue.add(nValue);
+        }
+      } else {
+        for (Value cb1 : selectedBounds) {
+          Set<Value> c1 = new HashSet<>();
+          c1.add(cb1);
+          boolean foundSubsumption = false;
+          for (Value cb2 : selectedBounds) {
+            boolean fs = cb1.getBoundary().isBoundarySubsumptionOf(cb2.getBoundary());
+            foundSubsumption |= fs;
+            if (fs) {
+              c1.add(cb2);
             }
-          } else {
-            if (currentBounds.size() > 0) {
-              currentBounds.add(lastBound);
-              checkForSubsumptionRules(
-                  inputs,
-                  i + 1,
-                  currentBounds.stream().map(Value::getRuleIdentifier).collect(Collectors.toList()),
-                  foundSubsumption || hasSubsumption);
+          }
+          if (c1.size() > 1) {
+            clusters.add(c1);
+            subsumptions.add(foundSubsumption);
+            subsumptionValue.add(cb1);
+          }
+        }
+      }
+      // check for subsets, that includes other subsets
+      for (int x = 0; x < clusters.size(); x++) {
+        if (clusters.get(x) != null) {
+          Set<Value> c1 = clusters.get(x);
+          for (int y = 0; y < clusters.size(); y++) {
+            if (clusters.get(y) != null) {
+              Set<Value> c2 = clusters.get(y);
+              if (c1.containsAll(c2) && x != y) {
+                clusters.set(y, null);
+              }
             }
-            currentBounds.clear();
           }
         }
-        lastBound = currentBound;
       }
-      if (currentBounds.size() > 0) {
-        currentBounds.add(lastBound);
-        checkForSubsumptionRules(
-            inputs,
-            i + 1,
-            currentBounds.stream().map(Value::getRuleIdentifier).collect(Collectors.toList()),
-            foundSubsumption || hasSubsumption);
+
+      for (int x = 0; x < clusters.size(); x++) {
+        if (clusters.get(x) != null) {
+          Set<Value> vals = clusters.get(x);
+          checkForSubsumptionRules(
+              inputs,
+              i + 1,
+              vals.stream().map(Value::getRuleIdentifier).collect(Collectors.toList()),
+              subsumptions.get(x) || hasSubsumption, subsumptionValue.get(x));
+        }
       }
     }
   }
 
   @Override
-  protected void afterVerifyDecision() {}
+  protected void afterVerifyDecision() {
+  }
 
   private String getMessageText(List<RuleIdentifier> currentRuleIdentifiers) {
     StringBuilder sb = new StringBuilder("Rules ");
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/Test.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/Test.java
deleted file mode 100644
index 4d5d453e3a7134e2bde758b4e5895eb1286a0093..0000000000000000000000000000000000000000
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/Test.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package de.unikoblenz.fgbks.dmn.core.verifier;
-
-import de.unikoblenz.fgbks.dmn.core.models.RuleIdentifier;
-import de.unikoblenz.fgbks.dmn.core.models.VerificationResult;
-import de.unikoblenz.fgbks.dmn.core.models.VerifierType;
-import org.camunda.bpm.dmn.engine.DmnDecision;
-import org.camunda.bpm.dmn.engine.impl.DmnDecisionTableImpl;
-import org.camunda.bpm.dmn.engine.impl.DmnDecisionTableRuleImpl;
-
-public class Test extends AbstractVerifier {
-
-  public Test() {
-    super(VerifierType.Subsumption);
-  }
-
-  @Override
-  protected void beforeVerifyDecision() {}
-
-  @Override
-  protected void verifyDecision(DmnDecision d) {
-    DmnDecisionTableImpl table = (DmnDecisionTableImpl) d.getDecisionLogic();
-    int c = 0;
-    VerificationResult.Builder vBuilder =
-        VerificationResult.getBuilder().withMessage(d.getName() + " Verification!!!");
-    for (DmnDecisionTableRuleImpl rule : table.getRules()) {
-      vBuilder.addRule(
-          RuleIdentifier.getBuilder()
-              .withDecisionName(d.getName())
-              .withDecisionKey(d.getKey())
-              .withRowNumber(++c)
-              .withRuleId(rule.getId())
-              .build());
-    }
-    addVerification(vBuilder.build());
-  }
-
-  @Override
-  protected void afterVerifyDecision() {}
-}
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/Boundary.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/Boundary.java
index 237e60b7e76587ffa50b594ff6752d666aa7b998..23b6f26c246473d03468f498768f81b34c19328c 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/Boundary.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/Boundary.java
@@ -3,9 +3,11 @@ package de.unikoblenz.fgbks.dmn.core.verifier.helper;
 import static de.unikoblenz.fgbks.dmn.core.verifier.helper.Boundary.BoundType.EXCLUSIVE;
 import static de.unikoblenz.fgbks.dmn.core.verifier.helper.Boundary.BoundType.INCLUSIVE;
 
+import de.unikoblenz.fgbks.base.builder.DefaultBuilder;
 import java.util.Objects;
 import java.util.Optional;
 
+/** Class for manage boundary and intervals. Can also handle String values. */
 public class Boundary implements Comparable<Boundary> {
 
   public enum BoundType {
@@ -194,6 +196,14 @@ public class Boundary implements Comparable<Boundary> {
             && other.isNumberInRange(this.getUpperBound(), this.getUpperBoundType());
   }
 
+  public boolean isBoundarySubsumptionOf(Boundary other) {
+    if (isBoundarySubsumption(other)) {
+      return isNumberInRange(other.getLowerBound(), other.getLowerBoundType())
+          && isNumberInRange(other.getUpperBound(), other.getUpperBoundType());
+    }
+    return false;
+  }
+
   /**
    * Check, if a other Boundary is NOT equals and NOT overlapping and NO subsumption Example:
    *
@@ -257,6 +267,32 @@ public class Boundary implements Comparable<Boundary> {
     return equals(other);
   }
 
+  /**
+   * Check, if a other Boundary is a subsumption (NOT equals and NO overlapping) Example:
+   *
+   * <blockquote>
+   *
+   * <pre>
+   *    false: (overlapping)
+   *     o------o
+   *        o-----o
+   *    false: (not overlapping)
+   *     o---o
+   *          o--o
+   *    false: (subsumption)
+   *      o--o
+   *       o-o
+   *    true: (equals)
+   *      o---o
+   *      o---o
+   *    false: (subsumption)
+   *      o------o
+   *        o--o
+   *  </blockquote></pre>
+   *
+   * @param o Boundary to check
+   * @return true or false
+   */
   @Override
   public boolean equals(Object o) {
     if (this == o) {
@@ -272,6 +308,12 @@ public class Boundary implements Comparable<Boundary> {
         && upperBoundType == boundary.upperBoundType;
   }
 
+  /**
+   * Create an new boundary, witch is lover than the current <br>
+   * >10 --> <=10
+   *
+   * @return An Optional of the Boundary, if the current has a possible boundary, which is lower
+   */
   public Optional<Boundary> getNewBoundaryLower() {
     if (lowerBound == Double.MIN_VALUE) {
       return Optional.empty();
@@ -285,6 +327,14 @@ public class Boundary implements Comparable<Boundary> {
             .build());
   }
 
+  /**
+   * Create a new boundary between two existing ones<br>
+   * <10 & >20 --> [10..20]
+   *
+   * @param other {@link Boundary}
+   * @return An Optional of the new Boundary between the two given ones Return an empty Optional, if
+   *     there is no interval in between
+   */
   public Optional<Boundary> getNewBoundaryBetween(Boundary other) {
     if (!isBoundaryNotInContact(Objects.requireNonNull(other))) {
       return Optional.empty();
@@ -308,6 +358,12 @@ public class Boundary implements Comparable<Boundary> {
     }
   }
 
+  /**
+   * Create a new boundary, witch begins at the upper bound of the original <br>
+   * <10 --> >=10
+   *
+   * @return An Optional of the Boundary if the current has a possible boundary, which is higher
+   */
   public Optional<Boundary> getNewBoundaryUpper() {
     if (upperBound == Double.MAX_VALUE) {
       return Optional.empty();
@@ -321,10 +377,19 @@ public class Boundary implements Comparable<Boundary> {
             .build());
   }
 
+  /**
+   * Create a new Boundary from two given ones. The Optional is empty, if the given two bounds are
+   * not direct followed by each other. <u>Example:</u><br>
+   * <code>
+   * [10..20]  &  >20 --> >=10<br> [10..20]  &  <10 --> <=20<br> [10..20]  &  <=10 --> empty
+   * Optional (Boundaries are overlapping)<br>
+   * </code>
+   *
+   * @param other the other boundary
+   */
   public Optional<Boundary> combineWith(Boundary other) {
-    // include subsumtion and overlapping????
     if (isBoundaryNotInContact(other)) {
-      if (this.upperBound == other.lowerBound) {
+      if (this.upperBound == other.lowerBound && this.upperBoundType != other.lowerBoundType) {
         return Optional.of(
             getBuilder()
                 .withLowerBound(this.lowerBound)
@@ -332,7 +397,8 @@ public class Boundary implements Comparable<Boundary> {
                 .withUpperBound(other.upperBound)
                 .withUpperBoundType(other.getUpperBoundType())
                 .build());
-      } else if (this.lowerBound == other.upperBound) {
+      } else if (this.lowerBound == other.upperBound
+          && other.upperBoundType != this.lowerBoundType) {
         return Optional.of(
             getBuilder()
                 .withLowerBound(other.lowerBound)
@@ -352,6 +418,18 @@ public class Boundary implements Comparable<Boundary> {
     return Objects.hash(lowerBound, lowerBoundType, upperBound, upperBoundType);
   }
 
+  /**
+   * Parse a String to a boundary object.<br>
+   * <u>Possible forms:</u><br>
+   * <code>
+   * Interval: [x..y] (inclusive x and inclusive y) <br> Interval: ]x..y[ (exclusive x and exclusive
+   * y) <br> Max Val: <=x (inclusive x) <br> Max Val: &lt;x (exclusive x) <br> Min Val: >=x
+   * (inclusive x) <br> Min Val: >x (exclusive x) <br>Equal: =x (inclusive x) <br>
+   * </code>
+   *
+   * @param expr String to parse
+   * @return a new Boundary object
+   */
   public static Boundary parseBoundary(String expr) {
     Builder builder = getBuilder();
     try {
@@ -394,6 +472,14 @@ public class Boundary implements Comparable<Boundary> {
     return builder.build();
   }
 
+  /**
+   * Parse a String value to a boundary object. The Value of the String equals the hashcode of the
+   * string value and has the form<br>
+   * <code>={stringValue.hashCode()}</code>
+   *
+   * @param stringValue the string to create the boundary
+   * @return a boundary
+   */
   public static Boundary parseBoundaryFromStringValue(String stringValue) {
     int hash = Objects.requireNonNull(stringValue).hashCode();
     return getBuilder()
@@ -404,6 +490,13 @@ public class Boundary implements Comparable<Boundary> {
         .build();
   }
 
+  /**
+   * Parse a String value to a boundary object. The Value of the String equals the hashcode of the
+   * string value and has the form<br>
+   * <code>={stringValue.hashCode()}</code>
+   *
+   * @return a boundary
+   */
   public static Boundary parseBoundaryFromBooleanValue(boolean bolVal) {
     int val = bolVal ? 0 : 1;
     return getBuilder()
@@ -414,6 +507,11 @@ public class Boundary implements Comparable<Boundary> {
         .build();
   }
 
+  /**
+   * Creats a "wildcard" boundary. [-infinity..+infinity]
+   *
+   * @return a boundary
+   */
   public static Boundary parseBoundaryFromNullValue() {
     // Wildcard
     return getBuilder()
@@ -476,7 +574,7 @@ public class Boundary implements Comparable<Boundary> {
             return upperBoundType == EXCLUSIVE ? -1 : 1;
           }
         }
-        return Double.compare(o.upperBound, this.upperBound);
+        return Double.compare(this.upperBound, o.upperBound);
       } else {
         return lowerBoundType == INCLUSIVE ? -1 : 1;
       }
@@ -492,49 +590,44 @@ public class Boundary implements Comparable<Boundary> {
     return new Boundary().new Builder();
   }
 
-  public class Builder {
-
-    private Builder() {}
+  public class Builder extends DefaultBuilder<Boundary> {
 
     public Builder withUpperBound(double bound) {
-      setUpperBound(bound);
+      value.setUpperBound(bound);
       return this;
     }
 
     public Builder withLowerBound(double bound) {
-      setLowerBound(bound);
+      value.setLowerBound(bound);
       return this;
     }
 
     public Builder withUpperBoundType(BoundType boundType) {
-      setUpperBoundType(boundType);
+      value.setUpperBoundType(boundType);
       return this;
     }
 
     public Builder withLowerBoundType(BoundType boundType) {
-      setLowerBoundType(boundType);
+      value.setLowerBoundType(boundType);
       return this;
     }
 
-    private Boundary validate() {
-      if (lowerBound == Double.MIN_VALUE) {
-        lowerBoundType = INCLUSIVE;
+    @Override
+    protected void validate() {
+      if (value.lowerBound == Double.MIN_VALUE) {
+        value.lowerBoundType = INCLUSIVE;
       }
-      if (upperBound == Double.MAX_VALUE) {
-        upperBoundType = INCLUSIVE;
+      if (value.upperBound == Double.MAX_VALUE) {
+        value.upperBoundType = INCLUSIVE;
       }
-      Objects.requireNonNull(lowerBoundType, "Lower bound type is null");
-      Objects.requireNonNull(upperBoundType, "Upper bound type is null");
-      if (lowerBound > upperBound && Double.MIN_VALUE != lowerBound) {
+      Objects.requireNonNull(value.lowerBoundType, "Lower bound type is null");
+      Objects.requireNonNull(value.upperBoundType, "Upper bound type is null");
+      if (value.lowerBound > value.upperBound && Double.MIN_VALUE != value.lowerBound) {
         throw new IllegalArgumentException(
             String.format(
-                "Lower bound %f is greater than upper bound %f.", lowerBound, upperBound));
+                "Lower bound %f is greater than upper bound %f.",
+                value.lowerBound, value.upperBound));
       }
-      return Boundary.this;
-    }
-
-    public Boundary build() {
-      return validate();
     }
   }
 }
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/InputType.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/InputType.java
index 9e08eed4b8a54cfe7150bc4067c098f581bcf815..c7842ff9a6ac1696ea308f5cc46111696eb07de4 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/InputType.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/InputType.java
@@ -5,14 +5,15 @@ import org.camunda.bpm.dmn.engine.impl.DmnDecisionTableInputImpl;
 
 public class InputType extends Type {
 
-  private InputType(String descisionKey, String id, DataType dataType) {
-    super(descisionKey, id, dataType);
+  private InputType(String descisionKey, String id, DataType dataType, String expression) {
+    super(descisionKey, id, dataType, expression);
   }
 
   public InputType(DmnDecision d, DmnDecisionTableInputImpl input) {
     this(
         d.getKey(),
         input.getId(),
-        DataType.getTypeFromString(input.getExpression().getTypeDefinition().getTypeName()));
+        DataType.getTypeFromString(input.getExpression().getTypeDefinition().getTypeName()),
+        input.getExpression().getExpression());
   }
 }
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/OutputType.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/OutputType.java
index a73a34bcf96a8707788578a45c5555ad81390d78..77b355908120523eacbe713f99c66182e32bf98d 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/OutputType.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/OutputType.java
@@ -5,14 +5,15 @@ import org.camunda.bpm.dmn.engine.impl.DmnDecisionTableOutputImpl;
 
 public class OutputType extends Type {
 
-  private OutputType(String descisionKey, String id, DataType dataType) {
-    super(descisionKey, id, dataType);
+  private OutputType(String descisionKey, String id, DataType dataType, String expression) {
+    super(descisionKey, id, dataType, expression);
   }
 
   public OutputType(DmnDecision d, DmnDecisionTableOutputImpl output) {
     this(
         d.getKey(),
         output.getId(),
-        DataType.getTypeFromString(output.getTypeDefinition().getTypeName()));
+        DataType.getTypeFromString(output.getTypeDefinition().getTypeName()),
+        output.getOutputName());
   }
 }
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/RuleMap.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/RuleMap.java
index 047c60199af2a484f7a92f226b0f39bdb2de4f68..5f375971a9957696d3c6d7f41462e18663cb4aed 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/RuleMap.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/RuleMap.java
@@ -4,8 +4,11 @@ import de.unikoblenz.fgbks.dmn.core.models.RuleIdentifier;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.logging.Logger;
 import java.util.stream.Collectors;
@@ -16,23 +19,35 @@ import org.camunda.bpm.dmn.engine.impl.DmnDecisionTableOutputImpl;
 import org.camunda.bpm.dmn.engine.impl.DmnDecisionTableRuleImpl;
 import org.camunda.bpm.dmn.engine.impl.DmnExpressionImpl;
 
+/** Class for storing inputs and outputs from a DMNDecsion List */
 public class RuleMap {
 
   private static final Logger LOGGER = Logger.getLogger(RuleMap.class.getSimpleName());
+  private List<DmnDecision> dmnDecisions;
   private Map<InputType, List<Value>> inputs;
   private Map<OutputType, List<Value>> outputs;
+  private Set<String> dmnDecisionsKeys;
 
-  public RuleMap() {
+  private RuleMap(List<DmnDecision> dmnDecisions) {
+    this.dmnDecisions = new ArrayList<>(dmnDecisions);
     this.inputs = new HashMap<>();
     this.outputs = new HashMap<>();
+    this.dmnDecisionsKeys = new HashSet<>();
   }
 
-  public static RuleMap createMapFromDMN(List<DmnDecision> decisionList) {
-    RuleMap ruleMap = new RuleMap();
+  /**
+   * Create a Map for all inputs and all outputs out of a list of DMN Decisions
+   *
+   * @param decisionList List of DMNDecision @NotNull
+   * @return a {@link RuleMap} from the list of DMNDecision
+   */
+  public static RuleMap createMapFromDmn(List<DmnDecision> decisionList) {
+    RuleMap ruleMap = new RuleMap(decisionList);
     for (DmnDecision d : decisionList) {
       if (d.isDecisionTable()) {
+        ruleMap.dmnDecisionsKeys.add(d.getKey());
         DmnDecisionTableImpl table = (DmnDecisionTableImpl) d.getDecisionLogic();
-
+        // inputs
         int i = 0;
         for (DmnDecisionTableInputImpl tableInput : table.getInputs()) {
           InputType it = new InputType(d, tableInput);
@@ -45,6 +60,7 @@ public class RuleMap {
           }
           i++;
         }
+        // outputs
         i = 0;
         for (DmnDecisionTableOutputImpl tableOutput : table.getOutputs()) {
           OutputType ot = new OutputType(d, tableOutput);
@@ -62,6 +78,12 @@ public class RuleMap {
     return ruleMap;
   }
 
+  /**
+   * Return a list of all input values from a given type.
+   *
+   * @param type the given input type
+   * @return a list of all Values from the type
+   */
   public List<Value> getValuesFromInputType(Type type) {
     if (!inputs.keySet().contains(type)) {
       return Collections.emptyList();
@@ -69,6 +91,13 @@ public class RuleMap {
     return new ArrayList<>(inputs.get(type));
   }
 
+  /**
+   * Return a list of input values with the given type, filtered by the given rule identifiers
+   *
+   * @param type the given input type
+   * @param ruleIdentifiersFilter the rules to filter
+   * @return a list of given input types
+   */
   public List<Value> getValuesFromInputType(Type type, List<RuleIdentifier> ruleIdentifiersFilter) {
     if (!inputs.keySet().contains(type)) {
       return Collections.emptyList();
@@ -83,6 +112,12 @@ public class RuleMap {
         .collect(Collectors.toList());
   }
 
+  /**
+   * Return a list of all output values from a given type.
+   *
+   * @param type the given output type
+   * @return a list of all values from the given output type
+   */
   public List<Value> getValuesFromOutputType(Type type) {
     if (!outputs.keySet().contains(type)) {
       return Collections.emptyList();
@@ -90,6 +125,13 @@ public class RuleMap {
     return new ArrayList<>(outputs.get(type));
   }
 
+  /**
+   * Return a list of output values with the given type, filtered by the given rule identifiers
+   *
+   * @param type the given output type
+   * @param ruleIdentifiersFilter the rules to filter
+   * @return a list of all values from the given output type
+   */
   public List<Value> getValuesFromOutputType(
       Type type, List<RuleIdentifier> ruleIdentifiersFilter) {
     if (!outputs.keySet().contains(type)) {
@@ -105,6 +147,12 @@ public class RuleMap {
         .collect(Collectors.toList());
   }
 
+  /**
+   * Return a list of output or input values with the given type
+   *
+   * @param type the given output or input type
+   * @return a list of all values from the given output or input type
+   */
   public List<Value> getValuesFromType(Type type) {
     if (outputs.keySet().contains(type)) {
       return new ArrayList<>(outputs.get(type));
@@ -114,6 +162,14 @@ public class RuleMap {
     return Collections.emptyList();
   }
 
+  /**
+   * Return a list of output or input values with the given type, filtered by the given rule
+   * identifiers
+   *
+   * @param type the given output or input type
+   * @param ruleIdentifiersFilter the rules to filter
+   * @return a list of all values from the given output or input type
+   */
   public List<Value> getValuesFromType(Type type, List<RuleIdentifier> ruleIdentifiersFilter) {
     if (ruleIdentifiersFilter == null) {
       return getValuesFromType(type);
@@ -134,25 +190,84 @@ public class RuleMap {
     return Collections.emptyList();
   }
 
+  /**
+   * Return a Set of input types, witch belongs to a given decisionKey
+   *
+   * @param decisionKey the decisionKey
+   * @return a set of Input types
+   */
   public Set<Type> getAllInputTypesFromDecisionKey(String decisionKey) {
     return inputs
         .keySet()
         .stream()
-        .filter(i -> i.getDescisionKey().equals(decisionKey))
+        .filter(i -> i.getDecisionKey().equals(Objects.requireNonNull(decisionKey)))
         .collect(Collectors.toSet());
   }
 
+  /**
+   * Return a Set of output types, witch belongs to a given decisionKey
+   *
+   * @param decisionKey the decisionKey
+   * @return a set of Output types
+   */
   public Set<Type> getAllOutputTypesFromDecisionKey(String decisionKey) {
     return outputs
         .keySet()
         .stream()
-        .filter(i -> i.getDescisionKey().equals(decisionKey))
+        .filter(i -> i.getDecisionKey().equals(decisionKey))
         .collect(Collectors.toSet());
   }
 
+  /**
+   * Return a Set of input and output types, witch belongs to a given decisionKey
+   *
+   * @param decisionKey the decisionKey
+   * @return a set of output and input types
+   */
   public Set<Type> getAllTypesFromDecisionKey(String decisionKey) {
     Set<Type> types = getAllInputTypesFromDecisionKey(decisionKey);
     types.addAll(getAllOutputTypesFromDecisionKey(decisionKey));
     return types;
   }
+
+  public Set<Set<String>> getIncludingInputDefinitions() {
+    Set<Set<String>> returnSet = new HashSet<>();
+    for (String d1 : dmnDecisionsKeys) {
+      Set<String> subset = new HashSet<>();
+      Set<Type> inputsD1 = getAllInputTypesFromDecisionKey(d1);
+      for (String d2 : dmnDecisionsKeys) {
+        Set<Type> inputsD2 = getAllInputTypesFromDecisionKey(d2);
+        boolean containsAll = true;
+        for (Type i1 : inputsD1) {
+          boolean f2 = false;
+          for (Type i2 : inputsD2) {
+            if (i1.getExpression() != null && i1.getExpression().equals(i2.getExpression())) {
+              f2 = true;
+              break;
+            }
+          }
+          if (!(containsAll &= f2)) {
+            break;
+          }
+        }
+        if (containsAll) {
+          subset.add(d2);
+        }
+      }
+      if (subset.size() > 1) {
+        returnSet.add(subset);
+      }
+    }
+    // check for subsets, that includes other subsets
+    Iterator<Set<String>> it = returnSet.iterator();
+    while (it.hasNext()) {
+      Set<String> s = it.next();
+      for (Set<String> subset : returnSet) {
+        if (subset.size() > s.size() && subset.containsAll(s)) {
+          it.remove();
+        }
+      }
+    }
+    return returnSet;
+  }
 }
diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/Type.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/Type.java
index f1ef1f69652b43284a9d452a310d3eabb1dfc054..43819482edc0fcc89f0c992341f6744164d5060c 100644
--- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/Type.java
+++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/Type.java
@@ -7,12 +7,13 @@ import org.camunda.bpm.dmn.engine.impl.DmnExpressionImpl;
 
 public abstract class Type {
 
-  protected final String descisionKey;
+  protected final String decisionKey;
   protected final String id;
   protected final DataType dataType;
+  protected final String expression;
 
-  public String getDescisionKey() {
-    return descisionKey;
+  public String getDecisionKey() {
+    return decisionKey;
   }
 
   public String getId() {
@@ -23,10 +24,15 @@ public abstract class Type {
     return dataType;
   }
 
-  protected Type(String descisionKey, String id, DataType dataType) {
-    this.descisionKey = descisionKey;
+  public String getExpression() {
+    return expression;
+  }
+
+  protected Type(String decisionKey, String id, DataType dataType, String expression) {
+    this.decisionKey = decisionKey;
     this.id = id;
     this.dataType = dataType;
+    this.expression = expression;
   }
 
   public Value getValue(
@@ -55,10 +61,20 @@ public abstract class Type {
         return Boundary.parseBoundaryFromBooleanValue(Boolean.valueOf(value.getExpression()));
       case STRING:
         return Boundary.parseBoundaryFromStringValue(value.getExpression());
+      case UNKNOWN:
+      case DATE:
+        throw new IllegalStateException(
+            String.format(
+                "Parsing boundary in table %s failed. Value: %s",
+                decisionKey, value.getExpression()));
     }
     return null;
   }
 
+  public boolean isEqualExpression(Type type) {
+    return this.expression.equals(type.expression);
+  }
+
   @Override
   public boolean equals(Object o) {
     if (this == o) {
@@ -68,17 +84,11 @@ public abstract class Type {
       return false;
     }
     Type type = (Type) o;
-    return descisionKey.equals(type.descisionKey)
-        && id.equals(type.id)
-        && dataType == type.dataType;
+    return decisionKey.equals(type.decisionKey) && id.equals(type.id) && dataType == type.dataType;
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(descisionKey, id, dataType);
-  }
-
-  public String getCombinedKey() {
-    return descisionKey + id;
+    return Objects.hash(decisionKey, id, dataType);
   }
 }
diff --git a/dmn-verifier-app/src/main/resources/sampleDMN.dmn b/dmn-verifier-app/src/main/resources/sampleDMN.dmn
index 303b1f47da76775601207909507db44fdef5099d..a7c2bdd24682a55b6dcedd8b80bc2ec5e4505a1c 100644
--- a/dmn-verifier-app/src/main/resources/sampleDMN.dmn
+++ b/dmn-verifier-app/src/main/resources/sampleDMN.dmn
@@ -2,17 +2,17 @@
 <definitions xmlns="http://www.omg.org/spec/DMN/20151101/dmn.xsd" xmlns:biodi="http://bpmn.io/schema/dmn/biodi/1.0" id="Definitions_1kjh9a2" name="DRD" namespace="http://camunda.org/schema/1.0/dmn">
   <decision id="Decision_13nychf" name="Identical test">
     <extensionElements>
-      <biodi:bounds x="120" y="145" width="180" height="80" />
+      <biodi:bounds x="121" y="77" width="180" height="80" />
     </extensionElements>
     <decisionTable id="decisionTable_1">
       <input id="input_1">
         <inputExpression id="inputExpression_1" typeRef="integer">
-          <text>Testnumber</text>
+          <text>testNumber</text>
         </inputExpression>
       </input>
       <input id="InputClause_0rrhtk1">
         <inputExpression id="LiteralExpression_16k88l6" typeRef="string">
-          <text></text>
+          <text>testString</text>
         </inputExpression>
       </input>
       <output id="output_1" typeRef="string" />
@@ -249,4 +249,60 @@
       </rule>
     </decisionTable>
   </decision>
+  <decision id="Decision_0daxsth" name="Overlapping rules">
+    <extensionElements>
+      <biodi:bounds x="768" y="132" width="180" height="80" />
+    </extensionElements>
+    <decisionTable id="DecisionTable_0q2corq">
+      <input id="InputClause_0l9m2o0">
+        <inputExpression id="LiteralExpression_1srvac8" typeRef="integer" />
+      </input>
+      <output id="OutputClause_02zjru8" typeRef="string" />
+      <rule id="DecisionRule_0tlti3q">
+        <inputEntry id="UnaryTests_1epuvm6">
+          <text>&lt;=20</text>
+        </inputEntry>
+        <outputEntry id="LiteralExpression_0p41xhl">
+          <text></text>
+        </outputEntry>
+      </rule>
+      <rule id="DecisionRule_1bwl4r7">
+        <inputEntry id="UnaryTests_1bvpeoa">
+          <text>&gt;=20</text>
+        </inputEntry>
+        <outputEntry id="LiteralExpression_1k69z44">
+          <text></text>
+        </outputEntry>
+      </rule>
+    </decisionTable>
+  </decision>
+  <decision id="Decision_1mjix3c" name="Identical test 2">
+    <extensionElements>
+      <biodi:bounds x="120" y="189" width="180" height="80" />
+    </extensionElements>
+    <decisionTable id="DecisionTable_1ndo00u">
+      <input id="InputClause_0ullwt4">
+        <inputExpression id="LiteralExpression_0at3xrm" typeRef="integer">
+          <text>testNumber</text>
+        </inputExpression>
+      </input>
+      <input id="InputClause_0wjsaiy">
+        <inputExpression id="LiteralExpression_0kvzk24" typeRef="string">
+          <text>testString</text>
+        </inputExpression>
+      </input>
+      <output id="OutputClause_1h8uwwl" typeRef="string" />
+      <rule id="DecisionRule_06iq2ey">
+        <inputEntry id="UnaryTests_0pt1lz0">
+          <text>=10</text>
+        </inputEntry>
+        <inputEntry id="UnaryTests_1vaw0zi">
+          <text>"Hallo"</text>
+        </inputEntry>
+        <outputEntry id="LiteralExpression_09yp5x6">
+          <text></text>
+        </outputEntry>
+      </rule>
+    </decisionTable>
+  </decision>
 </definitions>
diff --git a/dmn-verifier-app/src/test/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/wordnet/WordnetServiceTest.java b/dmn-verifier-app/src/test/java/de/unikoblenz/fgbks/base/wordnet/WordnetServiceTest.java
similarity index 80%
rename from dmn-verifier-app/src/test/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/wordnet/WordnetServiceTest.java
rename to dmn-verifier-app/src/test/java/de/unikoblenz/fgbks/base/wordnet/WordnetServiceTest.java
index fce6f9ffa68ef3c8e56423bb5004693b81a0a5f0..176d7567c5b4997b0d2f4f0994481809bc36466f 100644
--- a/dmn-verifier-app/src/test/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/wordnet/WordnetServiceTest.java
+++ b/dmn-verifier-app/src/test/java/de/unikoblenz/fgbks/base/wordnet/WordnetServiceTest.java
@@ -1,4 +1,4 @@
-package de.unikoblenz.fgbks.dmn.core.verifier.helper.wordnet;
+package de.unikoblenz.fgbks.base.wordnet;
 
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -7,7 +7,7 @@ import org.junit.jupiter.api.Test;
 class WordnetServiceTest {
 
   @Test
-  void areNounsSynonyms() {
+  void areNounsSynonymsTest() {
     WordnetService wns = WordnetService.getInstance();
     assertTrue(wns.areNounsSynonyms("bill", "invoice"));
     assertTrue(wns.areNounsSynonyms("exam", "examination"));
diff --git a/dmn-verifier-app/src/test/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/BoundaryTest.java b/dmn-verifier-app/src/test/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/BoundaryTest.java
index 3d329ed9cf1d203996a285855848814ca32af248..3b18e6a83c1aeb83059d4e670f1785b20e4abb5a 100644
--- a/dmn-verifier-app/src/test/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/BoundaryTest.java
+++ b/dmn-verifier-app/src/test/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/BoundaryTest.java
@@ -231,6 +231,11 @@ class BoundaryTest {
     b2 = Boundary.parseBoundary("[-10..100[");
     assertFalse(b1.isBoundaryNotInContact(b2));
     assertFalse(b2.isBoundaryNotInContact(b1));
+
+    b1 = Boundary.parseBoundary("[0..10]");
+    b2 = Boundary.parseBoundaryFromNullValue();
+    assertFalse(b1.isBoundaryNotInContact(b2));
+    assertFalse(b2.isBoundaryNotInContact(b1));
   }
 
   @Test
@@ -644,7 +649,7 @@ class BoundaryTest {
     assertEquals(b3, b1.combineWith(b2).get());
     assertEquals(b3, b2.combineWith(b1).get());
 
-    b1 = Boundary.parseBoundary("]0..10[");
+    b1 = Boundary.parseBoundary("[0..10[");
     b2 = Boundary.parseBoundary("<0");
     b3 = Boundary.parseBoundary("<10");
     assertEquals(b3, b1.combineWith(b2).get());