diff --git a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.ast b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.ast
index 03a7d83171338e92e3b8fe719ad7ef256f1eb03d..fc06d7cdc801f2c9df118794b1e6bae890832813 100644
--- a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.ast
+++ b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.ast
@@ -1,19 +1,16 @@
-abstract IlpElement ;
-ILP ::= IlpObjective IlpConstraint* IlpBound* IlpVariable* <Info:IlpVarInfo> ;
+ILP ::= IlpObjective IlpConstraint* IlpVariable* ;
 TimedOutILP:ILP ::= <Reason:String> ;
 
 // objective kind is either minimize or maximize
-IlpObjective:IlpElement ::= <Kind:IlpObjectiveKind> IlpLeftHandSide ;
+IlpObjective ::= <Kind:IlpObjectiveKind> IlpLeftHandSide ;
 
-IlpConstraint:IlpElement ::= <Name:String> IlpLeftHandSide <ClauseComparator:ClauseComparator> <RightHandSide:double> ;
+IlpConstraint ::= <Name:String> IlpLeftHandSide <ClauseComparator:ClauseComparator> <RightHandSide:double> ;
 
-IlpBound:IlpElement ::= <Ref:IlpVariable> <Type:IlpBoundType> ;
-
-IlpVariable:IlpElement ::= <Name:String> <Request:Request> <Impl:Implementation> ;
+abstract IlpVariable ::= <Name:String> <Request:Request> <Impl:Implementation> <Illegal:boolean>;
 IlpAllResourcesVariable:IlpVariable ;
 IlpMappingVariable:IlpVariable ::= <Resource:Resource> ;
 
 // sum of terms
-IlpLeftHandSide:IlpElement ::= IlpTerm* ;
+IlpLeftHandSide ::= IlpTerm* ;
 
-IlpTerm:IlpElement ::= <Value:double> <Ref:IlpVariable> ;
+IlpTerm ::= <Value:double> <Ref:IlpVariable> ;
diff --git a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jadd b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jadd
index 11e842dc3c9862c617afc16cacb9136178615775..e95048cbe2ff84e63c3f43333f822fa287378aac 100644
--- a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jadd
+++ b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jadd
@@ -8,12 +8,6 @@ aspect ILP {
     MAXIMIZE
   }
 
-  public enum IlpBoundType {
-    BINARY,
-    ZERO,
-    GREATER_EQUAL_ZERO
-  }
-
   public class IlpString {
     StringBuilder buffer;
 
@@ -48,12 +42,10 @@ aspect ILP {
   public class IlpVarInfo {
     public java.util.Map<String, IlpVariable> vars;
     public java.util.Map<Resource, IlpConstraint> resourceConstraints;
-    public java.util.Set<IlpVariable> illegal;
 
     public IlpVarInfo() {
       vars = new java.util.TreeMap<>();
       resourceConstraints = new java.util.HashMap<>();
-      illegal = new java.util.HashSet<>();
     }
 
     public IlpVariable getIlpVariable(Request request, Implementation impl, Resource resource) {
@@ -66,22 +58,18 @@ aspect ILP {
         resourceConstraints.put(resource, resourceConstraint);
       }
       if (result == null) {
-        result = new IlpMappingVariable(varName, request, impl, resource);
+        result = new IlpMappingVariable(varName, request, impl, false, resource);
         vars.put(varName, result);
         resourceConstraint.getIlpLeftHandSide().addIlpTerm(new IlpTerm(1, result));
       }
       return result;
     }
 
-    public void setIllegal(Request request, Implementation impl, Resource resource) {
-      illegal.add(getIlpVariable(request, impl, resource));
-    }
-
     public IlpVariable getIlpVariable(Request request, Implementation impl) {
       String varName = request.getIlpName() + "#" + impl.getIlpName();
       IlpVariable result = vars.get(varName);
       if (result == null) {
-        result = new IlpAllResourcesVariable(varName, request, impl);
+        result = new IlpAllResourcesVariable(varName, request, impl, false);
         vars.put(varName, result);
       }
       return result;
diff --git a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jrag b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jrag
index 2cec654a87a04787eb665dc2a931f9896ed74790..f8d8c9898ac066aca6cdb3f4511f307956ff839a 100644
--- a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jrag
+++ b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jrag
@@ -43,7 +43,7 @@ aspect ILP {
    */
   syn ILP Root.getILP() {
     de.tudresden.inf.st.mquat.utils.StopWatch stopWatch = de.tudresden.inf.st.mquat.utils.StopWatch.start();
-//    StopWatch stopWatch = StopWatch.start();
+
     long timeoutValue = (long) de.tudresden.inf.st.mquat.utils.StaticSettings.get(ILP_TIMEOUT_VALUE);
     java.util.concurrent.TimeUnit timeoutUnit = (java.util.concurrent.TimeUnit) de.tudresden.inf.st.mquat.utils.StaticSettings.get(ILP_TIMEOUT_UNIT);
     long timeoutNanos = timeoutUnit.toNanos(timeoutValue);
@@ -81,7 +81,6 @@ aspect ILP {
             olhs.addIlpTerm(term);
             oneImplLhs.addIlpTerm(new IlpTerm(1, var));
           }
-          // 2.3 NFP-Negotiation: Requirements to other components
           for (Clause reqClause : impl.requirementClauses()) {
             if (stopWatch.time() > timeoutNanos) {
               return ilpTimeout("Timeout in NFP-Negotiation");
@@ -102,6 +101,7 @@ aspect ILP {
                 reqLhs.addIlpTerm(new IlpTerm(makeNegative(reqClause.evalUsing(request, resource)),
                     info.getIlpVariable(request, impl, resource)));
               }
+              // 2b. non-functional requirements of required components
               result.addIlpConstraint(new IlpConstraint(
                   request.getIlpName() + "_" + impl.getIlpName() + "_reqs_" +
                       designator.asSoftwareDesignator().getPropertyRef().getRef().getIlpName() + "_from_" +
@@ -111,40 +111,39 @@ aspect ILP {
               for (Resource resource : this.getHardwareModel().getResourceList()) {
                 // check if constraint is fulfilled, otherwise remember this illegal combination
                 if (!reqClause.checkUsing(request, resource)) {
-                  info.setIllegal(request, impl, resource);
+                  info.getIlpVariable(request, impl, resource).setIllegal(true);
                 }
               }
             }
           }
 
-          // 2.2 Architecture constraints: One impl/resource and request
           oneImplLhs.addIlpTerm(new IlpTerm(-1, info.getIlpVariable(request, impl)));
+          // implementation variable definition
           result.addIlpConstraint(new IlpConstraint(request.getIlpName() + "_single_" + impl.getIlpName(),
               oneImplLhs, ClauseComparator.EQ, 0));
-          // 2.3 NFP-Negotiation: Use implementations of required components
           for (ComponentRequirement req : impl.getComponentRequirementList()) {
             IlpLeftHandSide reqImplLhs = new IlpLeftHandSide();
             for (Implementation reqImpl : req.getComponentRef().getRef().getImplementationList()) {
               reqImplLhs.addIlpTerm(new IlpTerm(1, info.getIlpVariable(request, reqImpl)));
             }
             reqImplLhs.addIlpTerm(new IlpTerm(-1, info.getIlpVariable(request, impl)));
+            // 1c. required components
             result.addIlpConstraint(new IlpConstraint(request.getIlpName() + "_" + impl.getIlpName() +
                 "_req_" + req.getComponentRef().getRef().getIlpName(),
                 reqImplLhs, ClauseComparator.GE, 0));
           }
         }
-        // 2.2 Architecture constraints: One impl per component and request
+        // 1b.
         result.addIlpConstraint(new IlpConstraint(request.getIlpName() + "_opc_" + comp.getIlpName(),
             oneCompLhs, ClauseComparator.LE, 1));
       }
-      // 2.1.a Request constraints: Target component (i.e., use one of its implementations)
       IlpLeftHandSide targetLhs = new IlpLeftHandSide();
       for (Implementation impl : request.getTarget().getRef().getImplementationList()) {
         IlpVariable var = info.getIlpVariable(request, impl);
         targetLhs.addIlpTerm(new IlpTerm(1, var));
       }
+      // 1a. functional requirement of the request
       result.addIlpConstraint(new IlpConstraint(request.getIlpName() + "_target", targetLhs, ClauseComparator.EQ, 1));
-      // 2.1.b Request constraints: Required NFPs of target component
       for (Clause requiredClause : request.getConstraintList()) {
         IlpLeftHandSide reqLhs = new IlpLeftHandSide();
         Property requiredProperty = requiredClause.getDesignator().asSoftwareDesignator().getPropertyRef().getRef();
@@ -157,6 +156,7 @@ aspect ILP {
             }
           }
         }
+        // 2a. non-functional requirement of the request
         result.addIlpConstraint(new IlpConstraint(request.getIlpName() + "_req_" + requiredProperty.getIlpName(),
             reqLhs, requiredClause.getClauseComparator(),
             requiredClause.evalUsing(request, null)));
@@ -174,25 +174,30 @@ aspect ILP {
 
     // 2.2 Architecture constraints: Only one config per hardware resource
     for (IlpConstraint constraint : info.resourceConstraints.values()) {
+      // 1d.
       result.addIlpConstraint(constraint);
     }
 
-    // Generals
+    // variables
     for (IlpVariable var : info.vars.values()) {
       result.addIlpVariable(var);
     }
 
-    // Bounds (all binary except illegal which are zero)
-    info.vars.values().removeAll(info.illegal);
-    for (IlpVariable var : info.vars.values()) {
-      // TODO uncomment addIlpBound line. Comment out to not clutter output for the moment.
-      result.addIlpBound(new IlpBound(var, IlpBoundType.BINARY));
-    }
-    for (IlpVariable var : info.illegal) {
-      result.addIlpBound(new IlpBound(var, IlpBoundType.ZERO));
-    }
-    result.setInfo(info);
     return result;
   }
 
+  syn IlpVariable ILP.resolve(String variableName) {
+    return variableMap().get(variableName);
+  }
+
+  syn java.util.Map<String, IlpVariable> ILP.variableMap() {
+    java.util.Map<String, IlpVariable> variableMap = new java.util.HashMap();
+    for (IlpVariable variable : getIlpVariableList()) {
+      if (!variable.getIllegal()) {
+        variableMap.put(variable.getName(), variable);
+      }
+    }
+    return variableMap;
+  }
+
 }
diff --git a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILPPrinting.jrag b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILPPrinting.jrag
index f1b1b479fe513a8cf2c46d23676f628a16a3f6fe..a437fe6033633c649bce6d779449a5668ff532af 100644
--- a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILPPrinting.jrag
+++ b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILPPrinting.jrag
@@ -7,14 +7,9 @@ aspect ILPPrinting {
     for (IlpConstraint c : getIlpConstraintList()) {
       result.append(c.printIlp()).lb();
     }
-    result.append("Bounds").lb();
-    for (IlpBound b : getIlpBoundList()) {
-      result.append(b.printIlp()).lb();
-    }
-    // TODO check if "Generals" is always correct
-    result.append("Generals").lb();
+    result.append("Binary").lb();
     for (IlpVariable v : getIlpVariableList()) {
-      if (v.isValid()) {
+      if (!v.getIllegal()) {
         result.append(v.getName()).append(" ");
       }
     }
@@ -49,40 +44,11 @@ aspect ILPPrinting {
     return result.append(" ").append(getRightHandSide());
   }
 
-  syn IlpString IlpBound.printIlp() {
-    IlpString result = new IlpString();
-    if (!getRef().isValid()) {
-      return result;
-    }
-    switch(getType()) {
-      case BINARY: result.append("0 <= ").append(getRef().getName()).append(" <= 1"); break;
-      case ZERO: result.append(getRef().getName()).append(" = 0"); break;
-      case GREATER_EQUAL_ZERO: result.append("0 <= ").append(getRef().getName()); break;
-      default: logger.error("Unknown IlpBound type {}", getType().toString());
-    }
-    return result;
-  }
-
-  inh ILP IlpElement.containingIlp();
-
-  eq ILP.getIlpObjective().containingIlp() = this;
-  eq ILP.getIlpConstraint(int i).containingIlp() = this;
-  eq ILP.getIlpBound(int i).containingIlp() = this;
-  eq ILP.getIlpVariable(int i).containingIlp() = this;
-
-  syn boolean IlpTerm.isValid() {
-    return getRef().isValid();
-  }
-
-  syn boolean IlpVariable.isValid() {
-    return !containingIlp().getInfo().illegal.contains(this);
-  }
-
   syn IlpString IlpLeftHandSide.printIlp() {
     IlpString result = new IlpString();
     boolean printed = false;
     for (IlpTerm t : getIlpTermList()) {
-      if (!t.isValid()) {
+      if (t.getRef().getIllegal()) {
         continue;
       } else {
         printed = true;