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 8883fe32c3164f7cc75918febb61907ccbc0d3f9..868e621d9e0b06db428e56fd57f59c1fe42d9759 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
@@ -66,12 +66,12 @@ public abstract class AbstractBoundary<T extends Comparable<? super T>> implemen
   }
 
   @Override
-  public Optional<Boundary> createBi(BoundaryBiCreaterType combineType, Boundary other) {
+  public Optional<Boundary> createBi(BoundaryBiCreaterType biCreaterType, Boundary other) {
     if (other instanceof InvalidBoundary) {
       return Optional.empty();
     }
-    BoundaryBiCreater biCreater = getBiCreaterFunction(combineType);
-    if (biCreater == null || !isValidOperation(combineType, other)) {
+    BoundaryBiCreater biCreater = getBiCreaterFunction(biCreaterType);
+    if (biCreater == null || !isValidOperation(biCreaterType, other)) {
       throw new BoundaryOperationNotSupportedException(); // TODO: add error text
     }
     return biCreater.create(this, other); // TODO, remove RAW type
@@ -119,8 +119,6 @@ public abstract class AbstractBoundary<T extends Comparable<? super T>> implemen
 
   protected abstract HashMap<BoundaryCreaterType, BoundaryCreater> getCreater();
 
-  protected abstract String getParsedText();
-
   @Override
   public String toString() {
     return "{" + getText() + "},{" + getParsedText() + "}";
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 092e7a8895a9cfc4c970c8fc4cfbf3e297305451..5c4498cd3ff32ffc387fb055dd0771e015921696 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
@@ -193,7 +193,7 @@ public abstract class AbstractGrowingBoundary<T extends Comparable<? super T>>
       T lowerBound, T upperBound, BoundType lowerBoundType, BoundType upperBoundType);
 
   @Override
-  protected String getParsedText() {
-    return "";
+  public String getParsedText() {
+    return lowerBoundType + " " + lowerBound + " " + upperBound + " " + upperBoundType;
   }
 }
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 7772b3d8b9c457eeb9a45fc23dfae144a093149c..29f997b69ee74d8a8cd531fbb194468be99f56be 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
@@ -12,6 +12,8 @@ public interface Boundary extends Comparable<Boundary> {
 
   String getText();
 
+  String getParsedText();
+
   boolean checkWith(BoundaryCheckType checkType, Boundary other);
 
   Optional<Boundary> create(BoundaryCreaterType createType);
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
index 0ff5fd3b501cd5fd2dcfe3132d96400d02647492..848b72e07bd3b28bc20ff332514615e18a490667 100644
--- 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
@@ -64,9 +64,10 @@ public class BiCreaterAppend extends AbstractBoundaryBiCreater<AbstractGrowingBo
       AbstractGrowingBoundary b1, AbstractGrowingBoundary b2) {
     int b1L = (int) b1.getLowerBound();
     int b1U = (int) b1.getUpperBound();
-    int b2L = (int) b1.getLowerBound();
-    int b2U = (int) b1.getUpperBound();
+    int b2L = (int) b2.getLowerBound();
+    int b2U = (int) b2.getUpperBound();
     if (b1U + 1 == b2L
+        && b1.getMaxValue().compareTo(b1U) != 0
         && b1.getUpperBoundType() == INCLUSIVE
         && b2.getLowerBoundType() == INCLUSIVE) {
       return Optional.of(
@@ -76,6 +77,7 @@ public class BiCreaterAppend extends AbstractBoundaryBiCreater<AbstractGrowingBo
               b1.getLowerBoundType(),
               b2.getUpperBoundType()));
     } else if (b2U + 1 == b1L
+        && b2.getMaxValue().compareTo(b2U) != 0
         && b2.getUpperBoundType() == INCLUSIVE
         && b1.getLowerBoundType() == INCLUSIVE) {
       return Optional.of(
@@ -92,8 +94,8 @@ public class BiCreaterAppend extends AbstractBoundaryBiCreater<AbstractGrowingBo
       AbstractGrowingBoundary b1, AbstractGrowingBoundary b2) {
     long b1L = (long) b1.getLowerBound();
     long b1U = (long) b1.getUpperBound();
-    long b2L = (long) b1.getLowerBound();
-    long b2U = (long) b1.getUpperBound();
+    long b2L = (long) b2.getLowerBound();
+    long b2U = (long) b2.getUpperBound();
     if (b1U + 1 == b2L
         && b1.getUpperBoundType() == INCLUSIVE
         && b2.getLowerBoundType() == INCLUSIVE) {
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterLowerBounds.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterLowerBounds.java
index 2723cf33707b556f417c9265729283550e670aa5..2a385096e0747be737aba0d310e3a50384a023eb 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterLowerBounds.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterLowerBounds.java
@@ -43,13 +43,16 @@ public class BiCreaterLowerBounds extends AbstractBoundaryBiCreater<AbstractGrow
         return Optional.empty();
       }
     }
+    if (b2.getLowerBound().equals(b2.getMinValue())) {
+      return Optional.empty();
+    }
     try {
       return Optional.of(
           b1.getCopy(
               b1.getLowerBound(),
               b2.getLowerBound(),
-              b1.getLowerBoundType().getOp(),
-              b2.getLowerBoundType()));
+              b1.getLowerBoundType(),
+              b2.getLowerBoundType().getOp()));
     } catch (Exception e) {
       return Optional.empty();
     }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterUpperBounds.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterUpperBounds.java
index a9a3ff2ae37a5ea925be5f4748c79bca62680220..eec40d2a27ef23632f14ee15fd7df309b8cc003b 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterUpperBounds.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/bicreater/BiCreaterUpperBounds.java
@@ -43,6 +43,9 @@ public class BiCreaterUpperBounds extends AbstractBoundaryBiCreater<AbstractGrow
         return Optional.empty();
       }
     }
+    if (b2.getUpperBound().equals(b2.getMaxValue())) {
+      return Optional.empty();
+    }
     try {
       return Optional.of(
           b1.getCopy(
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckEqual.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckEqual.java
index 1da5446244f82b28ac850ca21f831037bfafa18f..fe5c2ac2c70953c5c15143ba931e7bae4524123f 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckEqual.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/utils/boundary/checker/CheckEqual.java
@@ -28,9 +28,6 @@ public class CheckEqual extends AbstractBoundaryCheck<AbstractGrowingBoundary> {
     if (b1 == b2) {
       return true;
     }
-    if (b1.getText().equals(b2.getText())) {
-      return true;
-    }
     return ((b1.getLowerBound().equals(b2.getLowerBound())
         && b1.getLowerBoundType().equals(b2.getLowerBoundType())
         && b1.getUpperBound().equals(b2.getUpperBound())
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 2523efd075d9fd122c34e545218f2423f8443768..7a9cfafbf0756959bc9bed6cb2b9c732aa17a21c 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
@@ -27,6 +27,11 @@ public class InvalidBoundary implements Boundary {
     return "null";
   }
 
+  @Override
+  public String getParsedText() {
+    return "";
+  }
+
   @Override
   public boolean checkWith(BoundaryCheckType checkType, Boundary other) {
     return false;
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 3f4540aaedd21dd618248b3346adaf2c677ec384..c0484570d89eab357a9a88bcd5b37e60b10c8433 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
@@ -42,7 +42,7 @@ 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<>();
+  private static HashMap<BoundaryBiCreaterType, BoundaryBiCreater> biCreaterMap = new HashMap<>();
 
   static {
     checkerMap.put(IS_EQUAL, CheckStringEqual.getInstance());
@@ -53,12 +53,12 @@ public class StringBoundary extends AbstractBoundary<String> {
     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());
+    biCreaterMap.put(INTERSECTION, EmptyBiCreater.getInstance());
+    biCreaterMap.put(LOWER_BOUNDS, EmptyBiCreater.getInstance());
+    biCreaterMap.put(UPPER_BOUNDS, EmptyBiCreater.getInstance());
+    biCreaterMap.put(BETWEEN, EmptyBiCreater.getInstance());
+    biCreaterMap.put(APPEND, EmptyBiCreater.getInstance());
+    biCreaterMap.put(COMBINE, EmptyBiCreater.getInstance());
   }
 
   private boolean matchNoneOfValues;
@@ -137,7 +137,7 @@ public class StringBoundary extends AbstractBoundary<String> {
 
   @Override
   protected HashMap<BoundaryBiCreaterType, BoundaryBiCreater> getBiCreater() {
-    return combinerMap;
+    return biCreaterMap;
   }
 
   @Override
@@ -146,7 +146,7 @@ public class StringBoundary extends AbstractBoundary<String> {
   }
 
   @Override
-  protected String getParsedText() {
+  public String getParsedText() {
     return (matchNoneOfValues ? "not" : "") + Arrays.toString(values);
   }
 }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnDecisionTableImpl.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnDecisionTableImpl.java
index 2d8e47d5800dd85af0c0501b19e86505f2af298c..370ae7998172b6e2ebe881d9a4d5a2184a6470b5 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnDecisionTableImpl.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnDecisionTableImpl.java
@@ -101,7 +101,7 @@ public class VDmnDecisionTableImpl extends AbstractVDmnElement implements VDmnDe
 
     public Builder addRuleFromBuilder(VDmnRuleImpl.Builder dmnRuleBuilder) {
       addRule(Validate.notNull(dmnRuleBuilder.getUnbuildValue()));
-      dmnRuleBuilder.withDmnDecision(value);
+      dmnRuleBuilder.withDmnDecisionTable(value);
       return this;
     }
 
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnInputValueChangeableImpl.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnInputValueChangeableImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..6108f4b405b49cb97ed9ec82774be11735d12645
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnInputValueChangeableImpl.java
@@ -0,0 +1,23 @@
+package de.unikoblenz.fgbks.core.dmn.domain.vdmn.impl;
+
+import de.unikoblenz.fgbks.base.utils.boundary.Boundary;
+import org.apache.commons.lang3.Validate;
+
+public class VDmnInputValueChangeableImpl extends VDmnInputValueImpl {
+
+  public VDmnInputValueChangeableImpl(VDmnInputValueImpl inputValue) {
+    super();
+    Validate.notNull(inputValue);
+    super.boundary = inputValue.boundary;
+    super.description = inputValue.description;
+    super.dmnColumn = inputValue.dmnColumn;
+    super.dmnRule = inputValue.dmnRule;
+    super.id = inputValue.id;
+    super.text = inputValue.text;
+  }
+
+  public VDmnInputValueChangeableImpl withNewBoundary(Boundary boundary) {
+    super.boundary = Validate.notNull(boundary);
+    return this;
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnInputValueImpl.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnInputValueImpl.java
index 0d923df9320001daac30a3ca02a806ac0bd181e6..30130748fa81435b00f2637935604ec71192b855 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnInputValueImpl.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnInputValueImpl.java
@@ -9,9 +9,9 @@ import org.apache.commons.lang3.Validate;
 
 public class VDmnInputValueImpl extends VDmnValueImpl implements VDmnInputValue {
 
-  private Boundary boundary;
+  protected Boundary boundary;
 
-  private VDmnInputValueImpl() {}
+  protected VDmnInputValueImpl() {}
 
   public static Builder getBuilder() {
     return new VDmnInputValueImpl().new Builder();
@@ -29,6 +29,11 @@ public class VDmnInputValueImpl extends VDmnValueImpl implements VDmnInputValue
       return this;
     }
 
+    public Builder withDmnRuleFromBuilder(VDmnRuleImpl.Builder dmnRuleBuilder) {
+      value.dmnRule = dmnRuleBuilder.getUnbuildValue();
+      return this;
+    }
+
     public Builder withText(String text) {
       value.text = text;
       return this;
@@ -49,6 +54,11 @@ public class VDmnInputValueImpl extends VDmnValueImpl implements VDmnInputValue
       return this;
     }
 
+    public Builder withBoundary(Boundary boundary) {
+      value.boundary = boundary;
+      return this;
+    }
+
     @Override
     protected void validate() {
       super.validate();
@@ -60,9 +70,11 @@ public class VDmnInputValueImpl extends VDmnValueImpl implements VDmnInputValue
 
     @Override
     public VDmnInputValueImpl build() {
-      // create boundary
-      value.boundary =
-          value.dmnColumn.getTypeRef().getBoundaryFromText(value.getText()).orElse(null);
+      // create boundary, if not created before
+      if (value.boundary == null) {
+        value.boundary =
+            value.dmnColumn.getTypeRef().getBoundaryFromText(value.getText()).orElse(null);
+      }
       return super.build();
     }
   }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnRuleChangeableImpl.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnRuleChangeableImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..3179702c3bac283e763d1eff12bed1c737d47ad6
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnRuleChangeableImpl.java
@@ -0,0 +1,26 @@
+package de.unikoblenz.fgbks.core.dmn.domain.vdmn.impl;
+
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnInputValue;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnOutputValue;
+import org.apache.commons.lang3.Validate;
+
+public class VDmnRuleChangeableImpl extends VDmnRuleImpl {
+
+  public VDmnRuleChangeableImpl(VDmnRuleImpl rule) {
+    super();
+    Validate.notNull(rule);
+    super.dmnDecisionTable = rule.dmnDecisionTable;
+    super.inputValues = rule.inputValues;
+    super.outputValues = rule.outputValues;
+    super.rowNumber = rule.rowNumber;
+    super.id = rule.id;
+  }
+
+  public void setInputValue(int i, VDmnInputValue inputValue) {
+    inputValues.set(i, inputValue);
+  }
+
+  public void setOutputValue(int i, VDmnOutputValue outputValue) {
+    outputValues.set(i, outputValue);
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnRuleImpl.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnRuleImpl.java
index 114111e839451c7262ea80b76952d06668545303..013750e53158450b5f5868b0217fa1d0143fa512 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnRuleImpl.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/impl/VDmnRuleImpl.java
@@ -13,14 +13,14 @@ import org.apache.commons.lang3.Validate;
 
 public class VDmnRuleImpl extends AbstractVDmnElement implements VDmnRule {
 
-  private RowNumber rowNumber;
-  private VDmnDecisionTable dmnDecisionTable;
-  private List<VDmnInputValue> inputValues;
-  private List<VDmnOutputValue> outputValues;
-
-  private VDmnRuleImpl() {
-    inputValues = new ArrayList<>();
-    outputValues = new ArrayList<>();
+  protected RowNumber rowNumber;
+  protected VDmnDecisionTable dmnDecisionTable;
+  protected List<VDmnInputValue> inputValues;
+  protected List<VDmnOutputValue> outputValues;
+
+  protected VDmnRuleImpl() {
+    inputValues = new ArrayList<>(10);
+    outputValues = new ArrayList<>(3);
   }
 
   @Override
@@ -59,7 +59,7 @@ public class VDmnRuleImpl extends AbstractVDmnElement implements VDmnRule {
       return this;
     }
 
-    public Builder withDmnDecision(VDmnDecisionTable vDmnDecisionTable) {
+    public Builder withDmnDecisionTable(VDmnDecisionTable vDmnDecisionTable) {
       value.dmnDecisionTable = vDmnDecisionTable;
       return this;
     }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingRuleVerifier.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingRuleVerifier.java
index 39dbdf5a2638684a6f78caecea23aa2834bfc20d..e2cfb1077eaa0c31a66062dd9f406c05f72478b9 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingRuleVerifier.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingRuleVerifier.java
@@ -1,15 +1,265 @@
 package de.unikoblenz.fgbks.core.dmn.verification.verifier.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.core.dmn.domain.common.RowNumber;
+import de.unikoblenz.fgbks.core.dmn.domain.ids.InputEntryId;
+import de.unikoblenz.fgbks.core.dmn.domain.ids.RuleId;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnDecision;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnDecisionTable;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnInputColumn;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnInputValue;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnRule;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.impl.VDmnInputValueChangeableImpl;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.impl.VDmnInputValueImpl;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.impl.VDmnRuleChangeableImpl;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.impl.VDmnRuleImpl;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.impl.VDmnRuleImpl.Builder;
+import de.unikoblenz.fgbks.core.dmn.verification.result.VerificationResultEntry.VerificationClassification;
+import de.unikoblenz.fgbks.core.dmn.verification.result.VerificationResultEntryElement;
 import de.unikoblenz.fgbks.core.dmn.verification.verifier.AbstractVerifier;
 import de.unikoblenz.fgbks.core.dmn.verification.verifier.DmnVerifier;
 import de.unikoblenz.fgbks.core.dmn.verification.verifier.config.DefaultConfiguration;
 import de.unikoblenz.fgbks.core.dmn.verification.verifier.types.MissingRuleVerification;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
 
 @DmnVerifier(
     verifierType = MissingRuleVerification.class,
     verifierConfig = DefaultConfiguration.class)
 public class MissingRuleVerifier extends AbstractVerifier {
 
+  public static final long INITIAL_ROW_NUMER = 9999L;
+
   @Override
-  protected void doVerification() {}
+  protected void doVerification() {
+    for (VDmnDecision decision : dmnObjectContainer.getVDmnDefinition().getDmnDecisions()) {
+      findMissingRules(decision.getDmnDecisionTable());
+    }
+  }
+
+  private void findMissingRules(VDmnDecisionTable dmnDecisionTable) {
+    List<VDmnInputColumn> inputs = dmnDecisionTable.getInputColumns();
+    List<VDmnRuleChangeableImpl> missingRules =
+        checkForMissingRules(inputs, dmnDecisionTable.getRules());
+    // add errors for missing intervals
+    for (VDmnRule missingRule : missingRules) {
+      StringBuilder sb = new StringBuilder("In table ");
+      sb.append(dmnDecisionTable.getDecisionTableId()); // TODO: add real name
+      sb.append(", the following rule is not defined: (");
+      sb.append(
+          missingRule.getDmnInputValues().stream()
+              .map(v -> v.getBoundary().getParsedText())
+              .collect(Collectors.joining("), (")));
+      sb.append(")");
+
+      vreFactory.addElement(VerificationResultEntryElement.create(dmnDecisionTable));
+      vreFactory.addToEntry(VerificationClassification.WARNING, sb.toString());
+    }
+  }
+
+  private List<VDmnRuleChangeableImpl> checkForMissingRules(
+      List<VDmnInputColumn> inputs, List<VDmnRule> rules) {
+    // check, if missingIntervals are empty
+    List<VDmnRuleChangeableImpl> missingRules = new LinkedList<>();
+    missingRules.add(constructPseudoMissingRule(inputs));
+    // Check new Missing Rules for each rule
+    for (VDmnRule rule : rules) {
+      checkForMissingRules(inputs, rule, missingRules);
+    }
+    mergeRules(missingRules);
+    return missingRules;
+  }
+
+  private VDmnRuleChangeableImpl constructPseudoMissingRule(List<VDmnInputColumn> inputs) {
+    Builder b =
+        VDmnRuleImpl.getBuilder()
+            .withRuleId(new RuleId("TODO")) // TODO
+            .withDmnDecisionTable(inputs.get(0).getDmnDecisionTable())
+            .withRowNumber(new RowNumber(INITIAL_ROW_NUMER));
+
+    for (VDmnInputColumn col : inputs) {
+      b.addInputValue(
+          VDmnInputValueImpl.getBuilder()
+              .withInputEntryId(new InputEntryId("TODO")) // TODO
+              .withText("")
+              .withDmnInputColumn(col)
+              .withDmnRuleFromBuilder(b)
+              .build());
+    }
+    return new VDmnRuleChangeableImpl(b.build());
+  }
+
+  private void checkForMissingRules(
+      List<VDmnInputColumn> inputs,
+      VDmnRule currentRule,
+      List<VDmnRuleChangeableImpl> missingRules) {
+    // search the missing rules, which are in contact with the current rule
+    List<VDmnRuleChangeableImpl> inContactRules = new LinkedList<>();
+    for (VDmnRuleChangeableImpl missingRule : missingRules) {
+      if (isInContact(missingRule, currentRule)) {
+        inContactRules.add(missingRule);
+      }
+    }
+    // remove found rules from current missingRules
+    missingRules.removeAll(inContactRules);
+    // Build new missing rules from in contact rules
+    List<VDmnRuleChangeableImpl> newMissingRules = new LinkedList<>();
+    for (VDmnRuleChangeableImpl inContactRule : inContactRules) {
+      newMissingRules.addAll(constructNewMissingRules(inputs, inContactRule, currentRule));
+    }
+    // mergeRules(newMissingRules);
+    missingRules.addAll(newMissingRules);
+    mergeRules(missingRules);
+  }
+
+  private List<VDmnRuleChangeableImpl> constructNewMissingRules(
+      List<VDmnInputColumn> inputs, VDmnRuleChangeableImpl missingRule, VDmnRule currentRule) {
+    List<VDmnRuleChangeableImpl> newMissingRules = new LinkedList<>();
+    List<VDmnInputValue> missingInValues = new ArrayList<>(missingRule.getDmnInputValues());
+    List<VDmnInputValue> currentRuleValues = new ArrayList<>(currentRule.getDmnInputValues());
+    for (int i = 0; i < missingInValues.size(); i++) {
+      // change bound for i-1
+      if (i != 0) {
+        VDmnInputValue missingRuleValue = missingInValues.get(i - 1);
+        Boundary missingRuleBoundary = missingRuleValue.getBoundary();
+        Boundary valueBoundary = currentRuleValues.get(i - 1).getBoundary();
+        Optional<Boundary> b =
+            valueBoundary.createBi(BoundaryBiCreaterType.INTERSECTION, missingRuleBoundary);
+        if (b.isPresent()) {
+          missingRule.setInputValue(
+              i - 1,
+              VDmnInputValueImpl.getBuilder()
+                  .withInputEntryId(new InputEntryId("TODO")) // TODO
+                  .withText("")
+                  .withDmnInputColumn((VDmnInputColumn) missingRuleValue.getDmnColumn())
+                  .withDmnRule(missingRule)
+                  .withBoundary(b.get())
+                  .build());
+        }
+      }
+      // calc next missing intervals: left + right
+      VDmnInputValue currentValue = currentRuleValues.get(i);
+      // left
+      addMissingRules(
+          i,
+          inputs,
+          missingInValues
+              .get(i)
+              .getBoundary()
+              .createBi(BoundaryBiCreaterType.LOWER_BOUNDS, currentValue.getBoundary()),
+          missingRule,
+          newMissingRules);
+
+      // right
+      addMissingRules(
+          i,
+          inputs,
+          missingInValues
+              .get(i)
+              .getBoundary()
+              .createBi(BoundaryBiCreaterType.UPPER_BOUNDS, currentValue.getBoundary()),
+          missingRule,
+          newMissingRules);
+    }
+    return newMissingRules;
+  }
+
+  private void addMissingRules(
+      int i,
+      List<VDmnInputColumn> inputs,
+      Optional<Boundary> bi,
+      VDmnRuleChangeableImpl missingRule,
+      List<VDmnRuleChangeableImpl> newMissingRules) {
+    if (bi.isPresent()) {
+      List<VDmnInputValue> missingRuleValues = missingRule.getDmnInputValues();
+
+      Builder b =
+          VDmnRuleImpl.getBuilder()
+              .withRuleId(new RuleId("TODO")) // TODO
+              .withDmnDecisionTable(inputs.get(0).getDmnDecisionTable())
+              .withRowNumber(new RowNumber(INITIAL_ROW_NUMER));
+      for (VDmnInputValue inputValue : missingRuleValues) {
+        b.addInputValue(inputValue);
+      }
+
+      VDmnRuleChangeableImpl copy = new VDmnRuleChangeableImpl(b.build());
+
+      for (int x = 0; x < missingRuleValues.size(); x++) {
+        copy.setInputValue(
+            x,
+            VDmnInputValueImpl.getBuilder()
+                .withInputEntryId(new InputEntryId("TODO")) // TODO
+                .withText("")
+                .withDmnRule(copy)
+                .withBoundary(x == i ? bi.get() : missingRuleValues.get(x).getBoundary())
+                .withDmnInputColumn(inputs.get(x))
+                .build());
+      }
+      newMissingRules.add(copy);
+    }
+  }
+
+  private boolean isInContact(VDmnRule missingRule, VDmnRule currentRule) {
+    List<VDmnInputValue> inValsMissingRule = missingRule.getDmnInputValues();
+    List<VDmnInputValue> inValsCurrentRule = currentRule.getDmnInputValues();
+    for (int i = 0; i < inValsMissingRule.size(); i++) {
+      if (inValsMissingRule
+          .get(i)
+          .getBoundary()
+          .checkWith(BoundaryCheckType.IS_NOT_IN_CONTACT, inValsCurrentRule.get(i).getBoundary())) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private void mergeRules(List<VDmnRuleChangeableImpl> missingRules) {
+    boolean found = true;
+    while (found) {
+      List<VDmnRule> removeRules = new ArrayList<>(100);
+      found = false;
+      for (int i = 0; i < missingRules.size(); i++) {
+        List<VDmnInputValue> inputValuesI = missingRules.get(i).getDmnInputValues();
+        for (int u = i + 1; u < missingRules.size(); u++) {
+          List<VDmnInputValue> inputValuesU = missingRules.get(u).getDmnInputValues();
+          int foundCombination = -1;
+          Optional<Boundary> newOBoundary;
+          Boundary newBoundary = null;
+
+          for (int x = 0; x < inputValuesI.size(); x++) {
+            VDmnInputValue v1 = inputValuesI.get(x);
+            VDmnInputValue v2 = inputValuesU.get(x);
+            newOBoundary =
+                v1.getBoundary().createBi(BoundaryBiCreaterType.COMBINE, v2.getBoundary());
+            if (v1.getBoundary().checkWith(BoundaryCheckType.IS_EQUAL, v2.getBoundary())) {
+              // nothing
+            } else if (newOBoundary.isPresent() && foundCombination == -1) {
+              newBoundary = newOBoundary.get();
+              foundCombination = x;
+            } else {
+              foundCombination = -1;
+              break;
+            }
+          }
+          if (foundCombination >= 0) {
+            found = true;
+            missingRules
+                .get(i)
+                .setInputValue(
+                    foundCombination,
+                    new VDmnInputValueChangeableImpl(
+                            (VDmnInputValueImpl) inputValuesI.get(foundCombination))
+                        .withNewBoundary(newBoundary));
+            removeRules.add(missingRules.get(u));
+          }
+        }
+      }
+      missingRules.removeAll(removeRules);
+    }
+  }
 }