diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 933b6473ce1ea83ca681969501e2c05453c313a1..19869d6658eca905211de6b30978e19634ac3931 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
diff --git a/solve/build.gradle b/solve/build.gradle
index 2af7514a84c2d5d0725bea46e2eb5f38ae94acd7..6e3f256c44d063b012afa9043eea518e86ff0b71 100644
--- a/solve/build.gradle
+++ b/solve/build.gradle
@@ -1,7 +1,15 @@
+buildscript {
+    repositories.mavenCentral()
+    dependencies {
+        classpath group: 'org.jastadd', name: 'jastaddgradle', version: '1.13.3'
+    }
+}
+
 plugins {
     id 'application'
     id 'maven'
     id 'java'
+    id 'idea'
 }
 
 group 'de.tudresden.inf.st'
@@ -14,27 +22,24 @@ repositories {
     mavenLocal()
 }
 
+apply plugin: 'jastadd'
+
 dependencies {
-    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.8.1'
-    compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.10.0'
-    compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.10.0'
-    compile group: 'org.eclipse.emf', name: 'org.eclipse.emf.ecore', version: '2.12.0'
-    compile group: 'org.eclipse.emf', name: 'org.eclipse.emf.ecore.xmi', version: '2.12.0'
-    compile group: 'org.eclipse.emf', name: 'org.eclipse.emf.common', version: '2.12.0'
-    compile group: 'org.eclipse.emf', name: 'org.eclipse.emf.mwe.core', version: '1.3.13'
-    testCompile group: 'junit', name: 'junit', version: junitVersion
-    testCompile group: 'org.hamcrest', name: 'hamcrest-junit', version: '1.0.0.0'
-    testCompile 'com.opencsv:opencsv:3.8'
-    testCompile 'com.github.stefanbirkner:system-rules:1.19.0'
+    jastadd2 "org.jastadd:jastadd:2.3.5"
+
+    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.8.1'
+    implementation group: 'org.eclipse.emf', name: 'org.eclipse.emf.ecore', version: '2.12.0'
+    implementation group: 'org.eclipse.emf', name: 'org.eclipse.emf.ecore.xmi', version: '2.12.0'
+    implementation group: 'org.eclipse.emf', name: 'org.eclipse.emf.common', version: '2.12.0'
+    implementation group: 'org.eclipse.emf', name: 'org.eclipse.emf.mwe.core', version: '1.3.13'
+
+    testImplementation group: 'junit', name: 'junit', version: junitVersion
+    testImplementation group: 'org.hamcrest', name: 'hamcrest-junit', version: '1.0.0.0'
+    testImplementation 'com.opencsv:opencsv:3.8'
+    testImplementation 'com.github.stefanbirkner:system-rules:1.19.0'
 }
 
-run {
-    mainClassName = 'de.tudresden.inf.st.ttc18live.LiveContestDriverEMF'
-    standardInput = System.in
-    if (project.hasProperty("appArgs")) {
-        args Eval.me(appArgs)
-    }
-}
+mainClassName = 'de.tudresden.inf.st.ttc18live.LiveContestDriverEMF'
 
 task testMain(type: JavaExec, dependsOn: assemble) {
     group "application"
@@ -48,7 +53,7 @@ task preprocess(type: JavaExec) {
     args = [
             "libs/relast-compiler.jar",
             "--grammarName=src/main/jastadd/SocialNetworkGen",
-            "--listClass=RefList",
+            "--listClass=java.util.ArrayList",
             "--useJastAddNames",
             "--file",
             "src/main/jastadd/SocialNetwork.relast"
@@ -58,48 +63,71 @@ task preprocess(type: JavaExec) {
     outputs.files file("./src/main/jastadd/SocialNetworkGen.ast"), file("./src/main/jastadd/SocialNetworkGen.jadd")
 }
 
-task jastadd(type: JavaExec) {
-    group = 'Build'
-    main = "-jar"
-    args = [
-            "libs/jastadd2.jar",
-            "--debug",
-            "--cache=all",
-            "--flush=api",
-            "--rewrite=cnta",
-            "--incremental=param,debug",
-            "--package=de.tudresden.inf.st.ttc18live.jastadd.model",
-            "--o=src/gen/java",
-            "--tracing=api",
-    ] + fileTree("./src/main/jastadd/").matching {exclude "*.relast"}.matching {exclude "*.unused"}
+jastadd {
+    configureModuleBuild()
+    modules {
+        //noinspection GroovyAssignabilityCheck
+        module("solve") {
+
+//            java {
+//                basedir "src/"
+//                include "main/**/*.java"
+//                include "gen/**/*.java"
+//            }
+
+            jastadd {
+                basedir "src/"
+                include "main/jastadd/**/*.ast"
+                include "main/jastadd/**/*.jadd"
+                include "main/jastadd/**/*.jrag"
+                include "gen/jastadd/**/*.ast"
+                include "gen/jastadd/**/*.jadd"
+                include "gen/jastadd/**/*.jrag"
+            }
+        }
+    }
 
-    doFirst {
-        print("Calling jastadd2.jar " + fileTree("./src/main/jastadd/") + '\n')
-        delete fileTree('src/gen/java/')
+    cleanGen.doFirst {
+        delete "src/gen/java/de"
+        delete "src/gen-res/BuildInfo.properties"
     }
 
-    inputs.files fileTree("./solve/src/main/jastadd/") + file("libs/jastadd2.jar")
-    outputs.files file("src/gen/java/ASTNode.java")
+//    preprocessParser.doFirst {
+//        args += ["--no-beaver-symbol"]
+//    }
+
+    module = "solve"
+
+    astPackage = 'de.tudresden.inf.st.ttc18live.jastadd.model'
+
+    genDir = 'src/gen/java'
+
+    buildInfoDir = 'src/gen-res'
+
+    // jastaddOptions = ["--lineColumnNumbers", "--visitCheck=true", "--rewrite=cnta", "--cache=all"]
+    // default options are: '--rewrite=cnta', '--safeLazy', '--visitCheck=false', '--cacheCycle=false'
+    extraJastAddOptions = [
+            '--lineColumnNumbers',
+            '--cache=all',
+            "--flush=api",
+            "--incremental=param,debug",
+            "--tracing=api",
+    ]
 }
 
-sourceSets {
-    main {
-        java {
-            srcDir 'src/main/java'
-            srcDir 'src/gen/java'
-        }
-    }
+cleanGen.doFirst {
+    delete "src/gen/jastadd"
 }
 
-// always run tests
-test.outputs.upToDateWhen {false}
+File genSrc = file("src/gen/java")
+sourceSets.main.java.srcDir genSrc
+idea.module.generatedSourceDirs += genSrc
 
-// Comment this in to regenerate the generated AST
-jastadd.dependsOn preprocess
-compileJava.dependsOn jastadd
+// Workflow configuration for phases
+generateAst.dependsOn preprocess
 
-// always run jastadd
-jastadd.outputs.upToDateWhen {false}
+// always run tests
+test.outputs.upToDateWhen {false}
 
 // disable distribution
 jar.enabled = false
diff --git a/solve/libs/jastadd2.jar b/solve/libs/jastadd2.jar
deleted file mode 100644
index ea4b460839830a10fffbccbf89819fe67fca4a13..0000000000000000000000000000000000000000
Binary files a/solve/libs/jastadd2.jar and /dev/null differ
diff --git a/solve/libs/relast-compiler.jar b/solve/libs/relast-compiler.jar
index 1437dc7e386d47033e5bdeb34b6bafbd845aa9be..b1a7542048dd1611db7f479307b0285efd8bb1f6 100644
Binary files a/solve/libs/relast-compiler.jar and b/solve/libs/relast-compiler.jar differ
diff --git a/solve/src/main/jastadd/ApplyChanges.jadd b/solve/src/main/jastadd/ApplyChanges.jadd
index 274e1c29893f4f08ba50eb611175a4ef86da7848..59352158f21eb89193e60d7a151d850faa235a74 100644
--- a/solve/src/main/jastadd/ApplyChanges.jadd
+++ b/solve/src/main/jastadd/ApplyChanges.jadd
@@ -8,7 +8,6 @@ aspect ApplyChanges {
   public abstract void ModelChange.apply();
 
   public void ChangeTransaction.apply() {
-    logger.debug("Applying {}", this);
     getSourceChange().apply();
     for (ModelChange nestedChange : getNestedChanges()) {
       nestedChange.apply();
@@ -16,7 +15,6 @@ aspect ApplyChanges {
   }
 
   public void AssociationCollectionInsertion.apply() {
-    logger.debug("Applying {}", this);
     if (getAffectedElement().isUser()) {
       User user = java.util.Objects.requireNonNull(getAffectedElement().asUser(),
         () -> "Was no user, instead " + getAffectedElement());
@@ -42,18 +40,17 @@ aspect ApplyChanges {
       }
     }
     if (getFeature().equals("likedBy")) {
-      logger.debug("AssociationCollectionInsertion for likedBy will be handled by attributes.");
+      System.err.println("AssociationCollectionInsertion for likedBy will be handled by attributes.");
       return;
     }
-    logger.error("Unhandled change {}", this);
+    System.err.println("Unhandled change " + this);
   }
 
   public void AssociationPropertyChange.apply() {
-    logger.debug("Applying {}", this);
     if (getAffectedElement().isComment()) {
       switch (getFeature()) {
         case "commented": // inverse to Submission.comments -> Comments*
-          logger.debug("AssociationPropertyChange for commented already handled by parser.");
+          // AssociationPropertyChange for commented already handled by parser
           // newValue is a Submission
 //          Submission submission = (Submission) getNewValue();
 //          submission.addComment((Comment) getAffectedElement());
@@ -62,11 +59,10 @@ aspect ApplyChanges {
     } else if (getAffectedElement().isPost()) {
 
     }
-    logger.error("Unhandled change {}", this);
+    System.err.println("Unhandled change " + this);
   }
 
   public void AttributionPropertyChange.apply() {
-    logger.debug("Applying {}", this);
     if (getAffectedElement().isUser()) {
       switch (getFeature()) {
         case "name":
@@ -75,11 +71,10 @@ aspect ApplyChanges {
           return;
       }
     }
-    logger.error("Unhandled change {}", this);
+    System.err.println("Unhandled change " + this);
   }
 
   public void CompositionListInsertion.apply() {
-    logger.debug("Applying {}", this);
     if (getAffectedElement().isSubmission()) {
       Submission affected = java.util.Objects.requireNonNull(getAffectedElement().asSubmission(),
         () -> "Was no submission, instead " + getAffectedElement());
@@ -110,6 +105,6 @@ aspect ApplyChanges {
           return;
       }
     }
-    logger.error("Unhandled change {}", this);
+    System.err.println("Unhandled change " + this);
   }
 }
diff --git a/solve/src/main/jastadd/Checking.jrag b/solve/src/main/jastadd/Checking.jrag
index b4dd7f5e8e959f97cdab21eccf0b45ea9666dcb3..934f0cd7e2bd9243a70e7d6bf30d44032a884b96 100644
--- a/solve/src/main/jastadd/Checking.jrag
+++ b/solve/src/main/jastadd/Checking.jrag
@@ -4,7 +4,7 @@ aspect Checking {
     boolean valid = true;
     for (ASTNode node : listToCheck) {
       if (node == null) {
-        logger.warn("Found null {} in {}", nonterminalName, this);
+        System.err.println("Found null " + nonterminalName + " in " + this);
         valid = false;
       }
     }
@@ -15,7 +15,7 @@ aspect Checking {
     boolean valid = true;
     for (ModelElement modelElement : listToCheck) {
       if (modelElement == null) {
-        logger.warn("Found null {} in {}", nonterminalName, this);
+        System.err.println("Found null " + nonterminalName + " in " + this);
         valid = false;
       } else {
         valid &= modelElement.isValid();
@@ -26,7 +26,7 @@ aspect Checking {
 
   boolean ModelElement.checkThat(boolean condition, String message) {
     if (!condition) {
-      logger.warn(message);
+      System.err.println(message);
     }
     return condition;
   }
diff --git a/solve/src/main/jastadd/Logging.jadd b/solve/src/main/jastadd/Logging.jadd
deleted file mode 100644
index b34a088484642a8310328426004a757e1ca18c1b..0000000000000000000000000000000000000000
--- a/solve/src/main/jastadd/Logging.jadd
+++ /dev/null
@@ -1,6 +0,0 @@
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-aspect Logging {
-  static Logger ASTNode.logger = LogManager.getLogger(ASTNode.class);
-}
diff --git a/solve/src/main/jastadd/ModelNavigation.jrag b/solve/src/main/jastadd/ModelNavigation.jrag
index 7571a71dad8e307a4678c948056ec962f0abc2fe..843e259b166a79031683293b2e33b8f59e652e8b 100644
--- a/solve/src/main/jastadd/ModelNavigation.jrag
+++ b/solve/src/main/jastadd/ModelNavigation.jrag
@@ -15,7 +15,7 @@ aspect ModelNavigation {
     for (Comment comment : this.getCommentList()) {
       result.add(comment);
       if (comment == null) {
-        logger.warn("Comment to add was null in {}. Skipping.", this);
+        System.err.println("Comment to add was null in " + this + ". Skipping.");
         continue;
       }
       comment.addToComments(result);
diff --git a/solve/src/main/jastadd/RefList.jadd b/solve/src/main/jastadd/RefList.jadd
deleted file mode 100644
index a0566565528518a7d4fe5fa35b57aa4f9a32062b..0000000000000000000000000000000000000000
--- a/solve/src/main/jastadd/RefList.jadd
+++ /dev/null
@@ -1,3 +0,0 @@
-aspect RefList {
-  public class RefList<T extends ASTNode> extends java.util.ArrayList<T> {}
-}
diff --git a/solve/src/main/java/SocialNetwork/Comment.java b/solve/src/main/java/SocialNetwork/Comment.java
index 7a2254006936c5715640a4d9bff7298dda40b7c1..96b27c29ce61397b4d94f070b07c2f63baaddd6d 100644
--- a/solve/src/main/java/SocialNetwork/Comment.java
+++ b/solve/src/main/java/SocialNetwork/Comment.java
@@ -15,7 +15,6 @@ import org.eclipse.emf.common.util.EList;
  * <ul>
  *   <li>{@link SocialNetwork.Comment#getCommented <em>Commented</em>}</li>
  *   <li>{@link SocialNetwork.Comment#getLikedBy <em>Liked By</em>}</li>
- *   <li>{@link SocialNetwork.Comment#getPost <em>Post</em>}</li>
  * </ul>
  *
  * @see SocialNetwork.SocialNetworkPackage#getComment()
@@ -58,30 +57,4 @@ public interface Comment extends Submission {
 	 */
 	EList<User> getLikedBy();
 
-	/**
-	 * Returns the value of the '<em><b>Post</b></em>' reference.
-	 * <!-- begin-user-doc -->
-	 * <p>
-	 * If the meaning of the '<em>Post</em>' reference isn't clear,
-	 * there really should be more of a description here...
-	 * </p>
-	 * <!-- end-user-doc -->
-	 * @return the value of the '<em>Post</em>' reference.
-	 * @see #setPost(Post)
-	 * @see SocialNetwork.SocialNetworkPackage#getComment_Post()
-	 * @model required="true" ordered="false"
-	 * @generated
-	 */
-	Post getPost();
-
-	/**
-	 * Sets the value of the '{@link SocialNetwork.Comment#getPost <em>Post</em>}' reference.
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @param value the new value of the '<em>Post</em>' reference.
-	 * @see #getPost()
-	 * @generated
-	 */
-	void setPost(Post value);
-
 } // Comment
diff --git a/solve/src/main/java/SocialNetwork/impl/CommentImpl.java b/solve/src/main/java/SocialNetwork/impl/CommentImpl.java
index a0a35cb120d7d1c283c3d38dea07c9e052ef5796..dc4ae13f21d00cf83a7694469e026862483aabf1 100644
--- a/solve/src/main/java/SocialNetwork/impl/CommentImpl.java
+++ b/solve/src/main/java/SocialNetwork/impl/CommentImpl.java
@@ -3,23 +3,17 @@
 package SocialNetwork.impl;
 
 import SocialNetwork.Comment;
-import SocialNetwork.Post;
 import SocialNetwork.SocialNetworkPackage;
 import SocialNetwork.Submission;
 import SocialNetwork.User;
 
 import java.util.Collection;
-
-import org.eclipse.emf.common.notify.Notification;
 import org.eclipse.emf.common.notify.NotificationChain;
 
 import org.eclipse.emf.common.util.EList;
 
 import org.eclipse.emf.ecore.EClass;
 import org.eclipse.emf.ecore.InternalEObject;
-
-import org.eclipse.emf.ecore.impl.ENotificationImpl;
-
 import org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList;
 import org.eclipse.emf.ecore.util.InternalEList;
 
@@ -33,7 +27,6 @@ import org.eclipse.emf.ecore.util.InternalEList;
  * <ul>
  *   <li>{@link SocialNetwork.impl.CommentImpl#getCommented <em>Commented</em>}</li>
  *   <li>{@link SocialNetwork.impl.CommentImpl#getLikedBy <em>Liked By</em>}</li>
- *   <li>{@link SocialNetwork.impl.CommentImpl#getPost <em>Post</em>}</li>
  * </ul>
  *
  * @generated
@@ -49,16 +42,6 @@ public class CommentImpl extends SubmissionImpl implements Comment {
 	 */
 	protected EList<User> likedBy;
 
-	/**
-	 * The cached value of the '{@link #getPost() <em>Post</em>}' reference.
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @see #getPost()
-	 * @generated
-	 * @ordered
-	 */
-	protected Post post;
-
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -83,6 +66,7 @@ public class CommentImpl extends SubmissionImpl implements Comment {
 	 * <!-- end-user-doc -->
 	 * @generated
 	 */
+	@Override
 	public Submission getCommented() {
 		if (eContainerFeatureID() != SocialNetworkPackage.COMMENT__COMMENTED) return null;
 		return (Submission)eInternalContainer();
@@ -93,6 +77,7 @@ public class CommentImpl extends SubmissionImpl implements Comment {
 	 * <!-- end-user-doc -->
 	 * @generated
 	 */
+	@Override
 	public EList<User> getLikedBy() {
 		if (likedBy == null) {
 			likedBy = new EObjectWithInverseResolvingEList.ManyInverse<User>(User.class, this, SocialNetworkPackage.COMMENT__LIKED_BY, SocialNetworkPackage.USER__LIKES);
@@ -100,44 +85,6 @@ public class CommentImpl extends SubmissionImpl implements Comment {
 		return likedBy;
 	}
 
-	/**
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @generated
-	 */
-	public Post getPost() {
-		if (post != null && post.eIsProxy()) {
-			InternalEObject oldPost = (InternalEObject)post;
-			post = (Post)eResolveProxy(oldPost);
-			if (post != oldPost) {
-				if (eNotificationRequired())
-					eNotify(new ENotificationImpl(this, Notification.RESOLVE, SocialNetworkPackage.COMMENT__POST, oldPost, post));
-			}
-		}
-		return post;
-	}
-
-	/**
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @generated
-	 */
-	public Post basicGetPost() {
-		return post;
-	}
-
-	/**
-	 * <!-- begin-user-doc -->
-	 * <!-- end-user-doc -->
-	 * @generated
-	 */
-	public void setPost(Post newPost) {
-		Post oldPost = post;
-		post = newPost;
-		if (eNotificationRequired())
-			eNotify(new ENotificationImpl(this, Notification.SET, SocialNetworkPackage.COMMENT__POST, oldPost, post));
-	}
-
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -199,9 +146,6 @@ public class CommentImpl extends SubmissionImpl implements Comment {
 				return getCommented();
 			case SocialNetworkPackage.COMMENT__LIKED_BY:
 				return getLikedBy();
-			case SocialNetworkPackage.COMMENT__POST:
-				if (resolve) return getPost();
-				return basicGetPost();
 		}
 		return super.eGet(featureID, resolve, coreType);
 	}
@@ -219,9 +163,6 @@ public class CommentImpl extends SubmissionImpl implements Comment {
 				getLikedBy().clear();
 				getLikedBy().addAll((Collection<? extends User>)newValue);
 				return;
-			case SocialNetworkPackage.COMMENT__POST:
-				setPost((Post)newValue);
-				return;
 		}
 		super.eSet(featureID, newValue);
 	}
@@ -237,9 +178,6 @@ public class CommentImpl extends SubmissionImpl implements Comment {
 			case SocialNetworkPackage.COMMENT__LIKED_BY:
 				getLikedBy().clear();
 				return;
-			case SocialNetworkPackage.COMMENT__POST:
-				setPost((Post)null);
-				return;
 		}
 		super.eUnset(featureID);
 	}
@@ -256,8 +194,6 @@ public class CommentImpl extends SubmissionImpl implements Comment {
 				return getCommented() != null;
 			case SocialNetworkPackage.COMMENT__LIKED_BY:
 				return likedBy != null && !likedBy.isEmpty();
-			case SocialNetworkPackage.COMMENT__POST:
-				return post != null;
 		}
 		return super.eIsSet(featureID);
 	}
diff --git a/solve/src/main/java/de/tudresden/inf/st/ttc18live/AbstractLiveContestDriver.java b/solve/src/main/java/de/tudresden/inf/st/ttc18live/AbstractLiveContestDriver.java
index add02146930e5e1dd385b55821ab02a576e692be..3653cc5c9f1eb4c32f056344790a5498f188e3d9 100644
--- a/solve/src/main/java/de/tudresden/inf/st/ttc18live/AbstractLiveContestDriver.java
+++ b/solve/src/main/java/de/tudresden/inf/st/ttc18live/AbstractLiveContestDriver.java
@@ -2,14 +2,8 @@ package de.tudresden.inf.st.ttc18live;
 
 import de.tudresden.inf.st.ttc18live.jastadd.model.ModelChangeSet;
 import de.tudresden.inf.st.ttc18live.jastadd.model.SocialNetwork;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.config.Configuration;
 
 import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  * Abstract Driver for a JastAdd solution.
@@ -18,13 +12,13 @@ import java.util.stream.Collectors;
  */
 public abstract class AbstractLiveContestDriver {
 
-  private Boolean Debug;
-  private String ChangePath;
+  private final Boolean Debug;
+  private final String ChangePath;
   private String RunIndex;
   private int Sequences;
   private String Tool;
-  private String ChangeSet;
-  private String Query;
+  private final String ChangeSet;
+  private final String Query;
 
   private long stopwatch;
 
@@ -54,10 +48,6 @@ public abstract class AbstractLiveContestDriver {
 
   public void mainImpl() {
     // remove console logger
-    final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
-    final Configuration config = ctx.getConfiguration();
-    config.getRootLogger().removeAppender("Console");
-    ctx.updateLoggers();
     try {
       Initialize();
       Load();
@@ -143,7 +133,7 @@ public abstract class AbstractLiveContestDriver {
   private void Update(int iteration) throws Exception {
     System.err.print(iteration + " ");
 
-    String size_iteration = ChangeSet + Integer.toString(iteration);
+    String size_iteration = ChangeSet + iteration;
     if (traceEvents) {
       solution.getSocialNetwork().insertCustomEvent("TTC_TRANSFORMATION", size_iteration);
     }
@@ -167,19 +157,19 @@ public abstract class AbstractLiveContestDriver {
     } else {
       iterationStr = Integer.toString(iteration);
     }
-    System.out.println(String.format("%s;%s;%s;%s;%s;%s;Time;%s",
-        Tool, Query, ChangeSet, RunIndex, iterationStr, phase.toString(), Long.toString(stopwatch)));
+    System.out.printf("%s;%s;%s;%s;%s;%s;Time;%s%n",
+        Tool, Query, ChangeSet, RunIndex, iterationStr, phase.toString(), stopwatch);
     Runtime.getRuntime().gc();
     Runtime.getRuntime().gc();
     Runtime.getRuntime().gc();
     Runtime.getRuntime().gc();
     Runtime.getRuntime().gc();
     long memoryUsed = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
-    System.out.println(String.format("%s;%s;%s;%s;%s;%s;Memory;%s",
-        Tool, Query, ChangeSet, RunIndex, iterationStr, phase.toString(), Long.toString(memoryUsed)));
+    System.out.printf("%s;%s;%s;%s;%s;%s;Memory;%s%n",
+        Tool, Query, ChangeSet, RunIndex, iterationStr, phase.toString(), memoryUsed);
     if (result != null) {
-      System.out.println(String.format("%s;%s;%s;%s;%s;%s;Elements;%s",
-          Tool, Query, ChangeSet, RunIndex, iterationStr, phase.toString(), result));
+      System.out.printf("%s;%s;%s;%s;%s;%s;Elements;%s%n",
+          Tool, Query, ChangeSet, RunIndex, iterationStr, phase.toString(), result);
     }
   }
 
diff --git a/solve/src/main/java/de/tudresden/inf/st/ttc18live/LiveContestDriverEMF.java b/solve/src/main/java/de/tudresden/inf/st/ttc18live/LiveContestDriverEMF.java
index ac86b9f6234aedbea243a0794db9204daa6d1ed8..434e219fd02f76213dcac51872399c225c4c7ee9 100644
--- a/solve/src/main/java/de/tudresden/inf/st/ttc18live/LiveContestDriverEMF.java
+++ b/solve/src/main/java/de/tudresden/inf/st/ttc18live/LiveContestDriverEMF.java
@@ -71,8 +71,8 @@ public class LiveContestDriverEMF extends AbstractLiveContestDriver {
     return translator.translateChangeSet(emfChanges);
   }
 
-  @Override
-  public void Initial() {
-    throw new RuntimeException();
-  }
+//  @Override
+//  public void Initial() {
+//    throw new RuntimeException();
+//  }
 }
diff --git a/solve/src/main/java/de/tudresden/inf/st/ttc18live/Main.java b/solve/src/main/java/de/tudresden/inf/st/ttc18live/Main.java
index a4d10f84ab3426d5087c20e7765ebc37e817026d..df5fff59e7c42b207238c21a447dfc4c4561e391 100644
--- a/solve/src/main/java/de/tudresden/inf/st/ttc18live/Main.java
+++ b/solve/src/main/java/de/tudresden/inf/st/ttc18live/Main.java
@@ -4,8 +4,6 @@ import de.tudresden.inf.st.ttc18live.jastadd.model.*;
 import de.tudresden.inf.st.ttc18live.parser.ParsedSocialNetwork;
 import de.tudresden.inf.st.ttc18live.parser.change.ParsedModelChangeSet;
 import de.tudresden.inf.st.ttc18live.translator.XmlToJastaddTranslator;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
@@ -18,11 +16,10 @@ import java.util.stream.Collectors;
 
 @SuppressWarnings("FieldCanBeLocal")
 public class Main {
-  private static Logger logger = LogManager.getLogger(Main.class);
 
-  private static boolean splitApply = true;
-  private static int changeSet = 128;
-  private static int maxChanges = 20;
+  private static final boolean splitApply = true;
+  private static final int changeSet = 128;
+  private static final int maxChanges = 20;
 
   private static User mkUser(long id, SocialNetwork sn, Comment... likes) {
     User result = new User();
@@ -77,13 +74,14 @@ public class Main {
     sn.flushTreeCache();
 
     for (Comment comment : sn.comments()) {
-      logger.info("u3.getCommentLikerFriends({}): {}", comment, interestingUser.getCommentLikerFriends(comment));
+      System.out.println("u3.getCommentLikerFriends(" + comment + "): " +
+          interestingUser.getCommentLikerFriends(comment));
     }
     for (Comment comment : sn.comments()) {
-      logger.info("{}.score: {}", comment, comment.score());
+      System.out.println(comment + ".score: " + comment.score());
     }
 
-    logger.info("sn.query2: {}", sn.query(2));
+    System.out.println("sn.query2: " + sn.query(2));
 
     System.exit(0);
   }
@@ -93,24 +91,24 @@ public class Main {
     XmlToJastaddTranslator translator = parseSocialNetwork();
     SocialNetwork socialNetwork = translator.getSocialNetwork();
     socialNetwork.enableTracing();
-    logger.info("Validity: {}", socialNetwork.isValid());
+    System.out.println("Validity: " + socialNetwork.isValid());
 
 //    JsonSerializer.write(socialNetwork, "serializedModelOne");
-    logger.info("JastAdd model with {} users and {} posts",
-        socialNetwork.getNumUser(), socialNetwork.getNumPost());
+    System.out.println("JastAdd model with " + socialNetwork.getNumUser() +" users and "
+        + socialNetwork.getNumPost() + " posts");
 
-    logger.info("Query1: {}", socialNetwork.query(1));
-    logger.info("Query2: {}", socialNetwork.query(2));
+    System.out.println("Query1: " + socialNetwork.query(1));
+    System.out.println("Query2: " + socialNetwork.query(2));
 //    printQ2Scores(socialNetwork);
 
     for (int index = 1; index <= maxChanges; index++) {
       ModelChangeSet modelChangeSet = parseChanges(translator, index);
       if (modelChangeSet == null) {
-        logger.debug("Got null as modelChangeSet, skipping.");
+        System.out.println("Got null as modelChangeSet, skipping.");
         continue;
       }
-      logger.info("Validity after parsing of {} changes: {}",
-          modelChangeSet.getNumModelChange(), socialNetwork.isValid());
+      System.out.println("Validity after parsing of " + modelChangeSet.getNumModelChange()
+              + " changes: " + socialNetwork.isValid());
 
       // flush to get ids correct after parsing
       socialNetwork.flushTreeCache();
@@ -131,10 +129,10 @@ public class Main {
         socialNetwork.flushTreeCache();
       }
 
-      logger.info("Validity after application of changes: {}", socialNetwork.isValid());
+      System.out.println("Validity after application of changes: " + socialNetwork.isValid());
 
-      logger.info("Query1 after change {}: {}", index, socialNetwork.query(1));
-      logger.info("Query2 after change {}: {}", index, socialNetwork.query(2));
+      System.out.println("Query1 after change " + index + ": " + socialNetwork.query(1));
+      System.out.println("Query2 after change " + index + ": " + socialNetwork.query(2));
 
 //      printQ2Scores(socialNetwork);
     }
@@ -145,15 +143,15 @@ public class Main {
     java.util.List<Comment> scoringComments = socialNetwork.comments().stream()
         .filter(c -> c.score() > 0)
         .collect(Collectors.toList());
-    logger.info("Scores Q2: {}",
+    System.out.println("Scores Q2: " +
         scoringComments.stream()
             .map(c -> c.toString() + ":(" + c.score() + "." + c.getTimestamp() + ")")
             .collect(Collectors.joining(", ")));
     for (Comment comment : scoringComments) {
-      logger.debug("{} likedBy {}", comment, comment.getLikedByList());
+      System.out.println(comment + " likedBy " + comment.getLikedByList());
       for (User user : comment.getLikedByList()) {
-        logger.debug("{} and {}: {}", comment, user, user.getCommentLikerFriends(comment));
-        logger.debug("{} friends: {}", user, printList(user.getFriends()));
+        System.out.println(comment + " and " + user + ": " + user.getCommentLikerFriends(comment));
+        System.out.println(user + " friends: " + printList(user.getFriends()));
       }
     }
   }
@@ -177,8 +175,8 @@ public class Main {
     Unmarshaller unmarshaller = jc.createUnmarshaller();
     Path model1Content = Paths.get("src", "test", "resources", Integer.toString(changeSet), "initial.xmi");
     ParsedSocialNetwork parsedSocialNetwork = (ParsedSocialNetwork) unmarshaller.unmarshal(model1Content.toFile());
-    logger.info("Users: {}, Posts: {}",
-        parsedSocialNetwork.users.size(), parsedSocialNetwork.posts.size());
+    System.out.println("Users: " + parsedSocialNetwork.users.size()
+        + ", Posts: " + parsedSocialNetwork.posts.size());
     XmlToJastaddTranslator translator = new XmlToJastaddTranslator();
     translator.translateSocialNetwork(parsedSocialNetwork);
     return translator;
@@ -186,13 +184,13 @@ public class Main {
 
   private static ModelChangeSet parseChanges(XmlToJastaddTranslator translator, int index) throws JAXBException, ParseException {
     String suffix = String.format("change%02d.xmi", index);
-    logger.info("Parsing changes {}", suffix);
+    System.out.println("Parsing changes " + suffix);
     JAXBContext jc = JAXBContext.newInstance(ParsedModelChangeSet.class);
     Unmarshaller unmarshaller = jc.createUnmarshaller();
     unmarshaller.setEventHandler(new javax.xml.bind.helpers.DefaultValidationEventHandler());
     Path modelContent = Paths.get("src", "test", "resources", Integer.toString(changeSet), suffix);
     if (!modelContent.toFile().exists()) {
-      logger.warn("File {} does not exist!", modelContent);
+      System.err.println("File " + modelContent + " does not exist!");
       return null;
     }
     ParsedModelChangeSet parsedModelChangeSet = (ParsedModelChangeSet) unmarshaller.unmarshal(modelContent.toFile());
diff --git a/solve/src/main/java/de/tudresden/inf/st/ttc18live/parser/ParsedComment.java b/solve/src/main/java/de/tudresden/inf/st/ttc18live/parser/ParsedComment.java
index f11cd2220033cfdfe6eb53f28b93fedc3a9fdd95..9f1a14a38eecb444e7a350dabd4eb0ccfec73d58 100644
--- a/solve/src/main/java/de/tudresden/inf/st/ttc18live/parser/ParsedComment.java
+++ b/solve/src/main/java/de/tudresden/inf/st/ttc18live/parser/ParsedComment.java
@@ -13,8 +13,4 @@ import javax.xml.bind.annotation.XmlType;
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(namespace = "https://www.transformation-tool-contest.eu/2018/social_media", name = "Comment")
 public class ParsedComment extends ParsedSubmission {
-
-  @XmlAttribute(name = "post")
-  public String post;
-
 }
diff --git a/solve/src/main/java/de/tudresden/inf/st/ttc18live/serializer/ASTNodeSerializer.java b/solve/src/main/java/de/tudresden/inf/st/ttc18live/serializer/ASTNodeSerializer.java
index cb02878e36c3a312e3a73c0c8b49c485dde548b0..09139fbaaa7dfb984d2c3ae798238296cdcb948a 100644
--- a/solve/src/main/java/de/tudresden/inf/st/ttc18live/serializer/ASTNodeSerializer.java
+++ b/solve/src/main/java/de/tudresden/inf/st/ttc18live/serializer/ASTNodeSerializer.java
@@ -5,8 +5,6 @@ import com.fasterxml.jackson.databind.SerializerProvider;
 import com.fasterxml.jackson.databind.ser.std.StdSerializer;
 import de.tudresden.inf.st.ttc18live.jastadd.model.ASTNode;
 import de.tudresden.inf.st.ttc18live.jastadd.model.ASTNodeAnnotation;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
 
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
@@ -14,8 +12,6 @@ import java.lang.reflect.Method;
 
 public class ASTNodeSerializer extends StdSerializer<ASTNode> {
 
-  Logger logger = LogManager.getLogger(ASTNodeSerializer.class);
-
   public ASTNodeSerializer() {
     this(null);
   }
@@ -33,13 +29,11 @@ public class ASTNodeSerializer extends StdSerializer<ASTNode> {
     jgen.writeStringField("k", "NT");
     String className = value.getClass().getSimpleName();
     jgen.writeStringField("t", className);
-    logger.trace("class name: {}", className);
     jgen.writeObjectFieldStart("c");
     for (Method m : value.getClass().getMethods()) {
       try {
         if (m.getAnnotation(ASTNodeAnnotation.Child.class) != null) {
           String name = m.getAnnotation(ASTNodeAnnotation.Child.class).name();
-          logger.trace("child name: {}", name);
           jgen.writeFieldName(name);
           provider.defaultSerializeValue(m.invoke(value), jgen);
         } else if (m.getAnnotation(ASTNodeAnnotation.Token.class) != null) {
@@ -49,7 +43,6 @@ public class ASTNodeSerializer extends StdSerializer<ASTNode> {
           jgen.writeStringField("t", m.getReturnType().getName());
           jgen.writeFieldName("v");
           Object terminalValue = m.invoke(value);
-          logger.trace("terminal: {}", terminalValue);
           provider.defaultSerializeValue(terminalValue, jgen);
           jgen.writeEndObject();
         } else if (m.getAnnotation(ASTNodeAnnotation.ListChild.class) != null) {
diff --git a/solve/src/main/java/de/tudresden/inf/st/ttc18live/translator/XmlToJastaddTranslator.java b/solve/src/main/java/de/tudresden/inf/st/ttc18live/translator/XmlToJastaddTranslator.java
index 3777be70aabb94f27404c3c053cfebe69038b110..db6a9da17d2ba1ddc2d41bf61847ecaf99ad96e7 100644
--- a/solve/src/main/java/de/tudresden/inf/st/ttc18live/translator/XmlToJastaddTranslator.java
+++ b/solve/src/main/java/de/tudresden/inf/st/ttc18live/translator/XmlToJastaddTranslator.java
@@ -4,8 +4,6 @@ import de.tudresden.inf.st.ttc18live.Utils;
 import de.tudresden.inf.st.ttc18live.jastadd.model.*;
 import de.tudresden.inf.st.ttc18live.parser.*;
 import de.tudresden.inf.st.ttc18live.parser.change.*;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
 
 import java.text.DateFormat;
 import java.text.ParseException;
@@ -20,7 +18,6 @@ import java.util.List;
  */
 public class XmlToJastaddTranslator {
 
-  private final Logger logger = LogManager.getLogger(XmlToJastaddTranslator.class);
   /** Found forward references when translating change sets (by element) */
   private Map<ParsedModelElement, ModelElement> forwardReferencesElements;
   /** Found forward references when translating change sets (by path) */
@@ -48,11 +45,9 @@ public class XmlToJastaddTranslator {
     Map<User, String> userSubmissions = new HashMap<>();
     Map<User, String> userFriends = new HashMap<>();
     Map<User, String> userLikes = new HashMap<>();
-    Map<Comment, Long> commentPosts = new HashMap<>();
 
     socialNetwork = SocialNetwork.createSocialNetwork();
     for (ParsedUser parsedUser : parsedSocialNetwork.users) {
-      logger.trace("Parsing user id={}", parsedUser.id);
       User user = new User();
       user.setId(Long.valueOf(parsedUser.id));
       user.setName(parsedUser.name);
@@ -71,21 +66,18 @@ public class XmlToJastaddTranslator {
       userMap.put(user.getId(), user);
     }
     for (ParsedPost parsedPost : parsedSocialNetwork.posts) {
-      logger.trace("Parsing post id={}", parsedPost.id);
       Post post = new Post();
       post.setId(Long.valueOf(parsedPost.id));
       post.setTimestamp(convertTimestamp(parsedPost.timestamp));
       post.setContent(parsedPost.content);
-      addComments(parsedPost, post, commentPosts, submissionMap);
+      addComments(parsedPost, post, submissionMap);
       socialNetwork.addPost(post);
 
       // FIXME remove manual submission lookup
       submissionMap.put(post.getId(), post);
     }
-    logger.info("Got {} submissions", submissionMap.size());
 
     // resolveModelElement submissions
-    logger.info("Resolving submissions of {} users", userSubmissions.size());
     for (Map.Entry<User, String> userAndSubmissions : userSubmissions.entrySet()) {
       String[] submissionTokens = userAndSubmissions.getValue().split(" ");
       User user = userAndSubmissions.getKey();
@@ -94,7 +86,6 @@ public class XmlToJastaddTranslator {
       }
     }
     // resolveModelElement friends
-    logger.info("Resolving friends for {} users", userFriends.size());
     for (Map.Entry<User, String> userAndFriends : userFriends.entrySet()) {
       String[] friendsTokens = userAndFriends.getValue().split(" ");
       User user = userAndFriends.getKey();
@@ -103,7 +94,6 @@ public class XmlToJastaddTranslator {
       }
     }
     // resolveModelElement likes
-    logger.info("Resolving likes for {} users", userLikes.size());
     for (Map.Entry<User, String> userAndLikes : userLikes.entrySet()) {
       String[] likesTokens = userAndLikes.getValue().split(" ");
       User user = userAndLikes.getKey();
@@ -111,12 +101,11 @@ public class XmlToJastaddTranslator {
         user.addLike(((Comment) submissionMap.get(Long.valueOf(token))));
       }
     }
-    logger.info("Done translating");
     return socialNetwork;
   }
 
   private void addComments(ParsedSubmission parsedSubmission, Submission submission,
-                           Map<Comment, Long> commentPosts, Map<Long, Submission> submissionMap)
+                           Map<Long, Submission> submissionMap)
       throws ParseException {
     if (parsedSubmission.comments == null) {
       return;
@@ -126,9 +115,8 @@ public class XmlToJastaddTranslator {
       comment.setId(Long.valueOf(parsedComment.id));
       comment.setTimestamp(convertTimestamp(parsedComment.timestamp));
       comment.setContent(parsedComment.content);
-      commentPosts.put(comment, Long.valueOf(parsedComment.post));
       submission.addComment(comment);
-      addComments(parsedComment, comment, commentPosts, submissionMap);
+      addComments(parsedComment, comment, submissionMap);
 
       // FIXME remove manual submission lookup
       submissionMap.put(comment.getId(), comment);
@@ -151,7 +139,7 @@ public class XmlToJastaddTranslator {
 
   public ModelChangeSet translateModelChangeSet(ParsedModelChangeSet parsedModelChangeSet) throws ParseException {
     if (socialNetwork == null) {
-      logger.fatal("No previously parsed SocialNetwork found!");
+      System.err.println("No previously parsed SocialNetwork found!");
       return null;
     }
 
@@ -167,12 +155,10 @@ public class XmlToJastaddTranslator {
       return result;
     }
 
-    logger.debug("Found {} changes", parsedModelChangeSet.changes.size());
     ChangeListToRevise changeListToRevise = new ChangeListToRevise();
     List<ParsedModelChange> changes = parsedModelChangeSet.changes;
     for (int i = 0; i < changes.size(); i++) {
       ParsedModelChange parsedModelChange = changes.get(i);
-      logger.debug("change {} {}", i, parsedModelChange);
       result.addModelChange(translateModelChange(parsedModelChange, changeListToRevise, result, parsedModelChangeSet));
     }
     return result;
@@ -279,18 +265,16 @@ public class XmlToJastaddTranslator {
       userMap.put(id, user);
       me = user;
     } else if (parsedModelElement instanceof ParsedSubmission) {
-      ParsedSubmission parsedSubmission = (ParsedSubmission) parsedModelElement;
-      Submission submission;
+      final ParsedSubmission parsedSubmission = (ParsedSubmission) parsedModelElement;
+      final Submission submission;
+      final boolean submissionIsAPost;
       if (parsedModelElement instanceof ParsedPost) {
         submission = new Post();
+        submissionIsAPost = true;
         socialNetwork.addPost((Post) submission);
       } else if (parsedModelElement instanceof ParsedComment) {
         Comment comment = new Comment();
-        if (translateSubElements) {
-          Post post = (Post) resolveModelElement(((ParsedComment) parsedModelElement).post,
-              modelChangeSet, "Post", parsedModelChangeSet, false);
-          post.addComment(comment);
-        }
+        submissionIsAPost = false;
         submission = comment;
       } else {
         // submission can either be post or comment, nothing else.
@@ -308,11 +292,11 @@ public class XmlToJastaddTranslator {
         for (ParsedComment parsedSubComment : parsedSubmission.comments) {
           // translate to real comment. just resolve element
           Comment subComment = (Comment) translateModelElement(parsedSubComment, modelChangeSet, parsedModelChangeSet, translateSubElements);
-//          if (submissionIsAPost) {
-//            // assume subComment.post == parsedSubmission
-//            submission.addComment(subComment);
-//          }
-          // post and submitter for subComment are handled in this method already
+          if (submissionIsAPost) {
+            // assume subComment.post == parsedSubmission
+            submission.addComment(subComment);
+          }
+          // submitter for subComment is handled in this method already
           submission.addComment(subComment);
         }
       }
@@ -341,7 +325,6 @@ public class XmlToJastaddTranslator {
     // another example: "social:Comment #//@changes.1/@sourceChange/@addedElement"
     // general form: "'social:'<ClassName> ('initial.xmi#'<Id> | '#//@changes.'<sequenceId>'/@'<target> )
 
-    logger.debug("elementSpec: {}", elementSpec);
     // remove "social:"
     elementSpec = elementSpec.substring(7);
     String[] tokens = elementSpec.split(" ");
@@ -388,10 +371,10 @@ public class XmlToJastaddTranslator {
         return resolvePath(remainder, modelChangeSet.getModelChange(changeId));
       } else if (path.startsWith("initial")) {
         // refers to initial - should not happen, right?
-        logger.warn("Reference to initial. That was unexpected");
+        System.err.println("Reference to initial. That was unexpected");
       }
       // giving up
-      logger.warn("Can not resolveModelElement " + path);
+      System.err.println("Can not resolveModelElement " + path);
       id = 0;
     }
     ModelElement result;
@@ -424,22 +407,22 @@ public class XmlToJastaddTranslator {
         return resolvePath(remainder.substring(slashIndex + 1), sourceChange);
       }
       // or something not supported yet
-      logger.warn("Can not resolve ChangeTransaction {} at {}", remainder, modelChange);
+      System.err.println("Can not resolve ChangeTransaction " + remainder + " at " + modelChange);
       return null;
     } else if (modelChange instanceof AssociationCollectionInsertion) {
       if (remainder.startsWith("@addedElement")) {
         return ((AssociationCollectionInsertion) modelChange).getAddedElement();
       }
-      logger.warn("Can not resolve AssociationCollectionInsertion {} at {}", remainder, modelChange);
+      System.err.println("Can not resolve AssociationCollectionInsertion " + remainder + " at " + modelChange);
       return null;
     } else if (modelChange instanceof CompositionListInsertion) {
       if (remainder.startsWith("@addedElement")) {
         return ((CompositionListInsertion) modelChange).getAddedElement();
       }
-      logger.warn("Can not resolve CompositionListInsertion {} at {}", remainder, modelChange);
+      System.err.println("Can not resolve CompositionListInsertion " + remainder + " at " + modelChange);
       return null;
     }
-    logger.warn("Unknown change type: {} at {}", remainder, modelChange);
+    System.err.println("Unknown change type: " + remainder + " at " + modelChange);
     return null;
   }
 
@@ -456,7 +439,7 @@ public class XmlToJastaddTranslator {
         return resolvePathForward(remainder.substring(slashIndex + 1), sourceChange, modelChangeSet, parsedModelChangeSet, translateSubElements);
       }
       // or something not supported yet
-      logger.warn("Can not forward resolve ChangeTransaction {} at {}", remainder, parsedModelChange);
+      System.err.println("Can not forward resolve ChangeTransaction " + remainder + " at " + parsedModelChange);
       return null;
     } else if (parsedModelChange instanceof ParsedAssociationCollectionInsertion) {
       if (remainder.startsWith("@addedElement")) {
@@ -466,7 +449,7 @@ public class XmlToJastaddTranslator {
         forwardReferencesPaths.put(path, result);
         return result;
       }
-      logger.warn("Can not forward resolve AssociationCollectionInsertion {} at {}", remainder, parsedModelChange);
+      System.err.println("Can not forward resolve AssociationCollectionInsertion " + remainder + " at " + parsedModelChange);
       return null;
     } else if (parsedModelChange instanceof ParsedCompositionListInsertion) {
       if (remainder.startsWith("@addedElement")) {
@@ -475,10 +458,10 @@ public class XmlToJastaddTranslator {
         forwardReferencesElements.put(addedElement, result);
         return result;
       }
-      logger.warn("Can not forward resolve CompositionListInsertion {} at {}", remainder, parsedModelChange);
+      System.err.println("Can not forward resolve CompositionListInsertion " + remainder + " at " + parsedModelChange);
       return null;
     }
-    logger.warn("Unknown forward change type: {} at {}", remainder, parsedModelChange);
+    System.err.println("Unknown forward change type: " + remainder + " at " + parsedModelChange);
     return null;
   }
 
diff --git a/solve/src/test/java/de/tudresden/inf/st/ttc18live/test/AbstractAllTest.java b/solve/src/test/java/de/tudresden/inf/st/ttc18live/test/AbstractAllTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b145a7df0138fbe8866e9d4f6a6212aad530a404
--- /dev/null
+++ b/solve/src/test/java/de/tudresden/inf/st/ttc18live/test/AbstractAllTest.java
@@ -0,0 +1,118 @@
+package de.tudresden.inf.st.ttc18live.test;
+
+import com.opencsv.CSVReader;
+import de.tudresden.inf.st.ttc18live.AbstractLiveContestDriver;
+import de.tudresden.inf.st.ttc18live.LiveContestDriverXml;
+import org.junit.*;
+import org.junit.contrib.java.lang.system.EnvironmentVariables;
+import org.junit.contrib.java.lang.system.SystemOutRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+
+/**
+ * Test template against given expected query results.
+ *
+ * @author rschoene - Initial contribution
+ */
+@RunWith(Parameterized.class)
+public abstract class AbstractAllTest {
+  @Rule
+  public final EnvironmentVariables environmentVariables = new EnvironmentVariables();
+  @Rule public final SystemOutRule systemOutRule = new SystemOutRule().enableLog();
+
+  private final static int maxSequence = 5;
+  private final static Path modelsPath = Paths.get("src", "test", "resources", "models");
+
+  private final int query;
+  private final int size;
+  private final Map<Integer, String> localExpected;
+
+  @Parameterized.Parameters(name = "{2}")
+  public static Collection<Object[]> data() {
+    // query, size
+    Collection<Object[]> result = new ArrayList<>();
+    for (int query = 1; query <= 2; query++) {
+      for (int size : new int[]{1, 2, 4, 8}) {
+        result.add(new Object[]{query, size, "Q" + query + "@" + size});
+      }
+    }
+    return result;
+  }
+
+  /** query -> size -> { iteration -> value } */
+  private static Map<Integer, Map<Integer, Map<Integer, String>>> expected = new HashMap<>();
+
+  @BeforeClass
+  public static void readExpectedResults() {
+    Assert.assertTrue("Please create a link to the models directory of 'https://github.com/TransformationToolContest/ttc2018liveContest/' in 'src/test/resources/'",
+        modelsPath.toFile().exists());
+    InputStream inputStream = AllXmlTest.class.getResourceAsStream("/expected-results.csv");
+    try (InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
+         CSVReader reader = new CSVReader(inputStreamReader, ';', '"', 1)) {
+      reader.iterator().forEachRemaining( line -> {
+        String queryString = line[0];
+        String sizeString = line[1];
+        String iterationString = line[2];
+//        String phase = line[3];
+        String value = line[4];
+        Integer query = Integer.valueOf(queryString.substring(1));
+        Integer size = Integer.valueOf(sizeString);
+        Integer iteration = Integer.valueOf(iterationString);
+        expected.putIfAbsent(query, new HashMap<>());
+        expected.get(query).putIfAbsent(size, new HashMap<>());
+        expected.get(query).get(size).putIfAbsent(iteration, value);
+      });
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
+
+  private void setVars() {
+    environmentVariables.set("ChangeSet", Integer.toString(size));
+    environmentVariables.set("ChangePath", modelsPath.resolve(Integer.toString(size)).toFile().getAbsolutePath());
+    environmentVariables.set("Sequences", Integer.toString(maxSequence));
+    environmentVariables.set("Query", "Q" + query);
+  }
+
+  private AbstractLiveContestDriver driver;
+
+  public AbstractAllTest(int query, int size, @SuppressWarnings("unused") String name) {
+    this.query = query;
+    this.size = size;
+    this.localExpected = expected.get(query).get(size);
+    setVars();
+  }
+
+  @Before
+  public void setupDriver() {
+    driver = createDriver();
+  }
+
+  abstract AbstractLiveContestDriver createDriver();
+
+  @Test
+  public void test() {
+    System.out.println(query + "," + size + ":" + expected.get(query).get(size));
+    systemOutRule.clearLog();
+    driver.mainImpl();
+    Map<Integer, String> actual = new HashMap<>();
+    for (String line : systemOutRule.getLog().split("\n")) {
+      String[] tokens = line.split(";");
+      if ("Elements".equals(tokens[6])) {
+        int iteration = Integer.parseInt(tokens[4]);
+        actual.put(iteration, tokens[7]);
+      }
+    }
+    for (int iteration = 0; iteration <= maxSequence; iteration++) {
+      Assert.assertTrue("No result found for iteration " + iteration, actual.containsKey(iteration));
+      Assert.assertEquals("Wrong elements", localExpected.get(iteration), actual.get(iteration));
+    }
+  }
+}
diff --git a/solve/src/test/java/de/tudresden/inf/st/ttc18live/test/AllEmfTest.java b/solve/src/test/java/de/tudresden/inf/st/ttc18live/test/AllEmfTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9859238d9b140f205bac45a115971ff4d65e6a88
--- /dev/null
+++ b/solve/src/test/java/de/tudresden/inf/st/ttc18live/test/AllEmfTest.java
@@ -0,0 +1,26 @@
+package de.tudresden.inf.st.ttc18live.test;
+
+import de.tudresden.inf.st.ttc18live.AbstractLiveContestDriver;
+import de.tudresden.inf.st.ttc18live.LiveContestDriverEMF;
+
+/**
+ * Test against given expected query results using EMF solution.
+ *
+ * @author rschoene - Initial contribution
+ */
+public class AllEmfTest extends AbstractAllTest {
+
+  public AllEmfTest(int query, int size, String name) {
+    super(query, size, name);
+  }
+
+  @Override
+  AbstractLiveContestDriver createDriver() {
+    return new LiveContestDriverEMF() {
+//      @Override
+//      public void Initial() {
+//        // do nothing (i.e. do not throw an Exception)
+//      }
+    };
+  }
+}
diff --git a/solve/src/test/java/de/tudresden/inf/st/ttc18live/test/AllXmlTest.java b/solve/src/test/java/de/tudresden/inf/st/ttc18live/test/AllXmlTest.java
index 3511d574fd123e1860192fc8e4f99172d2fdef06..8ae095e24e20619c29734ec07a2df98229d2fd15 100644
--- a/solve/src/test/java/de/tudresden/inf/st/ttc18live/test/AllXmlTest.java
+++ b/solve/src/test/java/de/tudresden/inf/st/ttc18live/test/AllXmlTest.java
@@ -20,95 +20,18 @@ import java.util.HashMap;
 import java.util.Map;
 
 /**
- * Test against given expected query results.
+ * Test against given expected query results using XML solution.
  *
  * @author rschoene - Initial contribution
  */
-@RunWith(Parameterized.class)
-public class AllXmlTest {
-  @Rule public final EnvironmentVariables environmentVariables = new EnvironmentVariables();
-  @Rule public final SystemOutRule systemOutRule = new SystemOutRule().enableLog();
+public class AllXmlTest extends AbstractAllTest {
 
-  private final static int maxSequence = 5;
-  private final static Path modelsPath = Paths.get("src", "test", "resources", "models");
-
-  private final int query;
-  private final int size;
-  private final Map<Integer, String> localExpected;
-
-  @Parameterized.Parameters(name = "{2}")
-  public static Collection<Object[]> data() {
-    // query, size
-    Collection<Object[]> result = new ArrayList<>();
-    for (int query = 1; query <= 2; query++) {
-      for (int size : new int[]{1, 2, 4, 8}) {
-        result.add(new Object[]{query, size, "Q" + query + "@" + size});
-      }
-    }
-    return result;
+  public AllXmlTest(int query, int size, String name) {
+    super(query, size, name);
   }
 
-  /** query -> size -> { iteration -> value } */
-  private static Map<Integer, Map<Integer, Map<Integer, String>>> expected = new HashMap<>();
-
-  @BeforeClass
-  public static void readExpectedResults() {
-    Assert.assertTrue("Please create a link to the models directory of 'https://github.com/TransformationToolContest/ttc2018liveContest/' in 'src/test/resources/'",
-        modelsPath.toFile().exists());
-    InputStream inputStream = AllXmlTest.class.getResourceAsStream("/expected-results.csv");
-    try (InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
-         CSVReader reader = new CSVReader(inputStreamReader, ';', '"', 1)) {
-      reader.iterator().forEachRemaining( line -> {
-        String queryString = line[0];
-        String sizeString = line[1];
-        String iterationString = line[2];
-//        String phase = line[3];
-        String value = line[4];
-        Integer query = Integer.valueOf(queryString.substring(1));
-        Integer size = Integer.valueOf(sizeString);
-        Integer iteration = Integer.valueOf(iterationString);
-        expected.putIfAbsent(query, new HashMap<>());
-        expected.get(query).putIfAbsent(size, new HashMap<>());
-        expected.get(query).get(size).putIfAbsent(iteration, value);
-      });
-    } catch (IOException e) {
-      e.printStackTrace();
-    }
+  @Override
+  AbstractLiveContestDriver createDriver() {
+    return new LiveContestDriverXml();
   }
-
-  private void setVars() {
-    environmentVariables.set("ChangeSet", Integer.toString(size));
-    environmentVariables.set("ChangePath", modelsPath.resolve(Integer.toString(size)).toFile().getAbsolutePath());
-    environmentVariables.set("Sequences", Integer.toString(maxSequence));
-    environmentVariables.set("Query", "Q" + query);
-  }
-
-  private AbstractLiveContestDriver driver;
-
-  public AllXmlTest(int query, int size, @SuppressWarnings("unused") String name) {
-    this.query = query;
-    this.size = size;
-    this.localExpected = expected.get(query).get(size);
-    setVars();
-  }
-
-  @Before
-  public void setupDriver() {
-    driver = new LiveContestDriverXml();
-  }
-
-  @Test
-  public void test() {
-    System.out.println(query + "," + size + ":" + expected.get(query).get(size));
-    systemOutRule.clearLog();
-    driver.mainImpl();
-    for (String line : systemOutRule.getLog().split("\n")) {
-      String[] tokens = line.split(";");
-      if ("Elements".equals(tokens[6])) {
-        int iteration = Integer.valueOf(tokens[4]);
-        Assert.assertEquals("Wrong elements", localExpected.get(iteration), tokens[7]);
-      }
-    }
-  }
-
 }