diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..e597ae06e90f0eb78e2320b8893222784e2a47d6
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,75 @@
+apply plugin: 'java'
+apply plugin: 'eclipse'
+apply plugin: 'maven'
+apply plugin: 'jacoco'
+apply plugin: 'findbugs'
+
+project.version = '1.0.0-SNAPSHOT'
+project.group = 'de.prob'
+
+sourceCompatibility = 1.5
+
+repositories {
+	mavenCentral()
+	maven {
+	    	url "http://cobra.cs.uni-duesseldorf.de/artifactory/repo"
+	}
+}
+
+configurations { // configuration that holds jars to copy into lib
+	releaseJars 
+}
+ 
+def parser_version = '2.4.22-SNAPSHOT'
+
+dependencies {
+	//compile (group: 'com.microsoft', name: 'tla2tools', version: '1.4.6')
+	compile (group: 'de.tla', name: 'tlatools', version: '1.0.0-SNAPSHOT')
+	
+	compile (group: 'de.prob', name: 'prologlib', version: parser_version)
+	compile (group: 'de.prob', name: 'parserbase', version: parser_version)
+	compile (group: 'de.prob', name: 'bparser', version: parser_version)
+	compile (group: 'de.prob', name: 'ltlparser', version: parser_version)
+	
+	//compile(group: 'de.prob', name: 'de.prob.core.kernel', version: '2.0.0-milestone-13-SNAPSHOT')
+
+
+
+	testCompile (group: 'junit', name: 'junit', version: '4.7')
+
+	releaseJars (group: 'de.tla', name: 'tlatools', version: '1.0.0-SNAPSHOT')
+	releaseJars (group: 'de.prob', name: 'prologlib', version: parser_version)
+	releaseJars (group: 'de.prob', name: 'parserbase', version: parser_version)
+	releaseJars (group: 'de.prob', name: 'bparser', version: parser_version)
+	releaseJars (group: 'de.prob', name: 'ltlparser', version: parser_version)
+}
+
+jacoco {
+    toolVersion = "0.6.2.201302030002"
+    reportsDir = file("$buildDir/customJacocoReportDir")
+}
+
+jacocoTestReport {
+    reports {
+        xml.enabled false
+        csv.enabled false
+        html.destination "${buildDir}/jacocoHtml"
+    }
+}
+
+tasks.withType(FindBugs) {
+    reports {
+        xml.enabled = false
+        html.enabled = true
+    }
+}
+
+findbugs { 
+	ignoreFailures = true 
+}
+
+
+jar { from sourceSets.main.allJava }
+jar	{
+	from configurations.releaseJars.collect { it.isDirectory() ? it : zipTree(it) }
+}
\ No newline at end of file
diff --git a/src/main/java/de/tla2b/analysis/BOperation.java b/src/main/java/de/tla2b/analysis/BOperation.java
new file mode 100644
index 0000000000000000000000000000000000000000..7e99a87e6c885df66a873d8d8f73a0e811a6126b
--- /dev/null
+++ b/src/main/java/de/tla2b/analysis/BOperation.java
@@ -0,0 +1,145 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.analysis;
+
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+
+import de.tla2b.global.BBuiltInOPs;
+import de.tla2b.global.TranslationGlobals;
+
+import tla2sany.semantic.ASTConstants;
+import tla2sany.semantic.ExprNode;
+import tla2sany.semantic.FormalParamNode;
+import tla2sany.semantic.LetInNode;
+import tla2sany.semantic.OpApplNode;
+import tla2sany.semantic.OpDefNode;
+import tla2sany.semantic.SemanticNode;
+import tla2sany.semantic.SubstInNode;
+import tlc2.tool.BuiltInOPs;
+import tlc2.tool.ToolGlobals;
+
+public class BOperation implements ASTConstants, ToolGlobals, TranslationGlobals {
+	private String name;
+	private ExprNode node;
+	private ArrayList<OpApplNode> existQuans;
+	private ArrayList<String> opParams;
+	private ArrayList<String> unchangedVariables;
+
+	public BOperation(String name, ExprNode n,
+			ArrayList<OpApplNode> existQuans) {
+		this.name = name;
+		this.node = n;
+		this.existQuans = existQuans;
+		evalParams();
+		findUnchangedVariables();
+	}
+
+	private void evalParams() {
+		opParams = new ArrayList<String>();
+		for (int i = 0; i < existQuans.size(); i++) {
+			OpApplNode n = existQuans.get(i);
+			FormalParamNode[][] params = n.getBdedQuantSymbolLists();
+			for (int k = 0; k < params.length; k++) {
+				for (int j = 0; j < params[k].length; j++) {
+					opParams.add(params[k][j].getName().toString());
+				}
+			}
+		}
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public ExprNode getNode() {
+		return node;
+	}
+
+	public ArrayList<OpApplNode> getExistQuans() {
+		return new ArrayList<OpApplNode>(existQuans);
+	}
+
+	public ArrayList<String> getOpParams() {
+		return opParams;
+	}
+
+	public ArrayList<String> getUnchangedVariables(){
+		return unchangedVariables;
+	}
+	
+	private void findUnchangedVariables() {
+		unchangedVariables = new ArrayList<String>();
+		findUnchangedVaribalesInSemanticNode(node);
+	}
+	
+
+	/**
+	 * @param node2
+	 */
+	private void findUnchangedVaribalesInSemanticNode(SemanticNode node) {
+		switch (node.getKind()) {
+		case OpApplKind: {
+			findUnchangedVariablesInOpApplNode((OpApplNode) node);
+			return;
+		}
+		case LetInKind: {
+			LetInNode letNode = (LetInNode) node;
+			findUnchangedVaribalesInSemanticNode(letNode.getBody());
+			return;
+		}
+
+		case SubstInKind: {
+			SubstInNode substInNode = (SubstInNode) node;
+			findUnchangedVaribalesInSemanticNode(substInNode.getBody());
+			return;
+		}
+		}
+	}
+
+	/**
+	 * @param node2
+	 */
+	private void findUnchangedVariablesInOpApplNode(OpApplNode n) {
+
+		int kind = n.getOperator().getKind();
+		if (kind == UserDefinedOpKind
+				&& !BBuiltInOPs.contains(n.getOperator().getName())) {
+			OpDefNode def = (OpDefNode) n.getOperator();
+			findUnchangedVaribalesInSemanticNode(def.getBody());
+			return;
+		} else if (kind == BuiltInKind) {
+			int opcode = BuiltInOPs.getOpCode(n.getOperator().getName());
+			switch (opcode) {
+			case OPCODE_land: // \land
+			case OPCODE_cl: { // $ConjList
+				for (int i = 0; i < n.getArgs().length; i++) {
+					findUnchangedVaribalesInSemanticNode(n.getArgs()[i]);
+				}
+				return;
+			}
+			case OPCODE_unchanged:{
+				n.setToolObject(USED, false);
+				OpApplNode k = (OpApplNode) n.getArgs()[0];
+				if (k.getOperator().getKind() == VariableDeclKind) {
+					String name = k.getOperator().getName().toString();
+					unchangedVariables.add(name);
+				} else {
+					// Tuple
+					for (int i = 0; i < k.getArgs().length; i++) {
+						OpApplNode var = (OpApplNode) k.getArgs()[i];
+						String name = var.getOperator().getName().toString();
+						unchangedVariables.add(name);
+					}
+				}
+			}
+			
+			}
+		}
+	}
+	
+	
+}
diff --git a/src/main/java/de/tla2b/analysis/InstanceTransformation.java b/src/main/java/de/tla2b/analysis/InstanceTransformation.java
new file mode 100644
index 0000000000000000000000000000000000000000..9fe8a1bf2aebc321d5ad7867711ffea54391bb76
--- /dev/null
+++ b/src/main/java/de/tla2b/analysis/InstanceTransformation.java
@@ -0,0 +1,358 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.analysis;
+
+
+import java.util.Hashtable;
+
+import de.tla2b.global.BBuiltInOPs;
+
+import tla2sany.semantic.ASTConstants;
+import tla2sany.semantic.AbortException;
+import tla2sany.semantic.AtNode;
+import tla2sany.semantic.Context;
+import tla2sany.semantic.ExprNode;
+import tla2sany.semantic.ExprOrOpArgNode;
+import tla2sany.semantic.FormalParamNode;
+import tla2sany.semantic.LetInNode;
+import tla2sany.semantic.ModuleNode;
+import tla2sany.semantic.NumeralNode;
+import tla2sany.semantic.OpApplNode;
+import tla2sany.semantic.OpArgNode;
+import tla2sany.semantic.OpDeclNode;
+import tla2sany.semantic.OpDefNode;
+import tla2sany.semantic.StringNode;
+import tla2sany.semantic.Subst;
+import tla2sany.semantic.SubstInNode;
+import tlc2.tool.BuiltInOPs;
+import util.UniqueString;
+
+public class InstanceTransformation extends BuiltInOPs implements ASTConstants {
+
+	OpDefNode[] defs;
+	Hashtable<String, OpDefNode> defsHash;
+	private int substitutionId = 11;
+
+	/**
+	 * @param con
+	 */
+	public InstanceTransformation(ModuleNode n) {
+		defs = n.getOpDefs();
+
+		defsHash = new Hashtable<String, OpDefNode>();
+		for (int i = 0; i < defs.length; i++) {
+			defsHash.put(defs[i].getName().toString(), defs[i]);
+		}
+	}
+
+	/**
+	 * @throws AbortException
+	 * 
+	 */
+	public void start()  {
+		for (int i = 0; i < defs.length; i++) {
+			OpDefNode def = defs[i];
+			if (def.getSource() != def
+					&& !BBuiltInOPs.contains(def.getSource().getName())) {
+				// instance
+				String defName = def.getName().toString();
+				String prefix = defName.substring(0,
+						defName.lastIndexOf('!') + 1);
+				def.setParams(generateNewParams(def.getParams()));
+				ExprNode body;
+				try {
+					body = generateNewExprNode(def.getBody(), prefix);
+				} catch (AbortException e) {
+					throw new RuntimeException();
+				}
+				def.setBody(body);
+			}
+		}
+	}
+
+	/**
+	 * @param exprOrOpArgNode
+	 * @param prefix
+	 * @return
+	 * @throws AbortException
+	 */
+	private ExprOrOpArgNode generateNewExprOrOpArgNode(ExprOrOpArgNode n,
+			String prefix) throws AbortException {
+		if (n instanceof ExprNode) {
+			return generateNewExprNode((ExprNode) n, prefix);
+		} else {
+			throw new RuntimeException("OpArgNode not implemented jet");
+		}
+	}
+
+	/**
+	 * @param body
+	 * @param prefix
+	 * @return
+	 * @throws AbortException
+	 */
+	private ExprNode generateNewExprNode(ExprNode n, String prefix)
+			throws AbortException {
+		switch (n.getKind()) {
+		case OpApplKind: {
+			return generateNewOpApplNode((OpApplNode) n, prefix);
+		}
+
+		case NumeralKind: {
+			NumeralNode num = (NumeralNode) n;
+			return new NumeralNode(num.toString(), n.getTreeNode());
+		}
+
+		case StringKind: {
+			StringNode str = (StringNode) n;
+			return new StringNode(str.getTreeNode(), true);
+		}
+
+		case SubstInKind: {
+			SubstInNode substInNode = (SubstInNode) n;
+
+			Subst[] subs = substInNode.getSubsts();
+			for (int i = 0; i < subs.length; i++) {
+				OpDeclNode op = subs[i].getOp();
+				op.setToolObject(substitutionId, subs[i].getExpr());
+			}
+			return generateNewExprNode(substInNode.getBody(), prefix);
+		}
+		case AtNodeKind: { // @
+			AtNode old = (AtNode) n;
+			OpApplNode oldExcept = old.getExceptRef();
+			OpApplNode newExcept = (OpApplNode) oldExcept
+					.getToolObject(substitutionId);
+			OpApplNode oldComponent = old.getExceptComponentRef();
+			OpApplNode newComponent = (OpApplNode) oldComponent
+					.getToolObject(substitutionId);
+			return new AtNode(newExcept, newComponent);
+		}
+
+		case LetInKind: {
+			LetInNode oldLetNode = (LetInNode) n;
+			OpDefNode[] newLets = new OpDefNode[oldLetNode.getLets().length];
+			Context cc = oldLetNode.context;
+			for (int i = 0; i < oldLetNode.getLets().length; i++) {
+				OpDefNode let = oldLetNode.getLets()[i];
+				UniqueString newName = UniqueString.uniqueStringOf(prefix
+						+ let.getName().toString());
+				OpDefNode newLet = new OpDefNode(newName, let.getKind(),
+						generateNewParams(let.getParams()), let.isLocal(),
+						generateNewExprNode(let.getBody(), prefix),
+						let.getOriginallyDefinedInModuleNode(), null,
+						let.getTreeNode(), true, let.getSource());
+				let.setToolObject(substitutionId, newLet);
+				newLets[i] = newLet;
+				cc.addSymbolToContext(newName, newLet);
+			}
+
+			LetInNode newLetNode = new LetInNode(oldLetNode.getTreeNode(),
+					newLets, null, generateNewExprNode(oldLetNode.getBody(),
+							prefix), cc);
+			return newLetNode;
+		}
+
+		}
+		throw new RuntimeException();
+	}
+
+	/**
+	 * @param n
+	 * @param prefix
+	 * @return
+	 * @throws AbortException
+	 */
+	private ExprNode generateNewOpApplNode(OpApplNode n, String prefix)
+			throws AbortException {
+		switch (n.getOperator().getKind()) {
+		case VariableDeclKind:
+		case ConstantDeclKind: {
+			ExprOrOpArgNode e = (ExprOrOpArgNode) n.getOperator()
+					.getToolObject(substitutionId);
+			if (e != null) {
+				if (e instanceof ExprNode) {
+					// TODO newprefix, witout last prefix
+					return generateNewExprNode((ExprNode) e, "");
+				} else {
+					OpArgNode opArg = (OpArgNode) e;
+					while (opArg.getOp().getToolObject(substitutionId) != null) {
+						opArg = (OpArgNode) opArg.getOp().getToolObject(
+								substitutionId);
+					}
+					return new OpApplNode(opArg.getOp(), generateNewArgs(
+							n.getArgs(), prefix), n.getTreeNode(), null);
+				}
+			} else {
+				return new OpApplNode(n.getOperator(), generateNewArgs(
+						n.getArgs(), prefix), n.getTreeNode(), null);
+			}
+		}
+
+		case FormalParamKind: {
+			FormalParamNode f = (FormalParamNode) n.getOperator()
+					.getToolObject(substitutionId);
+			if (f == null) {
+				System.out.println(n.toString(4));
+				System.out.println(n);
+			}
+			return new OpApplNode(f, generateNewArgs(n.getArgs(), prefix),
+					n.getTreeNode(), null);
+		}
+
+		case BuiltInKind: {
+			return generateNewBuiltInNode(n, prefix);
+		}
+
+		case UserDefinedOpKind: {
+			// in case of a call of a LetInNode
+			OpDefNode letOp = (OpDefNode) n.getOperator().getToolObject(
+					substitutionId);
+			if (letOp != null) {
+				return new OpApplNode(letOp, generateNewArgs(n.getArgs(),
+						prefix), n.getTreeNode(), null);
+			}
+
+			// in case of a call of BBuiltInOp e.g. +, -
+			if (BBuiltInOPs.contains(n.getOperator().getName())) {
+				return new OpApplNode(n.getOperator(), generateNewArgs(
+						n.getArgs(), prefix), n.stn, null);
+			}
+
+			// normal userdefined Operator
+			String opName = prefix + n.getOperator().getName().toString();
+			OpDefNode op = defsHash.get(opName);
+			return new OpApplNode(op, generateNewArgs(n.getArgs(), prefix),
+					n.getTreeNode(), null);
+		}
+		}
+		throw new RuntimeException("OpApplkind not implemented jet");
+	}
+
+	/**
+	 * @param n
+	 * @param prefix
+	 * @return
+	 * @throws AbortException
+	 */
+	private ExprNode generateNewBuiltInNode(OpApplNode n, String prefix)
+			throws AbortException {
+		switch (getOpCode(n.getOperator().getName())) {
+
+		case OPCODE_exc: { // Except
+			OpApplNode newNode = new OpApplNode(n.getOperator().getName(),
+					null, n.getTreeNode(), null);
+			n.setToolObject(substitutionId, newNode); // needed for @ node
+			ExprOrOpArgNode[] newArgs = new ExprOrOpArgNode[n.getArgs().length];
+			newArgs[0] = generateNewExprOrOpArgNode(n.getArgs()[0], prefix);
+
+			for (int i = 1; i < n.getArgs().length; i++) {
+				OpApplNode pair = (OpApplNode) n.getArgs()[i];
+				OpApplNode newPair = new OpApplNode(pair.getOperator()
+						.getName(), null, pair.getTreeNode(), null);
+				// needed for @ node: we have to set a reference from the old
+				// pair to the new pair
+				// before evaluation the arguments which may be contains a @
+				// node
+				pair.setToolObject(substitutionId, newPair);
+				newPair.setArgs(generateNewArgs(pair.getArgs(), prefix));
+				newArgs[i] = newPair;
+			}
+			newNode.setArgs(newArgs);
+			return newNode;
+
+		}
+		case OPCODE_uc: { // CHOOSE x : P
+			FormalParamNode[] oldSymbols = n.getUnbdedQuantSymbols();
+			FormalParamNode[] newSymbols = new FormalParamNode[oldSymbols.length];
+			for (int i = 0; i < n.getUnbdedQuantSymbols().length; i++) {
+				FormalParamNode f = oldSymbols[i];
+				newSymbols[i] = new FormalParamNode(f.getName(), f.getArity(),
+						f.getTreeNode(), null, null);
+				f.setToolObject(substitutionId, newSymbols[i]);
+			}
+			OpApplNode newNode = new OpApplNode(n.getOperator().getName(),
+					newSymbols, generateNewArgs(n.getArgs(), prefix), null,
+					null, null, n.getTreeNode(), null);
+			return newNode;
+		}
+
+		case OPCODE_rfs:
+		case OPCODE_nrfs:
+		case OPCODE_fc: // Represents [x \in S |-> e]
+		case OPCODE_be: // \E x \in S : P
+		case OPCODE_bf: // \A x \in S : P
+		case OPCODE_bc: // CHOOSE x \in S: P
+		case OPCODE_sso: // $SubsetOf Represents {x \in S : P}
+		case OPCODE_soa: // $SetOfAll Represents {e : p1 \in S, p2,p3 \in S2}
+		{
+			// new formalparamnodes
+			FormalParamNode[][] oldParams = n.getBdedQuantSymbolLists();
+			FormalParamNode[][] newParams = new FormalParamNode[oldParams.length][0];
+			for (int i = 0; i < oldParams.length; i++) {
+				FormalParamNode[] temp = new FormalParamNode[oldParams[i].length];
+				for (int j = 0; j < oldParams[i].length; j++) {
+					FormalParamNode f = oldParams[i][j];
+					temp[j] = new FormalParamNode(f.getName(), f.getArity(),
+							f.getTreeNode(), null, null);
+					// set reference the old param to the new
+					f.setToolObject(substitutionId, temp[j]);
+				}
+				newParams[i] = temp;
+			}
+
+			// new ranges
+			ExprNode[] ranges = new ExprNode[n.getBdedQuantBounds().length];
+			for (int i = 0; i < n.getBdedQuantBounds().length; i++) {
+				ranges[i] = generateNewExprNode(n.getBdedQuantBounds()[i],
+						prefix);
+			}
+			OpApplNode newNode = new OpApplNode(n.getOperator().getName(),
+					null, generateNewArgs(n.getArgs(), prefix), newParams,
+					n.isBdedQuantATuple(), ranges, n.getTreeNode(), null);
+			return newNode;
+		}
+
+		default: { // =
+			OpApplNode newNode = new OpApplNode(n.getOperator(),
+					generateNewArgs(n.getArgs(), prefix), n.getTreeNode(), null);
+			return newNode;
+		}
+		}
+	}
+
+	/**
+	 * @param args
+	 * @param prefix
+	 * @return
+	 * @throws AbortException
+	 */
+	private ExprOrOpArgNode[] generateNewArgs(ExprOrOpArgNode[] args,
+			String prefix) throws AbortException {
+		ExprOrOpArgNode[] res = new ExprOrOpArgNode[args.length];
+		for (int i = 0; i < args.length; i++) {
+			res[i] = generateNewExprOrOpArgNode(args[i], prefix);
+		}
+		return res;
+	}
+
+	/**
+	 * @param oldParams
+	 * @return
+	 */
+	private FormalParamNode[] generateNewParams(FormalParamNode[] oldParams) {
+		FormalParamNode[] newParams = new FormalParamNode[oldParams.length];
+		for (int i = 0; i < oldParams.length; i++) {
+			FormalParamNode oldParam = oldParams[i];
+			FormalParamNode newParam = new FormalParamNode(oldParam.getName(),
+					oldParam.getArity(), oldParam.getTreeNode(), null, null);
+			// set reference to the old param to the new
+			oldParam.setToolObject(substitutionId, newParam);
+			newParams[i] = newParam;
+		}
+		return newParams;
+	}
+
+}
diff --git a/src/main/java/de/tla2b/analysis/RecursiveFunktion.java b/src/main/java/de/tla2b/analysis/RecursiveFunktion.java
new file mode 100644
index 0000000000000000000000000000000000000000..cfae0ae2d934da527e6a165463f70628fcc6cc6f
--- /dev/null
+++ b/src/main/java/de/tla2b/analysis/RecursiveFunktion.java
@@ -0,0 +1,60 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.analysis;
+
+import de.tla2b.exceptions.NotImplementedException;
+import tla2sany.semantic.ExprOrOpArgNode;
+import tla2sany.semantic.OpApplNode;
+import tla2sany.semantic.OpDefNode;
+import tlc2.tool.BuiltInOPs;
+
+public class RecursiveFunktion extends BuiltInOPs{
+
+	private OpDefNode def;
+	private OpApplNode rfs;
+	private OpApplNode ifThenElse;
+
+	public RecursiveFunktion(OpDefNode n, OpApplNode rfs) throws NotImplementedException {
+		def = n;
+		this.rfs = rfs;
+		evalDef();
+	}
+
+	/**
+	 * @throws NotImplementedException
+	 * 
+	 */
+	private void evalDef() throws NotImplementedException {
+		ExprOrOpArgNode e = rfs.getArgs()[0];
+
+		if (e instanceof OpApplNode) {
+			OpApplNode o = (OpApplNode) e;
+			switch (getOpCode(o.getOperator().getName()))
+			{
+			case OPCODE_ite:{ // IF THEN ELSE
+				ifThenElse = o;
+				return;
+			}
+			}
+			throw new NotImplementedException(
+					"Only IF/THEN/ELSE or CASE constructs are supported at the body of a recursive function.");
+		} else {
+			throw new NotImplementedException(
+					"Only IF/THEN/ELSE or CASE constructs are supported at the body of a recursive function.");
+		}
+	}
+	
+	public OpDefNode getOpDefNode(){
+		return def;
+	}
+	
+	public OpApplNode getRF(){
+		return rfs;
+	}
+	
+	public OpApplNode getIfThenElse(){
+		return ifThenElse;
+	}
+}
diff --git a/src/main/java/de/tla2b/analysis/SpecAnalyser.java b/src/main/java/de/tla2b/analysis/SpecAnalyser.java
new file mode 100644
index 0000000000000000000000000000000000000000..023c3c8764b0b9c2d65d778d9900f94d365a9c0f
--- /dev/null
+++ b/src/main/java/de/tla2b/analysis/SpecAnalyser.java
@@ -0,0 +1,601 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.analysis;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+
+import de.tla2b.config.ConfigfileEvaluator;
+import de.tla2b.exceptions.ConfigFileErrorException;
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.NotImplementedException;
+import de.tla2b.exceptions.SemanticErrorException;
+import de.tla2b.global.BBuiltInOPs;
+import de.tla2b.global.TranslationGlobals;
+import de.tla2b.types.IType;
+import de.tla2b.types.TLAType;
+
+
+
+
+import tla2sany.semantic.ASTConstants;
+import tla2sany.semantic.AssumeNode;
+import tla2sany.semantic.ExprNode;
+import tla2sany.semantic.ExprOrOpArgNode;
+import tla2sany.semantic.FormalParamNode;
+import tla2sany.semantic.LetInNode;
+import tla2sany.semantic.ModuleNode;
+import tla2sany.semantic.NumeralNode;
+import tla2sany.semantic.OpApplNode;
+import tla2sany.semantic.OpArgNode;
+import tla2sany.semantic.OpDeclNode;
+import tla2sany.semantic.OpDefNode;
+import tla2sany.semantic.SemanticNode;
+import tla2sany.semantic.StringNode;
+import tla2sany.semantic.SymbolNode;
+import tlc2.tool.BuiltInOPs;
+import tlc2.tool.ToolGlobals;
+
+public class SpecAnalyser extends BuiltInOPs implements ASTConstants,
+		ToolGlobals, IType, TranslationGlobals {
+	private OpDefNode spec;
+	private OpDefNode init;
+	private OpDefNode next;
+	private ArrayList<OpDefNode> invariants;
+
+	private ModuleNode moduleNode;
+	private ExprNode nextExpr;
+	private String nextName;
+	private ArrayList<OpDeclNode> bConstants;
+	// used to check if a b constant has arguments and is not overriden in the
+	// configfile
+
+	private ArrayList<BOperation> bOperations;
+	private ArrayList<ExprNode> inits;
+	private ArrayList<LetInNode> globalLets = new ArrayList<LetInNode>();
+	// these local definitions occur in assume nodes or in BOperations and will
+	// be added in the front part of the definitions clause of the resulting B
+	// Machine
+
+	private ArrayList<OpApplNode> ifThenElseNodes = new ArrayList<OpApplNode>();
+
+	private Set<OpDefNode> bDefinitionsSet = new HashSet<OpDefNode>();
+	// set of OpDefNodes which will appear in the resulting B Machine
+	private Set<OpDefNode> usedDefinitions = new HashSet<OpDefNode>();
+	// definitions which are used for the type inference algorithm
+	private Hashtable<OpDefNode, FormalParamNode[]> letParams = new Hashtable<OpDefNode, FormalParamNode[]>();
+	// additional parameters of an let Operator, these parameters are from the
+	// surrounding operator
+	private ArrayList<String> definitionMacros = new ArrayList<String>();
+
+	private ArrayList<RecursiveFunktion> recursiveFunctions = new ArrayList<RecursiveFunktion>();
+
+	/**
+	 * @param m
+	 * @param conEval
+	 */
+	public SpecAnalyser(ModuleNode m, ConfigfileEvaluator conEval) {
+		this.moduleNode = m;
+		this.spec = conEval.getSpecNode();
+		this.init = conEval.getInitNode();
+		this.next = conEval.getNextNode();
+		this.invariants = conEval.getInvariants();
+		this.bConstants = conEval.getbConstantList();
+	}
+
+	public SpecAnalyser(ModuleNode m) {
+		this.moduleNode = m;
+		Hashtable<String, OpDefNode> definitions = new Hashtable<String, OpDefNode>();
+		for (int i = 0; i < m.getOpDefs().length; i++) {
+			definitions.put(m.getOpDefs()[i].getName().toString(),
+					m.getOpDefs()[i]);
+		}
+		this.spec = definitions.get("Spec");
+		this.init = definitions.get("Init");
+		this.next = definitions.get("Next");
+
+		// TODO are constant in the right order
+		this.bConstants = new ArrayList<OpDeclNode>();
+		this.bConstants.addAll(Arrays.asList(m.getConstantDecls()));
+	}
+
+	public void start() throws SemanticErrorException, FrontEndException,
+			ConfigFileErrorException, NotImplementedException {
+		if (spec != null) {
+			evalSpec();
+		} else {
+			evalInit();
+			evalNext();
+		}
+		findOperations();
+
+		findDefinitions();
+		usedDefinitions.addAll(bDefinitionsSet);
+
+		// test whether there is a init predicate if there is a variable
+		if (moduleNode.getVariableDecls().length > 0 && inits == null) {
+			throw new SemanticErrorException("No initial predicate is defined.");
+		}
+
+		// check if there is B constant with arguments.
+		for (int i = 0; i < bConstants.size(); i++) {
+			OpDeclNode con = bConstants.get(i);
+			if (con.getArity() > 0) {
+				throw new ConfigFileErrorException(
+						String.format(
+								"Constant '%s' must be overriden in the configuration file.",
+								con.getName()));
+			}
+		}
+
+		evalRecursiveFunctions();
+	}
+
+	private void evalInit() {
+		if (init != null) {
+			inits = new ArrayList<ExprNode>();
+			inits = new ArrayList<ExprNode>();
+			inits.add(init.getBody());
+		}
+	}
+
+	private void evalNext() throws FrontEndException {
+		if (next != null) {
+			this.nextExpr = next.getBody();
+			this.nextName = next.getName().toString();
+		}
+	}
+
+	public void evalSpec() throws SemanticErrorException, FrontEndException {
+		if (spec != null) {
+			inits = new ArrayList<ExprNode>();
+			processConfigSpec(spec.getBody());
+		}
+
+	}
+
+	private void processConfigSpec(ExprNode exprNode)
+			throws SemanticErrorException, FrontEndException {
+
+		if (exprNode instanceof OpApplNode) {
+			OpApplNode opApp = (OpApplNode) exprNode;
+			ExprOrOpArgNode[] args = opApp.getArgs();
+			if (args.length == 0) {
+				SymbolNode opNode = opApp.getOperator();
+				if (opNode instanceof OpDefNode) {
+					OpDefNode def = (OpDefNode) opNode;
+					ExprNode body = def.getBody();
+					body.levelCheck(1);
+					if (body.getLevel() == 1) {
+						inits.add(exprNode);
+					} else {
+						processConfigSpec(body);
+					}
+					return;
+				}
+				throw new SemanticErrorException(
+						"Can not handle specification conjunction.");
+			}
+
+			int opcode = BuiltInOPs.getOpCode(opApp.getOperator().getName());
+			if (opcode == OPCODE_cl || opcode == OPCODE_land) {
+				for (int i = 0; i < args.length; i++) {
+					this.processConfigSpec((ExprNode) args[i]);
+				}
+				return;
+			}
+
+			if (opcode == OPCODE_box) {
+				SemanticNode boxArg = args[0];
+				if ((boxArg instanceof OpApplNode)
+						&& BuiltInOPs.getOpCode(((OpApplNode) boxArg)
+								.getOperator().getName()) == OPCODE_sa) {
+					ExprNode next = (ExprNode) ((OpApplNode) boxArg).getArgs()[0];
+					this.nextExpr = next;
+					this.nextName = "Next";
+					return;
+				}
+			}
+		}
+		if (exprNode.getLevel() <= 1) {
+			// init
+			inits.add(exprNode);
+		} else if (exprNode.getLevel() == 3) {
+			// temporal
+
+		} else {
+			throw new SemanticErrorException(
+					"Can not handle specification conjunction.");
+		}
+
+	}
+
+	/**
+	 * Searches for BOperations in a ExprNode. BOperations are seperated with
+	 * the aid of the disjunction (\/) operator.
+	 * 
+	 * @param exprNode
+	 * @param opName
+	 *            the name of the definition where exprNode occur
+	 * @throws FrontEndException
+	 * @throws ConfigFileErrorException
+	 */
+	private void findOperations() throws FrontEndException,
+			ConfigFileErrorException {
+		if (nextExpr == null)
+			return;
+		bOperations = new ArrayList<BOperation>();
+		ArrayList<OpApplNode> existQuans = new ArrayList<OpApplNode>();
+		findOperationsInSemanticNode(nextExpr, nextName, existQuans);
+	}
+
+	/**
+	 * 
+	 * @param node
+	 * @param opName
+	 * @param existQuans
+	 *            a list containing all existential quantifier which will be
+	 *            parameters in the resulting B Maschine
+	 * @throws FrontEndException
+	 * @throws ConfigFileErrorException
+	 */
+	private void findOperationsInSemanticNode(SemanticNode node, String opName,
+			ArrayList<OpApplNode> existQuans) throws FrontEndException,
+			ConfigFileErrorException {
+		switch (node.getKind()) {
+		case OpApplKind: {
+			findOperationsInOpApplNode((OpApplNode) node, opName, existQuans);
+			return;
+		}
+		case LetInKind: {
+			LetInNode letInNode = (LetInNode) node;
+			globalLets.add(letInNode);
+
+			findOperationsInSemanticNode(letInNode.getBody(), opName,
+					existQuans);
+			return;
+		}
+		case NumeralKind: {
+			int val = ((NumeralNode) node).val();
+			throw new FrontEndException(String.format(
+					"Expected an action at '%s'.\n%s", val, node.getLocation()
+							.toString()));
+		}
+
+		case StringKind: {
+			StringNode s = (StringNode) node;
+			throw new FrontEndException(String.format(
+					"Expected an action at '\"%s\"'.\n%s", s.getRep(), node
+							.getLocation().toString()));
+		}
+
+		default:
+			throw new FrontEndException(String.format(
+					"Expected an action.\n%s", node.getLocation().toString()));
+		}
+
+	}
+
+	private void findOperationsInOpApplNode(OpApplNode n, String name,
+			ArrayList<OpApplNode> existQuans) throws FrontEndException,
+			ConfigFileErrorException {
+		int kind = n.getOperator().getKind();
+		if (kind == UserDefinedOpKind
+				&& !BBuiltInOPs.contains(n.getOperator().getName())) {
+			OpDefNode def = (OpDefNode) n.getOperator();
+			usedDefinitions.add(def);
+			if (def.getParams().length > 0) {
+				BOperation op = new BOperation(def.getName().toString(), n,
+						existQuans);
+				bOperations.add(op);
+				return;
+			} else {
+				findOperationsInSemanticNode(def.getBody(), def.getName()
+						.toString(), existQuans);
+				return;
+			}
+
+		} else if (kind == BuiltInKind) {
+			int opcode = BuiltInOPs.getOpCode(n.getOperator().getName());
+			switch (opcode) {
+			case OPCODE_dl: // DisjList
+			{
+				if (n.getArgs().length == 1) {
+					findOperationsInSemanticNode(n.getArgs()[0], name,
+							existQuans);
+					return;
+				}
+				for (int i = 0; i < n.getArgs().length; i++) {
+					findOperationsInSemanticNode(n.getArgs()[i],
+							name + (i + 1), existQuans);
+				}
+				return;
+			}
+			case OPCODE_lor: {
+				for (int i = 0; i < n.getArgs().length; i++) {
+					findOperationsInSemanticNode(n.getArgs()[i],
+							name + (i + 1), existQuans);
+				}
+				return;
+			}
+			case OPCODE_be: { // BoundedExists
+				ArrayList<OpApplNode> clone = new ArrayList<OpApplNode>(
+						existQuans);
+				clone.add(n);
+				findOperationsInSemanticNode(n.getArgs()[0], name, clone);
+				return;
+			}
+
+			case OPCODE_unchanged:
+			case OPCODE_eq: // =
+			case OPCODE_noteq: // /=, #
+			case OPCODE_neg: // Negation
+			case OPCODE_lnot: // Negation
+			case OPCODE_cl: // $ConjList
+			case OPCODE_land: // \land
+			case OPCODE_equiv: // \equiv
+			case OPCODE_implies: // =>
+			case OPCODE_bf: // \A x \in S : P
+			case OPCODE_in: // \in
+			case OPCODE_notin: // \notin
+			case OPCODE_subseteq: // \subseteq - subset or equal
+			case OPCODE_fa: // $FcnApply f[1]
+			case OPCODE_ite: // IF THEN ELSE
+			case OPCODE_case: {
+				BOperation op = new BOperation(name, n, existQuans);
+				bOperations.add(op);
+				return;
+			}
+			}
+		}
+		throw new FrontEndException(String.format(
+				"Expected an action at '%s' :\n%s", n.getOperator().getName()
+						.toString(), n.getLocation().toString()));
+
+	}
+
+	/**
+	 * 
+	 * @throws ConfigFileErrorException
+	 */
+
+	private void findDefinitions() throws ConfigFileErrorException {
+		AssumeNode[] assumes = moduleNode.getAssumptions();
+		for (int i = 0; i < assumes.length; i++) {
+			visitExprNode(assumes[i].getAssume(), null);
+		}
+
+		if (inits != null) {
+			for (int i = 0; i < inits.size(); i++) {
+				visitExprNode(inits.get(i), null);
+			}
+		}
+		if (bOperations != null) {
+			for (int i = 0; i < bOperations.size(); i++) {
+				visitExprNode(bOperations.get(i).getNode(), null);
+			}
+		}
+
+		if (invariants != null) {
+			for (int i = 0; i < invariants.size(); i++) {
+				OpDefNode def = invariants.get(i);
+				bDefinitionsSet.add(def);
+				visitExprNode(def.getBody(), null);
+			}
+		}
+
+		for (int i = 0; i < globalLets.size(); i++) {
+			LetInNode letInNode = globalLets.get(i);
+			for (int j = 0; j < letInNode.getLets().length; j++) {
+				visitExprNode(letInNode.getLets()[j].getBody(), null);
+			}
+		}
+
+	}
+
+	/**
+	 * @param exprOrOpArgNode
+	 */
+	private void visitExprOrOpArgNode(ExprOrOpArgNode n,
+			FormalParamNode[] parameters) {
+		if (n instanceof ExprNode) {
+			visitExprNode((ExprNode) n, parameters);
+		} else if (n instanceof OpArgNode) {
+
+		}
+	}
+
+	private void visitExprNode(ExprNode node, FormalParamNode[] parameters) {
+		switch (node.getKind()) {
+		case OpApplKind: {
+			visitOpApplNode((OpApplNode) node, parameters);
+			return;
+		}
+		case LetInKind: {
+			LetInNode l = (LetInNode) node;
+			for (int i = 0; i < l.getLets().length; i++) {
+				OpDefNode letDef = l.getLets()[i];
+
+				if (parameters != null)
+					letParams.put(letDef, parameters);
+
+				visitExprNode(letDef.getBody(), letDef.getParams());
+			}
+			visitExprNode(l.getBody(), parameters);
+			return;
+		}
+
+		}
+	}
+
+	/**
+	 * @param node
+	 * @throws ConfigFileErrorException
+	 */
+	private void visitOpApplNode(OpApplNode node, FormalParamNode[] parameters) {
+		switch (node.getOperator().getKind()) {
+		case ConstantDeclKind: {
+			for (int i = 0; i < node.getArgs().length; i++) {
+				visitExprOrOpArgNode(node.getArgs()[i], parameters);
+			}
+			return;
+		}
+
+		case VariableDeclKind: {
+			for (int i = 0; i < node.getArgs().length; i++) {
+				visitExprOrOpArgNode(node.getArgs()[i], parameters);
+			}
+			return;
+		}
+
+		case BuiltInKind: {
+			visitBuiltInKind(node, parameters);
+			return;
+		}
+
+		case UserDefinedOpKind: {
+			OpDefNode def = (OpDefNode) node.getOperator();
+			//TODO
+			ModuleNode moduleNode = def.getSource().getOriginallyDefinedInModuleNode();
+			if(moduleNode.getName().toString().equals("TLA2B")){
+				return;
+			}
+			if (BBuiltInOPs.contains(def.getName())
+					&& STANDARD_MODULES.contains(def.getSource()
+							.getOriginallyDefinedInModuleNode().getName()
+							.toString())) {
+				
+				for (int i = 0; i < node.getArgs().length; i++) {
+					visitExprOrOpArgNode(node.getArgs()[i], parameters);
+				}
+				return;
+			}
+			bDefinitionsSet.add(def);
+			visitExprNode(def.getBody(), def.getParams());
+
+			for (int i = 0; i < node.getArgs().length; i++) {
+				visitExprOrOpArgNode(node.getArgs()[i], parameters);
+			}
+			return;
+		}
+
+		}
+
+	}
+
+	/**
+	 * @param node
+	 */
+	private void visitBuiltInKind(OpApplNode node, FormalParamNode[] parameters) {
+		switch (BuiltInOPs.getOpCode(node.getOperator().getName())) {
+
+		case OPCODE_be:
+		case OPCODE_bf:
+		case OPCODE_soa:
+		case OPCODE_sso:
+		case OPCODE_nrfs:
+		case OPCODE_fc: {
+			ExprNode[] in = node.getBdedQuantBounds();
+			for (int i = 0; i < in.length; i++) {
+				visitExprNode(in[i], parameters);
+			}
+			break;
+		}
+		case OPCODE_ite: {
+			ifThenElseNodes.add(node);
+			// if(!definitionMacro.contains(IF_THEN_ELSE)){
+			// definitionMacro.add(IF_THEN_ELSE);
+			// }
+			break;
+		}
+
+		case OPCODE_bc: {
+			if (!definitionMacros.contains(CHOOSE)) {
+				definitionMacros.add(CHOOSE);
+			}
+			break;
+		}
+		case OPCODE_unchanged: {
+			return;
+		}
+		}
+		for (int i = 0; i < node.getArgs().length; i++) {
+			visitExprOrOpArgNode(node.getArgs()[i], parameters);
+		}
+	}
+
+	/**
+	 * @throws NotImplementedException
+	 * 
+	 */
+	private void evalRecursiveFunctions() throws NotImplementedException {
+
+		for (OpDefNode def : bDefinitionsSet) {
+			if (def.getBody() instanceof OpApplNode) {
+				OpApplNode o = (OpApplNode) def.getBody();
+				switch (getOpCode(o.getOperator().getName())) {
+				case OPCODE_rfs: { // recursive Function
+					bDefinitionsSet.remove(def);
+					ifThenElseNodes.remove(o.getArgs()[0]);
+					RecursiveFunktion rf = new RecursiveFunktion(def, o);
+					recursiveFunctions.add(rf);
+					return;
+				}
+				}
+			}
+		}
+	}
+
+	public void evalIfThenElse() {
+		boolean b = false;
+		for (int i = 0; i < ifThenElseNodes.size() && !b; i++) {
+			OpApplNode node = ifThenElseNodes.get(i);
+			TLAType t = (TLAType) node.getToolObject(TYPE_ID);
+			if (t.getKind() != BOOL)
+				b = true;
+		}
+		if (b)
+			definitionMacros.add(IF_THEN_ELSE);
+	}
+
+	public ArrayList<LetInNode> getGlobalLets() {
+		return this.globalLets;
+	}
+
+	public ArrayList<BOperation> getBOperations() {
+		return this.bOperations;
+	}
+
+	public ArrayList<ExprNode> getInits() {
+		return this.inits;
+	}
+
+	public ExprNode getNext() {
+		return this.nextExpr;
+	}
+
+	public Set<OpDefNode> getBDefinitions() {
+		return bDefinitionsSet;
+	}
+
+	public Hashtable<OpDefNode, FormalParamNode[]> getLetParams() {
+		return letParams;
+	}
+
+	public ArrayList<String> getDefinitionMacros() {
+		return definitionMacros;
+	}
+
+	public Set<OpDefNode> getUsedDefinitions() {
+		return usedDefinitions;
+	}
+
+	public ArrayList<RecursiveFunktion> getRecursiveFunctions() {
+		return recursiveFunctions;
+	}
+}
diff --git a/src/main/java/de/tla2b/analysis/SymbolRenamer.java b/src/main/java/de/tla2b/analysis/SymbolRenamer.java
new file mode 100644
index 0000000000000000000000000000000000000000..fed156c6418ec9a4e50fdfe34bbc8ac97c12b228
--- /dev/null
+++ b/src/main/java/de/tla2b/analysis/SymbolRenamer.java
@@ -0,0 +1,359 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.analysis;
+
+
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+
+import de.tla2b.global.BBuiltInOPs;
+import de.tla2b.global.TranslationGlobals;
+
+import tla2sany.semantic.ASTConstants;
+import tla2sany.semantic.AssumeNode;
+import tla2sany.semantic.FormalParamNode;
+import tla2sany.semantic.LetInNode;
+import tla2sany.semantic.ModuleNode;
+import tla2sany.semantic.OpApplNode;
+import tla2sany.semantic.OpDeclNode;
+import tla2sany.semantic.OpDefNode;
+import tla2sany.semantic.SemanticNode;
+import tlc2.tool.BuiltInOPs;
+
+public class SymbolRenamer extends BuiltInOPs implements TranslationGlobals,
+		ASTConstants {
+
+	private final static Set<String> KEYWORDS = new HashSet<String>();
+	static {
+		KEYWORDS.add("seq");
+		KEYWORDS.add("left");
+		KEYWORDS.add("right");
+		KEYWORDS.add("max");
+		KEYWORDS.add("min");
+		KEYWORDS.add("succ");
+		KEYWORDS.add("pred");
+		KEYWORDS.add("dom");
+		KEYWORDS.add("ran");
+		KEYWORDS.add("fnc");
+		KEYWORDS.add("rel");
+		KEYWORDS.add("id");
+		KEYWORDS.add("card");
+		KEYWORDS.add("POW");
+		KEYWORDS.add("POW1");
+		KEYWORDS.add("FIN");
+		KEYWORDS.add("FIN1");
+		KEYWORDS.add("size");
+		KEYWORDS.add("rev");
+		KEYWORDS.add("first");
+		KEYWORDS.add("last");
+		KEYWORDS.add("front");
+		KEYWORDS.add("tail");
+		KEYWORDS.add("conc");
+		KEYWORDS.add("struct");
+		KEYWORDS.add("rec");
+		KEYWORDS.add("tree");
+		KEYWORDS.add("btree");
+		KEYWORDS.add("skip");
+		KEYWORDS.add("ANY");
+		KEYWORDS.add("WHERE");
+		KEYWORDS.add("END");
+		KEYWORDS.add("BE");
+		KEYWORDS.add("VAR");
+		KEYWORDS.add("ASSERT");
+		KEYWORDS.add("CHOICE");
+		KEYWORDS.add("OR");
+		KEYWORDS.add("SELECT");
+		KEYWORDS.add("EITHER");
+		KEYWORDS.add("WHEN");
+		KEYWORDS.add("BEGIN");
+		KEYWORDS.add("MACHINE");
+		KEYWORDS.add("REFINEMENT");
+		KEYWORDS.add("IMPLEMENTATION");
+		KEYWORDS.add("SETS");
+		KEYWORDS.add("CONSTRAINTS");
+		KEYWORDS.add("MODEL");
+		KEYWORDS.add("SYSTEM");
+		KEYWORDS.add("MACHINE");
+		KEYWORDS.add("EVENTS");
+		KEYWORDS.add("OPERATIONS");
+	}
+
+	private final static Hashtable<String, String> INFIX_OPERATOR = new Hashtable<String, String>();
+	static {
+		INFIX_OPERATOR.put("!!", "exclamationmark2");
+		INFIX_OPERATOR.put("??", "questionmark2");
+		INFIX_OPERATOR.put("&", "ampersand1");
+		INFIX_OPERATOR.put("&&", "ampersand2");
+		INFIX_OPERATOR.put("@@", "at2");
+		INFIX_OPERATOR.put("++", "plus2");
+		INFIX_OPERATOR.put("--", "minus2");
+		INFIX_OPERATOR.put("^", "circumflex1");
+		INFIX_OPERATOR.put("^^", "circumflex2");
+		INFIX_OPERATOR.put("##", "hash2");
+		INFIX_OPERATOR.put("%%", "percent2");
+		INFIX_OPERATOR.put("$", "dollar1");
+		INFIX_OPERATOR.put("$$", "dollar2");
+		INFIX_OPERATOR.put("|", "pipe1");
+		INFIX_OPERATOR.put("||", "pipe2");
+		INFIX_OPERATOR.put("//", "slash2");
+		INFIX_OPERATOR.put("**", "mult2");
+		INFIX_OPERATOR.put("...", "dot3");
+	}
+
+	private final static Hashtable<String, String> BBUILTIN_OPERATOR = new Hashtable<String, String>();
+	static {
+		BBUILTIN_OPERATOR.put("+", "plus");
+		BBUILTIN_OPERATOR.put("-", "minus");
+		BBUILTIN_OPERATOR.put("*", "mult");
+		BBUILTIN_OPERATOR.put("^", "power");
+		BBUILTIN_OPERATOR.put("<", "lt");
+		BBUILTIN_OPERATOR.put(">", "gt");
+		BBUILTIN_OPERATOR.put("\\leq", "leq");
+		BBUILTIN_OPERATOR.put("\\geq", "geq");
+		BBUILTIN_OPERATOR.put("%", "modulo");
+		BBUILTIN_OPERATOR.put("\\div", "div");
+		BBUILTIN_OPERATOR.put("..", "dot2");
+	}
+
+	private ModuleNode moduleNode;
+	private Set<OpDefNode> usedDefinitions;
+
+	private Set<String> globalNames = new HashSet<String>();
+	private Hashtable<OpDefNode, Set<String>> usedNamesTable = new Hashtable<OpDefNode, Set<String>>();
+
+	/**
+	 * @param moduleNode2
+	 * @param specAnalyser
+	 */
+	public SymbolRenamer(ModuleNode moduleNode, SpecAnalyser specAnalyser) {
+		this.moduleNode = moduleNode;
+		this.usedDefinitions = specAnalyser.getUsedDefinitions();
+	}
+
+	public SymbolRenamer(ModuleNode moduleNode) {
+		this.moduleNode = moduleNode;
+		usedDefinitions = new HashSet<OpDefNode>();
+		OpDefNode[] defs = moduleNode.getOpDefs();
+		usedDefinitions.add(defs[defs.length - 1]);
+	}
+
+	public void start() {
+		// Variables
+		for (int i = 0; i < moduleNode.getVariableDecls().length; i++) {
+			OpDeclNode v = moduleNode.getVariableDecls()[i];
+			String newName = incName(v.getName().toString());
+			globalNames.add(newName);
+			v.setToolObject(NEW_NAME, newName);
+		}
+
+		// constants
+		for (int i = 0; i < moduleNode.getConstantDecls().length; i++) {
+			OpDeclNode c = moduleNode.getConstantDecls()[i];
+			String newName = incName(c.getName().toString());
+			globalNames.add(newName);
+			c.setToolObject(NEW_NAME, newName);
+		}
+
+		for (int i = 0; i < moduleNode.getOpDefs().length; i++) {
+			OpDefNode def = moduleNode.getOpDefs()[i];
+			String newName = getOperatorName(def);
+			globalNames.add(newName);
+			def.setToolObject(NEW_NAME, newName);
+			usedNamesTable.put(def, new HashSet<String>());
+		}
+
+		for (int i = 0; i < moduleNode.getAssumptions().length; i++) {
+			AssumeNode assumeNode = moduleNode.getAssumptions()[i];
+			visitNode(assumeNode.getAssume(), new HashSet<String>());
+		}
+
+		for (int i = moduleNode.getOpDefs().length - 1; i >= 0; i--) {
+			OpDefNode def = moduleNode.getOpDefs()[i];
+			Set<String> usedNames = usedNamesTable.get(def);
+			for (int j = 0; j < def.getParams().length; j++) {
+				FormalParamNode p = def.getParams()[j];
+				String paramName = p.getName().toString();
+				String newParamName = incName(paramName);
+				p.setToolObject(NEW_NAME, newParamName);
+				//Parameter of different definitions calling each other can have the same name
+				//usedNames.add(newParamName);
+			}
+			visitNode(def.getBody(), usedNames);
+		}
+
+	}
+
+	private void visitNode(SemanticNode n, Set<String> usedNames) {
+		// System.out.println(n.toString(1)+ " "+ n.getKind());
+
+		switch (n.getKind()) {
+
+		case LetInKind: {
+			LetInNode letInNode = (LetInNode) n;
+			OpDefNode[] defs = letInNode.getLets();
+
+			// Initialize all local definitions (get a new name, get an empty
+			// list)
+			for (int i = 0; i < defs.length; i++) {
+				OpDefNode def = defs[i];
+				String newName = getOperatorName(def);
+				globalNames.add(newName);
+				def.setToolObject(NEW_NAME, newName);
+				usedNamesTable.put(def, new HashSet<String>(usedNames));
+			}
+
+			// first visit the IN expression
+			visitNode(letInNode.getBody(), usedNames);
+
+			// visit the definition itself
+			for (int i = defs.length - 1; i >= 0; i--) {
+				OpDefNode def = defs[i];
+				Set<String> usedNamesOfDef = usedNamesTable.get(def);
+				for (int j = 0; j < def.getParams().length; j++) {
+					FormalParamNode p = def.getParams()[j];
+					String paramName = p.getName().toString();
+					String newParamName = incName(paramName);
+					p.setToolObject(NEW_NAME, newParamName);
+					//usedNamesOfDef.add(newParamName);
+				}
+				visitNode(def.getBody(), usedNamesOfDef);
+			}
+			return;
+		}
+
+		case OpApplKind: {
+			OpApplNode opApplNode = (OpApplNode) n;
+			switch (opApplNode.getOperator().getKind()) {
+
+			case BuiltInKind: {
+				visitBuiltinNode(opApplNode, usedNames);
+				return;
+			}
+
+			case UserDefinedOpKind: {
+				OpDefNode def = (OpDefNode) opApplNode.getOperator();
+				if (BBuiltInOPs.contains(def.getName())) {
+					break;
+				}
+
+				usedNamesTable.get(def).addAll(usedNames);
+				for (int i = 0; i < n.getChildren().length; i++) {
+					visitNode(opApplNode.getArgs()[i], usedNames);
+				}
+				return;
+			}
+			}
+
+			for (int i = 0; i < opApplNode.getArgs().length; i++) {
+				visitNode(opApplNode.getArgs()[i], usedNames);
+			}
+			return;
+		}
+		}
+
+		if (n.getChildren() != null) {
+			for (int i = 0; i < n.getChildren().length; i++) {
+				visitNode(n.getChildren()[i], usedNames);
+			}
+		}
+	}
+
+	private void visitBuiltinNode(OpApplNode opApplNode, Set<String> usedNames) {
+
+		switch (getOpCode(opApplNode.getOperator().getName())) {
+
+		case OPCODE_nrfs:
+		case OPCODE_fc: // Represents [x \in S |-> e]
+		case OPCODE_bc: // CHOOSE x \in S: P
+		case OPCODE_soa: // $SetOfAll Represents {e : p1 \in S, p2,p3 \in S2}
+		case OPCODE_sso: // $SubsetOf Represents {x \in S : P}
+		case OPCODE_bf: // \A x \in S : P
+		case OPCODE_be: // \E x \in S : P
+		{
+			FormalParamNode[][] params = opApplNode.getBdedQuantSymbolLists();
+			Set<String> newUsedNames = new HashSet<String>(usedNames);
+			for (int i = 0; i < params.length; i++) {
+				for (int j = 0; j < params[i].length; j++) {
+					FormalParamNode param = params[i][j];
+					String paramName = param.getName().toString();
+					String newName = incName(paramName, usedNames);
+					param.setToolObject(NEW_NAME, newName);
+					newUsedNames.add(newName);
+				}
+			}
+			for (int i = 0; i < opApplNode.getBdedQuantBounds().length; i++) {
+				visitNode(opApplNode.getBdedQuantBounds()[i], usedNames);
+			}
+
+			visitNode(opApplNode.getArgs()[0], newUsedNames);
+
+			return;
+		}
+
+		default:
+			for (int i = 0; i < opApplNode.getArgs().length; i++) {
+				if (opApplNode.getArgs()[i] != null) {
+					visitNode(opApplNode.getArgs()[i], usedNames);
+				}
+			}
+
+		}
+	}
+
+	private String getOperatorName(OpDefNode def) {
+		String newName = def.getName().toString();
+
+		if (BBUILTIN_OPERATOR.containsKey(newName)) {
+			// a B built-in operator is defined outside of a standard module
+			if (!STANDARD_MODULES.contains(def.getSource()
+					.getOriginallyDefinedInModuleNode().getName().toString())) {
+				return incName(BBUILTIN_OPERATOR.get(newName));
+			}
+		}
+
+		// replace invalid infix operator names
+		for (String e : INFIX_OPERATOR.keySet()) {
+			if (newName.contains(e)) {
+				newName = newName.replace(e, INFIX_OPERATOR.get(e));
+			}
+		}
+
+		// replace exclamation marks
+		if (newName.contains("!")) {
+			newName = newName.replace('!', '_');
+		}
+
+		// replace slashes
+		if (newName.contains("\\")) {
+			newName = newName.replace("\\", "");
+		}
+
+		return incName(newName);
+	}
+
+	private Boolean existingName(String name) {
+		if (globalNames.contains(name) || KEYWORDS.contains(name)) {
+			return true;
+		} else
+			return false;
+	}
+
+	private String incName(String name) {
+		String res = name;
+		for (int i = 1; existingName(res); i++) {
+			res = name + "_" + i;
+		}
+		return res;
+	}
+
+	private String incName(String name, Set<String> tempSet) {
+		String res = name;
+		for (int i = 1; existingName(res) || tempSet.contains(res); i++) {
+			res = name + "_" + i;
+		}
+		return res;
+	}
+}
diff --git a/src/main/java/de/tla2b/analysis/SymbolSorter.java b/src/main/java/de/tla2b/analysis/SymbolSorter.java
new file mode 100644
index 0000000000000000000000000000000000000000..514837f1c390fee44d28a134fe04d0746b926da9
--- /dev/null
+++ b/src/main/java/de/tla2b/analysis/SymbolSorter.java
@@ -0,0 +1,83 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.analysis;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Hashtable;
+
+import tla2sany.semantic.ModuleNode;
+import tla2sany.semantic.OpDeclNode;
+import tla2sany.semantic.OpDefNode;
+
+public class SymbolSorter {
+	private ModuleNode moduleNode;
+
+	public SymbolSorter(ModuleNode moduleNode) {
+		this.moduleNode = moduleNode;
+	}
+
+	public void sort() {
+		// sort constants
+		Arrays.sort(moduleNode.getConstantDecls(), new OpDeclNodeComparator());
+		// sort variables
+		Arrays.sort(moduleNode.getVariableDecls(), new OpDeclNodeComparator());
+		// sort definitions
+		Arrays.sort(moduleNode.getOpDefs(), new OpDefNodeComparator());
+	}
+	
+	public static void sortDeclNodes(OpDeclNode[] opDeclNodes){
+		Arrays.sort(opDeclNodes, new OpDeclNodeComparator());
+	}
+	
+	public static void sortOpDefNodes(OpDefNode[] opDefNodes){
+		Arrays.sort(opDefNodes, new OpDefNodeComparator());
+	}
+
+	public static  Hashtable<String, OpDefNode> getDefsHashTable(OpDefNode[] opDefNodes){
+		 Hashtable<String, OpDefNode> definitions = new Hashtable<String, OpDefNode>();
+		for (int i = 0; i < opDefNodes.length; i++) {
+			OpDefNode def = opDefNodes[i];
+			// Definition in this module
+//			if (StandardModules.contains(def.getOriginallyDefinedInModuleNode()
+//					.getName().toString())
+//					|| StandardModules.contains(def.getSource()
+//							.getOriginallyDefinedInModuleNode().getName()
+//							.toString())) {
+//				continue;
+//			}
+			definitions.put(def.getName().toString(), def);
+		}
+		return definitions;
+	}
+	
+}
+
+class OpDeclNodeComparator implements Comparator<OpDeclNode> {
+	public int compare(OpDeclNode a, OpDeclNode b) {
+		if (a.getUid() < b.getUid())
+			return -1;
+		if (a.getUid() > b.getUid())
+			return 1;
+		return 0;
+	}
+}
+
+class OpDefNodeComparator implements Comparator<OpDefNode> {
+	public int compare(OpDefNode a, OpDefNode b) {
+		if (a.getLocation().equals(b.getLocation())) {
+			if (a.getSource().getUid() < b.getSource().getUid())
+				return -1;
+			if (a.getSource().getUid() > b.getSource().getUid())
+				return 1;
+			return 0;
+		}
+		if (a.getUid() < b.getUid())
+			return -1;
+		if (a.getUid() > b.getUid())
+			return 1;
+		return 0;
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/tla2b/analysis/TypeChecker.java b/src/main/java/de/tla2b/analysis/TypeChecker.java
new file mode 100644
index 0000000000000000000000000000000000000000..604118c9573427cd31ff5dc9c9931f2a2cbfa499
--- /dev/null
+++ b/src/main/java/de/tla2b/analysis/TypeChecker.java
@@ -0,0 +1,1572 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.analysis;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.Set;
+
+import de.tla2b.config.ConfigfileEvaluator;
+import de.tla2b.config.TLCValueNode;
+import de.tla2b.config.ValueObj;
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.NotImplementedException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.exceptions.UnificationException;
+import de.tla2b.global.BBuildIns;
+import de.tla2b.global.BBuiltInOPs;
+import de.tla2b.global.TranslationGlobals;
+import de.tla2b.types.*;
+
+import tla2sany.semantic.ASTConstants;
+import tla2sany.semantic.AssumeNode;
+import tla2sany.semantic.AtNode;
+import tla2sany.semantic.ExprNode;
+import tla2sany.semantic.ExprOrOpArgNode;
+import tla2sany.semantic.FormalParamNode;
+import tla2sany.semantic.LetInNode;
+import tla2sany.semantic.ModuleNode;
+import tla2sany.semantic.NumeralNode;
+import tla2sany.semantic.OpApplNode;
+import tla2sany.semantic.OpDeclNode;
+import tla2sany.semantic.OpDefNode;
+import tla2sany.semantic.StringNode;
+import tla2sany.semantic.SymbolNode;
+import tlc2.tool.BuiltInOPs;
+
+public class TypeChecker extends BuiltInOPs implements IType, ASTConstants,
+		BBuildIns, TranslationGlobals {
+
+	private final int TEMP_TYPE_ID = 6;
+	private int paramId;
+
+	private ArrayList<ExprNode> inits;
+	private ExprNode nextExpr;
+	private Set<OpDefNode> usedDefinitions;
+
+	private ArrayList<OpApplNode> recList = new ArrayList<OpApplNode>();
+	// every record node [a |-> 1 .. ] will be added to this List
+	private ModuleNode moduleNode;
+	private ArrayList<OpDeclNode> bConstList;
+
+	private Hashtable<OpDeclNode, ValueObj> constantAssignments;
+
+	/**
+	 * @param moduleNode2
+	 * @param conEval
+	 * @param specAnalyser
+	 */
+	public TypeChecker(ModuleNode moduleNode, ConfigfileEvaluator conEval,
+			SpecAnalyser specAnalyser) {
+		this.moduleNode = moduleNode;
+		if (conEval != null) {
+			this.bConstList = conEval.getbConstantList();
+			this.constantAssignments = conEval.getConstantAssignments();
+		}
+		this.inits = specAnalyser.getInits();
+		this.nextExpr = specAnalyser.getNext();
+		usedDefinitions = specAnalyser.getUsedDefinitions();
+
+		paramId = TYPE_ID;
+	}
+
+	public TypeChecker(ModuleNode moduleNode) {
+		this.moduleNode = moduleNode;
+
+		Set<OpDefNode> usedDefinitions = new HashSet<OpDefNode>();
+		OpDefNode[] defs = moduleNode.getOpDefs();
+		// used the last definition of the module
+		usedDefinitions.add(defs[defs.length - 1]);
+		this.usedDefinitions = usedDefinitions;
+
+		paramId = TYPE_ID;
+	}
+
+	public void start() throws TLA2BException {
+		OpDeclNode[] cons = moduleNode.getConstantDecls();
+		for (int i = 0; i < cons.length; i++) {
+			OpDeclNode con = cons[i];
+			if (constantAssignments != null
+					&& constantAssignments.containsKey(con)) {
+				TLAType t = constantAssignments.get(con).getType();
+				con.setToolObject(TYPE_ID, t);
+			} else {
+				Untyped u = new Untyped();
+				con.setToolObject(TYPE_ID, u);
+				u.addFollower(con);
+			}
+		}
+
+		OpDeclNode[] vars = moduleNode.getVariableDecls();
+		for (int i = 0; i < vars.length; i++) {
+			OpDeclNode var = vars[i];
+			Untyped u = new Untyped();
+			var.setToolObject(TYPE_ID, u);
+			u.addFollower(var);
+		}
+
+		evalDefinitions(moduleNode.getOpDefs());
+		evalAssumptions(moduleNode.getAssumptions());
+
+		if (inits != null) {
+			for (int i = 0; i < inits.size(); i++) {
+				visitExprNode(inits.get(i), BoolType.getInstance());
+			}
+		}
+
+		if (nextExpr != null) {
+			visitExprNode(nextExpr, BoolType.getInstance());
+		}
+
+		// check if a variable has no type
+		for (int i = 0; i < vars.length; i++) {
+			OpDeclNode var = vars[i];
+			TLAType varType = (TLAType) var.getToolObject(TYPE_ID);
+			if (varType.isUntyped()) {
+				throw new TypeErrorException("Variable '" + var.getName()
+						+ "' has no cype!");
+			}
+		}
+
+		// check if a constant has no type, only constants which will appear in
+		// the resulting B Machine are considered
+		for (int i = 0; i < cons.length; i++) {
+			OpDeclNode con = cons[i];
+			if (bConstList == null || bConstList.contains(con)) {
+				TLAType conType = (TLAType) con.getToolObject(TYPE_ID);
+				if (conType.isUntyped()) {
+					throw new TypeErrorException("The type of constant "
+							+ con.getName() + " is still untyped: " + conType);
+				}
+			}
+		}
+
+		evalRecList();
+	}
+
+	/**
+	 * 
+	 */
+	private void evalRecList() {
+		for (int i = 0; i < recList.size(); i++) {
+			OpApplNode n = recList.get(i);
+			StructType struct = (StructType) n.getToolObject(TYPE_ID);
+			ArrayList<String> fieldNames = new ArrayList<String>();
+			ExprOrOpArgNode[] args = n.getArgs();
+			for (int j = 0; j < args.length; j++) {
+				OpApplNode pair = (OpApplNode) args[j];
+				StringNode stringNode = (StringNode) pair.getArgs()[0];
+				fieldNames.add(stringNode.getRep().toString());
+			}
+			for (int j = 0; j < struct.getFields().size(); j++) {
+				String fieldName = struct.getFields().get(j);
+				if (!fieldNames.contains(fieldName)
+						&& struct.getType(fieldName).getKind() == MODELVALUE) {
+					EnumType e = (EnumType) struct.getType(fieldName);
+					e.setNoVal();
+				}
+			}
+		}
+
+	}
+
+	private void evalDefinitions(OpDefNode[] opDefs) throws TLA2BException {
+		for (int i = 0; i < opDefs.length; i++) {
+			OpDefNode def = opDefs[i];
+			// Definition in this module
+			String moduleName1 = def.getOriginallyDefinedInModuleNode()
+					.getName().toString();
+			String moduleName2 = def.getSource()
+					.getOriginallyDefinedInModuleNode().getName().toString();
+
+			if (STANDARD_MODULES.contains(moduleName1)
+					|| STANDARD_MODULES.contains(moduleName2)) {
+				continue;
+			}
+			if (usedDefinitions.contains(def))
+				visitOpDefNode(def);
+
+		}
+
+	}
+
+	/**
+	 * @param def
+	 * @throws TLA2BException
+	 */
+	private void visitOpDefNode(OpDefNode def) throws TLA2BException {
+		FormalParamNode[] params = def.getParams();
+		for (int i = 0; i < params.length; i++) {
+			FormalParamNode p = params[i];
+			if (p.getArity() > 0) {
+				throw new FrontEndException(String.format(
+						"TLA2B do not support 2nd-order operators: '%s'\n %s ",
+						def.getName(), def.getLocation()));
+			}
+			Untyped u = new Untyped();
+			p.setToolObject(paramId, u);
+			u.addFollower(p);
+		}
+		TLAType defType = visitExprNode(def.getBody(), new Untyped());
+		def.setToolObject(TYPE_ID, defType);
+		if (defType instanceof AbstractHasFollowers) {
+			((AbstractHasFollowers) defType).addFollower(def);
+		}
+
+	}
+
+	private void evalAssumptions(AssumeNode[] assumptions)
+			throws TLA2BException {
+		for (AssumeNode assumeNode : assumptions) {
+			visitExprNode(assumeNode.getAssume(), BoolType.getInstance());
+		}
+	}
+
+	/**
+	 * @param exprOrOpArgNode
+	 * @param instance
+	 * @throws TypeErrorException
+	 * @throws NotImplementedException
+	 */
+	private TLAType visitExprOrOpArgNode(ExprOrOpArgNode n, TLAType expected)
+			throws TLA2BException {
+		if (n instanceof ExprNode) {
+			return visitExprNode((ExprNode) n, expected);
+		} else {
+			throw new NotImplementedException("OpArgNode not implemented jet");
+		}
+
+	}
+
+	private TLAType visitExprNode(ExprNode exprNode, TLAType expected)
+			throws TLA2BException {
+
+		switch (exprNode.getKind()) {
+		case TLCValueKind: {
+			TLCValueNode valueNode = (TLCValueNode) exprNode;
+			try {
+				return valueNode.getType().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(
+						String.format(
+								"Expected %s, found %s at '%s'(assigned in the configuration file),\n%s ",
+								expected, valueNode.getType(),
+								valueNode.getValue(), exprNode.getLocation()));
+			}
+
+		}
+
+		case OpApplKind:
+			return visitOpApplNode((OpApplNode) exprNode, expected);
+
+		case NumeralKind:
+			try {
+				return IntType.getInstance().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found INTEGER at '%s',\n%s ", expected,
+						((NumeralNode) exprNode).val(), exprNode.getLocation()));
+			}
+		case StringKind: {
+			try {
+				return StringType.getInstance().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found STRING at '%s',\n%s ", expected,
+						((StringNode) exprNode).getRep(),
+						exprNode.getLocation()));
+			}
+		}
+		case AtNodeKind: { // @
+			AtNode a = (AtNode) exprNode;
+			OpApplNode pair2 = a.getExceptComponentRef();
+			ExprOrOpArgNode rightside = pair2.getArgs()[1];
+			TLAType type = (TLAType) rightside.getToolObject(TYPE_ID);
+			try {
+				TLAType res = type.unify(expected);
+				return res;
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at '@',\n%s ", expected, type,
+						exprNode.getLocation()));
+			}
+
+		}
+
+		case LetInKind: {
+			LetInNode l = (LetInNode) exprNode;
+			for (int i = 0; i < l.getLets().length; i++) {
+				visitOpDefNode(l.getLets()[i]);
+			}
+			return visitExprNode(l.getBody(), expected);
+		}
+
+		case SubstInKind: {
+			throw new RuntimeException(
+					"SubstInKind should never occur after InstanceTransformation");
+		}
+
+		case DecimalKind:{
+			// currently not supported
+		}
+		
+		
+		}
+
+		throw new NotImplementedException(exprNode.toString(2));
+
+	}
+
+	/**
+	 * @param n
+	 * @param expected
+	 * @return {@link TLAType}
+	 * @throws TLA2BException
+	 */
+	private TLAType visitOpApplNode(OpApplNode n, TLAType expected)
+			throws TLA2BException {
+
+		switch (n.getOperator().getKind()) {
+		case ConstantDeclKind: {
+			OpDeclNode con = (OpDeclNode) n.getOperator();
+
+			TLAType c = (TLAType) con.getToolObject(TYPE_ID);
+			if (c == null) {
+				throw new RuntimeException(con.getName() + " has no type yet!");
+			}
+			try {
+				TLAType result = expected.unify(c);
+				con.setToolObject(TYPE_ID, result);
+				return result;
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at constant '%s',\n%s",
+						expected, c, con.getName(), n.getLocation())
+
+				);
+			}
+		}
+
+		case VariableDeclKind: {
+			SymbolNode symbolNode = n.getOperator();
+			String vName = symbolNode.getName().toString();
+			TLAType v = (TLAType) symbolNode.getToolObject(TYPE_ID);
+			if (v == null) {
+				throw new RuntimeException(vName + " has no type yet!");
+			}
+			try {
+				TLAType result = expected.unify(v);
+				symbolNode.setToolObject(TYPE_ID, result);
+				return result;
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at variable '%s',\n%s",
+						expected, v, vName, n.getLocation()));
+			}
+		}
+
+		case BuiltInKind: {
+			return evalBuiltInKind(n, expected);
+		}
+
+		case FormalParamKind: {
+			SymbolNode symbolNode = n.getOperator();
+			String pName = symbolNode.getName().toString();
+			TLAType t = (TLAType) symbolNode.getToolObject(paramId);
+			if (t == null) {
+				t = (TLAType) symbolNode.getToolObject(TYPE_ID);
+			}
+			try {
+				TLAType result = expected.unify(t);
+				symbolNode.setToolObject(paramId, result);
+				return result;
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at parameter '%s',\n%s",
+						expected, t, pName, n.getLocation()));
+			}
+		}
+
+		case UserDefinedOpKind: {
+			OpDefNode def = (OpDefNode) n.getOperator();
+
+			// Definition is a BBuilt-in definition
+			String sourceModule = def.getSource()
+					.getOriginallyDefinedInModuleNode().getName().toString();
+			if (BBuiltInOPs.contains(def.getName())
+					&& STANDARD_MODULES.contains(sourceModule)) {
+				return evalBBuiltIns(n, expected);
+			}
+
+			TLAType found = ((TLAType) def.getToolObject(TYPE_ID));
+			if (found == null)
+				found = new Untyped();
+			// throw new RuntimeException(def.getName() + " has no type yet!");
+			found = found.cloneTLAType();
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at definition '%s',\n%s",
+						expected, found, def.getName(), n.getLocation()));
+			}
+			boolean untyped = false;
+			FormalParamNode[] params = def.getParams();
+			for (int i = 0; i < n.getArgs().length; i++) {
+				// clone the parameter type, because the parameter type is not
+				// set/changed at a definition call
+				FormalParamNode p = params[i];
+				TLAType pType = ((TLAType) p.getToolObject(TYPE_ID));
+				if (pType == null) {
+					pType = new Untyped();
+					// throw new RuntimeException("Parameter " + p.getName()
+					// + " has no type yet!\n" + p.getLocation());
+				}
+				pType = pType.cloneTLAType();
+				if (pType.isUntyped())
+					untyped = true;
+
+				pType = visitExprOrOpArgNode(n.getArgs()[i], pType); // unify
+																		// both
+																		// types
+				// set types of the arguments of the definition call to the
+				// parameters for reevaluation the def body
+				p.setToolObject(TEMP_TYPE_ID, pType);
+			}
+
+			if (found.isUntyped() || untyped) {
+				// evaluate the body of the definition again
+				paramId = TEMP_TYPE_ID;
+				found = visitExprNode(def.getBody(), found);
+				paramId = TYPE_ID;
+			}
+
+			n.setToolObject(TYPE_ID, found);
+
+			return found;
+
+		}
+
+		default: {
+			throw new NotImplementedException(n.getOperator().getName()
+					.toString());
+		}
+		}
+
+	}
+
+	/**
+	 * @param exprNode
+	 * @param expected
+	 * @return {@link TLAType}
+	 * @throws TLA2BException
+	 */
+	private TLAType evalBuiltInKind(OpApplNode n, TLAType expected)
+			throws TLA2BException {
+
+		switch (getOpCode(n.getOperator().getName())) {
+
+		/**********************************************************************
+		 * equality and disequality: =, #, /=
+		 **********************************************************************/
+		case OPCODE_eq: // =
+		case OPCODE_noteq: // /=, #
+		{
+			try {
+				BoolType.getInstance().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found BOOL at '%s',\n%s", expected, n
+								.getOperator().getName(), n.getLocation()));
+			}
+			TLAType left = visitExprOrOpArgNode(n.getArgs()[0],
+					new de.tla2b.types.Untyped());
+			visitExprOrOpArgNode(n.getArgs()[1], left);
+			return BoolType.getInstance();
+		}
+
+		/**********************************************************************
+		 * Logic Operators: \neg, \lnot, \land, \cl, \lor, \dl, \equiv, =>
+		 **********************************************************************/
+		case OPCODE_neg: // Negation
+		case OPCODE_lnot: // Negation
+		case OPCODE_cl: // $ConjList
+		case OPCODE_dl: // $DisjList
+		case OPCODE_land: // \land
+		case OPCODE_lor: // \lor
+		case OPCODE_equiv: // \equiv
+		case OPCODE_implies: // =>
+		{
+			try {
+				BoolType.getInstance().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found BOOL at '%s',\n%s", expected, n
+								.getOperator().getName(), n.getLocation()));
+			}
+			for (int i = 0; i < n.getArgs().length; i++) {
+				visitExprOrOpArgNode(n.getArgs()[i], BoolType.getInstance());
+			}
+			return BoolType.getInstance();
+		}
+
+		/**********************************************************************
+		 * Quantification: \A x \in S : P or \E x \in S : P
+		 **********************************************************************/
+		case OPCODE_be: // \E x \in S : P
+		case OPCODE_bf: // \A x \in S : P
+		{
+			try {
+				BoolType.getInstance().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found BOOL at '%s',\n%s", expected, n
+								.getOperator().getName(), n.getLocation()));
+			}
+			evalBoundedVariables(n);
+			visitExprOrOpArgNode(n.getArgs()[0], BoolType.getInstance());
+			return BoolType.getInstance();
+		}
+
+		/**********************************************************************
+		 * Set Operators
+		 **********************************************************************/
+		case OPCODE_se: // SetEnumeration {..}
+		{
+			SetType found = new SetType(new Untyped());
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found POW(_A) at set enumeration,\n%s",
+						expected, n.getLocation()));
+			}
+			TLAType current = found.getSubType();
+			for (int i = 0; i < n.getArgs().length; i++) {
+				current = visitExprOrOpArgNode(n.getArgs()[i], current);
+			}
+			return found;
+		}
+
+		case OPCODE_in: // \in
+		case OPCODE_notin: // \notin
+		{
+			if (!BoolType.getInstance().compare(expected)) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found BOOL at '%s',\n%s", expected, n
+								.getOperator().getName(), n.getLocation()));
+			}
+			TLAType element = visitExprOrOpArgNode(n.getArgs()[0],
+					new Untyped());
+			visitExprOrOpArgNode(n.getArgs()[1], new SetType(element));
+
+			return BoolType.getInstance();
+		}
+
+		case OPCODE_setdiff: // set difference
+		case OPCODE_cup: // set union
+		case OPCODE_cap: // set intersection
+		{
+			SetType found = new SetType(new Untyped());
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found POW(_A) at '%s',\n%s", expected, n
+								.getOperator().getName(), n.getLocation()));
+			}
+			TLAType left = visitExprOrOpArgNode(n.getArgs()[0], found);
+			TLAType right = visitExprOrOpArgNode(n.getArgs()[1], left);
+			return right;
+		}
+
+		case OPCODE_subseteq: // \subseteq - subset or equal
+		{
+			try {
+				BoolType.getInstance().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found BOOL at '%s',\n%s", expected, n
+								.getOperator().getName(), n.getLocation()));
+			}
+			TLAType left = visitExprOrOpArgNode(n.getArgs()[0], new SetType(
+					new Untyped()));
+			visitExprOrOpArgNode(n.getArgs()[1], left);
+			return BoolType.getInstance();
+		}
+
+		/**********************************************************************
+		 * Set Constructor
+		 **********************************************************************/
+		case OPCODE_sso: // $SubsetOf Represents {x \in S : P}
+		{
+
+			TLAType domainType = evalBoundedVariables(n);
+			SetType found = new SetType(domainType);
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at '%s',\n%s", expected, found,
+						n.getOperator().getName(), n.getLocation()));
+			}
+			visitExprOrOpArgNode(n.getArgs()[0], BoolType.getInstance());
+			return found;
+		}
+
+		case OPCODE_soa: // $SetOfAll Represents {e : p1 \in S, p2,p3 \in S2}
+		{
+			SetType found = new SetType(new Untyped());
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found POW(_A) at '%s',\n%s", expected, n
+								.getOperator().getName(), n.getLocation()));
+			}
+			evalBoundedVariables(n);
+			visitExprOrOpArgNode(n.getArgs()[0], found.getSubType());
+			return found;
+		}
+
+		case OPCODE_subset: // SUBSET (conforms POW in B)
+		{
+			SetType found = new SetType(new Untyped());
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found POW(_A) at 'SUBSET',\n%s",
+						expected, n.getLocation()));
+			}
+			visitExprOrOpArgNode(n.getArgs()[0], found.getSubType());
+			return found;
+		}
+
+		case OPCODE_union: // Union - Union{{1},{2}}
+		{
+			SetType found = new SetType(new Untyped());
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found POW(_A) at 'SUBSET',\n%s",
+						expected, n.getLocation()));
+			}
+			SetType setOfSet = (SetType) visitExprOrOpArgNode(n.getArgs()[0],
+					new SetType(found));
+			return setOfSet.getSubType();
+		}
+
+		/**********************************************************************
+		 * Prime
+		 **********************************************************************/
+		case OPCODE_prime: // prime
+		{
+			try {
+				OpApplNode node = (OpApplNode) n.getArgs()[0];
+				if (node.getOperator().getKind() != VariableDeclKind) {
+					throw new TypeErrorException("Expected variable at \""
+							+ node.getOperator().getName() + "\":\n"
+							+ node.getLocation());
+				}
+				return visitExprOrOpArgNode(n.getArgs()[0], expected);
+			} catch (ClassCastException e) {
+				throw new TypeErrorException(
+						"Expected variable as argument of prime operator:\n"
+								+ n.getArgs()[0].getLocation());
+			}
+		}
+
+		/***********************************************************************
+		 * Tuple: Tuple as Function 1..n to Set (Sequence)
+		 ***********************************************************************/
+		case OPCODE_tup: { // $Tuple
+			ArrayList<TLAType> list = new ArrayList<TLAType>();
+			for (int i = 0; i < n.getArgs().length; i++) {
+				list.add(visitExprOrOpArgNode(n.getArgs()[i], new Untyped()));
+			}
+			TLAType found = null;
+			if (list.size() == 0) {
+				found = new FunctionType(IntType.getInstance(), new Untyped());
+			} else if (list.size() == 1) {
+				found = new FunctionType(IntType.getInstance(), list.get(0));
+			} else {
+				found = new TupleType(list);
+			}
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at Tuple,\n%s", expected, found,
+						n.getLocation()));
+			}
+			n.setToolObject(TYPE_ID, found);
+			if (found instanceof AbstractHasFollowers) {
+				((AbstractHasFollowers) found).addFollower(n);
+			}
+			return found;
+		}
+
+		/***********************************************************************
+		 * Function constructors
+		 ***********************************************************************/
+		case OPCODE_rfs: // recursive function ( f[x\in Nat] == IF x = 0 THEN 1
+							// ELSE f[n-1]
+		{
+
+			FormalParamNode recFunc = n.getUnbdedQuantSymbols()[0];
+			FunctionType recType = new FunctionType();
+			recFunc.setToolObject(TYPE_ID, recType);
+			recType.addFollower(recFunc);
+
+			TLAType domainType = evalBoundedVariables(n);
+			FunctionType found = new FunctionType(domainType, new Untyped());
+			visitExprOrOpArgNode(n.getArgs()[0], found.getRange());
+
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException("Expected '" + expected
+						+ "', found '" + found + "'.\n" + n.getLocation());
+			}
+
+			TLAType t = null;
+			try {
+				t = (TLAType) recFunc.getToolObject(TYPE_ID);
+				found = found.unify(t);
+			} catch (UnificationException e) {
+				throw new TypeErrorException("Expected '" + expected
+						+ "', found '" + t + "'.\n" + n.getLocation());
+			}
+
+			return found;
+		}
+
+		case OPCODE_nrfs: // succ[n \in Nat] == n + 1
+		case OPCODE_fc: // [n \in Nat |-> n+1]
+		{
+			TLAType domainType = evalBoundedVariables(n);
+			FunctionType found = new FunctionType(domainType, new Untyped());
+			visitExprOrOpArgNode(n.getArgs()[0], found.getRange());
+
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException("Expected '" + expected
+						+ "', found '" + found + "'.\n" + n.getLocation());
+			}
+			return found;
+		}
+
+		/***********************************************************************
+		 * Function call
+		 ***********************************************************************/
+		case OPCODE_fa: // $FcnApply f[1]
+		{
+			TLAType domType;
+			ExprOrOpArgNode dom = n.getArgs()[1];
+			if (dom instanceof OpApplNode
+					&& ((OpApplNode) dom).getOperator().getName().toString()
+							.equals("$Tuple")) {
+				ArrayList<TLAType> domList = new ArrayList<TLAType>();
+				OpApplNode domOpAppl = (OpApplNode) dom;
+				for (int i = 0; i < domOpAppl.getArgs().length; i++) {
+					TLAType d = visitExprOrOpArgNode(domOpAppl.getArgs()[i],
+							new Untyped());
+					domList.add(d);
+				}
+				domType = new TupleType(domList);
+			} else {
+				domType = visitExprOrOpArgNode(n.getArgs()[1], new Untyped());
+			}
+			FunctionType func = new FunctionType(domType, expected);
+			FunctionType res = (FunctionType) visitExprOrOpArgNode(
+					n.getArgs()[0], func);
+			return res.getRange();
+		}
+
+		/***********************************************************************
+		 * Domain of Function
+		 ***********************************************************************/
+		case OPCODE_domain: {
+
+			FunctionType func = new FunctionType(new Untyped(), new Untyped());
+			func = (FunctionType) visitExprOrOpArgNode(n.getArgs()[0], func);
+			TLAType res = null;
+			try {
+				res = new SetType(func.getDomain()).unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected '%s', found '%s' at 'DOMAIN(..)',\n%s",
+						expected, n.getLocation()));
+			}
+			return res;
+		}
+		/***********************************************************************
+		 * Set of Function
+		 ***********************************************************************/
+		case OPCODE_sof: // [ A -> B]
+		{
+			SetType A = (SetType) visitExprOrOpArgNode(n.getArgs()[0],
+					new SetType(new Untyped()));
+			SetType B = (SetType) visitExprOrOpArgNode(n.getArgs()[1],
+					new SetType(new Untyped()));
+
+			SetType found = new SetType(new FunctionType(A.getSubType(),
+					B.getSubType()));
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected '%s', found '%s' at Set of Function,\n%s",
+						expected, found, n.getLocation()));
+			}
+			return found;
+		}
+
+		/**********************************************************************
+		 * Except
+		 **********************************************************************/
+		case OPCODE_exc: // Except
+		{
+			return evalExcept(n, expected);
+		}
+
+		/***********************************************************************
+		 * Cartesian Product: A \X B
+		 ***********************************************************************/
+		case OPCODE_cp: // $CartesianProd A \X B \X C as $CartesianProd(A, B, C)
+		{
+			ArrayList<TLAType> list = new ArrayList<TLAType>();
+			for (int i = 0; i < n.getArgs().length; i++) {
+				SetType t = (SetType) visitExprOrOpArgNode(n.getArgs()[i],
+						new SetType(new Untyped()));
+				list.add(t.getSubType());
+			}
+
+			SetType found = new SetType(new TupleType(list));
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at Cartesian Product,\n%s",
+						expected, found, n.getLocation()));
+			}
+			return found;
+		}
+
+		/***********************************************************************
+		 * Records
+		 ***********************************************************************/
+		case OPCODE_sor: // $SetOfRcds [L1 : e1, L2 : e2]
+		{
+			StructType struct = new StructType();
+			for (int i = 0; i < n.getArgs().length; i++) {
+				OpApplNode pair = (OpApplNode) n.getArgs()[i];
+				StringNode field = (StringNode) pair.getArgs()[0];
+				SetType fieldType = (SetType) visitExprOrOpArgNode(
+						pair.getArgs()[1], new SetType(new Untyped()));
+				struct.add(field.getRep().toString(), fieldType.getSubType());
+			}
+
+			SetType found = new SetType(struct);
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at Set of Records,\n%s",
+						expected, found, n.getLocation()));
+			}
+			n.setToolObject(TYPE_ID, found);
+			if (found instanceof AbstractHasFollowers) {
+				((AbstractHasFollowers) found).addFollower(n);
+			}
+			return found;
+		}
+
+		case OPCODE_rc: // [h_1 |-> 1, h_2 |-> 2]
+		{
+			StructType found = new StructType();
+			for (int i = 0; i < n.getArgs().length; i++) {
+				OpApplNode pair = (OpApplNode) n.getArgs()[i];
+				StringNode field = (StringNode) pair.getArgs()[0];
+				TLAType fieldType = visitExprOrOpArgNode(pair.getArgs()[1],
+						new Untyped());
+				found.add(field.getRep().toString(), fieldType);
+			}
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at Record,\n%s", expected,
+						found, n.getLocation()));
+			}
+			n.setToolObject(TYPE_ID, found);
+			if (found instanceof AbstractHasFollowers) {
+				((AbstractHasFollowers) found).addFollower(n);
+			}
+			recList.add(n);
+			return found;
+
+		}
+
+		case OPCODE_rs: // $RcdSelect r.c
+		{
+			String fieldName = ((StringNode) n.getArgs()[1]).getRep()
+					.toString();
+			StructType r = (StructType) visitExprOrOpArgNode(n.getArgs()[0],
+					new StructType());
+
+			StructType expectedStruct = new StructType();
+			expectedStruct.add(fieldName, expected);
+
+			try {
+				r = r.unify(expectedStruct);
+				return r.getType(fieldName);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Struct has no field %s with type %s: %s\n%s",
+						fieldName, r.getType(fieldName), r, n.getLocation()));
+			}
+		}
+
+		/***********************************************************************
+		 * miscellaneous constructs
+		 ***********************************************************************/
+		case OPCODE_ite: // IF THEN ELSE
+		{
+			visitExprOrOpArgNode(n.getArgs()[0], BoolType.getInstance());
+			TLAType then = visitExprOrOpArgNode(n.getArgs()[1], expected);
+			TLAType eelse = visitExprOrOpArgNode(n.getArgs()[2], then);
+			n.setToolObject(TYPE_ID, eelse);
+			if (eelse instanceof AbstractHasFollowers) {
+				((AbstractHasFollowers) eelse).addFollower(n);
+			}
+			return eelse;
+		}
+
+		case OPCODE_case: {
+			/**
+			 * CASE p1 -> e1 [] p2 -> e2 represented as $Case( $Pair(p1,
+			 * e1),$Pair(p2, e2) ) and CASE p1 -> e1 [] p2 -> e2 [] OTHER -> e3
+			 * represented as $Case( $Pair(p1, e1), $Pair(p2, e2), $Pair(null,
+			 * e3))
+			 **/
+			TLAType found = expected;
+			for (int i = 0; i < n.getArgs().length; i++) {
+				OpApplNode pair = (OpApplNode) n.getArgs()[i];
+				if (pair.getArgs()[0] != null) {
+					visitExprOrOpArgNode(pair.getArgs()[0],
+							BoolType.getInstance());
+				}
+				found = visitExprOrOpArgNode(pair.getArgs()[1], found);
+			}
+			return found;
+
+		}
+
+		case OPCODE_bc: { // CHOOSE x \in S: P
+			if (n.isBdedQuantATuple()[0]) {
+				throw new TypeErrorException(
+						"A tuple as parameter within the set constructor is not permitted.\n"
+								+ n.getLocation());
+			}
+			ExprNode[] bounds = n.getBdedQuantBounds();
+			SetType S = (SetType) visitExprNode(bounds[0], new SetType(
+					new Untyped()));
+			TLAType found = S.getSubType();
+
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at 'CHOOSE',\n%s", expected,
+						found, n.getLocation()));
+			}
+			FormalParamNode x = n.getBdedQuantSymbolLists()[0][0];
+			x.setToolObject(TYPE_ID, found);
+			if (found instanceof AbstractHasFollowers) {
+				((AbstractHasFollowers) found).addFollower(x);
+			}
+			visitExprOrOpArgNode(n.getArgs()[0], BoolType.getInstance());
+			return found;
+		}
+
+		case OPCODE_unchanged: {
+			return BoolType.getInstance().unify(expected);
+		}
+
+		/***********************************************************************
+		 * no TLA+ Built-ins
+		 ***********************************************************************/
+		case 0: {
+			return evalBBuiltIns(n, expected);
+		}
+		}
+
+		throw new NotImplementedException("Not supported Operator: "
+				+ n.getOperator().getName().toString() + "\n" + n.getLocation());
+	}
+
+	private TLAType evalBoundedVariables(OpApplNode n) throws TLA2BException {
+		ArrayList<TLAType> domList = new ArrayList<TLAType>();
+		FormalParamNode[][] params = n.getBdedQuantSymbolLists();
+		ExprNode[] bounds = n.getBdedQuantBounds();
+		for (int i = 0; i < bounds.length; i++) {
+			SetType boundType = (SetType) visitExprNode(bounds[i], new SetType(
+					new Untyped()));
+			TLAType subType = boundType.getSubType();
+
+			if (n.isBdedQuantATuple()[i]) {
+				if (subType instanceof TupleType) {
+					domList.add(subType);
+					TupleType t = (TupleType) subType;
+					if (params[i].length != t.getTypes().size()) {
+						throw new TypeErrorException("Expected tuple with "
+								+ params[i].length
+								+ " components, found tuple with "
+								+ t.getTypes().size() + " components.\n"
+								+ bounds[i].getLocation());
+					}
+					for (int j = 0; j < params[i].length; j++) {
+						FormalParamNode p = params[i][j];
+						TLAType paramType = t.getTypes().get(j);
+						p.setToolObject(TYPE_ID, paramType);
+						if (paramType instanceof AbstractHasFollowers) {
+							((AbstractHasFollowers) paramType).addFollower(p);
+						}
+					}
+				} else if (subType instanceof Untyped) {
+					TupleType tuple = new TupleType(params[i].length);
+					try {
+						tuple = (TupleType) tuple.unify(subType);
+					} catch (UnificationException e) {
+						throw new TypeErrorException(String.format(
+								"Expected %s, found %s ,\n%s", tuple, subType,
+								n.getLocation()));
+					}
+
+					domList.add(tuple);
+					for (int j = 0; j < params[i].length; j++) {
+						FormalParamNode p = params[i][j];
+						TLAType paramType = tuple.getTypes().get(j);
+						p.setToolObject(TYPE_ID, paramType);
+						if (paramType instanceof AbstractHasFollowers) {
+							((AbstractHasFollowers) paramType).addFollower(p);
+						}
+					}
+
+				} else {
+					throw new TypeErrorException("Expected tuple, found '"
+							+ subType + "'.\n" + bounds[i].getLocation());
+				}
+			} else {
+				// is not a tuple: all parameter have the same type
+				for (int j = 0; j < params[i].length; j++) {
+					domList.add(subType);
+					FormalParamNode p = params[i][j];
+					p.setToolObject(TYPE_ID, subType);
+					if (subType instanceof AbstractHasFollowers) {
+						((AbstractHasFollowers) subType).addFollower(p);
+					}
+				}
+			}
+		}
+
+		TLAType domType = null;
+		if (domList.size() == 1) {
+			domType = domList.get(0);
+		} else {
+			domType = new TupleType(domList);
+		}
+		return domType;
+	}
+
+	/**
+	 * @param n
+	 * @param expected
+	 * @return
+	 * @throws TLA2BException
+	 */
+	private TLAType evalExcept(OpApplNode n, TLAType expected)
+			throws TLA2BException {
+		TLAType t = visitExprOrOpArgNode(n.getArgs()[0], expected);
+		n.setToolObject(TYPE_ID, t);
+		if (t instanceof AbstractHasFollowers) {
+			((AbstractHasFollowers) t).addFollower(n);
+		}
+
+		for (int i = 1; i < n.getArgs().length; i++) {
+			OpApplNode pair = (OpApplNode) n.getArgs()[i];
+			ExprOrOpArgNode leftside = pair.getArgs()[0];
+			ExprOrOpArgNode rightside = pair.getArgs()[1];
+			// stored for @ node
+			Untyped untyped = new Untyped();
+			rightside.setToolObject(TYPE_ID, untyped);
+			untyped.addFollower(rightside);
+			TLAType valueType = visitExprOrOpArgNode(rightside, untyped);
+
+			OpApplNode seq = (OpApplNode) leftside;
+			LinkedList<ExprOrOpArgNode> list = new LinkedList<ExprOrOpArgNode>();
+			for (int j = 0; j < seq.getArgs().length; j++) {
+				list.add(seq.getArgs()[j]);
+			}
+			ExprOrOpArgNode first = list.poll();
+
+			if (first instanceof StringNode) {
+				String field = ((StringNode) first).getRep().toString();
+				TLAType res = evalType(list, valueType);
+				StructOrFunction s = new StructOrFunction(field, res);
+				try {
+					t = t.unify(s);
+				} catch (UnificationException e) {
+					throw new TypeErrorException(String.format(
+							"Expected %s, found %s at 'EXCEPT',\n%s", t, s,
+							pair.getLocation()));
+				}
+
+			} else {
+				// Function
+				ExprOrOpArgNode domExpr = first;
+				TLAType domType;
+				TLAType rangeType;
+				if (domExpr instanceof OpApplNode
+						&& ((OpApplNode) domExpr).getOperator().getName()
+								.toString().equals("$Tuple")) {
+					ArrayList<TLAType> domList = new ArrayList<TLAType>();
+					OpApplNode domOpAppl = (OpApplNode) domExpr;
+					for (int j = 0; j < domOpAppl.getArgs().length; j++) {
+						TLAType d = visitExprOrOpArgNode(
+								domOpAppl.getArgs()[j], new Untyped());
+						domList.add(d);
+					}
+					domType = new TupleType(domList);
+				} else {
+					domType = visitExprOrOpArgNode(domExpr, new Untyped());
+				}
+				rangeType = evalType(list, valueType);
+				FunctionType func = new FunctionType(domType, rangeType);
+				try {
+					t = t.unify(func);
+				} catch (UnificationException e) {
+					throw new TypeErrorException(String.format(
+							"Expected %s, found %s at 'EXCEPT',\n%s", t, func,
+							pair.getLocation()));
+				}
+			}
+		}
+		return t;
+
+	}
+
+	/**
+	 * @param list
+	 * @param valueType
+	 * @return
+	 * @throws TLA2BException
+	 */
+	private TLAType evalType(LinkedList<ExprOrOpArgNode> list, TLAType valueType)
+			throws TLA2BException {
+		if (list.size() == 0) {
+			return valueType;
+		}
+		ExprOrOpArgNode head = list.poll();
+		if (head instanceof StringNode) {
+			// record or function of strings
+			String name = ((StringNode) head).getRep().toString();
+			StructOrFunction res = new StructOrFunction(name, evalType(list,
+					valueType));
+			return res;
+		}
+		TLAType t = visitExprOrOpArgNode(head, new Untyped());
+		FunctionType res = new FunctionType(t, evalType(list, valueType));
+		return res;
+	}
+
+	private TLAType evalBBuiltIns(OpApplNode n, TLAType expected)
+			throws TLA2BException {
+		switch (BBuiltInOPs.getOpcode(n.getOperator().getName())) {
+		// B Builtins
+
+		/**********************************************************************
+		 * Standard Module Naturals
+		 **********************************************************************/
+		case B_OPCODE_gt: // >
+		case B_OPCODE_lt: // <
+		case B_OPCODE_leq: // <=
+		case B_OPCODE_geq: // >=
+		{
+			try {
+				BoolType.getInstance().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found BOOL at '%s',\n%s", expected, n
+								.getOperator().getName(), n.getLocation()));
+			}
+			for (int i = 0; i < n.getArgs().length; i++) {
+				visitExprOrOpArgNode(n.getArgs()[i], IntType.getInstance());
+			}
+			return BoolType.getInstance();
+		}
+
+		case B_OPCODE_plus: // +
+		case B_OPCODE_minus: // -
+		case B_OPCODE_times: // *
+		case B_OPCODE_div: // /
+		case B_OPCODE_mod: // % modulo
+		case B_OPCODE_exp: { // x hoch y, x^y
+			try {
+				IntType.getInstance().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found INTEGER at '%s',\n%s", expected, n
+								.getOperator().getName(), n.getLocation()));
+			}
+			for (int i = 0; i < n.getArgs().length; i++) {
+				visitExprOrOpArgNode(n.getArgs()[i], IntType.getInstance());
+			}
+			return IntType.getInstance();
+		}
+
+		case B_OPCODE_dotdot: // ..
+		{
+			try {
+				expected.unify(new SetType(IntType.getInstance()));
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found POW(INTEGER) at '..',\n%s",
+						expected, n.getLocation()));
+			}
+
+			for (int i = 0; i < n.getArgs().length; i++) {
+				visitExprOrOpArgNode(n.getArgs()[i], IntType.getInstance());
+			}
+			return new SetType(IntType.getInstance());
+		}
+
+		case B_OPCODE_nat: // Nat
+		{
+			try {
+				SetType found = new SetType(IntType.getInstance());
+				found = found.unify(expected);
+				return found;
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found POW(INTEGER) at 'Nat',\n%s",
+						expected, n.getLocation()));
+			}
+		}
+
+		/**********************************************************************
+		 * Standard Module Integers
+		 **********************************************************************/
+		case B_OPCODE_int: // Int
+		{
+			try {
+				SetType found = new SetType(IntType.getInstance());
+				found = found.unify(expected);
+				return found;
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found POW(INTEGER) at 'Int',\n%s",
+						expected, n.getLocation()));
+			}
+		}
+
+		case B_OPCODE_uminus: // -x
+		{
+			try {
+				IntType.getInstance().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found INTEGER at '-',\n%s", expected,
+						n.getLocation()));
+			}
+			visitExprOrOpArgNode(n.getArgs()[0], IntType.getInstance());
+			return IntType.getInstance();
+		}
+
+		/**********************************************************************
+		 * Standard Module FiniteSets
+		 **********************************************************************/
+		case B_OPCODE_finite: // IsFiniteSet
+		{
+			try {
+				BoolType.getInstance().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found BOOL at 'IsFiniteSet',\n%s",
+						expected, n.getLocation()));
+			}
+			visitExprOrOpArgNode(n.getArgs()[0], new SetType(new Untyped()));
+			return BoolType.getInstance();
+		}
+
+		case B_OPCODE_card: // Cardinality
+		{
+			try {
+				IntType.getInstance().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found INTEGER at 'Cardinality',\n%s",
+						expected, n.getLocation()));
+			}
+			visitExprOrOpArgNode(n.getArgs()[0], new SetType(new Untyped()));
+			return IntType.getInstance();
+		}
+
+		/**********************************************************************
+		 * Standard Module Sequences
+		 **********************************************************************/
+		case B_OPCODE_seq: { // Seq(S) - set of sequences, S must be a set
+
+			SetType S = (SetType) visitExprOrOpArgNode(n.getArgs()[0],
+					new SetType(new Untyped()));
+
+			SetType set_of_seq = new SetType(new FunctionType(
+					IntType.getInstance(), S.getSubType()));
+			try {
+				set_of_seq = set_of_seq.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at 'Seq',\n%s", expected,
+						set_of_seq, n.getLocation()));
+			}
+			return set_of_seq;
+		}
+
+		case B_OPCODE_len: { // lengh of the sequence
+			try {
+				IntType.getInstance().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found INTEGER at 'Len',\n%s", expected,
+						n.getLocation()));
+			}
+			visitExprOrOpArgNode(n.getArgs()[0],
+					new FunctionType(IntType.getInstance(), new Untyped()));
+			return IntType.getInstance();
+		}
+
+		case B_OPCODE_conc: { // s \o s2 - concatenation of s and s2
+			FunctionType found = new FunctionType(IntType.getInstance(),
+					new Untyped());
+			found = (FunctionType) visitExprOrOpArgNode(n.getArgs()[0], found);
+			found = (FunctionType) visitExprOrOpArgNode(n.getArgs()[1], found);
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found POW(INTEGER*_A) at '\\o',\n%s",
+						expected, n.getLocation()));
+			}
+			return found;
+		}
+
+		case B_OPCODE_append: // Append(s, e)
+		{
+			FunctionType found = new FunctionType(IntType.getInstance(),
+					new Untyped());
+			found = (FunctionType) visitExprOrOpArgNode(n.getArgs()[0], found);
+			visitExprOrOpArgNode(n.getArgs()[1], found.getRange());
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at 'Append',\n%s", expected,
+						found, n.getLocation()));
+			}
+			return found;
+		}
+
+		case B_OPCODE_head: { // HEAD(s) - the first element of the sequence
+			FunctionType func = new FunctionType(IntType.getInstance(),
+					new Untyped());
+			func = (FunctionType) visitExprOrOpArgNode(n.getArgs()[0], func);
+
+			TLAType found = func.getRange();
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at 'Head',\n%s", expected,
+						found, n.getLocation()));
+			}
+			return found;
+		}
+
+		case B_OPCODE_tail: { // Tail(s)
+			FunctionType found = new FunctionType(IntType.getInstance(),
+					new Untyped());
+			found = (FunctionType) visitExprOrOpArgNode(n.getArgs()[0], found);
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at 'Tail',\n%s", expected,
+						found, n.getLocation()));
+			}
+			return found;
+		}
+
+		case B_OPCODE_subseq: { // SubSeq(s,m,n)
+			FunctionType found = new FunctionType(IntType.getInstance(),
+					new Untyped());
+			found = (FunctionType) visitExprOrOpArgNode(n.getArgs()[0], found);
+			visitExprOrOpArgNode(n.getArgs()[1], IntType.getInstance());
+			visitExprOrOpArgNode(n.getArgs()[2], IntType.getInstance());
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at 'SubSeq',\n%s", expected,
+						found, n.getLocation()));
+			}
+			return found;
+		}
+
+		// TODO add BSeq to tla standard modules
+
+		/**********************************************************************
+		 * Standard Module TLA2B
+		 **********************************************************************/
+
+		case B_OPCODE_min: // MinOfSet(S)
+		case B_OPCODE_max: // MaxOfSet(S)
+		case B_OPCODE_setprod: // SetProduct(S)
+		case B_OPCODE_setsum: // SetSummation(S)
+		{
+			try {
+				IntType.getInstance().unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found INTEGER at '%s',\n%s", expected, n
+								.getOperator().getName(), n.getLocation()));
+			}
+			visitExprOrOpArgNode(n.getArgs()[0],
+					new SetType(IntType.getInstance()));
+			return IntType.getInstance();
+		}
+
+		case B_OPCODE_permseq: { // PermutedSequences(S)
+			SetType argType = (SetType) visitExprOrOpArgNode(n.getArgs()[0],
+					new SetType(new Untyped()));
+			SetType found = new SetType(new FunctionType(IntType.getInstance(),
+					argType.getSubType()));
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at 'PermutedSequences',\n%s",
+						expected, found, n.getLocation()));
+			}
+			return found;
+		}
+
+		/**********************************************************************
+		 * Standard Module TLA2B
+		 **********************************************************************/
+		case B_OPCODE_pow1: // POW1
+		{
+
+			SetType set = new SetType(new Untyped());
+			set = (SetType) visitExprOrOpArgNode(n.getArgs()[0], set);
+			SetType found = new SetType(set);
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at '%s',\n%s", expected, n
+								.getOperator().getName(), n.getLocation()));
+			}
+			return found;
+		}
+
+		/**********************************************************************
+		 * Standard Module Relations
+		 **********************************************************************/
+		case B_OPCODE_rel_inverse: // POW1
+		{
+			SetType set = new SetType(new TupleType(2));
+			set = (SetType) visitExprOrOpArgNode(n.getArgs()[0], set);
+			TupleType t = (TupleType) set.getSubType();
+			ArrayList<TLAType> list = new ArrayList<TLAType>();
+			list.add(t.getTypes().get(1));
+			list.add(t.getTypes().get(0));
+			SetType found = new SetType(new TupleType(list));
+			try {
+				found = found.unify(expected);
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found %s at '%s',\n%s", expected, found,
+						n.getOperator().getName(), n.getLocation()));
+			}
+			return found;
+		}
+
+		/***********************************************************************
+		 * TLA+ Built-Ins, but not in tlc.tool.BuiltInOPs
+		 ***********************************************************************/
+		case B_OPCODE_bool: // BOOLEAN
+			try {
+				SetType found = new SetType(BoolType.getInstance());
+				found = found.unify(expected);
+				return found;
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found POW(BOOL) at 'BOOLEAN',\n%s",
+						expected, n.getLocation()));
+			}
+
+		case B_OPCODE_string: // STRING
+			try {
+				SetType found = new SetType(StringType.getInstance());
+				found = found.unify(expected);
+				return found;
+			} catch (UnificationException e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found POW(STRING) at 'STRING',\n%s",
+						expected, n.getLocation()));
+			}
+
+		case B_OPCODE_true:
+		case B_OPCODE_false:
+			try {
+				BoolType.getInstance().unify(expected);
+				return BoolType.getInstance();
+			} catch (Exception e) {
+				throw new TypeErrorException(String.format(
+						"Expected %s, found BOOL at '%s',\n%s", expected, n
+								.getOperator().getName(), n.getLocation()));
+			}
+
+		default: {
+			throw new NotImplementedException(n.getOperator().getName()
+					.toString());
+		}
+		}
+	}
+
+	public static TLAType makePair(ArrayList<TLAType> list) {
+		if (list.size() == 0)
+			throw new RuntimeException("emptylist");
+		if (list.size() == 1)
+			return list.get(0);
+		PairType p = new PairType();
+		p.setFirst(list.get(0));
+		for (int i = 1; i < list.size(); i++) {
+			p.setSecond(list.get(i));
+			if (i < list.size() - 1) {
+				p = new PairType(p, null);
+			}
+		}
+		return p;
+	}
+
+}
diff --git a/src/main/java/de/tla2b/config/ConfigfileEvaluator.java b/src/main/java/de/tla2b/config/ConfigfileEvaluator.java
new file mode 100644
index 0000000000000000000000000000000000000000..99793b4b8d880fbffb2441219fbff3da1f04560a
--- /dev/null
+++ b/src/main/java/de/tla2b/config/ConfigfileEvaluator.java
@@ -0,0 +1,624 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.config;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+
+import de.tla2b.exceptions.ConfigFileErrorException;
+import de.tla2b.exceptions.UnificationException;
+import de.tla2b.types.BoolType;
+import de.tla2b.types.EnumType;
+import de.tla2b.types.IntType;
+import de.tla2b.types.ModelValueType;
+import de.tla2b.types.SetType;
+import de.tla2b.types.StringType;
+import de.tla2b.types.TLAType;
+import de.tla2b.types.Untyped;
+
+
+
+import tla2sany.semantic.InstanceNode;
+import tla2sany.semantic.ModuleNode;
+import tla2sany.semantic.OpDeclNode;
+import tla2sany.semantic.OpDefNode;
+import tla2sany.semantic.OpDefOrDeclNode;
+import tlc2.tool.ModelConfig;
+import tlc2.util.Vect;
+import tlc2.value.IntValue;
+import tlc2.value.ModelValue;
+import tlc2.value.SetEnumValue;
+import tlc2.value.Value;
+
+/**
+ * This class evaluates the configfile and collects all necessary information of
+ * the configfile. All used identifier in the configfile are checked to be valid
+ * in the context of the module
+ */
+public class ConfigfileEvaluator {
+
+	private ModelConfig configAst;
+	private ModuleNode moduleNode;
+	private Hashtable<String, OpDefNode> definitions;
+	// Hashtable of all definitons in module
+	private Hashtable<String, OpDeclNode> constants;
+	// Hashtable of all constants in the module
+
+	private OpDefNode specNode; // SPECIFICATION node, may be null
+	private OpDefNode nextNode; // NEXT node, may be null
+	private OpDefNode initNode; // INIT node, may be null
+	private ArrayList<OpDefNode> invariantNodeList;
+	// INVARIANT nodes, may be null
+	private ArrayList<String> enumeratedSet;
+	private LinkedHashMap<String, EnumType> enumeratedTypes;
+	private Hashtable<OpDeclNode, ValueObj> constantAssignments;
+	// k = 1, the ValueObj describes the right side of the assignment and
+	// contains it type
+	private Hashtable<OpDefNode, ValueObj> operatorAssignments;
+	// def = 1
+	
+	private ArrayList<OpDefNode> operatorModelvalues;
+
+	private ArrayList<OpDeclNode> bConstantList;
+	// List of constants in the resulting B machine. This list does not contain
+	// a TLA+ constant if the constant is substituted by a modelvalue with the
+	// same name (the constant name is moved to an enumerated set) or if the
+	// constants has arguments and is overriden by an operator
+	private Hashtable<OpDefNode, OpDefNode> operatorOverrideTable;
+	// This table contains mappings for operators which are overridden in the
+	// configuration file
+	private Hashtable<OpDeclNode, OpDefNode> constantOverrideTable;
+
+	// This table contains mappings for constants which are overridden in the
+	// configuration file. All constants with arguments have to be overridden in
+	// the configuration file.
+
+	/**
+	 * @param configAst
+	 * @param moduleNode
+	 */
+	public ConfigfileEvaluator(ModelConfig configAst, ModuleNode moduleNode) {
+		this.configAst = configAst;
+		this.moduleNode = moduleNode;
+
+		definitions = new Hashtable<String, OpDefNode>();
+		OpDefNode[] defs = moduleNode.getOpDefs();
+		for (int i = 0; i < defs.length; i++) {
+			definitions.put(defs[i].getName().toString(), defs[i]);
+		}
+
+		constants = new Hashtable<String, OpDeclNode>();
+		bConstantList = new ArrayList<OpDeclNode>();
+		OpDeclNode[] cons = moduleNode.getConstantDecls();
+		for (int i = 0; i < cons.length; i++) {
+			constants.put(cons[i].getName().toString(), cons[i]);
+			bConstantList.add(cons[i]);
+		}
+
+		this.constantOverrideTable = new Hashtable<OpDeclNode, OpDefNode>();
+		this.operatorOverrideTable = new Hashtable<OpDefNode, OpDefNode>();
+
+		this.constantAssignments = new Hashtable<OpDeclNode, ValueObj>();
+		this.operatorAssignments = new Hashtable<OpDefNode, ValueObj>();
+		this.operatorModelvalues = new ArrayList<OpDefNode>();
+
+		this.enumeratedSet = new ArrayList<String>();
+		this.enumeratedTypes = new LinkedHashMap<String, EnumType>();
+	}
+
+	/**
+	 * @throws ConfigFileErrorException
+	 * 
+	 */
+	public void start() throws ConfigFileErrorException {
+		evalNext(); // check if NEXT declaration is a valid definition
+		evalInit(); // check if INIT declaration is a valid definition
+		evalSpec(); // check if SPECIFICATION declaration is a valid definition
+
+		if (moduleNode.getVariableDecls().length > 0 && this.initNode == null
+				&& this.specNode == null) {
+			throw new ConfigFileErrorException(
+					"The module contains variables."
+							+ " Hence there must be eather a SPECIFICATION or INIT declaration.");
+		}
+
+		evalInvariants();
+		// check if INVARIANT declarations are valid definitions
+
+		evalConstantOrDefOverrides();
+
+		evalConstantOrOperatorAssignments();
+
+		evalModConOrDefAssignments();
+
+		evalModConOrDefOverrides();
+	}
+
+	private void evalNext() throws ConfigFileErrorException {
+		String next = configAst.getNext();
+		if (!next.equals("")) {
+			if (definitions.containsKey(next)) {
+				this.nextNode = definitions.get(next);
+			} else {
+				throw new ConfigFileErrorException(
+						"Invalid declaration of the next state predicate."
+								+ " Module does not contain the defintion '"
+								+ next + "'");
+			}
+		} else
+			next = null;
+
+	}
+
+	private void evalInit() throws ConfigFileErrorException {
+		String init = configAst.getInit();
+		if (!init.equals("")) {
+			if (definitions.containsKey(init)) {
+				this.initNode = definitions.get(init);
+			} else {
+				throw new ConfigFileErrorException(
+						"Invalid declaration of the initialisation predicate."
+								+ " Module does not contain the defintion '"
+								+ init + "'");
+			}
+		} else {
+			init = null;
+		}
+
+	}
+
+	private void evalSpec() throws ConfigFileErrorException {
+		String spec = configAst.getSpec();
+		if (!spec.equals("")) {
+			if (definitions.containsKey(spec)) {
+				this.specNode = definitions.get(spec);
+			} else {
+				throw new ConfigFileErrorException(
+						"Invalid declaration of the specification predicate."
+								+ "Module does not contain the defintion '"
+								+ spec + "'");
+			}
+		} else
+			spec = null;
+	}
+
+	private void evalInvariants() throws ConfigFileErrorException {
+
+		Vect v = configAst.getInvariants();
+		if (v.capacity() != 0) {
+			invariantNodeList = new ArrayList<OpDefNode>();
+			for (int i = 0; i < v.capacity(); i++) {
+				if (v.elementAt(i) != null) {
+					String inv = (String) v.elementAt(i);
+					if (!definitions.containsKey(inv)) {
+						throw new ConfigFileErrorException(
+								"Invalid invariant declaration. Module does not contain definition '"
+										+ inv + "'");
+					}
+					invariantNodeList.add(definitions.get(inv));
+				}
+			}
+		}
+
+	}
+
+	/**
+	 * Represents a override statement in the configuration file: k <- def
+	 * 
+	 * @throws ConfigFileErrorException
+	 */
+	@SuppressWarnings("unchecked")
+	private void evalConstantOrDefOverrides() throws ConfigFileErrorException {
+		Iterator<Map.Entry<String, String>> it = configAst.getOverrides()
+				.entrySet().iterator();
+		while (it.hasNext()) {
+			Map.Entry<String, String> entry = it.next();
+			String left = entry.getKey();
+			String right = entry.getValue();
+
+			OpDefNode rightDefNode = definitions.get(right);
+			if (rightDefNode == null) {
+				throw new ConfigFileErrorException("Invalid substitution for "
+						+ left + ".\n Module does not contain definition "
+						+ right + ".");
+			}
+
+			if (constants.containsKey(left)) {
+				// a constant is overridden by an operator
+				OpDeclNode conNode = constants.get(left);
+				if (conNode.getArity() != rightDefNode.getArity()) {
+					throw new ConfigFileErrorException(
+							String.format(
+									"Invalid substitution for %s.\n Constant %s has %s arguments while %s has %s arguments.",
+									left, left, conNode.getArity(), right,
+									rightDefNode.getArity()));
+				}
+				bConstantList.remove(conNode);
+				constantOverrideTable.put(conNode, rightDefNode);
+			} else if (definitions.containsKey(left)) {
+				// an operator is overridden by another operator
+				OpDefNode defNode = definitions.get(left);
+				if (defNode.getArity() != rightDefNode.getArity()) {
+					throw new ConfigFileErrorException(
+							String.format(
+									"Invalid substitution for %s.\n Operator %s has %s arguments while %s has %s arguments.",
+									left, left, defNode.getArity(), right,
+									rightDefNode.getArity()));
+				}
+
+				operatorOverrideTable.put(defNode, rightDefNode);
+			} else {
+				// every constants in the configuration file must appear in the
+				// TLA+
+				// module
+				throw new ConfigFileErrorException(
+						"Module does not contain the symbol: " + left);
+			}
+		}
+	}
+
+	private void evalConstantOrOperatorAssignments()
+			throws ConfigFileErrorException {
+		Vect configCons = configAst.getConstants();
+		// iterate over all constant or operator assignments in the config file
+		// k = 1 or def = 1
+		for (int i = 0; i < configCons.size(); i++) {
+			Vect symbol = (Vect) configCons.elementAt(i);
+			String symbolName = symbol.elementAt(0).toString();
+			Value symbolValue = (Value) symbol.elementAt(symbol.size() - 1);
+			TLAType symbolType = conGetType(symbol.elementAt(symbol.size() - 1));
+			if (constants.containsKey(symbolName)) {
+				OpDeclNode c = constants.get(symbolName);
+
+				ValueObj valueObj = new ValueObj(symbolValue, symbolType);
+				constantAssignments.put(c, valueObj);
+				/**
+				 * if conValue is a model value and the name of the value is the
+				 * same as the name of constants, then the constant declaration
+				 * in the resulting B machine disappears
+				 **/
+				if (symbolType instanceof EnumType && symbolName.equals(symbolValue.toString())) {
+					bConstantList.remove(c);
+				}
+			} else if (definitions.containsKey(symbolName)) {
+				OpDefNode def = definitions.get(symbolName);
+				ValueObj valueObj = new ValueObj(symbolValue, symbolType);
+				operatorAssignments.put(def, valueObj);
+				
+				if (symbolType instanceof SetType) {
+					if (((SetType) symbolType).getSubType() instanceof EnumType) {
+						operatorModelvalues.add(def);
+					}
+				} else if ((symbolType instanceof EnumType)) {
+					operatorModelvalues.add(def);
+				}
+				
+			} else {
+				// every constants or operator in the configuration file must
+				// appear in the TLA+
+				// module
+				throw new ConfigFileErrorException(
+						"Module does not contain the symbol: " + symbolName);
+			}
+		}
+
+	}
+
+	private void evalModConOrDefAssignments() throws ConfigFileErrorException {
+		// val = [Counter] 7
+		@SuppressWarnings("unchecked")
+		Hashtable<String, Vect> configCons = configAst.getModConstants();
+		Enumeration<String> moduleNames = configCons.keys();
+		while (moduleNames.hasMoreElements()) {
+			String moduleName = (String) moduleNames.nextElement();
+			ModuleNode mNode = searchModule(moduleName);
+			Vect assignments = configCons.get(moduleName);
+			for (int i = 0; i < assignments.size(); i++) {
+				Vect assigment = (Vect) assignments.elementAt(i);
+				OpDefOrDeclNode opDefOrDeclNode = searchDefinitionOrConstant(
+						mNode, (String) assigment.elementAt(0));
+				String symbolName = opDefOrDeclNode.getName().toString();
+				Value symbolValue = (Value) assigment.elementAt(1);
+				TLAType symbolType = conGetType(assigment.elementAt(1));
+				// System.out.println(symbolName + " " + symbolValue+ " " +
+				// symbolType);
+				if (opDefOrDeclNode instanceof OpDeclNode) {
+					// TODO test whether c is a extended constant
+					// Instanced constants have to overridden in the instance
+					// statement
+					OpDeclNode c = (OpDeclNode) opDefOrDeclNode;
+					ValueObj valueObj = new ValueObj(symbolValue, symbolType);
+					constantAssignments.put(c, valueObj);
+					/**
+					 * if conValue is a model value and the name of value is the
+					 * same as the name of constants, then the constant
+					 * declaration in the resulting B machine disappears
+					 **/
+					if (symbolName.equals(symbolValue.toString())) {
+						bConstantList.remove(c);
+					}
+				} else {
+					OpDefNode def = (OpDefNode) opDefOrDeclNode;
+					ValueObj valueObj = new ValueObj(symbolValue, symbolType);
+					operatorAssignments.put(def, valueObj);
+
+					if (symbolType instanceof SetType) {
+						if (((SetType) symbolType).getSubType() instanceof EnumType) {
+							operatorModelvalues.add(def);
+						}
+					} else if ((symbolType instanceof EnumType)) {
+						operatorModelvalues.add(def);
+					}
+					
+				}
+			}
+		}
+	}
+
+	private void evalModConOrDefOverrides() throws ConfigFileErrorException {
+		// foo <- [Counter] bar or k <- [Counter] bar
+		@SuppressWarnings("unchecked")
+		Hashtable<String, Hashtable<String, String>> configCons = configAst
+				.getModOverrides();
+		Enumeration<String> moduleNames = configCons.keys();
+		while (moduleNames.hasMoreElements()) {
+			String moduleName = moduleNames.nextElement();
+			ModuleNode mNode = searchModule(moduleName);
+			Hashtable<String, String> o = configCons.get(moduleName);
+
+			Iterator<Map.Entry<String, String>> it = o.entrySet().iterator();
+			while (it.hasNext()) {
+				Map.Entry<String, String> entry = it.next();
+				String left = entry.getKey();
+				String right = entry.getValue();
+
+				OpDefNode rightDefNode = definitions.get(right);
+				if (rightDefNode == null) {
+					throw new ConfigFileErrorException(
+							"Invalid substitution for " + left
+									+ ".\n Module does not contain definition "
+									+ right + ".");
+				}
+				OpDefOrDeclNode opDefOrDeclNode = searchDefinitionOrConstant(
+						mNode, left);
+
+				if (opDefOrDeclNode instanceof OpDefNode) {
+					// an operator is overridden by another operator
+					OpDefNode defNode = (OpDefNode) opDefOrDeclNode;
+					if (defNode.getArity() != rightDefNode.getArity()) {
+						throw new ConfigFileErrorException(
+								String.format(
+										"Invalid substitution for %s.\n Operator %s has %s arguments while %s has %s arguments.",
+										left, left, defNode.getArity(), right,
+										rightDefNode.getArity()));
+					}
+					operatorOverrideTable.put(defNode, rightDefNode);
+				}
+
+				else {
+					InstanceNode[] instanceNodes = moduleNode.getInstances();
+					for (int i = 0; i < instanceNodes.length; i++) {
+//						if (instanceNodes[i].getModule().getName().toString()
+//								.equals(moduleName)) {
+//							/*
+//							 * A constant overridden in a instanced module make
+//							 * no sence. Such a constant will be overridden by
+//							 * the instance statement
+//							 */
+//							throw new ConfigFileErrorException(
+//									String.format(
+//											"Invalid substitution for constant '%s' of module '%s'.\n A Constant of an instanced module can not be overriden.",
+//											left, mNode.getName().toString()));
+//						}
+					}
+					// a constant is overridden by an operator
+					OpDeclNode conNode = (OpDeclNode) opDefOrDeclNode;
+					if (conNode.getArity() != rightDefNode.getArity()) {
+						throw new ConfigFileErrorException(
+								String.format(
+										"Invalid substitution for %s.\n Constant %s has %s arguments while %s has %s arguments.",
+										left, left, conNode.getArity(), right,
+										rightDefNode.getArity()));
+					}
+					bConstantList.remove(conNode);
+					constantOverrideTable.put(conNode, rightDefNode);
+
+				}
+			}
+
+		}
+	}
+
+	public ModuleNode searchModule(String moduleName)
+			throws ConfigFileErrorException {
+		/*
+		 * Search module in extended modules
+		 */
+		@SuppressWarnings("unchecked")
+		HashSet<ModuleNode> extendedModules = moduleNode.getExtendedModuleSet();
+		for (Iterator<ModuleNode> iterator = extendedModules.iterator(); iterator
+				.hasNext();) {
+			ModuleNode m = (ModuleNode) iterator.next();
+			if (m.getName().toString().equals(moduleName)) {
+				return m;
+			}
+		}
+
+		/*
+		 * search module in instanced modules
+		 */
+		
+
+		OpDefNode [] defs = moduleNode.getOpDefs();
+		for (int j = defs.length-1; j > 0; j--) {
+			OpDefNode def = null;
+			OpDefNode source = defs[j];
+			while(def!=source){
+				def = source;
+				source = def.getSource();
+				ModuleNode m = def.getOriginallyDefinedInModuleNode();
+				if(m.getName().toString().equals(moduleName)){
+					return m;
+				}
+			}
+		}
+		throw new ConfigFileErrorException(
+				String.format(
+						"Module '%s' is not included in the specification.",
+						moduleName));
+	}
+
+	public OpDefOrDeclNode searchDefinitionOrConstant(ModuleNode n,
+			String defOrConName) throws ConfigFileErrorException {
+		for (int i = 0; i < n.getOpDefs().length; i++) {
+			if (n.getOpDefs()[i].getName().toString().equals(defOrConName)) {
+				return n.getOpDefs()[i];
+			}
+		}
+		for (int i = 0; i < n.getConstantDecls().length; i++) {
+			if (n.getConstantDecls()[i].getName().toString()
+					.equals(defOrConName)) {
+				return n.getConstantDecls()[i];
+			}
+		}
+		throw new ConfigFileErrorException(
+				"Module does not contain the symbol: " + defOrConName);
+	}
+
+	private TLAType conGetType(Object o) throws ConfigFileErrorException {
+		if (o instanceof IntValue) {
+
+			// IntValue iv = (IntValue) o;
+			return IntType.getInstance();
+		} else if (o.getClass().getName().equals("tlc2.value.SetEnumValue")) {
+			SetEnumValue set = (SetEnumValue) o;
+			SetType t = new SetType(new Untyped());
+			if (set.size() == 0) {
+				throw new ConfigFileErrorException(
+						"empty set is not permitted!");
+			}
+			TLAType elemType;
+
+			if (set.elems.elementAt(0).getClass().getName()
+					.equals("tlc2.value.ModelValue")) {
+				EnumType e = new EnumType(new ArrayList<String>());
+				for (int i = 0; i < set.size(); i++) {
+					if (set.elems.elementAt(i).getClass().getName()
+							.equals("tlc2.value.ModelValue")) {
+						String mv = ((ModelValue) set.elems.elementAt(i))
+								.toString();
+						if (!enumeratedSet.contains(mv)) {
+							enumeratedSet.add(mv);
+							e.modelvalues.add(mv);
+						} else {
+							e.modelvalues.add(mv);
+							EnumType e2 = enumeratedTypes.get(mv);
+							try {
+								e = e2.unify(e2);
+							} catch (UnificationException exception) {
+							}
+						}
+
+					} else {
+						throw new ConfigFileErrorException(
+								"Elements of the set must have the same type: "
+										+ o);
+					}
+				}
+				Iterator<String> it = e.modelvalues.iterator();
+				while (it.hasNext()) {
+					enumeratedTypes.put(it.next(), e);
+				}
+				elemType = e;
+			} else {
+				elemType = conGetType(set.elems.elementAt(0));
+				for (int i = 1; i < set.size(); i++) {
+					elemType = conGetType(set.elems.elementAt(i));
+					// all Elements have the same Type?
+					if (!t.getSubType().compare(elemType)) {
+						throw new ConfigFileErrorException(
+								"Elements of the set must have the same type: "
+										+ o);
+					}
+				}
+			}
+			t.setSubType(elemType);
+			return t;
+
+		} else if (o.getClass().getName().equals("tlc2.value.ModelValue")) {
+			ModelValue mv = (ModelValue) o;
+			if (!enumeratedSet.contains(mv.toString())) {
+				enumeratedSet.add(mv.toString());
+				ArrayList<String> temp = new ArrayList<String>();
+				temp.add(mv.toString());
+				EnumType e = new EnumType(temp);
+				enumeratedTypes.put(mv.toString(), e);
+				return e;
+			} else {
+				return enumeratedTypes.get(mv.toString());
+			}
+
+		} else if (o.getClass().getName().equals("tlc2.value.StringValue")) {
+			return StringType.getInstance();
+		} else if (o.getClass().getName().equals("tlc2.value.BoolValue")) {
+			return BoolType.getInstance();
+		} else {
+			throw new ConfigFileErrorException("Unkown ConstantType: " + o
+					+ " " + o.getClass());
+		}
+	}
+
+	public OpDefNode getSpecNode() {
+		return specNode;
+	}
+
+	public OpDefNode getNextNode() {
+		return nextNode;
+	}
+
+	public OpDefNode getInitNode() {
+		return initNode;
+	}
+
+	public Hashtable<OpDeclNode, OpDefNode> getConstantOverrideTable() {
+		return constantOverrideTable;
+	}
+
+	public ArrayList<OpDefNode> getInvariants() {
+		return this.invariantNodeList;
+	}
+
+	public Hashtable<OpDeclNode, ValueObj> getConstantAssignments() {
+		return this.constantAssignments;
+	}
+
+	public Hashtable<OpDefNode, ValueObj> getOperatorAssignments() {
+		return this.operatorAssignments;
+	}
+
+	public ArrayList<OpDeclNode> getbConstantList() {
+		return bConstantList;
+	}
+
+	public Hashtable<OpDefNode, OpDefNode> getOperatorOverrideTable() {
+		return operatorOverrideTable;
+	}
+
+	public ArrayList<String> getEnumerationSet() {
+		return this.enumeratedSet;
+	}
+	
+	public ArrayList<OpDefNode> getOperatorModelvalues(){
+		return this.operatorModelvalues;
+	}
+}
diff --git a/src/main/java/de/tla2b/config/ModuleOverrider.java b/src/main/java/de/tla2b/config/ModuleOverrider.java
new file mode 100644
index 0000000000000000000000000000000000000000..e344f8d70fd12964749248ec2ddd35d9667b0608
--- /dev/null
+++ b/src/main/java/de/tla2b/config/ModuleOverrider.java
@@ -0,0 +1,229 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.config;
+
+import java.util.Hashtable;
+
+import tla2sany.semantic.ASTConstants;
+import tla2sany.semantic.AbortException;
+import tla2sany.semantic.AssumeNode;
+import tla2sany.semantic.ExprNode;
+import tla2sany.semantic.ExprOrOpArgNode;
+import tla2sany.semantic.LetInNode;
+import tla2sany.semantic.ModuleNode;
+import tla2sany.semantic.OpApplNode;
+import tla2sany.semantic.OpDeclNode;
+import tla2sany.semantic.OpDefNode;
+import tla2sany.semantic.SymbolNode;
+import tlc2.tool.BuiltInOPs;
+
+public class ModuleOverrider extends BuiltInOPs implements ASTConstants {
+
+	private ModuleNode moduleNode;
+	private Hashtable<OpDeclNode, OpDefNode> constantOverrideTable;
+	private Hashtable<OpDefNode, OpDefNode> operatorOverrideTable;
+	private Hashtable<OpDefNode, ValueObj> operatorAssignments;
+
+	/**
+	 * @param constantOverrideTable
+	 * @param operatorOverrideTable
+	 */
+	public ModuleOverrider(ModuleNode moduleNode,
+			Hashtable<OpDeclNode, OpDefNode> constantOverrideTable,
+			Hashtable<OpDefNode, OpDefNode> operatorOverrideTable,
+			Hashtable<OpDefNode, ValueObj> operatorAssignments) {
+		this.moduleNode = moduleNode;
+		this.constantOverrideTable = constantOverrideTable;
+		this.operatorOverrideTable = operatorOverrideTable;
+		this.operatorAssignments = operatorAssignments;
+	}
+
+	/**
+	 * @param moduleNode2
+	 * @param conEval
+	 */
+	public ModuleOverrider(ModuleNode moduleNode, ConfigfileEvaluator conEval) {
+		this.moduleNode = moduleNode;
+		this.constantOverrideTable = conEval.getConstantOverrideTable();
+		this.operatorOverrideTable = conEval.getOperatorOverrideTable();
+		this.operatorAssignments = conEval.getOperatorAssignments();
+	}
+
+	public void start() {
+		OpDefNode[] defs = moduleNode.getOpDefs();
+		for (int i = 0; i < defs.length; i++) {
+			OpDefNode def = defs[i];
+			if (operatorAssignments.containsKey(def)) {
+				ExprNode oldExpr = def.getBody();
+				TLCValueNode valueNode;
+				try {
+					valueNode = new TLCValueNode(operatorAssignments.get(def),
+							oldExpr.getTreeNode());
+				} catch (AbortException e) {
+					throw new RuntimeException();
+				}
+				def.setBody(valueNode);
+			} else if (operatorAssignments.containsKey(def.getSource())) {
+				ExprNode oldExpr = def.getBody();
+				TLCValueNode valueNode;
+				try {
+					valueNode = new TLCValueNode(operatorAssignments.get(def
+							.getSource()), oldExpr.getTreeNode());
+				} catch (AbortException e) {
+					throw new RuntimeException();
+				}
+				def.setBody(valueNode);
+			}
+
+		}
+
+		for (int i = 0; i < defs.length; i++) {
+			OpApplNode res = visitExprNode(defs[i].getBody());
+			if (res != null) {
+				defs[i].setBody(res);
+			}
+		}
+
+		AssumeNode[] assumes = moduleNode.getAssumptions();
+		for (int i = 0; i < assumes.length; i++) {
+			AssumeNode assume = assumes[i];
+			OpApplNode res = visitExprNode(assume.getAssume());
+			if (res != null) {
+
+				AssumeNode newAssume = new AssumeNode(assume.stn, res, null,
+						null);
+				assumes[i] = newAssume;
+			}
+		}
+	}
+
+	private OpApplNode visitExprOrOpArgNode(ExprOrOpArgNode n) {
+		if (n instanceof ExprNode) {
+
+			return visitExprNode((ExprNode) n);
+		} else {
+			throw new RuntimeException("OpArgNode not implemented jet");
+		}
+	}
+
+	/**
+	 * @param body
+	 */
+	private OpApplNode visitExprNode(ExprNode n) {
+
+		switch (n.getKind()) {
+		case OpApplKind:
+			return (OpApplNode) visitOpApplNode((OpApplNode) n);
+
+		case StringKind:
+		case AtNodeKind: // @
+		case NumeralKind: {
+			return null;
+		}
+
+		case LetInKind: {
+			LetInNode l = (LetInNode) n;
+			for (int i = 0; i < l.getLets().length; i++) {
+				visitExprNode(l.getLets()[i].getBody());
+			}
+
+			OpApplNode res = visitExprNode(l.getBody());
+			if (res != null) {
+				throw new RuntimeException();
+			}
+			return null;
+		}
+		}
+		return null;
+	}
+
+	/**
+	 * @param n
+	 */
+	private OpApplNode visitOpApplNode(OpApplNode n) {
+		SymbolNode s = n.getOperator();
+		switch (s.getKind()) {
+		case ConstantDeclKind: {
+			if (constantOverrideTable.containsKey(s)) {
+				SymbolNode newOperator = constantOverrideTable.get(s);
+				OpApplNode newNode = null;
+				try {
+					newNode = new OpApplNode(newOperator, n.getArgs(),
+							n.getTreeNode(), null);
+				} catch (AbortException e) {
+					throw new RuntimeException();
+				}
+				for (int i = 0; i < n.getArgs().length; i++) {
+					if (n.getArgs()[i] != null) {
+						OpApplNode res = visitExprOrOpArgNode(n.getArgs()[i]);
+						if (res != null) {
+							n.getArgs()[i] = res;
+						}
+					}
+
+				}
+				// n.setOperator(constantOverrideTable.get(s));
+				return newNode;
+			}
+			break;
+
+		}
+		case FormalParamKind: // Params are not global in the modul
+		case VariableDeclKind: // TODO try to override variable
+			break;
+
+		case BuiltInKind:// Buildin operator can not be overridden by in the
+							// configuration file
+			ExprNode[] ins = n.getBdedQuantBounds();
+			for (int i = 0; i < ins.length; i++) {
+
+				OpApplNode res = visitExprOrOpArgNode(ins[i]);
+				if (res != null) {
+					ins[i] = res;
+				}
+			}
+			break;
+
+		case UserDefinedOpKind: {
+			if (operatorOverrideTable.containsKey(s)) {
+				SymbolNode newOperator = operatorOverrideTable.get(s);
+				OpApplNode newNode = null;
+				OpDefNode def = (OpDefNode) n.getOperator();
+				try {
+					newNode = new OpApplNode(newOperator, n.getArgs(),
+							n.getTreeNode(), def.getOriginallyDefinedInModuleNode());
+				} catch (AbortException e) {
+					e.printStackTrace();
+				}
+
+				for (int i = 0; i < n.getArgs().length; i++) {
+					if (n.getArgs()[i] != null) {
+						OpApplNode res = visitExprOrOpArgNode(n.getArgs()[i]);
+						if (res != null) {
+							n.getArgs()[i] = res;
+						}
+					}
+
+				}
+				// n.setOperator(constantOverrideTable.get(s));
+				return newNode;
+			}
+			break;
+		}
+		}
+
+		for (int i = 0; i < n.getArgs().length; i++) {
+			if (n.getArgs()[i] != null) {
+				OpApplNode res = visitExprOrOpArgNode(n.getArgs()[i]);
+				if (res != null) {
+					n.getArgs()[i] = res;
+				}
+			}
+
+		}
+		return null;
+	}
+
+}
diff --git a/src/main/java/de/tla2b/config/TLCValueNode.java b/src/main/java/de/tla2b/config/TLCValueNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f47a062423b0f1e7a30e21812e2f0f6fa836db1
--- /dev/null
+++ b/src/main/java/de/tla2b/config/TLCValueNode.java
@@ -0,0 +1,43 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.config;
+
+import de.tla2b.global.TranslationGlobals;
+import de.tla2b.types.TLAType;
+import tla2sany.semantic.AbortException;
+import tla2sany.semantic.NumeralNode;
+import tla2sany.st.TreeNode;
+import tlc2.value.Value;
+
+public class TLCValueNode extends NumeralNode implements TranslationGlobals {
+
+	private Value value;
+	private TLAType type;
+
+	/**
+	 * @param kind
+	 * @param stn
+	 * @throws AbortException 
+	 */
+	public TLCValueNode(ValueObj valObj, TreeNode stn) throws AbortException {
+		super("1337", stn);
+		this.value = valObj.getValue();
+		this.type = valObj.getType();
+	}
+
+	public String toString2() {
+		return "\n*TLCValueNode: Value: '"
+				+ value.toString() + "'";
+				
+	}
+
+	public TLAType getType() {
+		return type;
+	}
+
+	public Value getValue() {
+		return value;
+	}
+}
diff --git a/src/main/java/de/tla2b/config/ValueObj.java b/src/main/java/de/tla2b/config/ValueObj.java
new file mode 100644
index 0000000000000000000000000000000000000000..668add56ef239c479dbda0aa241520f8daa04e27
--- /dev/null
+++ b/src/main/java/de/tla2b/config/ValueObj.java
@@ -0,0 +1,35 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.config;
+
+import de.tla2b.types.TLAType;
+import tlc2.value.Value;
+
+public class ValueObj {
+	private Value value;
+	private TLAType type;
+
+	public ValueObj(Value value, TLAType t) {
+		this.value = value;
+		this.type = t;
+	}
+
+	public Value getValue() {
+		return value;
+	}
+
+	public void setValue(Value value) {
+		this.value = value;
+	}
+
+	public void setType(TLAType type) {
+		this.type = type;
+	}
+	
+	public TLAType getType(){
+		return type;
+	}
+		
+}
diff --git a/src/main/java/de/tla2b/exceptions/ConfigFileErrorException.java b/src/main/java/de/tla2b/exceptions/ConfigFileErrorException.java
new file mode 100644
index 0000000000000000000000000000000000000000..e3f61bf965f63be772d2b10652b9644c24af90d8
--- /dev/null
+++ b/src/main/java/de/tla2b/exceptions/ConfigFileErrorException.java
@@ -0,0 +1,10 @@
+package de.tla2b.exceptions;
+
+
+@SuppressWarnings("serial")
+public class ConfigFileErrorException extends TLA2BException{
+
+	public ConfigFileErrorException(String s) {
+		super(s);
+	}
+}
diff --git a/src/main/java/de/tla2b/exceptions/FrontEndException.java b/src/main/java/de/tla2b/exceptions/FrontEndException.java
new file mode 100644
index 0000000000000000000000000000000000000000..ffca417cadc710e48e22fe18c115a7c6db95ef04
--- /dev/null
+++ b/src/main/java/de/tla2b/exceptions/FrontEndException.java
@@ -0,0 +1,17 @@
+package de.tla2b.exceptions;
+
+import tla2sany.modanalyzer.SpecObj;
+
+@SuppressWarnings("serial")
+public class FrontEndException extends TLA2BException{
+
+	public SpecObj spec;
+	public FrontEndException(String e){
+		super(e);
+	}
+
+	public FrontEndException(String string, SpecObj spec) {
+		super(string);
+		this.spec = spec;
+	}
+}
diff --git a/src/main/java/de/tla2b/exceptions/ModuleErrorException.java b/src/main/java/de/tla2b/exceptions/ModuleErrorException.java
new file mode 100644
index 0000000000000000000000000000000000000000..ac91a246218bd77be479def32846c1479d292c67
--- /dev/null
+++ b/src/main/java/de/tla2b/exceptions/ModuleErrorException.java
@@ -0,0 +1,10 @@
+package de.tla2b.exceptions;
+
+
+@SuppressWarnings("serial")
+public class ModuleErrorException extends TLA2BException{
+	public ModuleErrorException(String e){
+		super(e);
+	}
+
+}
diff --git a/src/main/java/de/tla2b/exceptions/NotImplementedException.java b/src/main/java/de/tla2b/exceptions/NotImplementedException.java
new file mode 100644
index 0000000000000000000000000000000000000000..d386450ccf274b3f2957468d126e0efbba697fef
--- /dev/null
+++ b/src/main/java/de/tla2b/exceptions/NotImplementedException.java
@@ -0,0 +1,10 @@
+package de.tla2b.exceptions;
+
+
+@SuppressWarnings("serial")
+public class NotImplementedException extends TLA2BException {
+	public NotImplementedException(String e){
+		super(e);
+	}
+
+}
diff --git a/src/main/java/de/tla2b/exceptions/SemanticErrorException.java b/src/main/java/de/tla2b/exceptions/SemanticErrorException.java
new file mode 100644
index 0000000000000000000000000000000000000000..6af42f002872b1d925d7710e362819ba0bc9be7c
--- /dev/null
+++ b/src/main/java/de/tla2b/exceptions/SemanticErrorException.java
@@ -0,0 +1,14 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.exceptions;
+
+@SuppressWarnings("serial")
+public class SemanticErrorException extends TLA2BException {
+	
+	public SemanticErrorException(String e){
+		super(e);
+	}
+
+}
diff --git a/src/main/java/de/tla2b/exceptions/TLA2BException.java b/src/main/java/de/tla2b/exceptions/TLA2BException.java
new file mode 100644
index 0000000000000000000000000000000000000000..edb67f65d4bd0439e6334e19b0c0c04491777225
--- /dev/null
+++ b/src/main/java/de/tla2b/exceptions/TLA2BException.java
@@ -0,0 +1,9 @@
+package de.tla2b.exceptions;
+
+@SuppressWarnings("serial")
+public abstract class TLA2BException extends Exception{
+
+	public TLA2BException(String e){
+		super(e);
+	}
+}
diff --git a/src/main/java/de/tla2b/exceptions/TLA2BIOException.java b/src/main/java/de/tla2b/exceptions/TLA2BIOException.java
new file mode 100644
index 0000000000000000000000000000000000000000..f8541148e9d3ca58c627d4e292dca11562ea5a7a
--- /dev/null
+++ b/src/main/java/de/tla2b/exceptions/TLA2BIOException.java
@@ -0,0 +1,10 @@
+package de.tla2b.exceptions;
+
+@SuppressWarnings("serial")
+public class TLA2BIOException extends TLA2BException {
+
+	
+	public TLA2BIOException(String e){
+		super(e);
+	}
+}
diff --git a/src/main/java/de/tla2b/exceptions/TypeErrorException.java b/src/main/java/de/tla2b/exceptions/TypeErrorException.java
new file mode 100644
index 0000000000000000000000000000000000000000..cea021a7de097285f2208fd5edbe1e1cccd56514
--- /dev/null
+++ b/src/main/java/de/tla2b/exceptions/TypeErrorException.java
@@ -0,0 +1,11 @@
+package de.tla2b.exceptions;
+
+
+@SuppressWarnings("serial")
+public class TypeErrorException extends TLA2BException {
+
+
+	public TypeErrorException(String s) {
+		super(s);
+	}
+}
diff --git a/src/main/java/de/tla2b/exceptions/UnificationException.java b/src/main/java/de/tla2b/exceptions/UnificationException.java
new file mode 100644
index 0000000000000000000000000000000000000000..710fbc9a332bc6bda869c639cf395e7bbccacf7e
--- /dev/null
+++ b/src/main/java/de/tla2b/exceptions/UnificationException.java
@@ -0,0 +1,12 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.exceptions;
+@SuppressWarnings("serial")
+public class UnificationException extends TLA2BException{
+
+	public UnificationException() {
+		super(null);
+	}
+}
diff --git a/src/main/java/de/tla2b/global/BBuildIns.java b/src/main/java/de/tla2b/global/BBuildIns.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a6e238542e7611103b0710c1237cf2f61c05a4e
--- /dev/null
+++ b/src/main/java/de/tla2b/global/BBuildIns.java
@@ -0,0 +1,126 @@
+package de.tla2b.global;
+
+import util.UniqueString;
+
+public interface BBuildIns {
+	public static final UniqueString OP_dotdot = UniqueString
+			.uniqueStringOf("..");
+	public static final UniqueString OP_plus = UniqueString.uniqueStringOf("+");
+	public static final UniqueString OP_minus = UniqueString
+			.uniqueStringOf("-");
+	public static final UniqueString OP_times = UniqueString
+			.uniqueStringOf("*");
+	public static final UniqueString OP_div = UniqueString
+			.uniqueStringOf("\\div");
+	public static final UniqueString OP_mod = UniqueString.uniqueStringOf("%");
+	public static final UniqueString OP_exp = UniqueString.uniqueStringOf("^");
+
+	public static final UniqueString OP_uminus = UniqueString
+			.uniqueStringOf("-.");
+
+	public static final UniqueString OP_lt = UniqueString.uniqueStringOf("<");
+	public static final UniqueString OP_leq = UniqueString
+			.uniqueStringOf("\\leq");
+	public static final UniqueString OP_gt = UniqueString.uniqueStringOf(">");
+	public static final UniqueString OP_geq = UniqueString
+			.uniqueStringOf("\\geq");
+
+	public static final UniqueString OP_nat = UniqueString
+			.uniqueStringOf("Nat");
+	public static final UniqueString OP_int = UniqueString
+			.uniqueStringOf("Int");
+	public static final UniqueString OP_bool = UniqueString
+			.uniqueStringOf("BOOLEAN");
+	public static final UniqueString OP_true = UniqueString
+			.uniqueStringOf("TRUE");
+	public static final UniqueString OP_false = UniqueString
+			.uniqueStringOf("FALSE");
+	public static final UniqueString OP_string = UniqueString
+			.uniqueStringOf("STRING");
+
+	// Sets
+	public static final UniqueString OP_card = UniqueString
+			.uniqueStringOf("Cardinality");
+	public static final UniqueString OP_finite = UniqueString
+			.uniqueStringOf("IsFiniteSet");
+
+	// Sequences
+	public static final UniqueString OP_len = UniqueString
+			.uniqueStringOf("Len");
+	public static final UniqueString OP_append = UniqueString
+			.uniqueStringOf("Append");
+	public static final UniqueString OP_seq = UniqueString
+			.uniqueStringOf("Seq");
+	public static final UniqueString OP_head = UniqueString
+			.uniqueStringOf("Head");
+	public static final UniqueString OP_tail = UniqueString
+			.uniqueStringOf("Tail");
+	public static final UniqueString OP_subseq = UniqueString
+			.uniqueStringOf("SubSeq");
+	public static final UniqueString OP_conc = UniqueString
+	.uniqueStringOf("\\o");
+	
+	//TLA2B
+	public static final UniqueString OP_min = UniqueString
+			.uniqueStringOf("MinOfSet");
+	public static final UniqueString OP_max = UniqueString
+			.uniqueStringOf("MaxOfSet");
+	public static final UniqueString OP_setprod = UniqueString
+			.uniqueStringOf("SetProduct");
+	public static final UniqueString OP_setsum = UniqueString
+			.uniqueStringOf("SetSummation");
+	public static final UniqueString OP_permseq = UniqueString
+			.uniqueStringOf("PermutedSequences");
+
+	//BBuildIns
+	public static final UniqueString OP_pow1 = UniqueString
+			.uniqueStringOf("POW1");
+	
+	
+	//Relations
+	public static final UniqueString OP_rel_inverse = UniqueString
+			.uniqueStringOf("rel_inverse");
+	
+	public static final int B_OPCODE_dotdot = 1;
+	public static final int B_OPCODE_plus = 2;
+	public static final int B_OPCODE_minus = 3;
+	public static final int B_OPCODE_times = 4;
+	public static final int B_OPCODE_div = 5;
+	public static final int B_OPCODE_exp = 6;
+	public static final int B_OPCODE_uminus = 7;
+	public static final int B_OPCODE_mod = 8;
+
+	public static final int B_OPCODE_lt = B_OPCODE_mod + 1;
+	public static final int B_OPCODE_leq = B_OPCODE_mod + 2;
+	public static final int B_OPCODE_gt = B_OPCODE_mod + 3;
+	public static final int B_OPCODE_geq = B_OPCODE_mod + 4;
+
+	public static final int B_OPCODE_nat = B_OPCODE_geq + 1;
+	public static final int B_OPCODE_bool = B_OPCODE_geq + 2;
+	public static final int B_OPCODE_true = B_OPCODE_geq + 3;
+	public static final int B_OPCODE_false = B_OPCODE_geq + 4;
+	public static final int B_OPCODE_int = B_OPCODE_geq + 5;
+	public static final int B_OPCODE_string = B_OPCODE_geq + 6;
+
+	public static final int B_OPCODE_finite = B_OPCODE_string + 1;
+	public static final int B_OPCODE_card = B_OPCODE_string + 2;
+
+	public static final int B_OPCODE_len = B_OPCODE_card + 1;
+	public static final int B_OPCODE_append = B_OPCODE_card + 2;
+	public static final int B_OPCODE_seq = B_OPCODE_card + 3;
+	public static final int B_OPCODE_head = B_OPCODE_card + 4;
+	public static final int B_OPCODE_tail = B_OPCODE_card + 5;
+	public static final int B_OPCODE_subseq = B_OPCODE_card + 6;
+	public static final int B_OPCODE_conc = B_OPCODE_card + 7;
+
+	public static final int B_OPCODE_min = B_OPCODE_conc + 1;
+	public static final int B_OPCODE_max = B_OPCODE_conc + 2;
+	public static final int B_OPCODE_setprod = B_OPCODE_conc + 3;
+	public static final int B_OPCODE_setsum = B_OPCODE_conc + 4;
+	public static final int B_OPCODE_permseq = B_OPCODE_conc + 5;
+	
+	public static final int B_OPCODE_pow1 = B_OPCODE_permseq + 1;
+	
+	
+	public static final int B_OPCODE_rel_inverse = B_OPCODE_pow1 + 1;
+}
diff --git a/src/main/java/de/tla2b/global/BBuiltInOPs.java b/src/main/java/de/tla2b/global/BBuiltInOPs.java
new file mode 100644
index 0000000000000000000000000000000000000000..b3d770ae27bdcd51efd1f8d15d359d7e445d3736
--- /dev/null
+++ b/src/main/java/de/tla2b/global/BBuiltInOPs.java
@@ -0,0 +1,64 @@
+package de.tla2b.global;
+
+
+import java.util.Hashtable;
+
+import util.UniqueString;
+
+public class BBuiltInOPs implements BBuildIns{
+	private static Hashtable<UniqueString, Integer> B_Opcode_Table;
+	static {
+		B_Opcode_Table = new Hashtable<UniqueString, Integer>();
+		B_Opcode_Table.put(OP_dotdot, B_OPCODE_dotdot);
+		B_Opcode_Table.put(OP_plus, B_OPCODE_plus);
+		B_Opcode_Table.put(OP_minus, B_OPCODE_minus);
+		B_Opcode_Table.put(OP_times, B_OPCODE_times);
+		B_Opcode_Table.put(OP_div, B_OPCODE_div);
+		B_Opcode_Table.put(OP_mod, B_OPCODE_mod);
+		B_Opcode_Table.put(OP_exp, B_OPCODE_exp);
+		B_Opcode_Table.put(OP_uminus, B_OPCODE_uminus);
+		
+		B_Opcode_Table.put(OP_lt, B_OPCODE_lt);
+		B_Opcode_Table.put(OP_leq, B_OPCODE_leq);
+		B_Opcode_Table.put(OP_gt, B_OPCODE_gt);
+		B_Opcode_Table.put(OP_geq, B_OPCODE_geq);
+		B_Opcode_Table.put(OP_bool, B_OPCODE_bool);
+		B_Opcode_Table.put(OP_true, B_OPCODE_true);
+		B_Opcode_Table.put(OP_false, B_OPCODE_false);
+		B_Opcode_Table.put(OP_nat, B_OPCODE_nat);
+		B_Opcode_Table.put(OP_int, B_OPCODE_int);
+		B_Opcode_Table.put(OP_string, B_OPCODE_string);
+		
+		B_Opcode_Table.put(OP_finite, B_OPCODE_finite);
+		B_Opcode_Table.put(OP_card, B_OPCODE_card);
+		
+		B_Opcode_Table.put(OP_len, B_OPCODE_len);
+		B_Opcode_Table.put(OP_append, B_OPCODE_append);
+		B_Opcode_Table.put(OP_seq, B_OPCODE_seq);
+		B_Opcode_Table.put(OP_head, B_OPCODE_head);
+		B_Opcode_Table.put(OP_tail, B_OPCODE_tail);
+		B_Opcode_Table.put(OP_subseq, B_OPCODE_subseq);
+		B_Opcode_Table.put(OP_conc, B_OPCODE_conc);
+		
+		B_Opcode_Table.put(OP_min, B_OPCODE_min);
+		B_Opcode_Table.put(OP_max, B_OPCODE_max);
+		B_Opcode_Table.put(OP_setprod, B_OPCODE_setprod);
+		B_Opcode_Table.put(OP_setsum, B_OPCODE_setsum);
+		B_Opcode_Table.put(OP_permseq, B_OPCODE_permseq);
+		
+		B_Opcode_Table.put(OP_pow1, B_OPCODE_pow1);
+		
+		//relations
+		B_Opcode_Table.put(OP_rel_inverse, B_OPCODE_rel_inverse);
+		
+		
+	}
+	
+	public static boolean contains(UniqueString s){
+		return B_Opcode_Table.containsKey(s);
+	}
+	
+	public static int getOpcode(UniqueString s){
+		return B_Opcode_Table.get(s);
+	}
+}
diff --git a/src/main/java/de/tla2b/global/Priorities.java b/src/main/java/de/tla2b/global/Priorities.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf3f23168d0ff0c7f543aaf23c300dd7e2991be3
--- /dev/null
+++ b/src/main/java/de/tla2b/global/Priorities.java
@@ -0,0 +1,76 @@
+package de.tla2b.global;
+
+public interface Priorities {
+	public static final int P_max = 300;
+	
+	public static final int P_record_acc = 250;
+	public static final int P_uminus = 210;
+	public static final int P_exp = 200;
+	
+	public static final int P_times = 190;
+	public static final int P_div = 190;
+	public static final int P_mod = 190;
+	
+	
+	
+	public static final int P_plus = 180;
+	public static final int P_minus = 180;
+	public static final int P_setdiff = 180;
+	
+	public static final int P_dotdot = 170;
+	
+	public static final int P_maplet = 160;
+	
+	public static final int P_take_first = 160;
+	public static final int P_drop_last = 160;
+	public static final int P_conc = 160;
+	
+	public static final int P_intersect = 140;
+	public static final int P_union = 140;
+	
+	
+	public static final int P_append = 130;
+	
+	public static final int P_total_f = 125;
+	
+	public static final int P_comma = 115;
+	
+
+	
+	public static final int P_rel_overriding = 90;
+	
+	public static final int P_in = 60;
+	public static final int P_notin = 60;
+	public static final int P_subseteq = 60;
+	
+	public static final int P_equals = 50;
+	public static final int P_noteq = 50;
+	public static final int P_gt = 50;
+	public static final int P_lt = 50;
+	public static final int P_leq = 50;
+	public static final int P_geq = 50;
+	
+	public static final int P_equiv = 60;
+	
+	public static final int P_and = 40;
+	public static final int P_or = 40;
+	
+
+	public static final int P_implies = 30;
+	
+	public static final int P_min = 0;
+	
+	
+	
+	
+
+	
+
+	
+	
+	
+	
+	
+	
+	
+}
diff --git a/src/main/java/de/tla2b/global/TranslationGlobals.java b/src/main/java/de/tla2b/global/TranslationGlobals.java
new file mode 100644
index 0000000000000000000000000000000000000000..3fcfb30e1e04f868efde550a4713b0acc5ed94c1
--- /dev/null
+++ b/src/main/java/de/tla2b/global/TranslationGlobals.java
@@ -0,0 +1,32 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.global;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import tla2sany.semantic.FrontEnd;
+
+public interface TranslationGlobals {
+	final String VERSION = "1.0.7";
+
+	final int TLCValueKind = 100;
+
+	final int USED = FrontEnd.getToolId();
+	final int OVERRIDE_SUBSTITUTION_ID = 17;
+	final int CONSTANT_OBJECT = 18;
+	final int DEF_OBJECT = 19;
+	final int PRINT_DEFINITION = 11;
+	final int TYPE_ID = 5;
+	final int LET_PARAMS_ID = 13;
+	final int NEW_NAME = 20;
+
+	final String CHOOSE = " CHOOSE(X) == \"a member of X\"; EXTERNAL_FUNCTION_CHOOSE(T) == (POW(T)-->T)";
+	final String IF_THEN_ELSE = " IF_THEN_ELSE(P, a, b) == (%t_.(t_ = TRUE & P = TRUE | a )\\/%t_.(t_= TRUE & not(P= TRUE) | b ))(TRUE)";
+
+	final ArrayList<String> STANDARD_MODULES = new ArrayList<String>(
+			Arrays.asList(new String[] { "Naturals", "FiniteSets", "Integers",
+					"Sequences", "TLC", "Relations", "TLA2B", "BBuildIns" }));
+}
diff --git a/src/main/java/de/tla2b/pprint/AbstractExpressionPrinter.java b/src/main/java/de/tla2b/pprint/AbstractExpressionPrinter.java
new file mode 100644
index 0000000000000000000000000000000000000000..78231d91570b2b7319b73ca9f2e91db907c0b46e
--- /dev/null
+++ b/src/main/java/de/tla2b/pprint/AbstractExpressionPrinter.java
@@ -0,0 +1,1379 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.pprint;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.LinkedList;
+
+import de.tla2b.config.TLCValueNode;
+import de.tla2b.global.BBuildIns;
+import de.tla2b.global.BBuiltInOPs;
+import de.tla2b.global.Priorities;
+import de.tla2b.global.TranslationGlobals;
+import de.tla2b.types.EnumType;
+import de.tla2b.types.FunctionType;
+import de.tla2b.types.IType;
+import de.tla2b.types.SetType;
+import de.tla2b.types.StructType;
+import de.tla2b.types.TLAType;
+import de.tla2b.types.TupleType;
+
+import tla2sany.semantic.ASTConstants;
+import tla2sany.semantic.AtNode;
+import tla2sany.semantic.ExprNode;
+import tla2sany.semantic.ExprOrOpArgNode;
+import tla2sany.semantic.FormalParamNode;
+import tla2sany.semantic.LetInNode;
+import tla2sany.semantic.NumeralNode;
+import tla2sany.semantic.OpApplNode;
+import tla2sany.semantic.OpDefNode;
+import tla2sany.semantic.StringNode;
+import tla2sany.semantic.SymbolNode;
+import tlc2.tool.BuiltInOPs;
+
+public abstract class AbstractExpressionPrinter extends BuiltInOPs implements
+		ASTConstants, IType, BBuildIns, Priorities, TranslationGlobals {
+	// private int substitutionId = 10;
+
+	final int NOBOOL = 0;
+	final int VALUE = 1;
+	final int PREDICATE = 2;
+	final int VALUEORPREDICATE = 3;
+
+	protected ExprReturn visitExprOrOpArgNode(ExprOrOpArgNode n, DContext d,
+			int expected) {
+		if (n instanceof ExprNode) {
+			return visitExprNode((ExprNode) n, d, expected);
+		} else {
+			throw new RuntimeException("OpArgNode not implemented jet");
+		}
+	}
+
+	protected ExprReturn visitExprNode(ExprNode n, DContext d, int expected) {
+		StringBuilder out = new StringBuilder();
+		switch (n.getKind()) {
+		case OpApplKind:
+			return visitOpApplNode((OpApplNode) n, d, expected);
+
+		case NumeralKind: {
+			// this is hack to represent a TLCValue in abstract syntax tree of
+			// the module
+			if (n instanceof TLCValueNode) {
+				out.append(((TLCValueNode) n).getValue());
+				return new ExprReturn(out);
+			}
+			out.append(((NumeralNode) n).val());
+			return new ExprReturn(out);
+		}
+
+		case StringKind: {
+			StringNode s = (StringNode) n;
+			out.append("\"" + s.getRep() + "\"");
+			return new ExprReturn(out);
+		}
+
+		case LetInKind: {
+			LetInNode letInNode = (LetInNode) n;
+			return visitLetInNode(letInNode, d, expected);
+
+		}
+		case AtNodeKind: { // @
+			AtNode at = (AtNode) n;
+			String base = visitExprNode(at.getAtBase(), d, NOBOOL).out
+					.toString();
+			TLAType t = (TLAType) at.getExceptRef().getToolObject(TYPE_ID);
+
+			OpApplNode seq = at.getAtModifier();
+
+			LinkedList<ExprOrOpArgNode> list = new LinkedList<ExprOrOpArgNode>();
+			for (int j = 0; j < seq.getArgs().length; j++) {
+				list.add(seq.getArgs()[j]);
+			}
+			out.append(base);
+			out.append(evalAtValue(list, t));
+			return new ExprReturn(out);
+		}
+		case TLCValueKind: {
+			TLCValueNode val = (TLCValueNode) n;
+			return new ExprReturn(val.getValue().toString());
+		}
+
+		}
+		throw new RuntimeException(n.toString(2));
+	}
+
+	/**
+	 * @param list
+	 * @param t
+	 */
+	private StringBuilder evalAtValue(LinkedList<ExprOrOpArgNode> list,
+			TLAType t) {
+		StringBuilder sb = new StringBuilder();
+		if (list.size() == 0)
+			return sb;
+		ExprOrOpArgNode first = list.poll();
+		if (t instanceof StructType) {
+			StructType s = (StructType) t;
+			sb.append("'");
+			String fieldName = ((StringNode) first).getRep().toString();
+			sb.append(fieldName);
+			return sb.append(evalAtValue(list, s.getType(fieldName)));
+		} else {
+			FunctionType func = (FunctionType) t;
+
+			TLAType range = func.getRange();
+			sb.append("(");
+
+			if (first instanceof OpApplNode
+					&& ((OpApplNode) first).getOperator().getName().toString()
+							.equals("$Tuple")) {
+				OpApplNode domOpAppl = (OpApplNode) first;
+				for (int j = 0; j < domOpAppl.getArgs().length; j++) {
+					if (j != 0) {
+						sb.append(", ");
+					}
+					sb.append(visitExprOrOpArgNode(domOpAppl.getArgs()[j],
+							new DContext(), VALUE).out);
+				}
+			} else {
+				sb.append(visitExprOrOpArgNode(first, new DContext(), VALUE).out);
+			}
+			sb.append(")");
+			return sb.append(evalAtValue(list, range));
+		}
+	}
+
+	protected ExprReturn visitLetInNode(LetInNode l, DContext d, int expected) {
+		for (int i = 0; i < l.getLets().length; i++) {
+			// do something
+		}
+		return visitExprNode(l.getBody(), d, VALUEORPREDICATE);
+	}
+
+	private ExprReturn visitOpApplNode(OpApplNode n, DContext d, int expected) {
+		StringBuilder out = new StringBuilder();
+		switch (n.getOperator().getKind()) {
+		case ConstantDeclKind: {
+			out.append(getPrintName(n.getOperator()));
+			if (expected == PREDICATE) {
+				out.append(" = TRUE");
+				return new ExprReturn(out, P_equals);
+			}
+			return new ExprReturn(out);
+		}
+		case VariableDeclKind: {
+			out.append(getPrintName(n.getOperator()));
+			if (expected == PREDICATE) {
+				out.append(" = TRUE");
+				return new ExprReturn(out, P_equals);
+			}
+			return new ExprReturn(out);
+		}
+		case BuiltInKind:
+			return evalBuiltInKind(n, d, expected);
+
+		case FormalParamKind: {
+			return visitFormalParamNode(n, d, expected);
+		}
+
+		case UserDefinedOpKind: {
+			return visitUserdefinedOp(n, d, expected);
+		}
+
+		}
+		throw new RuntimeException(n.toString(2));
+	}
+
+	/**
+	 * @param n
+	 * @param d
+	 * @param expected
+	 * @return
+	 */
+	protected ExprReturn visitFormalParamNode(OpApplNode n, DContext d,
+			int expected) {
+		StringBuilder out = new StringBuilder();
+		out.append(getPrintName(n.getOperator()));
+		if (expected == PREDICATE) {
+			out.append(" = TRUE");
+			return new ExprReturn(out, P_equals);
+		}
+		return new ExprReturn(out);
+	}
+
+	/**
+	 * @param n
+	 * @param d
+	 * @param expected
+	 * @return
+	 */
+	protected ExprReturn visitUserdefinedOp(OpApplNode n, DContext d,
+			int expected) {
+		StringBuilder out = new StringBuilder();
+		OpDefNode def = (OpDefNode) n.getOperator();
+		// Operator is a B built-in operator
+		if (BBuiltInOPs.contains(def.getName())
+				&& STANDARD_MODULES.contains(def.getSource()
+						.getOriginallyDefinedInModuleNode().getName()
+						.toString())) {
+			return evalBBuiltIns(n, d, expected);
+		}
+
+		out.append(getPrintName(def));
+
+		if (n.getArgs().length > 0) {
+			out.append("(");
+			for (int i = 0; i < n.getArgs().length; i++) {
+				out.append(visitExprOrOpArgNode(n.getArgs()[i], d, VALUE).out);
+				if (i < n.getArgs().length - 1) {
+					out.append(", ");
+				}
+			}
+			out.append(")");
+
+		}
+		TLAType defType = (TLAType) n.getToolObject(TYPE_ID);
+		if (defType != null && defType.getKind() == BOOL) {
+			return makeBoolValue(out, expected, P_max);
+		}
+		return new ExprReturn(out);
+	}
+
+	/**
+	 * @param n
+	 * @param d
+	 * @param expected
+	 * @return
+	 */
+	private ExprReturn evalBuiltInKind(OpApplNode n, DContext d, int expected) {
+		StringBuilder out = new StringBuilder();
+		switch (getOpCode(n.getOperator().getName())) {
+
+		/**********************************************************************
+		 * equality and disequality: =, #, /=
+		 **********************************************************************/
+		case OPCODE_eq: { // =
+			out = evalOpMoreArgs(n, " = ", d, VALUE, P_equals);
+			return makeBoolValue(out, expected, P_equals);
+		}
+
+		case OPCODE_noteq: // /=
+		{
+			out = evalOpMoreArgs(n, " /= ", d, VALUE, P_noteq);
+			return makeBoolValue(out, expected, P_noteq);
+		}
+
+		/**********************************************************************
+		 * Logic Operators
+		 **********************************************************************/
+		case OPCODE_cl: // $ConjList
+		{
+			for (int i = 0; i < n.getArgs().length; i++) {
+				if (i == 0) {
+					out.append(brackets(
+							visitExprOrOpArgNode(n.getArgs()[i], d, PREDICATE),
+							P_and, true));
+				} else {
+					out.append("\n" + d.indent + " & ");
+					out.append(brackets(
+							visitExprOrOpArgNode(n.getArgs()[i], d, PREDICATE),
+							P_and, false));
+				}
+			}
+			return makeBoolValue(out, expected, P_and);
+		}
+		case OPCODE_land: // \land
+		{
+			out = evalOpMoreArgs(n, " & ", d, PREDICATE, P_and);
+			return makeBoolValue(out, expected, P_and);
+		}
+		case OPCODE_dl: // $DisjList
+		{
+			for (int i = 0; i < n.getArgs().length; i++) {
+				if (i == 0) {
+					out.append(brackets(
+							visitExprOrOpArgNode(n.getArgs()[i], d, PREDICATE),
+							P_or, true));
+				} else {
+					out.append("\n" + d.indent + " or ");
+					out.append(brackets(
+							visitExprOrOpArgNode(n.getArgs()[i], d, PREDICATE),
+							P_or, false));
+				}
+			}
+			return makeBoolValue(out, expected, P_or);
+		}
+
+		case OPCODE_lor: // \/
+		{
+			out = evalOpMoreArgs(n, " or ", d, PREDICATE, P_or);
+			return makeBoolValue(out, expected, P_or);
+		}
+		case OPCODE_equiv: // \equiv
+		{
+			out = evalOpMoreArgs(n, " <=> ", d, PREDICATE, P_equiv);
+			return makeBoolValue(out, expected, P_equiv);
+		}
+		case OPCODE_implies: // =>
+		{
+			out = evalOpMoreArgs(n, " => ", d, PREDICATE, P_implies);
+			return makeBoolValue(out, expected, P_implies);
+		}
+
+		case OPCODE_lnot: { // \lnot
+			out.append("not(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, PREDICATE).out);
+			out.append(")");
+			return makeBoolValue(out, expected, P_max);
+		}
+
+		case OPCODE_be: { // \E x \in S : P
+			return evalBoundedQuantor(n, d, expected, "#");
+		}
+
+		case OPCODE_bf: { // \A x \in S : P
+			return evalBoundedQuantor(n, d, expected, "!");
+		}
+
+		/**********************************************************************
+		 * Set Operators
+		 **********************************************************************/
+		case OPCODE_se: // SetEnumeration {..}
+		{
+			out.append("{");
+			out.append(evalOpMoreArgs(n, ", ", d, VALUE, P_comma));
+			out.append("}");
+			return new ExprReturn(out, P_max);
+		}
+
+		case OPCODE_in: // \in
+		{
+			ExprReturn r = visitExprOrOpArgNode(n.getArgs()[0], d, VALUE);
+			out.append(brackets(r, P_in, true));
+			out.append(" : ");
+			r = visitExprOrOpArgNode(n.getArgs()[1], d, NOBOOL);
+			out.append(brackets(r, P_in, false));
+			return makeBoolValue(out, expected, P_in);
+		}
+		case OPCODE_notin: // \notin
+		{
+			ExprReturn r = visitExprOrOpArgNode(n.getArgs()[0], d, VALUE);
+			out.append(brackets(r, P_notin, true));
+			out.append(" /: ");
+			r = visitExprOrOpArgNode(n.getArgs()[1], d, NOBOOL);
+			out.append(brackets(r, P_notin, false));
+			return makeBoolValue(out, expected, P_notin);
+		}
+
+		case OPCODE_setdiff: // set difference
+		{
+			out = evalOpMoreArgs(n, " - ", d, NOBOOL, P_setdiff);
+			return new ExprReturn(out, P_setdiff);
+		}
+
+		case OPCODE_cup: // set union
+		{
+			out = evalOpMoreArgs(n, " \\/ ", d, NOBOOL, P_union);
+			return new ExprReturn(out, P_union);
+		}
+
+		case OPCODE_cap: // set intersection
+		{
+			out = evalOpMoreArgs(n, " /\\ ", d, NOBOOL, P_intersect);
+			return new ExprReturn(out, P_intersect);
+		}
+
+		case OPCODE_subseteq: // \subseteq {1,2} <: {1,2,3}
+		{
+			out = evalOpMoreArgs(n, " <: ", d, NOBOOL, P_subseteq);
+			return makeBoolValue(out, expected, P_subseteq);
+		}
+
+		case OPCODE_subset: // SUBSET
+		{
+			out.append("POW(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append(")");
+			return new ExprReturn(out);
+		}
+
+		case OPCODE_union: // Union - Union{{1},{2}}
+		{
+			out.append("union(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append(")");
+			return new ExprReturn(out);
+		}
+
+		/**********************************************************************
+		 * Set Constructor
+		 **********************************************************************/
+		case OPCODE_sso: { // $SubsetOf Represents {x \in S : P}
+			// TODO tuple with more than 2 arguments
+			FormalParamNode[][] params = n.getBdedQuantSymbolLists();
+			ExprNode[] bounds = n.getBdedQuantBounds();
+
+			StringBuilder temp = new StringBuilder();
+			if (params[0].length > 0) {
+				temp.append("(");
+				for (int j = 0; j < params[0].length; j++) {
+					FormalParamNode p = params[0][j];
+					temp.append(getPrintName(p));
+					if (j < params[0].length - 1)
+						temp.append(", ");
+				}
+				temp.append(")");
+			} else {
+				FormalParamNode p = n.getBdedQuantSymbolLists()[0][0];
+				temp.append(getPrintName(p));
+			}
+
+			out.append("{");
+			out.append(temp);
+			out.append("|");
+			out.append(temp);
+			out.append(" : ");
+			ExprNode in = n.getBdedQuantBounds()[0];
+			out.append(visitExprNode(in, d, NOBOOL).out);
+			out.append(" & ");
+			out.append(brackets(
+					visitExprOrOpArgNode(n.getArgs()[0], d, PREDICATE), P_and,
+					false));
+			out.append("}");
+			return new ExprReturn(out);
+		}
+
+		case OPCODE_soa: { // $SetOfAll Represents {e : p1 \in S, p2,p3 \in S2}
+			out.append("{t_|#");
+			FormalParamNode[][] params = n.getBdedQuantSymbolLists();
+			ExprNode[] bounds = n.getBdedQuantBounds();
+			for (int i = 0; i < bounds.length; i++) {
+				for (int j = 0; j < params[i].length; j++) {
+					FormalParamNode p = params[i][j];
+					out.append(getPrintName(p));
+					if (i < bounds.length - 1 || j < params[i].length - 1)
+						out.append(", ");
+				}
+			}
+			out.append(".(");
+			out.append(visitBounded(n, d));
+			out.append(" & t_ = ");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, VALUE).out);
+			out.append(")}");
+			return new ExprReturn(out);
+		}
+		/***********************************************************************
+		 * Tuple: Tuple as Function 1..n to Set (Sequence)
+		 ***********************************************************************/
+		case OPCODE_tup: { // $Tuple
+			TLAType t = (TLAType) n.getToolObject(TYPE_ID);
+			if (t instanceof TupleType) {
+				out.append("(");
+				out.append(evalOpMoreArgs(n, ", ", d, VALUE, P_comma));
+				out.append(")");
+			} else {
+				out.append("[");
+				out.append(evalOpMoreArgs(n, ", ", d, VALUE, P_comma));
+				out.append("]");
+			}
+			return new ExprReturn(out);
+		}
+
+		/***********************************************************************
+		 * Cartesian Product: A \X B
+		 ***********************************************************************/
+		case OPCODE_cp: { // $CartesianProd A \X B \X C
+			out.append(evalOpMoreArgs(n, "*", d, VALUE, P_times));
+			return new ExprReturn(out, P_times);
+		}
+
+		/***********************************************************************
+		 * Functions
+		 ***********************************************************************/
+		case OPCODE_nrfs:
+		case OPCODE_fc: // Represents [x \in S |-> e].
+		case OPCODE_rfs: {
+			out.append("%");
+			FormalParamNode[][] vars = n.getBdedQuantSymbolLists();
+			for (int i = 0; i < vars.length; i++) {
+				for (int j = 0; j < vars[i].length; j++) {
+					out.append(getPrintName(vars[i][j]));
+					if (j < vars[i].length - 1) {
+						out.append(",");
+					}
+				}
+				if (i < vars.length - 1) {
+					out.append(",");
+				}
+			}
+			out.append(".(");
+			out.append(visitBounded(n, d));
+			out.append("| ");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, VALUE).out);
+			out.append(")");
+			return new ExprReturn(out);
+		}
+
+		case OPCODE_fa: { // f[1]
+			out.append(brackets(
+					visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL), P_max,
+					true));
+			out.append("(");
+			ExprOrOpArgNode dom = n.getArgs()[1];
+			if (dom instanceof OpApplNode
+					&& ((OpApplNode) dom).getOperator().getName().toString()
+							.equals("$Tuple")) {
+				OpApplNode domOpAppl = (OpApplNode) dom;
+				for (int i = 0; i < domOpAppl.getArgs().length; i++) {
+					if (i != 0)
+						out.append(", ");
+					out.append(visitExprOrOpArgNode(domOpAppl.getArgs()[i], d,
+							VALUE).out);
+				}
+			} else {
+				out.append(visitExprOrOpArgNode(dom, d, VALUE).out);
+			}
+			out.append(")");
+			if (expected == PREDICATE) {
+				out.append(" = TRUE");
+				return new ExprReturn(out, P_equals);
+			}
+			return new ExprReturn(out);
+		}
+
+		case OPCODE_domain:
+			out.append("dom(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append(")");
+			return new ExprReturn(out);
+
+		case OPCODE_sof: // [ A -> B]
+		{
+			out.append(evalOpMoreArgs(n, " --> ", d, NOBOOL, P_total_f));
+			return new ExprReturn(out, P_total_f);
+		}
+
+		/**********************************************************************
+		 * Except
+		 **********************************************************************/
+		case OPCODE_exc: // Except
+		{
+			TLAType t = (TLAType) n.getToolObject(TYPE_ID);
+			String oldRecOrFunc = visitExprOrOpArgNode(n.getArgs()[0], d,
+					NOBOOL).out.toString();
+
+			if (t.getKind() == STRUCT) {
+				StructType structType = (StructType) t;
+
+				Hashtable<String, String> temp = new Hashtable<String, String>();
+				for (int i = 1; i < n.getArgs().length; i++) {
+					OpApplNode pair = (OpApplNode) n.getArgs()[i];
+					ExprOrOpArgNode first = pair.getArgs()[0];
+					ExprOrOpArgNode second = pair.getArgs()[1];
+					OpApplNode seq = (OpApplNode) first;
+
+					String val = visitExprOrOpArgNode((ExprOrOpArgNode) second,
+							d, VALUE).out.toString();
+
+					LinkedList<ExprOrOpArgNode> list = new LinkedList<ExprOrOpArgNode>();
+					for (int j = 0; j < seq.getArgs().length; j++) {
+						list.add(seq.getArgs()[j]);
+					}
+
+					StringNode s = (StringNode) list.poll();
+					String fieldName = s.getRep().toString();
+
+					String res = evalExceptValue(list,
+							structType.getType(fieldName), val, oldRecOrFunc
+									+ "'" + fieldName);
+					temp.put(fieldName, res);
+				}
+
+				out.append("rec(");
+				StructType st = (StructType) t;
+				for (int i = 0; i < st.getFields().size(); i++) {
+					String fieldName = st.getFields().get(i);
+					out.append(fieldName);
+					out.append(" : ");
+					String value = temp.get(fieldName);
+					if (value == null) {
+						value = oldRecOrFunc + "'" + fieldName;
+					}
+					out.append(value);
+
+					if (i < st.getFields().size() - 1) {
+						out.append(", ");
+					}
+				}
+				out.append(")");
+				return new ExprReturn(out);
+
+			} else {
+				// function
+				FunctionType func = (FunctionType) t;
+
+				out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+				out.append(" <+ {");
+				for (int i = 1; i < n.getArgs().length; i++) {
+					OpApplNode pair = (OpApplNode) n.getArgs()[i];
+					OpApplNode domSeq = (OpApplNode) pair.getArgs()[0];
+					ExprOrOpArgNode domExpr = domSeq.getArgs()[0];
+					StringBuilder dom = new StringBuilder();
+					if (domExpr instanceof OpApplNode
+							&& ((OpApplNode) domExpr).getOperator().getName()
+									.toString().equals("$Tuple")) {
+						OpApplNode domOpAppl = (OpApplNode) domExpr;
+						dom.append("(");
+						for (int j = 0; j < domOpAppl.getArgs().length; j++) {
+							if (j != 0) {
+								dom.append(", ");
+							}
+							dom.append(visitExprOrOpArgNode(
+									domOpAppl.getArgs()[j], d, VALUE).out);
+						}
+						dom.append(")");
+					} else {
+						dom.append(visitExprOrOpArgNode(pair.getArgs()[0], d,
+								VALUE).out);
+					}
+					out.append(dom);
+
+					out.append(" |-> ");
+
+					ExprOrOpArgNode first = pair.getArgs()[0];
+					ExprOrOpArgNode second = pair.getArgs()[1];
+					OpApplNode seq = (OpApplNode) first;
+
+					
+					String val = brackets(visitExprOrOpArgNode((ExprOrOpArgNode) second,
+							d, VALUE), P_maplet, false).toString();
+					//String val = visitExprOrOpArgNode((ExprOrOpArgNode) second,
+					//		d, VALUE).out.toString();
+
+					LinkedList<ExprOrOpArgNode> list = new LinkedList<ExprOrOpArgNode>();
+					for (int j = 0; j < seq.getArgs().length; j++) {
+						list.add(seq.getArgs()[j]);
+					}
+					list.poll();
+					String res = evalExceptValue(list, func.getRange(), val,
+							oldRecOrFunc + "(" + dom + ")");
+					out.append(res);
+					// out.append(brackets(
+					// visitExprOrOpArgNode(pair.getArgs()[1], d, VALUE),
+					// P_maplet, false));
+					if (i < n.getArgs().length - 1) {
+						out.append(", ");
+					}
+				}
+				out.append("}");
+				return new ExprReturn(out, P_rel_overriding);
+
+			}
+		}
+
+		/***********************************************************************
+		 * Records
+		 ***********************************************************************/
+		case OPCODE_sor: { // $SetOfRcds [L1 : e1, L2 : e2]
+			SetType pow = (SetType) n.getToolObject(TYPE_ID);
+			StructType struct = (StructType) pow.getSubType();
+			Hashtable<String, StringBuilder> pairs = new Hashtable<String, StringBuilder>();
+			ExprOrOpArgNode[] args = n.getArgs();
+			for (int i = 0; i < args.length; i++) {
+				OpApplNode pair = (OpApplNode) args[i];
+				StringNode stringNode = (StringNode) pair.getArgs()[0];
+				pairs.put(stringNode.getRep().toString(),
+						visitExprOrOpArgNode(pair.getArgs()[1], d, VALUE).out);
+			}
+			out.append("struct(");
+			for (int i = 0; i < struct.getFields().size(); i++) {
+				String fieldName = struct.getFields().get(i);
+				out.append(fieldName);
+				out.append(" : ");
+				if (pairs.containsKey(fieldName)) {
+					out.append(pairs.get(fieldName));
+				} else {
+					out.append(struct.getType(fieldName));
+				}
+				if (i < struct.getFields().size() - 1)
+					out.append(",");
+			}
+			out.append(")");
+			return new ExprReturn(out, P_max);
+		}
+
+		case OPCODE_rc: { // [h_1 |-> 1, h_2 |-> 2]
+			StructType struct = (StructType) n.getToolObject(TYPE_ID);
+			Hashtable<String, StringBuilder> pairs = new Hashtable<String, StringBuilder>();
+			ExprOrOpArgNode[] args = n.getArgs();
+			for (int i = 0; i < args.length; i++) {
+				OpApplNode pair = (OpApplNode) args[i];
+				StringNode stringNode = (StringNode) pair.getArgs()[0];
+				pairs.put(stringNode.getRep().toString(),
+						visitExprOrOpArgNode(pair.getArgs()[1], d, VALUE).out);
+			}
+			out.append("rec(");
+			for (int i = 0; i < struct.getFields().size(); i++) {
+				String fieldName = struct.getFields().get(i);
+				out.append(fieldName);
+				out.append(" : ");
+				if (pairs.containsKey(fieldName)) {
+					out.append(pairs.get(fieldName));
+				} else {
+					out.append(getDummy(struct.getType(fieldName)));
+				}
+				if (i < struct.getFields().size() - 1)
+					out.append(",");
+			}
+			out.append(")");
+			return new ExprReturn(out, P_max);
+		}
+
+		case OPCODE_rs: { // $RcdSelect r.c
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append("'");
+			StringNode stringNode = (StringNode) n.getArgs()[1];
+			out.append(stringNode.getRep().toString());
+			if (expected == PREDICATE) {
+				out.append(" = TRUE");
+				return new ExprReturn(out, P_equals);
+			}
+			return new ExprReturn(out, P_record_acc);
+		}
+
+		/***********************************************************************
+		 * miscellaneous constructs
+		 ***********************************************************************/
+		case OPCODE_ite: // IF THEN ELSE
+		{
+			return evalIfThenElse(n, d, expected);
+
+		}
+
+		case OPCODE_case: { // CASE p1 -> e1 [] p2 -> e2
+			out.append("(");
+			StringBuilder all = new StringBuilder();
+			for (int i = 0; i < n.getArgs().length; i++) {
+				OpApplNode pair = (OpApplNode) n.getArgs()[i];
+				out.append("%t_.(t_ = 0 & ");
+				if (pair.getArgs()[0] == null) {
+					out.append("not(" + all + ")");
+				} else {
+					ExprReturn p = visitExprOrOpArgNode(pair.getArgs()[0], d,
+							PREDICATE);
+					if (i != 0) {
+						all.append(" or ");
+					}
+					all.append(brackets(p, P_or, i == 0));
+					out.append(brackets(p, P_and, false));
+				}
+				out.append(" | ");
+				out.append(visitExprOrOpArgNode(pair.getArgs()[1], d, VALUE).out);
+				out.append(")");
+				if (i < n.getArgs().length - 1) {
+					out.append(" \\/ ");
+				}
+			}
+			out.append(")(0)");
+			return new ExprReturn(out);
+		}
+
+		case OPCODE_bc: { // CHOOSE x \in S: P
+			out.append("CHOOSE({");
+			FormalParamNode x = n.getBdedQuantSymbolLists()[0][0];
+			out.append(getPrintName(x));
+			out.append("|");
+			out.append(getPrintName(x));
+			out.append(" : ");
+			ExprNode in = n.getBdedQuantBounds()[0];
+			out.append(visitExprNode(in, d, NOBOOL).out);
+			out.append(" & ");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, PREDICATE).out);
+			out.append("})");
+			return new ExprReturn(out);
+
+		}
+
+		/***********************************************************************
+		 * UNCHANGED
+		 ************************************************************************/
+		case OPCODE_unchanged:
+			Boolean b = (Boolean) n.getToolObject(USED);
+			if (b != null) {
+				return new ExprReturn("TRUE = TRUE", P_equals);
+			}
+			OpApplNode k = (OpApplNode) n.getArgs()[0];
+			if (k.getOperator().getKind() == VariableDeclKind) {
+				String name = k.getOperator().getName().toString();
+				out.append(name + "_n = " + name);
+			} else {
+				// Tuple
+				for (int i = 0; i < k.getArgs().length; i++) {
+					String name = visitExprOrOpArgNode(k.getArgs()[i], d, VALUE).out
+							.toString();
+					out.append(name + "_n = " + name);
+					if (i < k.getArgs().length - 1) {
+						out.append(" & ");
+					}
+				}
+			}
+			return new ExprReturn(out);
+
+			/***********************************************************************
+			 * Prime
+			 ***********************************************************************/
+		case OPCODE_prime: // prime
+		{
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, VALUE).out);
+			out.append("_n");
+			return new ExprReturn(out);
+		}
+
+		/***********************************************************************
+		 * Sany internal
+		 ***********************************************************************/
+		case OPCODE_seq: // !
+		{
+			return visitExprOrOpArgNode(n.getArgs()[0], d, expected);
+		}
+
+		/***********************************************************************
+		 * no TLA+ Built-ins
+		 ***********************************************************************/
+		case 0: {
+			return evalBBuiltIns(n, d, expected);
+		}
+
+		case OPCODE_sa: // []_
+		case OPCODE_box: // []
+		case OPCODE_diamond: // <>
+		case OPCODE_wf: // weak fairness
+		{
+			throw new RuntimeException("Not supported operator: "
+					+ n.toString(2));
+		}
+
+		}
+		throw new RuntimeException(n.toString(2));
+	}
+
+	/**
+	 * @param list
+	 * @param type
+	 * @param string
+	 * @return
+	 */
+	private String evalExceptValue(LinkedList<ExprOrOpArgNode> list,
+			TLAType type, String val, String prefix) {
+		StringBuilder sb = new StringBuilder();
+		ExprOrOpArgNode head = list.poll();
+		if (head == null) {
+			return val;
+		}
+		if (type.getKind() == STRUCT) {
+			StructType structType = (StructType) type;
+			String field = ((StringNode) head).getRep().toString();
+
+			ArrayList<String> fields = structType.getFields();
+			sb.append("rec(");
+
+			for (int i = 0; i < fields.size(); i++) {
+				String currentField = fields.get(i);
+				sb.append(currentField);
+				sb.append(" : ");
+				if (currentField.equals(field)) {
+					String value;
+					if (list.size() > 0) {
+						value = evalExceptValue(list,
+								structType.getType(currentField), val, prefix
+										+ "'" + currentField);
+					} else {
+						value = val;
+					}
+
+					sb.append(value);
+				} else {
+					sb.append(prefix + "'" + currentField);
+				}
+				if (i < fields.size() - 1) {
+					sb.append(", ");
+				}
+			}
+			sb.append(")");
+
+		} else {
+			FunctionType func = (FunctionType) type;
+			sb.append("(");
+			sb.append(prefix);
+			sb.append(" <+ {");
+			String dom = visitExprOrOpArgNode(head, new DContext(), VALUE).out
+					.toString();
+			sb.append(dom);
+			sb.append(" |-> ");
+
+			if (list.size() > 0) {
+				String res = evalExceptValue(list, func.getRange(), val, prefix
+						+ "(" + dom + ")");
+				sb.append(res);
+			} else {
+				sb.append(val);
+			}
+			sb.append("}");
+			sb.append(")");
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * @param n
+	 * @return
+	 */
+	protected ExprReturn evalIfThenElse(OpApplNode n, DContext d, int expected) {
+		TLAType t = (TLAType) n.getToolObject(TYPE_ID);
+
+		if (t.getKind() == BOOL) {
+			d.indent.append(" ");
+			ExprReturn iif = visitExprOrOpArgNode(n.getArgs()[0], d, PREDICATE);
+			ExprReturn then = visitExprOrOpArgNode(n.getArgs()[1], d, PREDICATE);
+			ExprReturn eelse = visitExprOrOpArgNode(n.getArgs()[2], d,
+					PREDICATE);
+			String res = String.format(
+					"(%s \n%s => %s) \n\t & (not(%s) \n%s => %s)",
+					brackets(iif, P_implies, true), d.indent,
+					brackets(then, P_implies, false), iif.out, d.indent,
+					brackets(eelse, P_implies, false));
+			return makeBoolValue(new StringBuilder(res), expected, P_and);
+		} else {
+			// ExprReturn iif = visitExprOrOpArgNode(n.getArgs()[0], d,
+			// PREDICATE);
+			// ExprReturn then = visitExprOrOpArgNode(n.getArgs()[1], d,
+			// VALUE);
+			// ExprReturn eelse = visitExprOrOpArgNode(n.getArgs()[2], d,
+			// VALUE);
+			// String res = String
+			// .format("(%%t_.( t_ = 0 & %s | %s )\\/%%t_.( t_ = 0 & not(%s) | %s ))(0)",
+			// iif.out, then.out, iif.out, eelse.out);
+			// return new ExprReturn(res);
+			ExprReturn iif = visitExprOrOpArgNode(n.getArgs()[0], d, VALUE);
+			ExprReturn then = visitExprOrOpArgNode(n.getArgs()[1], d, VALUE);
+			ExprReturn eelse = visitExprOrOpArgNode(n.getArgs()[2], d, VALUE);
+			String res = String.format("IF_THEN_ELSE(%s, %s, %s)", iif.out,
+					then.out, eelse.out);
+			return new ExprReturn(res);
+		}
+	}
+
+	private ExprReturn evalBoundedQuantor(OpApplNode n, DContext d,
+			int expected, String symbol) {
+		StringBuilder out = new StringBuilder();
+		out.append(symbol);
+		FormalParamNode[][] params = n.getBdedQuantSymbolLists();
+		for (int i = 0; i < params.length; i++) {
+			for (int j = 0; j < params[i].length; j++) {
+				out.append(getPrintName(params[i][j]));
+				if (j < params[i].length - 1) {
+					out.append(",");
+				}
+			}
+			if (i < params.length - 1) {
+				out.append(",");
+			}
+		}
+		out.append(".(");
+		out.append(visitBounded(n, d));
+		out.append(symbol.equals("#") ? " & " : " => ");
+		out.append(brackets(visitExprOrOpArgNode(n.getArgs()[0], d, PREDICATE),
+				symbol.equals("#") ? P_and : P_implies, false));
+		out.append(")");
+		return makeBoolValue(out, expected, P_max);
+	}
+
+	@SuppressWarnings("unused")
+	private ExprReturn evalStructOrRec(String string, OpApplNode n, DContext d) {
+		StringBuilder out = new StringBuilder();
+		out.append(string);
+		out.append("(");
+		ExprOrOpArgNode[] args = n.getArgs();
+		for (int i = 0; i < args.length; i++) {
+			OpApplNode pair = (OpApplNode) args[i];
+			StringNode stringNode = (StringNode) pair.getArgs()[0];
+			out.append(stringNode.getRep().toString());
+			out.append(" : ");
+			out.append(visitExprOrOpArgNode(pair.getArgs()[1], d, VALUE).out);
+			if (i != args.length - 1)
+				out.append(", ");
+		}
+		out.append(")");
+		return new ExprReturn(out, P_max);
+	}
+
+	protected ExprReturn evalBBuiltIns(OpApplNode n, DContext d, int expected) {
+		StringBuilder out = new StringBuilder();
+
+		switch (BBuiltInOPs.getOpcode(n.getOperator().getName())) {
+
+		/**********************************************************************
+		 * Standard Module Naturals
+		 **********************************************************************/
+		case B_OPCODE_nat: // Nat
+		{
+			out.append("NATURAL");
+			return new ExprReturn(out);
+		}
+
+		case B_OPCODE_plus: // +
+			out.append(evalOpMoreArgs(n, " + ", d, NOBOOL, P_plus));
+			return new ExprReturn(out, P_plus);
+
+		case B_OPCODE_minus: // -
+		{
+			out.append(evalOpMoreArgs(n, " - ", d, NOBOOL, P_minus));
+			return new ExprReturn(out, P_minus);
+		}
+
+		case B_OPCODE_times: // *
+		{
+			out.append(evalOpMoreArgs(n, " * ", d, NOBOOL, P_times));
+			return new ExprReturn(out, P_times);
+		}
+
+		case B_OPCODE_exp: // x^y
+		{
+			out.append(evalOpMoreArgs(n, " ** ", d, NOBOOL, P_exp));
+			return new ExprReturn(out, P_exp);
+		}
+
+		case B_OPCODE_lt: // <
+		{
+			out.append(evalOpMoreArgs(n, " < ", d, NOBOOL, P_lt));
+			return makeBoolValue(out, expected, P_lt);
+		}
+
+		case B_OPCODE_gt: // >
+		{
+			out.append(evalOpMoreArgs(n, " > ", d, NOBOOL, P_gt));
+			return makeBoolValue(out, expected, P_gt);
+		}
+
+		case B_OPCODE_leq: // <=
+		{
+			out.append(evalOpMoreArgs(n, " <= ", d, NOBOOL, P_leq));
+			return makeBoolValue(out, expected, P_leq);
+		}
+
+		case B_OPCODE_geq: // >=
+		{
+			out.append(evalOpMoreArgs(n, " >= ", d, NOBOOL, P_geq));
+			return makeBoolValue(out, expected, P_geq);
+		}
+
+		case B_OPCODE_mod: // modulo
+		{
+			ExprReturn first = visitExprOrOpArgNode(n.getArgs()[0], d, VALUE);
+			ExprReturn second = visitExprOrOpArgNode(n.getArgs()[1], d, VALUE);
+			String res = String.format("(%s - %s * (%s / %s))",
+					brackets(first, P_minus, true),
+					brackets(second, P_times, true),
+					brackets(first, P_div, true),
+					brackets(second, P_div, false));
+			return new ExprReturn(res);
+		}
+
+		case B_OPCODE_div: // /
+		{
+			out.append(evalOpMoreArgs(n, " / ", d, NOBOOL, P_div));
+			return new ExprReturn(out, P_div);
+		}
+
+		case B_OPCODE_dotdot: // ..
+		{
+			out.append(evalOpMoreArgs(n, " .. ", d, NOBOOL, P_dotdot));
+			return new ExprReturn(out, P_dotdot);
+		}
+
+		/**********************************************************************
+		 * Standard Module Integers
+		 **********************************************************************/
+		case B_OPCODE_int: // Int
+		{
+			out.append("INTEGER");
+			return new ExprReturn(out);
+		}
+
+		case B_OPCODE_uminus: // -x
+		{
+			out.append("-");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			return new ExprReturn(out, P_uminus);
+		}
+
+		/**********************************************************************
+		 * Standard Module FiniteSets
+		 **********************************************************************/
+		case B_OPCODE_card: // Cardinality
+		{
+			out.append("card(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append(")");
+			return new ExprReturn(out);
+		}
+
+		case B_OPCODE_finite: { // IsFiniteSet
+			ExprReturn exprr = visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL);
+			// String res = String
+			// .format("#seq_.(seq_ : seq(%s) & !s.(s : %s => #n.(n : 1 .. size(seq_) & seq_(n) = s)))",
+			// exprr.out, exprr.out);
+			String res = String.format("%s : FIN(%s)", exprr.out, exprr.out);
+			out.append(res);
+			return makeBoolValue(out, expected, P_max);
+		}
+
+		/**********************************************************************
+		 * Standard Module Sequences
+		 **********************************************************************/
+		case B_OPCODE_seq: { // Seq(S) - set of sequences
+			out.append("seq(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append(")");
+			return new ExprReturn(out);
+		}
+
+		case B_OPCODE_len: { // length of the sequence
+			out.append("size(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append(")");
+			return new ExprReturn(out);
+		}
+
+		case B_OPCODE_conc: { // s \o s2 - concatenation of s and s2
+			out.append(evalOpMoreArgs(n, " ^ ", d, NOBOOL, P_conc));
+			return new ExprReturn(out, P_conc);
+		}
+
+		case B_OPCODE_append: { // Append(s,x)
+			out.append(evalOpMoreArgs(n, " <- ", d, NOBOOL, P_append));
+			return new ExprReturn(out, P_append);
+		}
+
+		case B_OPCODE_head: { // Head(s)
+			out.append("first(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append(")");
+			return new ExprReturn(out);
+		}
+
+		case B_OPCODE_tail: { // Tail(s)
+			out.append("tail(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append(")");
+			return new ExprReturn(out);
+		}
+
+		case B_OPCODE_subseq: { // SubSeq(s,m,n)
+			StringBuilder s = visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out;
+			out.append("(");
+			out.append(s);
+			out.append("/|\\"); // taking first n elements
+			out.append(visitExprOrOpArgNode(n.getArgs()[2], d, NOBOOL).out);
+			out.append(")\\|/"); // dropping first m-1 elements
+			out.append(visitExprOrOpArgNode(n.getArgs()[1], d, NOBOOL).out);
+			out.append("-1");
+			return new ExprReturn(out, P_drop_last);
+		}
+
+		/**********************************************************************
+		 * Standard Module TLA2B
+		 **********************************************************************/
+		case B_OPCODE_min: { // MinOfSet(s)
+			out.append("min(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append(")");
+			return new ExprReturn(out);
+		}
+
+		case B_OPCODE_max: { // MaxOfSet(s)
+			out.append("max(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append(")");
+			return new ExprReturn(out);
+		}
+
+		case B_OPCODE_setprod: { // SetProduct(s)
+			out.append("PI(z_).(z_:");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append("|z_)");
+			return new ExprReturn(out);
+		}
+
+		case B_OPCODE_setsum: { // SetSummation(s)
+			out.append("SIGMA(z_).(z_:");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append("|z_)");
+			return new ExprReturn(out);
+		}
+
+		case B_OPCODE_permseq: { // PermutedSequences(s)
+			out.append("perm(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append(")");
+			return new ExprReturn(out);
+		}
+		/**********************************************************************
+		 * Standard Module TLA2B
+		 **********************************************************************/
+		case B_OPCODE_pow1: { // POW1
+			out.append("POW1(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append(")");
+			return new ExprReturn(out);
+		}
+
+		/**********************************************************************
+		 * Standard Module Relations
+		 **********************************************************************/
+
+		case B_OPCODE_rel_inverse: { // POW1
+			out.append("(");
+			out.append(visitExprOrOpArgNode(n.getArgs()[0], d, NOBOOL).out);
+			out.append("~)");
+			return new ExprReturn(out);
+		}
+
+		/***********************************************************************
+		 * TLA+ Built-Ins, but not in tlc.tool.BuiltInOPs
+		 ***********************************************************************/
+		case B_OPCODE_bool: // BOOLEAN
+			out.append("BOOL");
+			return new ExprReturn(out);
+
+		case B_OPCODE_true: // TRUE
+			out.append("TRUE");
+			if (expected == PREDICATE) {
+				out.append(" = TRUE");
+				return new ExprReturn(out, P_equals);
+			}
+			return new ExprReturn(out);
+
+		case B_OPCODE_false: // FALSE
+			out.append("FALSE");
+			if (expected == PREDICATE) {
+				out.append(" = TRUE");
+				return new ExprReturn(out, P_equals);
+			}
+			return new ExprReturn(out);
+
+		case B_OPCODE_string: // STRING
+			out.append("STRING");
+			return new ExprReturn(out);
+
+		}
+
+		throw new RuntimeException(n.toString(2));
+	}
+
+	protected StringBuilder visitBounded(OpApplNode n, DContext d) {
+		StringBuilder out = new StringBuilder();
+		FormalParamNode[][] params = n.getBdedQuantSymbolLists();
+		ExprNode[] in = n.getBdedQuantBounds();
+		boolean[] isTuple = n.isBdedQuantATuple();
+		for (int i = 0; i < params.length; i++) {
+			if (isTuple[i]) {
+				out.append("(");
+				for (int j = 0; j < params[i].length; j++) {
+					out.append(getPrintName(params[i][j]));
+					if (j == 0)
+						out.append(", ");
+				}
+				out.append(")");
+				out.append(" : ");
+				out.append(visitExprNode(in[i], d, NOBOOL).out);
+				if (i < params.length - 1) {
+					out.append(" & ");
+				}
+			} else {
+				for (int j = 0; j < params[i].length; j++) {
+					out.append(getPrintName(params[i][j]));
+					out.append(" : ");
+					out.append(visitExprNode(in[i], d, NOBOOL).out);
+					if (j < params[i].length - 1 || i < params.length - 1) {
+						out.append(" & ");
+					}
+				}
+			}
+		}
+		return out;
+	}
+
+	protected StringBuilder evalOpMoreArgs(OpApplNode n, String operator,
+			DContext d, int expected, int priority) {
+		StringBuilder out = new StringBuilder();
+		ExprOrOpArgNode[] args = n.getArgs();
+		for (int i = 0; i < args.length; i++) {
+			ExprReturn r = visitExprOrOpArgNode(args[i], d, expected);
+			if (i == 0) {
+				out.append(brackets(r, priority, true));
+			} else {
+				out.append(operator);
+				out.append(brackets(r, priority, false));
+			}
+
+		}
+		return out;
+	}
+
+	protected ExprReturn makeBoolValue(StringBuilder out, int expected,
+			int priority) {
+		StringBuilder res = new StringBuilder();
+		if (expected == VALUE) {
+			res.append("bool(" + out + ")");
+			return new ExprReturn(res);
+		} else {
+			return new ExprReturn(out, priority);
+		}
+	}
+
+	protected StringBuilder brackets(ExprReturn r, int p, boolean left) {
+		StringBuilder res = new StringBuilder();
+		if ((left && r.getPriority() < p) || (!left && r.getPriority() <= p)) {
+			res.append("(");
+			res.append(r.getOut());
+			res.append(")");
+		} else
+			res.append(r.getOut());
+		return res;
+	}
+
+	protected String getPrintName(SymbolNode node) {
+		if (node.getToolObject(NEW_NAME) != null) {
+			return (String) node.getToolObject(NEW_NAME);
+		} else {
+			return node.getName().toString();
+		}
+	}
+
+	private String getDummy(TLAType type) {
+		switch (type.getKind()) {
+		case INTEGER:
+			return "0";
+
+		case STRING:
+			return "\"\"";
+
+		case POW:
+			return "{}";
+
+		case BOOL:
+			return "FALSE";
+		case MODELVALUE:
+			EnumType e = (EnumType) type;
+			return "noVal" + e.id;
+		default:
+			break;
+		}
+		return null;
+
+	}
+}
diff --git a/src/main/java/de/tla2b/pprint/BAstCreator.java b/src/main/java/de/tla2b/pprint/BAstCreator.java
new file mode 100644
index 0000000000000000000000000000000000000000..6d6b6fff89029db5a2101775907a20a9392ef8ef
--- /dev/null
+++ b/src/main/java/de/tla2b/pprint/BAstCreator.java
@@ -0,0 +1,1222 @@
+package de.tla2b.pprint;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.List;
+
+import tla2sany.semantic.ASTConstants;
+import tla2sany.semantic.AssumeNode;
+import tla2sany.semantic.ExprNode;
+import tla2sany.semantic.ExprOrOpArgNode;
+import tla2sany.semantic.FormalParamNode;
+import tla2sany.semantic.ModuleNode;
+import tla2sany.semantic.NumeralNode;
+import tla2sany.semantic.OpApplNode;
+import tla2sany.semantic.OpDeclNode;
+import tla2sany.semantic.OpDefNode;
+import tla2sany.semantic.StringNode;
+import tlc2.tool.BuiltInOPs;
+import de.be4.classicalb.core.parser.node.AAbstractConstantsMachineClause;
+import de.be4.classicalb.core.parser.node.AAbstractMachineParseUnit;
+import de.be4.classicalb.core.parser.node.AAddExpression;
+import de.be4.classicalb.core.parser.node.AAnySubstitution;
+import de.be4.classicalb.core.parser.node.AAssignSubstitution;
+import de.be4.classicalb.core.parser.node.ABecomesSuchSubstitution;
+import de.be4.classicalb.core.parser.node.ABoolSetExpression;
+import de.be4.classicalb.core.parser.node.ABooleanFalseExpression;
+import de.be4.classicalb.core.parser.node.ABooleanTrueExpression;
+import de.be4.classicalb.core.parser.node.ACardExpression;
+import de.be4.classicalb.core.parser.node.AComprehensionSetExpression;
+import de.be4.classicalb.core.parser.node.AConcatExpression;
+import de.be4.classicalb.core.parser.node.AConjunctPredicate;
+import de.be4.classicalb.core.parser.node.AConvertBoolExpression;
+import de.be4.classicalb.core.parser.node.ACoupleExpression;
+import de.be4.classicalb.core.parser.node.ADisjunctPredicate;
+import de.be4.classicalb.core.parser.node.ADivExpression;
+import de.be4.classicalb.core.parser.node.ADomainExpression;
+import de.be4.classicalb.core.parser.node.AEmptySetExpression;
+import de.be4.classicalb.core.parser.node.AEqualPredicate;
+import de.be4.classicalb.core.parser.node.AEquivalencePredicate;
+import de.be4.classicalb.core.parser.node.AExistsPredicate;
+import de.be4.classicalb.core.parser.node.AFinSubsetExpression;
+import de.be4.classicalb.core.parser.node.AFirstExpression;
+import de.be4.classicalb.core.parser.node.AForallPredicate;
+import de.be4.classicalb.core.parser.node.AFunctionExpression;
+import de.be4.classicalb.core.parser.node.AGeneralUnionExpression;
+import de.be4.classicalb.core.parser.node.AGreaterEqualPredicate;
+import de.be4.classicalb.core.parser.node.AGreaterPredicate;
+import de.be4.classicalb.core.parser.node.AIdentifierExpression;
+import de.be4.classicalb.core.parser.node.AImplicationPredicate;
+import de.be4.classicalb.core.parser.node.AInitialisationMachineClause;
+import de.be4.classicalb.core.parser.node.AInsertTailExpression;
+import de.be4.classicalb.core.parser.node.AIntegerExpression;
+import de.be4.classicalb.core.parser.node.AIntegerSetExpression;
+import de.be4.classicalb.core.parser.node.AIntersectionExpression;
+import de.be4.classicalb.core.parser.node.AIntervalExpression;
+import de.be4.classicalb.core.parser.node.AInvariantMachineClause;
+import de.be4.classicalb.core.parser.node.ALambdaExpression;
+import de.be4.classicalb.core.parser.node.ALessEqualPredicate;
+import de.be4.classicalb.core.parser.node.ALessPredicate;
+import de.be4.classicalb.core.parser.node.AMachineHeader;
+import de.be4.classicalb.core.parser.node.AMemberPredicate;
+import de.be4.classicalb.core.parser.node.AMinusOrSetSubtractExpression;
+import de.be4.classicalb.core.parser.node.AMultOrCartExpression;
+import de.be4.classicalb.core.parser.node.ANaturalSetExpression;
+import de.be4.classicalb.core.parser.node.ANegationPredicate;
+import de.be4.classicalb.core.parser.node.ANotEqualPredicate;
+import de.be4.classicalb.core.parser.node.ANotMemberPredicate;
+import de.be4.classicalb.core.parser.node.AOperation;
+import de.be4.classicalb.core.parser.node.AOperationsMachineClause;
+import de.be4.classicalb.core.parser.node.APowSubsetExpression;
+import de.be4.classicalb.core.parser.node.APowerOfExpression;
+import de.be4.classicalb.core.parser.node.APropertiesMachineClause;
+import de.be4.classicalb.core.parser.node.ARecEntry;
+import de.be4.classicalb.core.parser.node.ARecExpression;
+import de.be4.classicalb.core.parser.node.ARecordFieldExpression;
+import de.be4.classicalb.core.parser.node.ASeqExpression;
+import de.be4.classicalb.core.parser.node.ASequenceExtensionExpression;
+import de.be4.classicalb.core.parser.node.ASetExtensionExpression;
+import de.be4.classicalb.core.parser.node.ASizeExpression;
+import de.be4.classicalb.core.parser.node.AStringExpression;
+import de.be4.classicalb.core.parser.node.AStringSetExpression;
+import de.be4.classicalb.core.parser.node.AStructExpression;
+import de.be4.classicalb.core.parser.node.ASubsetPredicate;
+import de.be4.classicalb.core.parser.node.ATailExpression;
+import de.be4.classicalb.core.parser.node.ATotalFunctionExpression;
+import de.be4.classicalb.core.parser.node.AUnaryMinusExpression;
+import de.be4.classicalb.core.parser.node.AUnionExpression;
+import de.be4.classicalb.core.parser.node.AVariablesMachineClause;
+import de.be4.classicalb.core.parser.node.EOF;
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.be4.classicalb.core.parser.node.PMachineClause;
+import de.be4.classicalb.core.parser.node.POperation;
+import de.be4.classicalb.core.parser.node.PPredicate;
+import de.be4.classicalb.core.parser.node.PRecEntry;
+import de.be4.classicalb.core.parser.node.Start;
+import de.be4.classicalb.core.parser.node.TIdentifierLiteral;
+import de.be4.classicalb.core.parser.node.TIntegerLiteral;
+import de.be4.classicalb.core.parser.node.TStringLiteral;
+import de.tla2b.analysis.BOperation;
+import de.tla2b.analysis.SpecAnalyser;
+import de.tla2b.config.ConfigfileEvaluator;
+import de.tla2b.global.BBuildIns;
+import de.tla2b.global.BBuiltInOPs;
+import de.tla2b.global.Priorities;
+import de.tla2b.global.TranslationGlobals;
+import de.tla2b.types.IType;
+import de.tla2b.types.SetType;
+import de.tla2b.types.StructType;
+import de.tla2b.types.TLAType;
+import de.tla2b.types.TupleType;
+
+public class BAstCreator extends BuiltInOPs implements TranslationGlobals,
+		ASTConstants, IType, BBuildIns, Priorities {
+	Start start;
+	List<PMachineClause> machineClauseList;
+	ConfigfileEvaluator conEval;
+	SpecAnalyser specAnalyser;
+
+	private ModuleNode moduleNode;
+
+	public Start getStartNode() {
+		return start;
+	}
+
+	public BAstCreator(ModuleNode moduleNode, ConfigfileEvaluator conEval,
+			SpecAnalyser specAnalyser) {
+		this.conEval = conEval;
+		this.moduleNode = moduleNode;
+		this.specAnalyser = specAnalyser;
+
+		machineClauseList = new ArrayList<PMachineClause>();
+
+		AAbstractMachineParseUnit aAbstractMachineParseUnit = new AAbstractMachineParseUnit();
+		AMachineHeader machineHeader = new AMachineHeader();
+		List<TIdentifierLiteral> headerName = createTIdentifierLiteral(moduleNode
+				.getName().toString());
+		machineHeader.setName(headerName);
+		aAbstractMachineParseUnit.setHeader(machineHeader);
+
+		createConstantsClause();
+		createPropertyClause();
+		createVariableClause();
+		createInvariantClause();
+		createInitClause();
+		createOperationsClause();
+
+		aAbstractMachineParseUnit.setMachineClauses(machineClauseList);
+
+		start = new Start(aAbstractMachineParseUnit, new EOF());
+
+	}
+
+	private void createOperationsClause() {
+		ArrayList<BOperation> bOperations = specAnalyser.getBOperations();
+		if (bOperations == null || bOperations.size() == 0) {
+			return;
+		}
+
+		List<POperation> opList = new ArrayList<POperation>();
+		for (int i = 0; i < bOperations.size(); i++) {
+			BOperation op = bOperations.get(i);
+			String defName = op.getName();
+			List<PExpression> paramList = new ArrayList<PExpression>();
+			for (int j = 0; j < op.getOpParams().size(); j++) {
+				paramList.add(createIdentifierNode(op.getOpParams().get(j)));
+			}
+			AOperation operation = new AOperation();
+			operation.setOpName(createTIdentifierLiteral(defName));
+			operation.setParameters(paramList);
+			operation.setReturnValues(new ArrayList<PExpression>());
+
+			AAnySubstitution any = new AAnySubstitution();
+			OpDeclNode[] vars = moduleNode.getVariableDecls();
+			List<PExpression> anyParams = new ArrayList<PExpression>();
+			for (int j = 0; j < vars.length; j++) {
+				String varName = vars[j].getName().toString();
+				if (op.getUnchangedVariables().contains(varName))
+					continue;
+				anyParams.add(createIdentifierNode(varName + "_n"));
+			}
+			any.setIdentifiers(anyParams);
+			any.setWhere(visitExprOrOpArgNodePredicate(op.getNode()));
+
+			List<PExpression> varList = new ArrayList<PExpression>();
+			List<PExpression> valueList = new ArrayList<PExpression>();
+			for (int j = 0; j < vars.length; j++) {
+				String varName = vars[j].getName().toString();
+				if (op.getUnchangedVariables().contains(varName))
+					continue;
+				varList.add(createIdentifierNode(varName));
+				valueList.add(createIdentifierNode(varName + "_n"));
+			}
+			AAssignSubstitution assign = new AAssignSubstitution(varList,
+					valueList);
+			any.setThen(assign);
+			operation.setOperationBody(any);
+			opList.add(operation);
+		}
+
+		AOperationsMachineClause opClause = new AOperationsMachineClause(opList);
+		machineClauseList.add(opClause);
+	}
+
+	private void createInitClause() {
+		OpDeclNode[] vars = moduleNode.getVariableDecls();
+		if (vars.length == 0)
+			return;
+		List<PExpression> varList = new ArrayList<PExpression>();
+		for (int i = 0; i < vars.length; i++) {
+			varList.add(createIdentifierNode(vars[i].getName().toString()));
+		}
+		ABecomesSuchSubstitution becomes = new ABecomesSuchSubstitution();
+		becomes.setIdentifiers(varList);
+
+		List<PPredicate> predList = new ArrayList<PPredicate>();
+		for (ExprNode node : specAnalyser.getInits()) {
+			predList.add(visitExprNodePredicate(node));
+		}
+		becomes.setPredicate(createConjunction(predList));
+		AInitialisationMachineClause initClause = new AInitialisationMachineClause(
+				becomes);
+		machineClauseList.add(initClause);
+	}
+
+	private void createVariableClause() {
+		List<OpDeclNode> bVariables = Arrays.asList(moduleNode
+				.getVariableDecls());
+		if (bVariables.size() > 0) {
+			List<PExpression> list = new ArrayList<PExpression>();
+			for (OpDeclNode opDeclNode : bVariables) {
+				AIdentifierExpression id = new AIdentifierExpression(
+						createTIdentifierLiteral(opDeclNode.getName()
+								.toString()));
+				list.add(id);
+			}
+			AVariablesMachineClause varClause = new AVariablesMachineClause(
+					list);
+			machineClauseList.add(varClause);
+		}
+	}
+
+	private void createConstantsClause() {
+		List<OpDeclNode> bConstants = Arrays.asList(moduleNode
+				.getConstantDecls());
+		if (bConstants.size() > 0) {
+			List<PExpression> list = new ArrayList<PExpression>();
+			for (OpDeclNode opDeclNode : bConstants) {
+				AIdentifierExpression id = new AIdentifierExpression(
+						createTIdentifierLiteral(opDeclNode.getName()
+								.toString()));
+				list.add(id);
+			}
+			AAbstractConstantsMachineClause abstractConstantsClause = new AAbstractConstantsMachineClause(
+					list);
+			machineClauseList.add(abstractConstantsClause);
+		}
+	}
+
+	private void createPropertyClause() {
+		List<PPredicate> list = new ArrayList<PPredicate>();
+		AssumeNode[] assumes = moduleNode.getAssumptions();
+		if (assumes.length == 0) {
+			return;
+		}
+		for (AssumeNode assumeNode : assumes) {
+			list.add(visitAssumeNode(assumeNode));
+		}
+
+		APropertiesMachineClause propertiesClause = new APropertiesMachineClause();
+		propertiesClause.setPredicates(createConjunction(list));
+
+		machineClauseList.add(propertiesClause);
+	}
+
+	private void createInvariantClause() {
+		OpDeclNode[] vars = moduleNode.getVariableDecls();
+		if (vars.length == 0)
+			return;
+
+		List<PPredicate> predList = new ArrayList<PPredicate>();
+		for (int i = 0; i < vars.length; i++) {
+			TLAType varType = (TLAType) vars[i].getToolObject(TYPE_ID);
+
+			AMemberPredicate member = new AMemberPredicate();
+			member.setLeft(createIdentifierNode(vars[i].getName().toString()));
+			member.setRight(new AIntegerSetExpression());
+
+			predList.add(member);
+		}
+		AInvariantMachineClause invClause = new AInvariantMachineClause(
+				createConjunction(predList));
+		machineClauseList.add(invClause);
+	}
+
+	private PPredicate visitAssumeNode(AssumeNode assumeNode) {
+		return visitExprNodePredicate(assumeNode.getAssume());
+	}
+
+	private PPredicate visitExprNodePredicate(ExprNode n) {
+		switch (n.getKind()) {
+		case OpApplKind:
+			return visitOpApplNodePredicate((OpApplNode) n);
+
+		case NumeralKind: {
+		}
+
+		}
+
+		throw new RuntimeException();
+	}
+
+	private PExpression visitExprNodeExpression(ExprNode n) {
+
+		switch (n.getKind()) {
+
+		case OpApplKind:
+			return visitOpApplNodeExpression((OpApplNode) n);
+
+		case NumeralKind: {
+			String number = String.valueOf(((NumeralNode) n).val());
+			return new AIntegerExpression(new TIntegerLiteral(number));
+		}
+
+		case StringKind: {
+			StringNode s = (StringNode) n;
+			return new AStringExpression(new TStringLiteral(s.getRep()
+					.toString()));
+		}
+
+		}
+
+		throw new RuntimeException();
+	}
+
+	private PPredicate visitOpApplNodePredicate(OpApplNode n) {
+		switch (n.getOperator().getKind()) {
+		case ConstantDeclKind: {
+			return new AEqualPredicate(createIdentifierNode(n.getOperator()
+					.getName().toString()), new ABooleanTrueExpression());
+		}
+		case VariableDeclKind: {
+			return new AEqualPredicate(createIdentifierNode(n.getOperator()
+					.getName().toString()), new ABooleanTrueExpression());
+
+		}
+		case BuiltInKind:
+			return visitBuiltInKindPredicate(n);
+
+		case UserDefinedOpKind: {
+			return visitUserdefinedOpPredicate(n);
+		}
+
+		}
+		System.out.println(n.getOperator().getName());
+		throw new RuntimeException();
+	}
+
+	private PExpression visitOpApplNodeExpression(OpApplNode n) {
+		switch (n.getOperator().getKind()) {
+		case ConstantDeclKind: {
+			return createIdentifierNode(n.getOperator().getName().toString());
+		}
+		case VariableDeclKind: {
+			return createIdentifierNode(n.getOperator().getName().toString());
+		}
+
+		case FormalParamKind: {
+			return createIdentifierNode(n.getOperator().getName().toString());
+		}
+
+		case BuiltInKind:
+			return visitBuiltInKindExpression(n);
+
+		case UserDefinedOpKind: {
+			return visitUserdefinedOpExpression(n);
+		}
+		}
+
+		System.out.println(n.getOperator().getName());
+		throw new RuntimeException();
+	}
+
+	private PPredicate visitUserdefinedOpPredicate(OpApplNode n) {
+		OpDefNode def = (OpDefNode) n.getOperator();
+		// Operator is a B built-in operator
+		if (BBuiltInOPs.contains(def.getName())
+				&& STANDARD_MODULES.contains(def.getSource()
+						.getOriginallyDefinedInModuleNode().getName()
+						.toString())) {
+			return visitBBuitInsPredicate(n);
+		}
+
+		// new Definition or what else
+
+		throw new RuntimeException();
+	}
+
+	private PExpression visitUserdefinedOpExpression(OpApplNode n) {
+		OpDefNode def = (OpDefNode) n.getOperator();
+		// Operator is a B built-in operator
+		if (BBuiltInOPs.contains(def.getName())
+				&& STANDARD_MODULES.contains(def.getSource()
+						.getOriginallyDefinedInModuleNode().getName()
+						.toString())) {
+			return visitBBuitInsExpression(n);
+		}
+
+		// new Definition or what else
+
+		throw new RuntimeException();
+	}
+
+	private PPredicate visitBBuitInsPredicate(OpApplNode n) {
+		switch (BBuiltInOPs.getOpcode(n.getOperator().getName())) {
+
+		case B_OPCODE_lt: // <
+			return new ALessPredicate(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case B_OPCODE_gt: // >
+			return new AGreaterPredicate(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case B_OPCODE_leq: // <=
+			return new ALessEqualPredicate(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case B_OPCODE_geq: // >=
+			return new AGreaterEqualPredicate(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case B_OPCODE_finite: // IsFiniteSet({1,2,3})
+		{
+			AMemberPredicate member = new AMemberPredicate();
+			member.setLeft(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			member.setRight(new AFinSubsetExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0])));
+			return member;
+		}
+		case B_OPCODE_true: // TRUE
+			return new AEqualPredicate(new ABooleanTrueExpression(),
+					new ABooleanTrueExpression());
+
+		case B_OPCODE_false: // FALSE
+			return new AEqualPredicate(new ABooleanFalseExpression(),
+					new ABooleanTrueExpression());
+
+		}
+		System.out.println(n.getOperator().getName());
+		throw new RuntimeException();
+	}
+
+	private PExpression visitBBuitInsExpression(OpApplNode n) {
+		switch (BBuiltInOPs.getOpcode(n.getOperator().getName())) {
+
+		case B_OPCODE_bool: // BOOLEAN
+			return new ABoolSetExpression();
+
+		case B_OPCODE_true: // TRUE
+			return new ABooleanTrueExpression();
+		case B_OPCODE_false: // FALSE
+			return new ABooleanFalseExpression();
+
+			/**********************************************************************
+			 * Standard Module Naturals
+			 **********************************************************************/
+		case B_OPCODE_nat: // Nat
+			return new ANaturalSetExpression();
+
+		case B_OPCODE_plus: // +
+			return new AAddExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case B_OPCODE_minus: // -
+			return new AMinusOrSetSubtractExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case B_OPCODE_times: // *
+			return new AMultOrCartExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case B_OPCODE_exp: // x^y
+			return new APowerOfExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case B_OPCODE_lt: // <
+			return new AConvertBoolExpression(new ALessPredicate(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1])));
+
+		case B_OPCODE_gt: // >
+			return new AConvertBoolExpression(new AGreaterPredicate(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1])));
+
+		case B_OPCODE_leq: // <=
+			return new AConvertBoolExpression(new ALessEqualPredicate(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1])));
+
+		case B_OPCODE_geq: // >=
+			return new AConvertBoolExpression(new AGreaterEqualPredicate(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1])));
+
+		case B_OPCODE_mod: // modulo
+		{
+			PExpression f = visitExprOrOpArgNodeExpression(n.getArgs()[0]);
+			PExpression s = visitExprOrOpArgNodeExpression(n.getArgs()[1]);
+			PExpression f2 = visitExprOrOpArgNodeExpression(n.getArgs()[0]);
+			PExpression s2 = visitExprOrOpArgNodeExpression(n.getArgs()[1]);
+
+			ADivExpression div = new ADivExpression(f, s);
+			AMultOrCartExpression mult = new AMultOrCartExpression(s2, div);
+			AMinusOrSetSubtractExpression minus = new AMinusOrSetSubtractExpression(
+					f2, mult);
+			return minus;
+		}
+
+		case B_OPCODE_div: // /
+			return new ADivExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case B_OPCODE_dotdot: // ..
+			return new AIntervalExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case B_OPCODE_int: // Int
+			return new AIntegerSetExpression();
+
+		case B_OPCODE_uminus: // -x
+			return new AUnaryMinusExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+
+		case B_OPCODE_card: // Cardinality
+			return new ACardExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+
+		case B_OPCODE_finite: // IsFiniteSet({1,2,3})
+		{
+			AMemberPredicate member = new AMemberPredicate();
+			member.setLeft(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			member.setRight(new AFinSubsetExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0])));
+			return new AConvertBoolExpression(member);
+		}
+
+		case B_OPCODE_string: // STRING
+			return new AStringSetExpression();
+
+			/**********************************************************************
+			 * Standard Module Sequences
+			 **********************************************************************/
+
+		case B_OPCODE_seq: // Seq(S) - set of sequences
+			return new ASeqExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+
+		case B_OPCODE_len: // length of the sequence
+			return new ASizeExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+
+		case B_OPCODE_conc: // s \o s2 - concatenation of s and s2
+			return new AConcatExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case B_OPCODE_append: // Append(s,x)
+			return new AInsertTailExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case B_OPCODE_head: // Head(s)
+			return new AFirstExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+
+		case B_OPCODE_tail: // Tail(s)
+			return new ATailExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+
+		case B_OPCODE_subseq: { // SubSeq(s,m,n)
+			// StringBuilder s = visitExprOrOpArgNode(n.getArgs()[0], d,
+			// NOBOOL).out;
+			// out.append("(");
+			// out.append(s);
+			// out.append("/|\\"); // taking first n elements
+			// out.append(visitExprOrOpArgNode(n.getArgs()[2], d, NOBOOL).out);
+			// out.append(")\\|/"); // dropping first m-1 elements
+			// out.append(visitExprOrOpArgNode(n.getArgs()[1], d, NOBOOL).out);
+			// out.append("-1");
+			// return new ExprReturn(out, P_drop_last);
+		}
+
+		}
+		System.out.println(n.getOperator().getName());
+		throw new RuntimeException();
+	}
+
+	private PExpression visitBuiltInKindExpression(OpApplNode n) {
+		switch (getOpCode(n.getOperator().getName())) {
+
+		case OPCODE_land: // \land
+		{
+			AConjunctPredicate conjunction = new AConjunctPredicate();
+			conjunction.setLeft(visitExprOrOpArgNodePredicate(n.getArgs()[0]));
+			conjunction.setRight(visitExprOrOpArgNodePredicate(n.getArgs()[1]));
+			return new AConvertBoolExpression(conjunction);
+		}
+
+		case OPCODE_cl: // $ConjList
+		{
+			List<PPredicate> list = new ArrayList<PPredicate>();
+			for (int i = 0; i < n.getArgs().length; i++) {
+				list.add(visitExprOrOpArgNodePredicate(n.getArgs()[i]));
+			}
+			return new AConvertBoolExpression(createConjunction(list));
+		}
+
+		case OPCODE_dl: // $DisjList
+		{
+			List<PPredicate> list = new ArrayList<PPredicate>();
+			for (int i = 0; i < n.getArgs().length; i++) {
+				list.add(visitExprOrOpArgNodePredicate(n.getArgs()[i]));
+			}
+			return new AConvertBoolExpression(createDisjunction(list));
+		}
+
+		case OPCODE_lor: // \/
+		{
+			ADisjunctPredicate disjunction = new ADisjunctPredicate();
+			disjunction.setLeft(visitExprOrOpArgNodePredicate(n.getArgs()[0]));
+			disjunction.setRight(visitExprOrOpArgNodePredicate(n.getArgs()[1]));
+			return new AConvertBoolExpression(disjunction);
+		}
+
+		case OPCODE_lnot: // \lnot
+			return new AConvertBoolExpression(new ANegationPredicate(
+					visitExprOrOpArgNodePredicate(n.getArgs()[0])));
+
+		case OPCODE_in: // \in
+		{
+			AMemberPredicate memberPredicate = new AMemberPredicate();
+			memberPredicate
+					.setLeft(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			memberPredicate
+					.setRight(visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+			return new AConvertBoolExpression(memberPredicate);
+		}
+
+		case OPCODE_notin: // \notin
+		{
+			ANotMemberPredicate notMemberPredicate = new ANotMemberPredicate();
+			notMemberPredicate.setLeft(visitExprOrOpArgNodeExpression(n
+					.getArgs()[0]));
+			notMemberPredicate.setRight(visitExprOrOpArgNodeExpression(n
+					.getArgs()[1]));
+			return new AConvertBoolExpression(notMemberPredicate);
+		}
+
+		case OPCODE_eq: { // =
+			AEqualPredicate equal = new AEqualPredicate();
+			equal.setLeft(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			equal.setRight(visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+			return new AConvertBoolExpression(equal);
+		}
+
+		case OPCODE_noteq: // /=
+		{
+			ANotEqualPredicate notEqual = new ANotEqualPredicate();
+			notEqual.setLeft(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			notEqual.setRight(visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+			return new AConvertBoolExpression(notEqual);
+		}
+
+		/**********************************************************************
+		 * Set Operators
+		 **********************************************************************/
+
+		case OPCODE_se: // SetEnumeration {..}
+		{
+			if (n.getArgs().length == 0) {
+				return new AEmptySetExpression();
+			} else {
+				List<PExpression> list = new ArrayList<PExpression>();
+
+				for (int i = 0; i < n.getArgs().length; i++) {
+					list.add(visitExprOrOpArgNodeExpression(n.getArgs()[i]));
+				}
+				return new ASetExtensionExpression(list);
+			}
+		}
+
+		case 0: {
+			return visitBBuitInsExpression(n);
+		}
+
+		case OPCODE_setdiff: // set difference
+		{
+			AMinusOrSetSubtractExpression minus = new AMinusOrSetSubtractExpression();
+			minus.setLeft(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			minus.setRight(visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+			return minus;
+		}
+
+		case OPCODE_cup: // set union
+		{
+			AUnionExpression union = new AUnionExpression();
+			union.setLeft(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			union.setRight(visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+			return union;
+		}
+
+		case OPCODE_cap: // set intersection
+		{
+			AIntersectionExpression inter = new AIntersectionExpression();
+			inter.setLeft(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			inter.setRight(visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+			return inter;
+		}
+
+		case OPCODE_subset: // SUBSET
+		{
+			APowSubsetExpression pow = new APowSubsetExpression();
+			pow.setExpression(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			return pow;
+		}
+
+		case OPCODE_union: // Union - Union{{1},{2}}
+		{
+			AGeneralUnionExpression union = new AGeneralUnionExpression();
+			union.setExpression(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			return union;
+		}
+
+		case OPCODE_subseteq: // \subseteq {1,2} <: {1,2,3}
+		{
+			ASubsetPredicate subset = new ASubsetPredicate();
+			subset.setLeft(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			subset.setRight(visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+			return new AConvertBoolExpression(subset);
+		}
+
+		case OPCODE_sso: { // $SubsetOf Represents {x \in S : P}
+			// TODO tuple with more than 2 arguments
+			FormalParamNode[][] params = n.getBdedQuantSymbolLists();
+			ExprNode[] bounds = n.getBdedQuantBounds();
+
+			List<PExpression> list = new ArrayList<PExpression>();
+			FormalParamNode p = n.getBdedQuantSymbolLists()[0][0];
+			list.add(createIdentifierNode(p.getName().toString()));
+
+			AComprehensionSetExpression compre = new AComprehensionSetExpression();
+			compre.setIdentifiers(list);
+
+			AMemberPredicate member = new AMemberPredicate();
+			member.setLeft(createIdentifierNode(p.getName().toString()));
+			ExprNode in = n.getBdedQuantBounds()[0];
+			member.setRight(visitExprNodeExpression(in));
+
+			AConjunctPredicate conj = new AConjunctPredicate(member,
+					visitExprOrOpArgNodePredicate(n.getArgs()[0]));
+			compre.setPredicates(conj);
+			return compre;
+		}
+
+		case OPCODE_soa: { // $SetOfAll Represents {e : p1 \in S, p2,p3 \in S2}
+
+			AExistsPredicate exist = new AExistsPredicate();
+			FormalParamNode[][] params = n.getBdedQuantSymbolLists();
+			ExprNode[] bounds = n.getBdedQuantBounds();
+
+			List<PExpression> idList = new ArrayList<PExpression>();
+			List<PPredicate> predList = new ArrayList<PPredicate>();
+			for (int i = 0; i < bounds.length; i++) {
+				FormalParamNode p = params[i][0];
+				AMemberPredicate member = new AMemberPredicate();
+				member.setLeft(createIdentifierNode(p.getName().toString()));
+				ExprNode in = n.getBdedQuantBounds()[i];
+				member.setRight(visitExprNodeExpression(in));
+				predList.add(member);
+				idList.add(createIdentifierNode(p.getName().toString()));
+			}
+			final String nameOfTempVariable = "t_";
+			AEqualPredicate equals = new AEqualPredicate();
+			equals.setLeft(createIdentifierNode(nameOfTempVariable));
+			equals.setRight(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			predList.add(equals);
+			exist.setIdentifiers(idList);
+			exist.setPredicate(createConjunction(predList));
+
+			AComprehensionSetExpression compre = new AComprehensionSetExpression();
+			List<PExpression> tList = new ArrayList<PExpression>();
+			tList.add(createIdentifierNode(nameOfTempVariable));
+			compre.setIdentifiers(tList);
+			compre.setPredicates(exist);
+			return compre;
+		}
+
+		case OPCODE_nrfs:
+		case OPCODE_fc: // Represents [x \in S |-> e].
+		case OPCODE_rfs: {
+			FormalParamNode[][] params = n.getBdedQuantSymbolLists();
+			ExprNode[] bounds = n.getBdedQuantBounds();
+			List<PExpression> idList = new ArrayList<PExpression>();
+			List<PPredicate> predList = new ArrayList<PPredicate>();
+			for (int i = 0; i < params.length; i++) {
+				for (int j = 0; j < params[i].length; j++) {
+					FormalParamNode p = params[i][j];
+					AMemberPredicate member = new AMemberPredicate();
+					member.setLeft(createIdentifierNode(p.getName().toString()));
+					ExprNode in = n.getBdedQuantBounds()[i];
+					member.setRight(visitExprNodeExpression(in));
+					predList.add(member);
+					idList.add(createIdentifierNode(p.getName().toString()));
+				}
+			}
+			ALambdaExpression lambda = new ALambdaExpression();
+			lambda.setIdentifiers(idList);
+			lambda.setPredicate(createConjunction(predList));
+			lambda.setExpression(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			return lambda;
+		}
+
+		case OPCODE_fa: { // f[1]
+			AFunctionExpression func = new AFunctionExpression();
+			func.setIdentifier(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			List<PExpression> paramList = new ArrayList<PExpression>();
+
+			ExprOrOpArgNode dom = n.getArgs()[1];
+			if (dom instanceof OpApplNode
+					&& ((OpApplNode) dom).getOperator().getName().toString()
+							.equals("$Tuple")) {
+				OpApplNode domOpAppl = (OpApplNode) dom;
+				for (int i = 0; i < domOpAppl.getArgs().length; i++) {
+					paramList.add(visitExprOrOpArgNodeExpression(domOpAppl
+							.getArgs()[i]));
+				}
+			} else {
+				paramList.add(visitExprOrOpArgNodeExpression(dom));
+			}
+			func.setParameters(paramList);
+			return func;
+		}
+
+		case OPCODE_domain:
+			return new ADomainExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+
+		case OPCODE_sof: // [ A -> B]
+			return new ATotalFunctionExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case OPCODE_tup: { // $Tuple
+			List<PExpression> list = new ArrayList<PExpression>();
+			for (int i = 0; i < n.getArgs().length; i++) {
+				list.add(visitExprOrOpArgNodeExpression(n.getArgs()[i]));
+			}
+			TLAType t = (TLAType) n.getToolObject(TYPE_ID);
+			if (t instanceof TupleType) {
+				return new ACoupleExpression(list);
+			} else {
+				return new ASequenceExtensionExpression(list);
+			}
+		}
+
+		case OPCODE_cp: // $CartesianProd A \X B \X C
+			return new AMultOrCartExpression(
+					visitExprOrOpArgNodeExpression(n.getArgs()[0]),
+					visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+
+		case OPCODE_sor: { // $SetOfRcds [L1 : e1, L2 : e2]
+			SetType pow = (SetType) n.getToolObject(TYPE_ID);
+			StructType struct = (StructType) pow.getSubType();
+			ExprOrOpArgNode[] args = n.getArgs();
+			Hashtable<String, PExpression> pairTable = new Hashtable<String, PExpression>();
+			for (int i = 0; i < args.length; i++) {
+				OpApplNode pair = (OpApplNode) args[i];
+				StringNode stringNode = (StringNode) pair.getArgs()[0];
+				pairTable.put(stringNode.getRep().toString(),
+						visitExprOrOpArgNodeExpression(pair.getArgs()[1]));
+
+			}
+			List<PRecEntry> recList = new ArrayList<PRecEntry>();
+			for (int i = 0; i < struct.getFields().size(); i++) {
+				String fieldName = struct.getFields().get(i);
+				AIdentifierExpression field = createIdentifierNode(fieldName);
+				ARecEntry rec = new ARecEntry();
+				rec.setIdentifier(field);
+				if (pairTable.containsKey(fieldName)) {
+					rec.setValue(pairTable.get(fieldName));
+				} else {
+					rec.setValue(struct.getType(fieldName).getBNode());
+				}
+				recList.add(rec);
+			}
+
+			return new AStructExpression(recList);
+		}
+
+		case OPCODE_rc: { // [h_1 |-> 1, h_2 |-> 2]
+			StructType struct = (StructType) n.getToolObject(TYPE_ID);
+			Hashtable<String, PExpression> pairTable = new Hashtable<String, PExpression>();
+			ExprOrOpArgNode[] args = n.getArgs();
+			for (int i = 0; i < args.length; i++) {
+				OpApplNode pair = (OpApplNode) args[i];
+				StringNode stringNode = (StringNode) pair.getArgs()[0];
+				pairTable.put(stringNode.getRep().toString(),
+						visitExprOrOpArgNodeExpression(pair.getArgs()[1]));
+			}
+			List<PRecEntry> recList = new ArrayList<PRecEntry>();
+			for (int i = 0; i < struct.getFields().size(); i++) {
+				String fieldName = struct.getFields().get(i);
+				AIdentifierExpression field = createIdentifierNode(fieldName);
+				ARecEntry rec = new ARecEntry();
+				rec.setIdentifier(field);
+				if (pairTable.containsKey(fieldName)) {
+					rec.setValue(pairTable.get(fieldName));
+				} else {
+					// insert null element
+				}
+				recList.add(rec);
+			}
+
+			return new ARecExpression(recList);
+		}
+
+		case OPCODE_rs: { // $RcdSelect r.c
+			ARecordFieldExpression rcdSelect = new ARecordFieldExpression();
+			rcdSelect.setRecord(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			StringNode stringNode = (StringNode) n.getArgs()[1];
+			rcdSelect.setIdentifier(createIdentifierNode(stringNode.getRep()
+					.toString()));
+			return rcdSelect;
+		}
+
+		case OPCODE_prime: // prime
+		{
+			OpApplNode node = (OpApplNode) n.getArgs()[0];
+			return createIdentifierNode(node.getOperator().getName().toString()
+					+ "_n");
+		}
+
+		}
+
+		System.out.println(n.getOperator().getName());
+		throw new RuntimeException();
+	}
+
+	private PPredicate visitBuiltInKindPredicate(OpApplNode n) {
+		switch (getOpCode(n.getOperator().getName())) {
+		case OPCODE_land: // \land
+		{
+			AConjunctPredicate conjunction = new AConjunctPredicate();
+			conjunction.setLeft(visitExprOrOpArgNodePredicate(n.getArgs()[0]));
+			conjunction.setRight(visitExprOrOpArgNodePredicate(n.getArgs()[1]));
+			return conjunction;
+		}
+
+		case OPCODE_cl: // $ConjList
+		{
+			List<PPredicate> list = new ArrayList<PPredicate>();
+			for (int i = 0; i < n.getArgs().length; i++) {
+				list.add(visitExprOrOpArgNodePredicate(n.getArgs()[i]));
+			}
+			return createConjunction(list);
+		}
+
+		case OPCODE_lor: // \/
+		{
+			ADisjunctPredicate disjunction = new ADisjunctPredicate();
+			disjunction.setLeft(visitExprOrOpArgNodePredicate(n.getArgs()[0]));
+			disjunction.setRight(visitExprOrOpArgNodePredicate(n.getArgs()[1]));
+			return disjunction;
+		}
+
+		case OPCODE_dl: // $DisjList
+		{
+			List<PPredicate> list = new ArrayList<PPredicate>();
+			for (int i = 0; i < n.getArgs().length; i++) {
+				list.add(visitExprOrOpArgNodePredicate(n.getArgs()[i]));
+			}
+			return createDisjunction(list);
+		}
+
+		case OPCODE_lnot: // \lnot
+			return new ANegationPredicate(
+					visitExprOrOpArgNodePredicate(n.getArgs()[0]));
+
+		case OPCODE_equiv: // \equiv
+			return new AEquivalencePredicate(
+					visitExprOrOpArgNodePredicate(n.getArgs()[0]),
+					visitExprOrOpArgNodePredicate(n.getArgs()[1]));
+
+		case OPCODE_implies: // =>
+			return new AImplicationPredicate(
+					visitExprOrOpArgNodePredicate(n.getArgs()[0]),
+					visitExprOrOpArgNodePredicate(n.getArgs()[1]));
+
+		case OPCODE_be: { // \E x \in S : P
+			FormalParamNode[][] params = n.getBdedQuantSymbolLists();
+			ArrayList<PExpression> list = new ArrayList<PExpression>();
+			for (int i = 0; i < params.length; i++) {
+				for (int j = 0; j < params[i].length; j++) {
+					list.add(createIdentifierNode(params[i][j].getName()
+							.toString()));
+				}
+			}
+			AConjunctPredicate conjunction = new AConjunctPredicate();
+			conjunction.setLeft(visitBounded(n));
+			conjunction.setRight(visitExprOrOpArgNodePredicate(n.getArgs()[0]));
+			return new AExistsPredicate(list, conjunction);
+		}
+
+		case OPCODE_bf: { // \A x \in S : P
+			FormalParamNode[][] params = n.getBdedQuantSymbolLists();
+			ArrayList<PExpression> list = new ArrayList<PExpression>();
+			for (int i = 0; i < params.length; i++) {
+				for (int j = 0; j < params[i].length; j++) {
+					list.add(createIdentifierNode(params[i][j].getName()
+							.toString()));
+				}
+			}
+			AImplicationPredicate implication = new AImplicationPredicate();
+			implication.setLeft(visitBounded(n));
+			implication.setRight(visitExprOrOpArgNodePredicate(n.getArgs()[0]));
+			return new AForallPredicate(list, implication);
+		}
+
+		case OPCODE_eq: { // =
+			AEqualPredicate equal = new AEqualPredicate();
+			equal.setLeft(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			equal.setRight(visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+			return equal;
+		}
+
+		case OPCODE_noteq: // /=
+		{
+			ANotEqualPredicate notEqual = new ANotEqualPredicate();
+			notEqual.setLeft(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			notEqual.setRight(visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+			return notEqual;
+		}
+
+		case OPCODE_in: // \in
+		{
+			AMemberPredicate memberPredicate = new AMemberPredicate();
+			memberPredicate
+					.setLeft(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			memberPredicate
+					.setRight(visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+			return memberPredicate;
+		}
+
+		case OPCODE_notin: // \notin
+		{
+			ANotMemberPredicate notMemberPredicate = new ANotMemberPredicate();
+			notMemberPredicate.setLeft(visitExprOrOpArgNodeExpression(n
+					.getArgs()[0]));
+			notMemberPredicate.setRight(visitExprOrOpArgNodeExpression(n
+					.getArgs()[1]));
+			return notMemberPredicate;
+		}
+
+		case OPCODE_subseteq: // \subseteq {1,2} <: {1,2,3}
+		{
+			ASubsetPredicate subset = new ASubsetPredicate();
+			subset.setLeft(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			subset.setRight(visitExprOrOpArgNodeExpression(n.getArgs()[1]));
+			return subset;
+		}
+
+		case OPCODE_fa: { // f[1]
+			AFunctionExpression func = new AFunctionExpression();
+			func.setIdentifier(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			List<PExpression> paramList = new ArrayList<PExpression>();
+
+			ExprOrOpArgNode dom = n.getArgs()[1];
+			if (dom instanceof OpApplNode
+					&& ((OpApplNode) dom).getOperator().getName().toString()
+							.equals("$Tuple")) {
+				OpApplNode domOpAppl = (OpApplNode) dom;
+				for (int i = 0; i < domOpAppl.getArgs().length; i++) {
+					paramList.add(visitExprOrOpArgNodeExpression(domOpAppl
+							.getArgs()[i]));
+				}
+			} else {
+				paramList.add(visitExprOrOpArgNodeExpression(dom));
+			}
+			func.setParameters(paramList);
+			return new AEqualPredicate(func, new ABooleanTrueExpression());
+		}
+
+		case OPCODE_rs: { // $RcdSelect r.c
+			ARecordFieldExpression rcdSelect = new ARecordFieldExpression();
+			rcdSelect.setRecord(visitExprOrOpArgNodeExpression(n.getArgs()[0]));
+			StringNode stringNode = (StringNode) n.getArgs()[1];
+			rcdSelect.setIdentifier(createIdentifierNode(stringNode.getRep()
+					.toString()));
+			return new AEqualPredicate(rcdSelect, new ABooleanTrueExpression());
+		}
+
+		case OPCODE_prime: // prime
+		{
+			OpApplNode node = (OpApplNode) n.getArgs()[0];
+			return new AEqualPredicate(createIdentifierNode(node.getOperator()
+					.getName().toString()
+					+ "_n"), new ABooleanTrueExpression());
+		}
+
+		case 0:
+			return visitBBuitInsPredicate(n);
+
+		}
+
+		System.out.println(n.getOperator().getName());
+		throw new RuntimeException();
+	}
+
+	private PPredicate visitBounded(OpApplNode n) {
+		FormalParamNode[][] params = n.getBdedQuantSymbolLists();
+		ExprNode[] in = n.getBdedQuantBounds();
+		boolean[] isTuple = n.isBdedQuantATuple();
+
+		List<PPredicate> predList = new ArrayList<PPredicate>();
+		for (int i = 0; i < params.length; i++) {
+			if (isTuple[i]) {
+
+				ArrayList<PExpression> list = new ArrayList<PExpression>();
+				for (int j = 0; j < params[i].length; j++) {
+					list.add(createIdentifierNode(params[i][j].getName()
+							.toString()));
+				}
+				AMemberPredicate member = new AMemberPredicate();
+				member.setLeft(new ACoupleExpression(list));
+				member.setRight(visitExprNodeExpression(in[i]));
+				predList.add(member);
+			} else {
+				for (int j = 0; j < params[i].length; j++) {
+					AMemberPredicate member = new AMemberPredicate();
+					member.setLeft(createIdentifierNode(params[i][j].getName()
+							.toString()));
+					member.setRight(visitExprNodeExpression(in[i]));
+					predList.add(member);
+				}
+			}
+		}
+		return createConjunction(predList);
+	}
+
+	private PPredicate visitExprOrOpArgNodePredicate(ExprOrOpArgNode n) {
+		if (n instanceof ExprNode) {
+			return visitExprNodePredicate((ExprNode) n);
+		} else {
+			throw new RuntimeException("OpArgNode not implemented jet");
+		}
+	}
+
+	private PExpression visitExprOrOpArgNodeExpression(ExprOrOpArgNode n) {
+
+		if (n instanceof ExprNode) {
+			return visitExprNodeExpression((ExprNode) n);
+		} else {
+			throw new RuntimeException("OpArgNode not implemented jet");
+		}
+	}
+
+	public static AIdentifierExpression createIdentifierNode(String name) {
+		return new AIdentifierExpression(createTIdentifierLiteral(name));
+	}
+
+	private PPredicate createConjunction(List<PPredicate> list) {
+		if (list.size() == 1)
+			return list.get(0);
+		AConjunctPredicate conj = new AConjunctPredicate();
+		conj.setLeft(list.get(0));
+		for (int i = 1; i < list.size(); i++) {
+			if (i < list.size() - 1) {
+				conj.setRight(list.get(i));
+				conj = new AConjunctPredicate(conj, null);
+			} else {
+				conj.setRight(list.get(i));
+			}
+		}
+		return conj;
+	}
+
+	private PPredicate createDisjunction(List<PPredicate> list) {
+		if (list.size() == 1)
+			return list.get(0);
+		ADisjunctPredicate disjunction = new ADisjunctPredicate();
+		disjunction.setLeft(list.get(0));
+		for (int i = 1; i < list.size(); i++) {
+			if (i < list.size() - 1) {
+				disjunction.setRight(list.get(i));
+				disjunction = new ADisjunctPredicate(disjunction, null);
+			} else {
+				disjunction.setRight(list.get(i));
+			}
+		}
+		return disjunction;
+	}
+
+	public static List<TIdentifierLiteral> createTIdentifierLiteral(String name) {
+		List<TIdentifierLiteral> list = new ArrayList<TIdentifierLiteral>();
+		TIdentifierLiteral tid = new TIdentifierLiteral(name);
+		list.add(tid);
+		return list;
+	}
+
+}
diff --git a/src/main/java/de/tla2b/pprint/BMachinePrinter.java b/src/main/java/de/tla2b/pprint/BMachinePrinter.java
new file mode 100644
index 0000000000000000000000000000000000000000..555df520e439cb5ad8f0164c39e00e8651402024
--- /dev/null
+++ b/src/main/java/de/tla2b/pprint/BMachinePrinter.java
@@ -0,0 +1,697 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.pprint;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Set;
+
+import de.tla2b.analysis.BOperation;
+import de.tla2b.analysis.RecursiveFunktion;
+import de.tla2b.analysis.SpecAnalyser;
+import de.tla2b.config.ConfigfileEvaluator;
+import de.tla2b.config.ValueObj;
+import de.tla2b.global.BBuiltInOPs;
+import de.tla2b.global.TranslationGlobals;
+import de.tla2b.types.EnumType;
+import de.tla2b.types.SetType;
+import de.tla2b.types.TLAType;
+
+import tla2sany.semantic.AssumeNode;
+import tla2sany.semantic.ExprNode;
+import tla2sany.semantic.FormalParamNode;
+import tla2sany.semantic.LetInNode;
+import tla2sany.semantic.ModuleNode;
+import tla2sany.semantic.OpApplNode;
+import tla2sany.semantic.OpDeclNode;
+import tla2sany.semantic.OpDefNode;
+import tlc2.value.SetEnumValue;
+
+public class BMachinePrinter extends AbstractExpressionPrinter implements
+		TranslationGlobals {
+	private ModuleNode module;
+	private ArrayList<OpDeclNode> bConstants;
+	private ArrayList<ExprNode> inits;
+	private ArrayList<BOperation> bOperations;
+	private ArrayList<OpDefNode> invariants;
+	private ArrayList<LetInNode> globalLets;
+	private ArrayList<String> setEnumeration;
+	private ArrayList<String> definitionMacro;
+	private Hashtable<OpDeclNode, ValueObj> constantAssignments;
+	private ArrayList<OpDefNode> operatorModelvalues;
+	private Set<OpDefNode> bDefinitions;
+	// set of OpDefNodes which are called in the specification
+	private Hashtable<OpDefNode, FormalParamNode[]> letParams;
+
+	private ArrayList<RecursiveFunktion> recursiveFunktions;
+	private ArrayList<LetInNode> tempLetInNodes = new ArrayList<LetInNode>();
+
+	/**
+	 * @param moduleNode
+	 * @param conEval
+	 * @param specAnalyser
+	 */
+	public BMachinePrinter(ModuleNode moduleNode, ConfigfileEvaluator conEval,
+			SpecAnalyser specAnalyser) {
+		this.module = moduleNode;
+
+		if (conEval == null) {
+			bConstants = new ArrayList<OpDeclNode>();
+			for (int i = 0; i < moduleNode.getConstantDecls().length; i++) {
+				bConstants.add(moduleNode.getConstantDecls()[i]);
+			}
+		} else {
+			this.bConstants = conEval.getbConstantList();
+			this.invariants = conEval.getInvariants();
+			this.setEnumeration = conEval.getEnumerationSet();
+			this.constantAssignments = conEval.getConstantAssignments();
+			this.operatorModelvalues = conEval.getOperatorModelvalues();
+		}
+
+		this.inits = specAnalyser.getInits();
+		this.bOperations = specAnalyser.getBOperations();
+		this.globalLets = specAnalyser.getGlobalLets();
+		this.definitionMacro = specAnalyser.getDefinitionMacros();
+		this.bDefinitions = specAnalyser.getBDefinitions();
+		this.letParams = specAnalyser.getLetParams();
+		this.recursiveFunktions = specAnalyser.getRecursiveFunctions();
+	}
+
+	public StringBuilder start() {
+		StringBuilder out = new StringBuilder();
+		out.append("MACHINE " + module.getName().toString() + "\n");
+
+		out.append(evalEnumeratedSets());
+
+		// Constants and Properties
+		out.append(evalConsDecl());
+		out.append(evalPropertyStatements());
+		tempLetInNodes.clear();
+		StringBuilder operations = evalOperations();
+		globalLets.addAll(tempLetInNodes);
+		tempLetInNodes.clear();
+
+		out.append(evalDefinitions());
+
+		out.append(evalVariables());
+
+		out.append(evalInvariants());
+
+		out.append(evalInit());
+
+		out.append(operations);
+		out.append("END");
+		return out;
+	}
+
+	/**
+	 * @return
+	 */
+	private StringBuilder evalEnumeratedSets() {
+		StringBuilder out = new StringBuilder();
+
+		if (setEnumeration == null || setEnumeration.size() == 0)
+			return out;
+
+		out.append("SETS\n ");
+
+		ArrayList<EnumType> printed = new ArrayList<EnumType>();
+		int counter = 1;
+
+		OpDeclNode[] cons = module.getConstantDecls();
+		boolean first = true;
+		for (int i = 0; i < cons.length; i++) {
+			TLAType type = (TLAType) cons[i].getToolObject(TYPE_ID);
+			EnumType e = null;
+			if (type instanceof SetType) {
+				if (((SetType) type).getSubType() instanceof EnumType) {
+					e = (EnumType) ((SetType) type).getSubType();
+				} else
+					continue;
+
+			} else if ((type instanceof EnumType)) {
+				e = (EnumType) type;
+			} else
+				continue;
+
+			if (!printed.contains(e)) {
+				e.id = counter;
+				if (!first) {
+					out.append("; ");
+				}
+				out.append("ENUM" + counter + " = {");
+				Iterator<String> it2 = e.modelvalues.iterator();
+				while (it2.hasNext()) {
+					out.append(it2.next());
+					if (it2.hasNext()) {
+						out.append(", ");
+					}
+				}
+				if (e.hasNoVal()) {
+					out.append(", noVal" + counter);
+				}
+				out.append("}");
+				printed.add(e);
+				counter++;
+				first = false;
+			}
+		}
+
+		if (operatorModelvalues != null && operatorModelvalues.size() > 0) {
+			for (int i = 0; i < operatorModelvalues.size(); i++) {
+				OpDefNode def = operatorModelvalues.get(i);
+				TLAType type = (TLAType) def.getToolObject(TYPE_ID);
+				EnumType e = null;
+				if (type instanceof SetType) {
+					if (((SetType) type).getSubType() instanceof EnumType) {
+						e = (EnumType) ((SetType) type).getSubType();
+					} else
+						continue;
+
+				} else if ((type instanceof EnumType)) {
+					e = (EnumType) type;
+				} else
+					continue;
+
+				if (!printed.contains(e)) {
+					e.id = counter;
+					if (!first) {
+						out.append("; ");
+					}
+					out.append("ENUM" + counter + " = {");
+					Iterator<String> it2 = e.modelvalues.iterator();
+					while (it2.hasNext()) {
+						out.append(it2.next());
+						if (it2.hasNext()) {
+							out.append(", ");
+						}
+					}
+					if (e.hasNoVal()) {
+						out.append(", noVal" + counter);
+					}
+					out.append("}");
+					printed.add(e);
+					counter++;
+					first = false;
+				}
+
+			}
+
+		}
+
+		out.append("\n");
+		return out;
+	}
+
+	private StringBuilder evalInvariants() {
+		StringBuilder out = new StringBuilder();
+		OpDeclNode[] vars = module.getVariableDecls();
+		if (vars.length > 0) {
+			out.append("INVARIANT\n ");
+			for (int i = 0; i < vars.length; i++) {
+				TLAType varType = (TLAType) vars[i].getToolObject(TYPE_ID);
+				out.append(getPrintName(vars[i]) + " : " + varType + "\n");
+				if (i != vars.length - 1)
+					out.append(" & ");
+			}
+			if (invariants != null) {
+				for (int i = 0; i < invariants.size(); i++) {
+					out.append(" & " + invariants.get(i).getName().toString()
+							+ "\n");
+				}
+			}
+		}
+		return out;
+	}
+
+	private StringBuilder evalInit() {
+		StringBuilder out = new StringBuilder();
+		OpDeclNode[] vars = module.getVariableDecls();
+		if (vars.length == 0)
+			return out;
+		out.append("INITIALISATION\n ");
+		for (int i = 0; i < vars.length; i++) {
+			out.append(getPrintName(vars[i]));
+			if (i < vars.length - 1)
+				out.append(", ");
+		}
+		out.append(":(");
+		for (int i = 0; i < inits.size(); i++) {
+			if (i != 0) {
+				out.append(" & ");
+			}
+			out.append(visitExprNode(inits.get(i), new DContext(), PREDICATE).out);
+		}
+		out.append(")\n");
+		return out;
+	}
+
+	private StringBuilder evalOperations() {
+		StringBuilder out = new StringBuilder();
+		if (bOperations == null)
+			return out;
+
+		out.append("OPERATIONS\n");
+		for (int i = 0; i < bOperations.size(); i++) {
+			BOperation op = bOperations.get(i);
+			String defName = op.getName();
+
+			DContext d = new DContext("\t");
+			out.append(" " + defName.replace('!', '_') + "_Op");
+			if (op.getOpParams().size() > 0) {
+				out.append("(");
+				for (int j = 0; j < op.getOpParams().size(); j++) {
+					if (j != 0)
+						out.append(", ");
+					out.append(op.getOpParams().get(j));
+				}
+				out.append(")");
+			}
+			out.append(" = ");
+			out.append("ANY ");
+			OpDeclNode[] vars = module.getVariableDecls();
+			boolean first = true;
+			for (int j = 0; j < vars.length; j++) {
+				String varName = vars[j].getName().toString();
+				if (op.getUnchangedVariables().contains(varName))
+					continue;
+				if (!first) {
+					out.append(", ");
+				}
+				out.append(varName + "_n");
+				first = false;
+			}
+			out.append("\n\tWHERE ");
+			if (op.getOpParams().size() > 0) {
+				for (int j = 0; j < op.getExistQuans().size(); j++) {
+					OpApplNode o = op.getExistQuans().get(j);
+					out.append(visitBounded(o, d));
+					out.append(" & ");
+				}
+				out.append("\n\t ");
+			}
+			for (int j = 0; j < vars.length; j++) {
+				String varName = vars[j].getName().toString();
+				if (op.getUnchangedVariables().contains(varName))
+					continue;
+				out.append(varName + "_n : " + vars[j].getToolObject(TYPE_ID));
+				out.append(" & ");
+			}
+			out.append(visitExprOrOpArgNode(op.getNode(), d, PREDICATE).out);
+
+			out.append("\n\tTHEN ");
+
+			boolean first2 = true;
+			for (int j = 0; j < vars.length; j++) {
+				String varName = vars[j].getName().toString();
+				if (op.getUnchangedVariables().contains(varName))
+					continue;
+				if (!first2) {
+					out.append(", ");
+				}
+				out.append(varName);
+				first2 = false;
+			}
+
+			out.append(" := ");
+
+			boolean first3 = true;
+			for (int j = 0; j < vars.length; j++) {
+				String varName = vars[j].getName().toString();
+				if (op.getUnchangedVariables().contains(varName))
+					continue;
+				if (!first3) {
+					out.append(", ");
+				}
+				out.append(varName + "_n");
+				first3 = false;
+			}
+			out.append(" END");
+			if (i != bOperations.size() - 1) {
+				out.append(";\n\n");
+			}
+		}
+		out.append("\n");
+		return out;
+	}
+
+	private StringBuilder evalVariables() {
+		StringBuilder out = new StringBuilder();
+		OpDeclNode[] vars = module.getVariableDecls();
+		if (vars.length > 0) {
+			out.append("VARIABLES\n ");
+			for (int i = 0; i < vars.length; i++) {
+				String[] comments = vars[i].getPreComments();
+				if (comments.length > 0) {
+					String pragma = comments[comments.length - 1];
+					if (pragma.startsWith("(*@")) {
+						pragma = pragma.replace('(', '/').replace(')', '/');
+						out.append(pragma).append(" ");
+					}
+
+				}
+				out.append(getPrintName(vars[i]));
+				if (i != vars.length - 1)
+					out.append(",\n ");
+			}
+			out.append("\n");
+		}
+		return out;
+	}
+
+	private StringBuilder evalDefinitions() {
+		StringBuilder out = new StringBuilder();
+		ArrayList<OpDefNode> bDefs = new ArrayList<OpDefNode>();
+		for (int i = 0; i < module.getOpDefs().length; i++) {
+			OpDefNode def = module.getOpDefs()[i];
+			if (bDefinitions.contains(def))
+				bDefs.add(def);
+		}
+
+		if (bDefs.size() + globalLets.size() + definitionMacro.size() == 0)
+			return out;
+		out.append("DEFINITIONS\n");
+		for (int i = 0; i < definitionMacro.size(); i++) {
+			out.append(definitionMacro.get(i));
+			if (i != definitionMacro.size() - 1
+					|| bDefs.size() + globalLets.size() > 0) {
+				out.append(";\n");
+			}
+		}
+
+		for (int i = 0; i < bDefs.size(); i++) {
+			out.append(visitOpDefNode(bDefs.get(i)));
+			if (!(i == bDefs.size() - 1 && globalLets.size() == 0))
+				out.append(";\n\n");
+		}
+
+		for (int i = 0; i < globalLets.size(); i++) {
+			LetInNode letInNode = globalLets.get(i);
+			for (int j = 0; j < letInNode.getLets().length; j++) {
+				out.append(evalLet(letInNode.getLets()[j]));
+				if (i != letInNode.getLets().length - 1)
+					out.append(";\n");
+			}
+			if (i != globalLets.size() - 1)
+				out.append(";\n");
+		}
+		out.append("\n");
+		return out;
+	}
+
+	/**
+	 * @param letDef
+	 * @return
+	 */
+	private StringBuilder evalLet(OpDefNode letDef) {
+		StringBuilder out = new StringBuilder();
+		String defName = getPrintName(letDef);
+		out.append(" " + defName);
+		FormalParamNode[] shiftParams = letParams.get(letDef);
+		if (shiftParams == null)
+			shiftParams = new FormalParamNode[0];
+		if (letDef.getParams().length + shiftParams.length > 0) {
+			out.append("(");
+			for (int i = 0; i < letDef.getParams().length; i++) {
+				if (i != 0)
+					out.append(",");
+				out.append(letDef.getParams()[i].getName().toString());
+			}
+			for (int i = 0; i < shiftParams.length; i++) {
+				if (letDef.getParams().length > 0 || i != 0)
+					out.append(", ");
+				out.append(shiftParams[i].getName().toString());
+
+			}
+			out.append(")");
+		}
+		out.append(" == ");
+		DContext d = new DContext("\t");
+		out.append(visitExprNode(letDef.getBody(), d, VALUEORPREDICATE).out);
+		return out;
+
+	}
+
+	/**
+	 * @param def
+	 */
+	private StringBuilder visitOpDefNode(OpDefNode def) {
+		StringBuilder out = new StringBuilder();
+		// ConstantObj conObj = (ConstantObj) def.getSource().getToolObject(
+		// CONSTANT_OBJECT);
+		// if (conObj != null) {
+		// System.out.println("hier");
+		// // config substitution
+		// // out.append(" " + defName.replace('!', '_'));
+		// String defName = getPrintName(def);
+		// String defValue = conObj.getValue().toString();
+		// if(defName.equals(defName.equals(defValue)))
+		// return out;
+		// out.append(" " + defName);
+		// out.append(" == " + defValue);
+		// return out;
+		// }
+
+		DContext d = new DContext("\t");
+		tempLetInNodes.clear();
+		StringBuilder body = visitExprNode(def.getBody(), d, VALUEORPREDICATE).out;
+
+		for (int i = 0; i < tempLetInNodes.size(); i++) {
+			LetInNode letInNode = tempLetInNodes.get(i);
+			for (int j = 0; j < letInNode.getLets().length; j++) {
+				out.append(evalLet(letInNode.getLets()[j]));
+				out.append(";\n");
+			}
+
+		}
+		tempLetInNodes.clear();
+
+		out.append(" " + getPrintName(def));
+		FormalParamNode[] params = def.getParams();
+		if (params.length > 0) {
+			out.append("(");
+			for (int i = 0; i < params.length; i++) {
+				if (i != 0)
+					out.append(", ");
+				out.append(getPrintName(params[i]));
+			}
+			out.append(")");
+		}
+		out.append(" == ");
+		out.append(body);
+		return out;
+	}
+
+	private StringBuilder evalConsDecl() {
+		StringBuilder out = new StringBuilder();
+		if (bConstants.size() + recursiveFunktions.size() == 0)
+			return out;
+		out.append("ABSTRACT_CONSTANTS\n");
+		// out.append("CONSTANTS ");
+		for (int i = 0; i < bConstants.size(); i++) {
+			String[] comments = bConstants.get(i).getPreComments();
+			if (comments.length > 0) {
+				String pragma = comments[comments.length - 1];
+				if (pragma.startsWith("(*@")) {
+					pragma = pragma.replace('(', '/').replace(')', '/');
+					out.append(pragma).append(" ");
+				}
+
+			}
+			out.append(getPrintName(bConstants.get(i)));
+			if (i < bConstants.size() - 1 || recursiveFunktions.size() > 0)
+				out.append(",\n ");
+		}
+		for (int i = 0; i < recursiveFunktions.size(); i++) {
+			out.append(getPrintName(recursiveFunktions.get(i).getOpDefNode()));
+			if (i < recursiveFunktions.size() - 1)
+				out.append(", ");
+		}
+		out.append("\n");
+		return out;
+	}
+
+	private StringBuilder evalPropertyStatements() {
+		StringBuilder out = new StringBuilder();
+		if (bConstants.size() == 0 && module.getAssumptions().length == 0) {
+			return out;
+		}
+		out.append("PROPERTIES\n ");
+		boolean notFirst = false;
+		for (int i = 0; i < bConstants.size(); i++) {
+			OpDeclNode con = bConstants.get(i);
+			if (notFirst) {
+				out.append(" & ");
+			}
+			if (constantAssignments != null
+					&& constantAssignments.containsKey(con)) {
+				ValueObj v = constantAssignments.get(con);
+				TLAType t = v.getType();
+				boolean isEnum = false;
+				if (t instanceof SetType) {
+					TLAType sub = ((SetType) t).getSubType();
+					if (sub instanceof EnumType) {
+						EnumType en = (EnumType) sub;
+						SetEnumValue set = (SetEnumValue) v.getValue();
+						if (set.elems.size() == en.modelvalues.size()) {
+							isEnum = true;
+						}
+					}
+				}
+				if (isEnum) {
+					out.append(String.format("%s = %s\n", getPrintName(con),
+							((SetType) t).getSubType()));
+				} else {
+					out.append(String.format("%s = %s\n", getPrintName(con), v
+							.getValue().toString()));
+				}
+
+			} else {
+				out.append(String.format("%s : %s\n", getPrintName(con),
+						con.getToolObject(TYPE_ID)));
+			}
+
+			notFirst = true;
+		}
+		out.append(evalAssumptions());
+		return out;
+	}
+
+	private StringBuilder evalAssumptions() {
+		AssumeNode[] assumes = module.getAssumptions();
+		StringBuilder out = new StringBuilder();
+		if (assumes.length == 0)
+			return out;
+		if (bConstants.size() > 0) {
+			out.append(" & ");
+		}
+		tempLetInNodes.clear();
+		for (int i = 0; i < assumes.length; i++) {
+			if (i != 0) {
+				out.append(" & ");
+			}
+			out.append(visitAssumeNode(assumes[i]));
+			out.append("\n");
+		}
+		globalLets.addAll(tempLetInNodes);
+		tempLetInNodes.clear();
+
+		if (recursiveFunktions.size() == 0)
+			return out;
+		if (bConstants.size() + assumes.length > 0) {
+			out.append(" & ");
+		}
+		for (int i = 0; i < recursiveFunktions.size(); i++) {
+			if (i != 0) {
+				out.append(" & ");
+			}
+			out.append(visitRecursiveFunction(recursiveFunktions.get(i)));
+			out.append("\n");
+		}
+
+		return out;
+	}
+
+	/**
+	 * @param recursiveFunktion
+	 * @return
+	 */
+	private StringBuilder visitRecursiveFunction(RecursiveFunktion rf) {
+		StringBuilder out = new StringBuilder();
+		OpApplNode o = rf.getRF();
+		OpApplNode ifThenElse = rf.getIfThenElse();
+		out.append(getPrintName(rf.getOpDefNode()));
+		out.append(" = ");
+
+		DContext d = new DContext();
+
+		FormalParamNode[][] vars = o.getBdedQuantSymbolLists();
+		StringBuilder pre = new StringBuilder();
+		for (int i = 0; i < vars.length; i++) {
+			for (int j = 0; j < vars[i].length; j++) {
+				pre.append(vars[i][j].getName());
+				if (j < vars[i].length - 1) {
+					pre.append(",");
+				}
+			}
+			if (i < vars.length - 1) {
+				pre.append(",");
+			}
+		}
+		StringBuilder bound = visitBounded(o, d);
+
+		ExprReturn iif = visitExprOrOpArgNode(ifThenElse.getArgs()[0], d,
+				PREDICATE);
+		ExprReturn then = visitExprOrOpArgNode(ifThenElse.getArgs()[1], d,
+				VALUE);
+		ExprReturn eelse = visitExprOrOpArgNode(ifThenElse.getArgs()[2], d,
+				VALUE);
+		String res = String.format(
+				"%%%s.(%s & %s | %s) \\/ %%%s.(%s & not(%s) | %s)", pre, bound,
+				iif.out, then.out, pre, bound, iif.out, eelse.out);
+		out.append(res);
+		return out;
+	}
+
+	private StringBuilder visitAssumeNode(AssumeNode n) {
+		// there are named or unnamend assumptions
+		StringBuilder out = new StringBuilder();
+		DContext d = new DContext();
+		out.append(visitExprNode(n.getAssume(), d, PREDICATE).out);
+
+		return out;
+	}
+
+	@Override
+	protected ExprReturn visitLetInNode(LetInNode l, DContext d, int expected) {
+		tempLetInNodes.add(l);
+		return visitExprNode(l.getBody(), d, VALUEORPREDICATE);
+	}
+
+	@Override
+	protected ExprReturn visitUserdefinedOp(OpApplNode n, DContext d,
+			int expected) {
+		StringBuilder out = new StringBuilder();
+		OpDefNode def = (OpDefNode) n.getOperator();
+		// Operator is a B built-in operator
+		if (BBuiltInOPs.contains(def.getName())
+				&& STANDARD_MODULES.contains(def.getSource()
+						.getOriginallyDefinedInModuleNode().getName()
+						.toString())) {
+			return evalBBuiltIns(n, d, expected);
+		}
+
+		out.append(getPrintName(def));
+
+		FormalParamNode[] shiftedParams = letParams.get(def);
+		if (n.getArgs().length > 0
+				|| (shiftedParams != null && shiftedParams.length > 0)) {
+			out.append("(");
+			for (int i = 0; i < n.getArgs().length; i++) {
+				out.append(visitExprOrOpArgNode(n.getArgs()[i], d, VALUE).out);
+				if (i < n.getArgs().length - 1) {
+					out.append(", ");
+				}
+			}
+			if (shiftedParams != null) {
+				for (int i = 0; i < shiftedParams.length; i++) {
+					if (n.getArgs().length > 0 || i != 0)
+						out.append(", ");
+					out.append(shiftedParams[i].getName().toString());
+
+				}
+			}
+			out.append(")");
+
+		}
+		TLAType defType = (TLAType) n.getToolObject(TYPE_ID);
+		if (defType != null && defType.getKind() == BOOL) {
+			return makeBoolValue(out, expected, P_max);
+		}
+		return new ExprReturn(out);
+	}
+
+}
diff --git a/src/main/java/de/tla2b/pprint/DContext.java b/src/main/java/de/tla2b/pprint/DContext.java
new file mode 100644
index 0000000000000000000000000000000000000000..988026efabe0eb6bc5b993f389e58f7a586ecc6e
--- /dev/null
+++ b/src/main/java/de/tla2b/pprint/DContext.java
@@ -0,0 +1,18 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.pprint;
+
+public class DContext {
+	public StringBuilder indent;
+	
+	
+	public DContext(){
+		indent = new StringBuilder();
+	}
+	
+	public DContext(String indent){
+		this.indent = new StringBuilder(indent);
+	}
+}
diff --git a/src/main/java/de/tla2b/pprint/ExprReturn.java b/src/main/java/de/tla2b/pprint/ExprReturn.java
new file mode 100644
index 0000000000000000000000000000000000000000..dfe31fd78ba7f7f799d896a141b2fadf79ab75bb
--- /dev/null
+++ b/src/main/java/de/tla2b/pprint/ExprReturn.java
@@ -0,0 +1,53 @@
+package de.tla2b.pprint;
+
+public class ExprReturn {
+	public StringBuilder out= new StringBuilder();
+	private int priority;
+	
+	
+	public ExprReturn(){
+		priority = 300;
+	}
+
+	public ExprReturn(String s){
+		out.append(s);
+		priority = 300;
+	}
+	
+	public ExprReturn(StringBuilder out2) {
+		out.append(out2);
+		priority = 300;
+	}
+	
+	public ExprReturn(StringBuilder out2, int priority2) {
+		out.append(out2);
+		priority = priority2;
+	}
+
+	public ExprReturn(String out2, int priority2) {
+		out.append(out2);
+		priority = priority2;
+	}
+	
+
+	
+	public StringBuilder getOut() {
+		return out;
+	}
+	public void setOut(StringBuilder out) {
+		this.out = out;
+	}
+	public int getPriority() {
+		return priority;
+	}
+	public void setPriority(int priority) {
+		this.priority = priority;
+	}
+	
+	@Override
+	public String toString(){
+		String s = "P: "+ priority + " Out: " +out.toString();
+		return s;
+	}
+
+}
diff --git a/src/main/java/de/tla2b/pprint/ExpressionPrinter.java b/src/main/java/de/tla2b/pprint/ExpressionPrinter.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb2e432b6faef92836da7cdbce289df144a04a57
--- /dev/null
+++ b/src/main/java/de/tla2b/pprint/ExpressionPrinter.java
@@ -0,0 +1,103 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.pprint;
+
+
+import java.util.Hashtable;
+
+import de.tla2b.global.BBuiltInOPs;
+import de.tla2b.types.TLAType;
+
+import tla2sany.semantic.ExprOrOpArgNode;
+import tla2sany.semantic.FormalParamNode;
+import tla2sany.semantic.ModuleNode;
+import tla2sany.semantic.OpApplNode;
+import tla2sany.semantic.OpDefNode;
+
+public class ExpressionPrinter extends AbstractExpressionPrinter {
+
+	private Hashtable<FormalParamNode, ExprOrOpArgNode> paramterSubstitution;
+	private ModuleNode moduleNode;
+	private StringBuilder BExpression;
+
+	public ExpressionPrinter(ModuleNode n) {
+		this.moduleNode = n;
+		paramterSubstitution = new Hashtable<FormalParamNode, ExprOrOpArgNode>();
+	}
+
+	public void start() {
+		OpDefNode[] defs = moduleNode.getOpDefs();
+		ExprReturn e = visitExprNode(defs[defs.length - 1].getBody(),
+				new DContext(), VALUEORPREDICATE);
+		BExpression = e.out;
+	}
+
+	public StringBuilder getBExpression() {
+		return BExpression;
+	}
+
+	@Override
+	protected ExprReturn visitUserdefinedOp(OpApplNode n, DContext d,
+			int expected) {
+		OpDefNode def = (OpDefNode) n.getOperator();
+		if (BBuiltInOPs.contains(def.getName())) {
+			return evalBBuiltIns(n, d, expected);
+		}
+
+		// substitute the parameters and inline the boby of the operator
+		FormalParamNode[] params = def.getParams();
+		if (params.length > 0) {
+			for (int i = 0; i < n.getArgs().length; i++) {
+				this.paramterSubstitution.put(params[i], n.getArgs()[i]);
+			}
+		}
+		return visitExprNode(def.getBody(), new DContext(), expected);
+	}
+
+	@Override
+	protected ExprReturn evalIfThenElse(OpApplNode n, DContext d, int expected) {
+		TLAType t = (TLAType) n.getToolObject(TYPE_ID);
+
+		if (t.getKind() == BOOL) {
+			d.indent.append(" ");
+			ExprReturn iif = visitExprOrOpArgNode(n.getArgs()[0], d, PREDICATE);
+			ExprReturn then = visitExprOrOpArgNode(n.getArgs()[1], d, PREDICATE);
+			ExprReturn eelse = visitExprOrOpArgNode(n.getArgs()[2], d,
+					PREDICATE);
+			String res = String.format(
+					"(%s \n%s => %s) \n\t & (not(%s) \n%s => %s)",
+					brackets(iif, P_implies, true), d.indent,
+					brackets(then, P_implies, false), iif.out, d.indent,
+					brackets(eelse, P_implies, false));
+			return makeBoolValue(new StringBuilder(res), expected, P_and);
+		} else {
+			ExprReturn iif = visitExprOrOpArgNode(n.getArgs()[0], d, PREDICATE);
+			ExprReturn then = visitExprOrOpArgNode(n.getArgs()[1], d, VALUE);
+			ExprReturn eelse = visitExprOrOpArgNode(n.getArgs()[2], d, VALUE);
+			String res = String
+					.format("(%%t_.( t_ = 0 & %s | %s )\\/%%t_.( t_ = 0 & not(%s) | %s ))(0)",
+							iif.out, then.out, iif.out, eelse.out);
+			return new ExprReturn(res);
+		}
+	}
+
+	@Override
+	protected ExprReturn visitFormalParamNode(OpApplNode n, DContext d,
+			int expected) {
+		StringBuilder out = new StringBuilder();
+		ExprOrOpArgNode e = paramterSubstitution.get((FormalParamNode) n
+				.getOperator());
+		if (e != null) {
+			return visitExprOrOpArgNode(e, d, expected);
+		}
+		out.append(getPrintName(n.getOperator()));
+		if (expected == PREDICATE) {
+			out.append(" = TRUE");
+			return new ExprReturn(out, P_equals);
+		}
+		return new ExprReturn(out);
+	}
+
+}
diff --git a/src/main/java/de/tla2b/translation/ExpressionTranslator.java b/src/main/java/de/tla2b/translation/ExpressionTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..61096f5f8ad306a47ca2db88c106769d4da8c8fd
--- /dev/null
+++ b/src/main/java/de/tla2b/translation/ExpressionTranslator.java
@@ -0,0 +1,351 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.translation;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+import de.tla2b.analysis.SymbolRenamer;
+import de.tla2b.analysis.TypeChecker;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TLA2BIOException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.pprint.ExpressionPrinter;
+
+import tla2sany.drivers.FrontEndException;
+import tla2sany.drivers.InitException;
+import tla2sany.drivers.SANY;
+import tla2sany.modanalyzer.ParseUnit;
+import tla2sany.modanalyzer.SpecObj;
+import tla2sany.parser.ParseException;
+import tla2sany.semantic.ModuleNode;
+import tla2sany.st.SyntaxTreeConstants;
+import tla2sany.st.TreeNode;
+import util.ToolIO;
+
+public class ExpressionTranslator implements SyntaxTreeConstants {
+	private String TLAExpression;
+	private ArrayList<String> variables;
+	private ArrayList<String> noVariables;
+	private StringBuilder BExpression;
+
+	public static String translateExpression(String tlaExpression)
+			throws TLA2BException {
+		ToolIO.reset();
+		ToolIO.setMode(ToolIO.TOOL);
+		ExpressionTranslator et = new ExpressionTranslator(tlaExpression);
+		try {
+			et.start();
+		} catch (RuntimeException e) {
+			throw new TLA2BIOException(e.getMessage());
+		}
+
+		return et.BExpression.toString();
+	}
+
+	public ExpressionTranslator(String TLAExpression) {
+		this.TLAExpression = TLAExpression;
+		this.variables = new ArrayList<String>();
+		this.noVariables = new ArrayList<String>();
+	}
+
+	public void start() throws TLA2BException {
+
+		String dir = System.getProperty("java.io.tmpdir");
+		ToolIO.setUserDir(dir);
+
+		createStandardModule(dir);
+
+		File tempFile = null;
+		String moduleName = null;
+		String module = null;
+		try {
+			tempFile = File.createTempFile("Testing", ".tla");
+
+			moduleName = tempFile.getName().substring(0,
+					tempFile.getName().indexOf("."));
+
+			module = "----MODULE " + moduleName + " ----\n"
+					+ "Expression == " + TLAExpression + "\n====";
+
+			FileWriter fw = new FileWriter(tempFile);
+			fw.write(module);
+			fw.close();
+		} catch (IOException e) {
+			throw new TLA2BIOException("Can not create file "
+					+ tempFile.getName() + " in directory '" + dir + "'");
+		}
+
+		SpecObj spec = parseModuleWithoutSemanticAnalyse(moduleName, module);
+		evalVariables(spec, moduleName);
+
+		StringBuilder sb = new StringBuilder();
+		sb.append("----MODULE " + moduleName + " ----\n");
+		sb.append("EXTENDS Naturals, Integers, Sequences, FiniteSets, TLA2B \n");
+		if (variables.size() > 0) {
+			sb.append("VARIABLES ");
+			for (int i = 0; i < variables.size(); i++) {
+				if (i != 0) {
+					sb.append(", ");
+				}
+				sb.append(variables.get(i));
+			}
+			sb.append("\n");
+		}
+		sb.append("Expression");
+		sb.append(" == ");
+		sb.append(TLAExpression);
+		sb.append("\n====================");
+		// System.out.println(sb);
+
+		try {
+			FileWriter fw = new FileWriter(tempFile);
+			fw.write(sb.toString());
+			fw.close();
+			tempFile.deleteOnExit();
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw new TLA2BIOException(e.getMessage());
+		}
+		ToolIO.reset();
+		BExpression = translate(moduleName, sb.toString());
+	}
+
+	private static StringBuilder translate(String moduleName, String expr)
+			throws TLA2BException {
+
+		ModuleNode moduleNode = parseModule(moduleName, expr);
+
+		TypeChecker tc = new TypeChecker(moduleNode);
+		try {
+			tc.start();
+		} catch (TLA2BException e) {
+			String[] m = ToolIO.getAllMessages();
+			String message = m[0] + "\n" + expr + "\n\n****TypeError****\n"
+					+ e.getLocalizedMessage();
+			// System.out.println(message);
+			throw new TypeErrorException(message);
+		}
+
+		SymbolRenamer symRenamer = new SymbolRenamer(moduleNode);
+		symRenamer.start();
+
+		ExpressionPrinter p = new ExpressionPrinter(moduleNode);
+		p.start();
+		return p.getBExpression();
+
+	}
+
+	/**
+	 * @param moduleFileName
+	 * @throws de.tla2b.exceptions.FrontEndException
+	 */
+	private SpecObj parseModuleWithoutSemanticAnalyse(String moduleFileName, String module)
+			throws de.tla2b.exceptions.FrontEndException {
+		SpecObj spec = new SpecObj(moduleFileName, null);
+
+		try {
+			SANY.frontEndInitialize(spec, ToolIO.out);
+			SANY.frontEndParse(spec, ToolIO.out);
+
+		} catch (InitException e1) {
+			System.out.println(e1);
+		} catch (ParseException e1) {
+			System.out.println(e1);
+		}
+
+		if (spec.parseErrors.isFailure()) {
+			String message = module + "\n\n";
+			message += Tla2BTranslator.allMessagesToString(ToolIO
+					.getAllMessages());
+			throw new de.tla2b.exceptions.FrontEndException(message, spec);
+		}
+		return spec;
+	}
+
+	public static ModuleNode parseModule(String moduleName, String module)
+			throws de.tla2b.exceptions.FrontEndException {
+		SpecObj spec = new SpecObj(moduleName, null);
+		try {
+			SANY.frontEndMain(spec, moduleName, ToolIO.out);
+		} catch (FrontEndException e) {
+			// Error in Frontend, should never happens
+			return null;
+		}
+
+		if (spec.parseErrors.isFailure()) {
+			String[] m = ToolIO.getAllMessages();
+			String message = module + "\n\n"
+					+ spec.parseErrors;
+			// System.out.println(spec.parseErrors);
+			message += Tla2BTranslator.allMessagesToString(ToolIO
+					.getAllMessages());
+			throw new de.tla2b.exceptions.FrontEndException(message, spec);
+		}
+
+		if (spec.semanticErrors.isFailure()) {
+			String[] m = ToolIO.getAllMessages();
+			String message = module + "\n\n" + spec.semanticErrors;
+			message += Tla2BTranslator.allMessagesToString(ToolIO
+					.getAllMessages());
+			throw new de.tla2b.exceptions.FrontEndException(message, spec);
+		}
+
+		// RootModule
+		ModuleNode n = spec.getExternalModuleTable().rootModule;
+		if (spec.getInitErrors().isFailure()) {
+			System.err.println(spec.getInitErrors());
+			throw new de.tla2b.exceptions.FrontEndException(
+					Tla2BTranslator
+							.allMessagesToString(ToolIO.getAllMessages()),
+					spec);
+		}
+
+		if (n == null) { // Parse Error
+			// System.out.println("Rootmodule null");
+			throw new de.tla2b.exceptions.FrontEndException(
+					Tla2BTranslator
+							.allMessagesToString(ToolIO.getAllMessages()),
+					spec);
+		}
+		return n;
+	}
+
+	/**
+	 * @param spec
+	 * @return
+	 */
+	private void evalVariables(SpecObj spec, String moduleName) {
+		ParseUnit p = (ParseUnit) spec.parseUnitContext.get(moduleName);
+		TreeNode n_module = p.getParseTree();
+		TreeNode n_body = n_module.heirs()[2];
+		TreeNode n_operatorDefintion = n_body.heirs()[0];
+		TreeNode expr = n_operatorDefintion.heirs()[2];
+		searchVarInSyntaxTree(expr);
+
+		for (int i = 0; i < noVariables.size(); i++) {
+			variables.remove(noVariables.get(i));
+		}
+
+	}
+
+	private final static Set<String> KEYWORDS = new HashSet<String>();
+	static {
+		KEYWORDS.add("BOOLEAN");
+		KEYWORDS.add("TRUE");
+		KEYWORDS.add("FALSE");
+		KEYWORDS.add("Nat");
+		KEYWORDS.add("Int");
+		KEYWORDS.add("Cardinality");
+		KEYWORDS.add("IsFiniteSet");
+		KEYWORDS.add("Append");
+		KEYWORDS.add("Head");
+		KEYWORDS.add("Tail");
+		KEYWORDS.add("Len");
+		KEYWORDS.add("Seq");
+		KEYWORDS.add("SubSeq");
+		KEYWORDS.add("SelectSeq");
+		KEYWORDS.add("MinOfSet");
+		KEYWORDS.add("MaxOfSet");
+		KEYWORDS.add("SetProduct");
+		KEYWORDS.add("SetSummation");
+		KEYWORDS.add("PermutedSequences");
+		KEYWORDS.add("@");
+
+	}
+
+	/**
+	 * 
+	 */
+	private void searchVarInSyntaxTree(TreeNode treeNode) {
+		// System.out.println(treeNode.getKind() + " " + treeNode.getImage());
+		switch (treeNode.getKind()) {
+		case N_GeneralId: {
+			String con = treeNode.heirs()[1].getImage();
+			if (!variables.contains(con) && !KEYWORDS.contains(con)) {
+				variables.add(con);
+			}
+			break;
+		}
+		case N_IdentLHS: { // left side of a definition
+			TreeNode[] children = treeNode.heirs();
+			noVariables.add(children[0].getImage());
+			break;
+		}
+		case N_IdentDecl: { // parameter of a LET definition
+							// e.g. x in LET foo(x) == e
+			noVariables.add(treeNode.heirs()[0].getImage());
+			break;
+		}
+		case N_FunctionDefinition: {
+			// the first child is the function name
+			noVariables.add(treeNode.heirs()[0].getImage());
+			break;
+		}
+		case N_UnboundQuant: {
+			TreeNode[] children = treeNode.heirs();
+			for (int i = 1; i < children.length - 2; i = i + 2) {
+				// System.out.println(children[i].getImage());
+			}
+			searchVarInSyntaxTree(treeNode.heirs()[children.length - 1]);
+			break;
+		}
+		case N_QuantBound: {
+			TreeNode[] children = treeNode.heirs();
+			for (int i = 0; i < children.length - 2; i = i + 2) {
+				String boundedVar = children[i].getImage();
+				if (!noVariables.contains(boundedVar)) {
+					noVariables.add(boundedVar);
+				}
+			}
+			searchVarInSyntaxTree(treeNode.heirs()[children.length - 1]);
+			break;
+		}
+		case N_SubsetOf: { // { x \in S : e }
+			TreeNode[] children = treeNode.heirs();
+			String boundedVar = children[1].getImage(); // x
+			if (!noVariables.contains(boundedVar)) {
+				noVariables.add(boundedVar);
+			}
+			searchVarInSyntaxTree(treeNode.heirs()[3]); // S
+			searchVarInSyntaxTree(treeNode.heirs()[5]); // e
+			break;
+		}
+
+		}
+
+		for (int i = 0; i < treeNode.heirs().length; i++) {
+			searchVarInSyntaxTree(treeNode.heirs()[i]);
+		}
+	}
+
+	private static File tla2b;
+	private void createStandardModule(String dir) throws TLA2BIOException {
+		tla2b = new File(dir, "TLA2B.tla");
+		try {
+			tla2b.createNewFile();
+			FileWriter fw = new FileWriter(tla2b);
+			fw.write(TLA2B);
+			fw.close();
+			tla2b.deleteOnExit();
+		} catch (IOException e) {
+			throw new TLA2BIOException(
+					"Can not create standard module TLA2B.tla in directory '"
+							+ dir + "'");
+		}
+
+	}
+
+	private static final String TLA2B = "--------- MODULE TLA2B ---------\n"
+			+ "LOCAL INSTANCE Naturals \n" + "LOCAL INSTANCE Sequences \n"
+			+ "MinOfSet(S) == CHOOSE p \\in S: \\A n \\in S: p \\leq n \n"
+			+ "MaxOfSet(S) == CHOOSE p \\in S: \\A n \\in S: p \\geq n \n"
+			+ "SetProduct(S)  == S \n" + "SetSummation(S) == S \n"
+			+ "PermutedSequences(S) == S\n" + "==============================";
+}
diff --git a/src/main/java/de/tla2b/translation/TLA2B.java b/src/main/java/de/tla2b/translation/TLA2B.java
new file mode 100644
index 0000000000000000000000000000000000000000..0875681a782c9a442f3a961cfd5aae1a2802eab3
--- /dev/null
+++ b/src/main/java/de/tla2b/translation/TLA2B.java
@@ -0,0 +1,276 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.translation;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Date;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.NotImplementedException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.global.TranslationGlobals;
+import util.FileUtil;
+import util.ToolIO;
+
+public class TLA2B implements TranslationGlobals {
+	private String mainFile;
+	private String path;
+	private String configFileName;
+	private String mainModuleName;
+
+	private static boolean error = false;
+
+	public static boolean hasError() {
+		return error;
+	}
+
+	public TLA2B() {
+		mainFile = null;
+		path = null;
+		configFileName = null;
+		mainModuleName = null;
+	}
+
+	public void handleParameter(String[] args) {
+		int i;
+		for (i = 0; (i < args.length) && (args[i].charAt(0) == '-'); i++) {
+			if (args[i].equals("-version")) {
+				System.out.println("TLA2B version " + VERSION);
+				System.exit(-1);
+			} else if (args[i].equals("-expr")) {
+				if (i + 1 == args.length) {
+					System.err.println("Error: expected a module file.");
+					System.exit(-1);
+				}
+				evalExpression(args[i + 1]);
+				return;
+			}
+
+			else if (args[i].equals("-config")) {
+				i++;
+				if (i < args.length) {
+					configFileName = args[i];
+				} else {
+					System.err
+							.println("Error: expect a file name for -config option.");
+				}
+
+			} else {
+				System.err.println("Illegal switch: " + args[i]);
+				System.exit(-1);
+			}
+		}
+
+		if (i == args.length) {
+			System.err.println("Error: expected a module file.");
+			System.exit(-1);
+		}
+		mainFile = args[i];
+	}
+
+	private void evalModuleFileName() throws IOException {
+		File file = new File(mainFile);
+		String canonicalPath;
+		if(file.exists()){
+			canonicalPath = file.getCanonicalPath();
+		}else {
+			throw new IOException("File '"+ mainFile + "' does not exit.");
+		}
+		
+
+		String moduleName = canonicalPath;
+		if (moduleName.toLowerCase().endsWith(".tla")) {
+			moduleName = moduleName.substring(0, moduleName.length() - 4);
+		}
+
+		moduleName = moduleName.replace("\\", File.separator);
+		moduleName = moduleName.replace("/", File.separator);
+
+		mainModuleName = moduleName
+				.substring(moduleName.lastIndexOf(FileUtil.separator) + 1);
+
+		path = moduleName.substring(0, moduleName.lastIndexOf(FileUtil.separator) + 1);
+
+		if (path.equals("")) {
+			ToolIO.setUserDir("." + File.separator);
+		} else {
+			ToolIO.setUserDir(path);
+		}
+
+	}
+
+	private void evalConfigFile() {
+		// Config file
+		File file;
+		if (configFileName == null) {
+
+			file = new File(path + mainModuleName + ".cfg");
+			// use config if it exists
+			if (file.exists()) {
+				configFileName = mainModuleName + ".cfg";
+			}
+		} else {
+			// user input
+			if (!configFileName.toLowerCase().endsWith(".cfg")) {
+				configFileName = configFileName + ".cfg";
+			}
+		}
+	}
+
+	public static void main(String[] args) {
+		// To indicate an error we use the exit code -1
+		TLA2B tla2b = new TLA2B();
+		tla2b.handleParameter(args);
+
+		
+		try {
+			tla2b.evalModuleFileName();
+		} catch (IOException e) {
+			System.err.println(e.getMessage());
+			System.exit(-1);
+		}
+		
+		tla2b.evalConfigFile();
+
+		ToolIO.setMode(ToolIO.TOOL);
+		Tla2BTranslator t = new Tla2BTranslator();
+		try {
+			t.start(tla2b.mainModuleName, tla2b.configFileName);
+		} catch (FrontEndException e) {
+			error = true;
+			System.err.println(e.getMessage());
+			System.exit(-1);
+		} catch (TLA2BException e) {
+			error = true;
+			System.err.println(e.getMessage());
+			System.exit(-1);
+		} catch (RuntimeException e) {
+			error = true;
+			System.err.println(e.getMessage());
+			System.exit(-1);
+		}
+		StringBuilder s = new StringBuilder();
+		try {
+			s = t.translate();
+		} catch (NotImplementedException e) {
+			error = true;
+			System.err.print("**** Translation Error ****\n");
+			System.err.print("Not implemented:\n");
+			System.err.println(e.getMessage());
+			System.exit(-1);
+		} catch (TLA2BException e) {
+			error = true;
+			System.err.print("**** Translation Error ****\n");
+			System.err.println(e.getMessage());
+			System.exit(-1);
+		}
+		s.insert(0, "/*@ generated by TLA2B " + VERSION + " " + new Date()
+				+ " */\n");
+		tla2b.createMachineFile(s);
+	}
+
+	private void createMachineFile(StringBuilder s) {
+		String machineFileName = path + mainModuleName + "_tla.mch";
+		File machineFile;
+		machineFile = new File(machineFileName);
+		if (machineFile.exists()) {
+			try {
+				BufferedReader in;
+
+				in = new BufferedReader(new FileReader(machineFile));
+
+				String firstLine = null;
+				firstLine = in.readLine();
+				in.close();
+				if (!firstLine.startsWith("/*@ generated by TLA2B ")) {
+					System.err.println("Error: File " + machineFileName
+							+ " already exists"
+							+ " and was not generated by TLA2B.\n"
+							+ "Delete or move this file.");
+					System.exit(-1);
+				}
+			} catch (IOException e) {
+				System.err.println(e.getMessage());
+				System.exit(-1);
+			}
+		}
+
+		try {
+			machineFile.createNewFile();
+		} catch (IOException e) {
+			System.err.println(String.format("Could not create File %s.",
+					machineFileName));
+			System.exit(-1);
+		}
+
+		Writer fw = null;
+		try {
+			String res = s.toString();
+			fw = new FileWriter(machineFile);
+			fw.write(res);
+			fw.close();
+			System.out.println("B-Machine " + mainModuleName
+					+ "_tla.mch created.");
+		} catch (IOException e) {
+			System.err.println("Error while creating file " + mainModuleName
+					+ "mch.");
+			System.exit(-1);
+		}
+
+	}
+
+	public static String translateFile(String mainFile) throws TLA2BException, IOException {
+		TLA2B tla2b = new TLA2B();
+		tla2b.mainFile = mainFile;
+		tla2b.evalModuleFileName();
+		Tla2BTranslator t = new Tla2BTranslator();
+		t.start(tla2b.mainModuleName, tla2b.configFileName);
+		StringBuilder s = t.translate();
+		return s.toString();
+	}
+
+	/**
+	 * @throws IOException
+	 * 
+	 */
+	private static void evalExpression(String file) {
+
+		ToolIO.setMode(ToolIO.TOOL);
+		String expr = null;
+		try {
+			expr = fileToString(file);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		ExpressionTranslator et = new ExpressionTranslator(expr);
+		try {
+			et.start();
+		} catch (TLA2BException e) {
+			System.err.println("------ExpressionError----------------");
+			System.err.println(e.getMessage());
+		}
+
+	}
+
+	public static String fileToString(String fileName) throws IOException {
+		StringBuilder res = new StringBuilder();
+		BufferedReader in = new BufferedReader(new FileReader(fileName));
+		String str;
+		boolean first = true;
+		while ((str = in.readLine()) != null) {
+			if (!first)
+				res.append("\n");
+			res.append(str);
+		}
+		in.close();
+		return res.toString();
+	}
+
+}
diff --git a/src/main/java/de/tla2b/translation/Tla2BTranslator.java b/src/main/java/de/tla2b/translation/Tla2BTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..bba0f4436b6c8717a234e1030129d26c29bff548
--- /dev/null
+++ b/src/main/java/de/tla2b/translation/Tla2BTranslator.java
@@ -0,0 +1,215 @@
+package de.tla2b.translation;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import de.tla2b.analysis.InstanceTransformation;
+import de.tla2b.analysis.SpecAnalyser;
+import de.tla2b.analysis.SymbolRenamer;
+import de.tla2b.analysis.SymbolSorter;
+import de.tla2b.analysis.TypeChecker;
+import de.tla2b.config.ConfigfileEvaluator;
+import de.tla2b.config.ModuleOverrider;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.global.TranslationGlobals;
+import de.tla2b.pprint.BAstCreator;
+import de.tla2b.pprint.BMachinePrinter;
+import tla2sany.drivers.FrontEndException;
+import tla2sany.drivers.SANY;
+import tla2sany.modanalyzer.SpecObj;
+import tla2sany.semantic.ModuleNode;
+import tlc2.tool.ModelConfig;
+import util.FileUtil;
+import util.ToolIO;
+
+public class Tla2BTranslator implements TranslationGlobals {
+	private ModuleNode moduleNode;
+	private ModelConfig modelConfig;
+	private TypeChecker typechecker;
+	private String moduleName;
+
+	public Tla2BTranslator() {
+		this.moduleName = "Testing";
+	}
+
+	public Tla2BTranslator(String moduleName) {
+		this.moduleName = moduleName;
+	}
+
+	public void start(String moduleFileName, String configFileName)
+			throws TLA2BException {
+		String moduleName = Tla2BTranslator.evalFileName(moduleFileName);
+		moduleNode = parseModule(moduleName);
+
+		modelConfig = null;
+		if (configFileName != null) {
+			modelConfig = new ModelConfig(configFileName, null);
+			modelConfig.parse();
+		}
+	}
+
+	public static StringBuilder translateString(String moduleName,
+			String moduleString, String configString) throws FrontEndException,
+			TLA2BException {
+		ToolIO.setMode(ToolIO.TOOL);
+		ToolIO.reset();
+		Tla2BTranslator translator = new Tla2BTranslator(moduleName);
+		translator.startTest(moduleString, configString);
+		return translator.translate();
+	}
+
+	public void startTest(String moduleString, String configString)
+			throws de.tla2b.exceptions.FrontEndException, TLA2BException {
+		File dir = new File("temp/");
+		dir.mkdirs();
+		
+		try {
+			File f = new File("temp/"+ moduleName+ ".tla");
+			f.createNewFile();
+			FileWriter fw = new FileWriter(f);
+			fw.write(moduleString);
+			fw.close();
+			f.deleteOnExit();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		
+		ToolIO.setUserDir("temp/");
+		moduleNode = parseModule(moduleName + ".tla");
+		
+		
+		modelConfig = null;
+		if (configString != null) {
+			File f = new File("temp/" + moduleName +".cfg");
+			try {
+				f.createNewFile();
+				FileWriter fw = new FileWriter(f);
+				fw.write(configString);
+				fw.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			modelConfig = new ModelConfig(moduleName +".cfg", null);
+			modelConfig.parse();
+			f.deleteOnExit();
+		}
+		dir.deleteOnExit();
+	}
+
+	
+	public StringBuilder translate() throws TLA2BException {
+		InstanceTransformation trans = new InstanceTransformation(moduleNode);
+		trans.start();
+
+		SymbolSorter symbolSorter = new SymbolSorter(moduleNode);
+		symbolSorter.sort();
+
+		SpecAnalyser specAnalyser;
+
+		ConfigfileEvaluator conEval = null;
+		if (modelConfig != null) {
+
+			conEval = new ConfigfileEvaluator(modelConfig, moduleNode);
+			conEval.start();
+
+			ModuleOverrider modOver = new ModuleOverrider(moduleNode, conEval);
+			modOver.start();
+			specAnalyser = new SpecAnalyser(moduleNode, conEval);
+		} else {
+			specAnalyser = new SpecAnalyser(moduleNode);
+		}
+
+		specAnalyser.start();
+		
+		typechecker = new TypeChecker(moduleNode, conEval, specAnalyser);
+		typechecker.start();
+
+		specAnalyser.evalIfThenElse();
+
+		SymbolRenamer symRenamer = new SymbolRenamer(moduleNode, specAnalyser);
+		symRenamer.start();
+		BMachinePrinter p = new BMachinePrinter(moduleNode, conEval,
+				specAnalyser);
+		//BAstCreator bAstCreator = new BAstCreator(moduleNode, conEval, specAnalyser);
+		
+		return p.start();
+	}
+	
+	public static ModuleNode parseModule(String moduleName)
+			throws de.tla2b.exceptions.FrontEndException {
+		SpecObj spec = new SpecObj(moduleName, null);
+		try {
+			SANY.frontEndMain(spec, moduleName, ToolIO.out);
+		} catch (FrontEndException e) {
+			// Error in Frontend, should never happens
+			return null;
+		}
+
+		if (spec.parseErrors.isFailure()) {
+			throw new de.tla2b.exceptions.FrontEndException(
+					allMessagesToString(ToolIO.getAllMessages())
+							+ spec.parseErrors, spec);
+		}
+
+		if (spec.semanticErrors.isFailure()) {
+			throw new de.tla2b.exceptions.FrontEndException(
+			// allMessagesToString(ToolIO.getAllMessages())
+					"" + spec.semanticErrors, spec);
+		}
+
+		// RootModule
+		ModuleNode n = spec.getExternalModuleTable().rootModule;
+		if (spec.getInitErrors().isFailure()) {
+			System.err.println(spec.getInitErrors());
+			return null;
+		}
+
+		if (n == null) { // Parse Error
+			// System.out.println("Rootmodule null");
+			throw new de.tla2b.exceptions.FrontEndException(
+					allMessagesToString(ToolIO.getAllMessages()), spec);
+		}
+		return n;
+	}
+
+	public static String allMessagesToString(String[] allMessages) {
+		StringBuilder sb = new StringBuilder();
+		for (int i = 0; i < allMessages.length - 1; i++) {
+			sb.append(allMessages[i] + "\n");
+		}
+		return sb.toString();
+	}
+
+	public static String evalFileName(String name) {
+		if (name.toLowerCase().endsWith(".tla")) {
+			name = name.substring(0, name.length() - 4);
+		}
+
+		if (name.toLowerCase().endsWith(".cfg")) {
+			name = name.substring(0, name.length() - 4);
+		}
+
+		String sourceModuleName = name.substring(name
+				.lastIndexOf(FileUtil.separator) + 1);
+
+		String path = name.substring(0,
+				name.lastIndexOf(FileUtil.separator) + 1);
+		if (!path.equals(""))
+			ToolIO.setUserDir(path);
+		return sourceModuleName;
+	}
+
+	public ModuleNode getModuleNode() {
+		return moduleNode;
+	}
+
+	public ModelConfig getModelConfig() {
+		return modelConfig;
+	}
+
+	public TypeChecker getTypecheChecker() {
+		return typechecker;
+	}
+
+}
diff --git a/src/main/java/de/tla2b/types/AbstractHasFollowers.java b/src/main/java/de/tla2b/types/AbstractHasFollowers.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc6bc447a4d78ad3d7817ec55b747ee1569e541f
--- /dev/null
+++ b/src/main/java/de/tla2b/types/AbstractHasFollowers.java
@@ -0,0 +1,92 @@
+package de.tla2b.types;
+
+import java.util.ArrayList;
+import tla2sany.semantic.SemanticNode;
+
+public abstract class AbstractHasFollowers extends TLAType {
+
+	public ArrayList<Object> followers;
+
+	public AbstractHasFollowers(int t) {
+		super(t);
+		followers = new ArrayList<Object>();
+	}
+
+	public ArrayList<Object> getFollowers() {
+		return followers;
+	}
+
+	public void addFollower(Object o) {
+		// only (partial) untyped types need follower
+		if (this.followers != null) {
+			for (int i = 0; i < followers.size(); i++) {
+				if (followers.get(i) == o)
+					return;
+			}
+			followers.add(o);
+		}
+
+	}
+
+	public void deleteFollower(Object o) {
+		followers.remove(o);
+	}
+
+	public void deleteFollowers() {
+		followers = null;
+	}
+
+	public void removeFollower(Object o) {
+		followers.remove(o);
+	}
+
+	public String followersToString() {
+		return followers.toString();
+	}
+
+	protected void setFollowersTo(TLAType newType) {
+		if (this.followers == null)
+			return;
+		for (int i = 0; i < this.followers.size(); i++) {
+
+			Object follower = this.followers.get(i);
+			if (follower instanceof SemanticNode) {
+				((SemanticNode) follower).setToolObject(5, newType);
+				if (newType instanceof AbstractHasFollowers) {
+					((AbstractHasFollowers) newType).addFollower(follower);
+				}
+			} else if (follower instanceof AbstractSymbol) {
+				((AbstractSymbol) follower).setType(newType);
+			} else if (follower instanceof SetType) {
+				((SetType) follower).setSubType(newType);
+			} else if (follower instanceof TupleType) {
+				((TupleType) follower).update(this, newType);
+			} else if (follower instanceof PairType) {
+				PairType pair = ((PairType) follower);
+				if (pair.getFirst() == this) {
+					pair.setFirst(newType);
+				}
+				if (pair.getSecond() == this) {
+					pair.setSecond(newType);
+				}
+
+			} else if (follower instanceof FunctionType) {
+				((FunctionType) follower).update(this, newType);
+			} else if (follower instanceof StructType) {
+				((StructType) follower).setNewType(this, newType);
+			} else if (follower instanceof StructOrFunction) {
+				((StructOrFunction) follower).setNewType(this, newType);
+			} else {
+				throw new RuntimeException("Unknown follower type: "
+						+ follower.getClass());
+			}
+		}
+	}
+
+	public boolean hasFollower() {
+		if (followers.size() == 0) {
+			return false;
+		} else
+			return true;
+	}
+}
diff --git a/src/main/java/de/tla2b/types/AbstractSymbol.java b/src/main/java/de/tla2b/types/AbstractSymbol.java
new file mode 100644
index 0000000000000000000000000000000000000000..498abc0e7570d9db4d3cf87f4de744ddcfd8c8c9
--- /dev/null
+++ b/src/main/java/de/tla2b/types/AbstractSymbol.java
@@ -0,0 +1,23 @@
+package de.tla2b.types;
+
+public abstract class AbstractSymbol {
+
+	private TLAType type;
+	
+	public AbstractSymbol(TLAType t){
+		setType(t);
+	}
+	
+	public TLAType getType() {
+		return type;
+	}
+
+
+	protected void setType(TLAType t) {
+		this.type = t;
+		if (type instanceof AbstractHasFollowers) {
+			AbstractHasFollowers p = (AbstractHasFollowers) t;
+			p.addFollower(this);
+		}
+	}
+}
diff --git a/src/main/java/de/tla2b/types/BoolType.java b/src/main/java/de/tla2b/types/BoolType.java
new file mode 100644
index 0000000000000000000000000000000000000000..013822a26580803600506494f3751cba2bf7b824
--- /dev/null
+++ b/src/main/java/de/tla2b/types/BoolType.java
@@ -0,0 +1,62 @@
+package de.tla2b.types;
+
+import de.be4.classicalb.core.parser.node.ABoolSetExpression;
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.tla2b.exceptions.UnificationException;
+
+public class BoolType extends TLAType {
+
+	private static BoolType instance = new BoolType();
+
+	private BoolType() {
+		super(BOOL);
+	}
+
+	public static BoolType getInstance() {
+		return instance;
+	}
+
+	@Override
+	public String toString() {
+		return "BOOL";
+	}
+
+	@Override
+	public boolean isUntyped() {
+		return false;
+	}
+
+	@Override
+	public boolean compare(TLAType o) {
+		if (o.getKind() == UNTYPED || o.getKind() == BOOL)
+			return true;
+		else
+			return false;
+	}
+	
+	@Override
+	public BoolType unify(TLAType o) throws UnificationException {
+		if (o.getKind() == BOOL) {
+			return this;
+		} else if (o instanceof Untyped) {
+			((Untyped) o).setFollowersTo(this);
+			return this;
+		} else
+			throw new UnificationException();
+	}
+
+	@Override
+	public BoolType cloneTLAType() {
+		return this;
+	}
+	
+	@Override
+	public boolean contains(TLAType o) {
+		return false;
+	}
+
+	@Override
+	public PExpression getBNode() {
+		return new ABoolSetExpression();
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/tla2b/types/EnumType.java b/src/main/java/de/tla2b/types/EnumType.java
new file mode 100644
index 0000000000000000000000000000000000000000..c36ed7c712899662edd51c0982be9b7b6a448d0d
--- /dev/null
+++ b/src/main/java/de/tla2b/types/EnumType.java
@@ -0,0 +1,86 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.types;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.tla2b.exceptions.UnificationException;
+
+
+
+public class EnumType extends AbstractHasFollowers {
+	public LinkedHashSet<String> modelvalues;
+	public int id;
+	private boolean noVal = false;
+
+	public EnumType(ArrayList<String> enums) {
+		super(MODELVALUE);
+		modelvalues = new LinkedHashSet<String>(enums);
+	}
+
+	public void setNoVal() {
+		noVal = true;
+	}
+
+	public boolean hasNoVal() {
+		return noVal;
+	}
+
+	public LinkedHashSet<String> getValues() {
+		return modelvalues;
+	}
+
+	@Override
+	public boolean isUntyped() {
+		return false;
+	}
+
+	@Override
+	public boolean compare(TLAType o) {
+		if (o.getKind() == UNTYPED || o.getKind() == MODELVALUE)
+			return true;
+		else
+			return false;
+	}
+
+	@Override
+	public EnumType unify(TLAType o) throws UnificationException {
+		if (o instanceof Untyped) {
+			((Untyped) o).setFollowersTo(this);
+			return this;
+		}
+		if (o instanceof EnumType) {
+			EnumType e = (EnumType) o;
+			e.setFollowersTo(this);
+			this.modelvalues.addAll(((EnumType) o).modelvalues);
+			return this;
+		}
+		throw new UnificationException();
+	}
+
+	@Override
+	public EnumType cloneTLAType() {
+		return this;
+	}
+	
+	@Override
+	public boolean contains(TLAType o) {
+		//TODO is this really false
+		return false;
+	}
+
+	@Override
+	public String toString() {
+		return "ENUM" + id;
+	}
+	
+	@Override
+	public PExpression getBNode() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/tla2b/types/FunctionType.java b/src/main/java/de/tla2b/types/FunctionType.java
new file mode 100644
index 0000000000000000000000000000000000000000..06a6d93eb3e821ae7ba705cf5c55cb455e962d7a
--- /dev/null
+++ b/src/main/java/de/tla2b/types/FunctionType.java
@@ -0,0 +1,122 @@
+package de.tla2b.types;
+
+import de.be4.classicalb.core.parser.node.APartialFunctionExpression;
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.tla2b.exceptions.UnificationException;
+
+public class FunctionType extends AbstractHasFollowers {
+	private TLAType domain;
+	private TLAType range;
+
+	public FunctionType(TLAType domain, TLAType range) {
+		super(FUNCTION);
+		this.setDomain(domain);
+		this.setRange(range);
+	}
+
+	public FunctionType() {
+		super(FUNCTION);
+		this.setDomain(new Untyped());
+		this.setRange(new Untyped());
+	}
+
+
+	public void update(TLAType oldType, TLAType newType) {
+		if (domain == oldType)
+			setDomain(newType);
+		if (range == oldType)
+			setRange(newType);
+	}
+
+	@Override
+	public boolean compare(TLAType o) {
+		if (this.contains(o))
+			return false;
+		if (o.getKind() == UNTYPED)
+			return true;
+		if (o instanceof FunctionType) {
+			FunctionType f = (FunctionType) o;
+			return domain.compare(f.domain) && range.compare(f.range);
+		}
+		if(o instanceof TupleType){
+			return o.compare(this);
+		}
+
+		return false;
+	}
+
+	@Override
+	public boolean contains(TLAType o) {
+		return domain.equals(o) || domain.contains(o) || range.equals(o)
+				|| range.contains(o);
+	}
+
+	@Override
+	public boolean isUntyped() {
+		return domain.isUntyped() || range.isUntyped();
+	}
+
+	@Override
+	public TLAType cloneTLAType() {
+		return new FunctionType(domain.cloneTLAType(), range.cloneTLAType());
+	}
+
+	@Override
+	public FunctionType unify(TLAType o) throws UnificationException {
+		if (!this.compare(o))
+			throw new UnificationException();
+		if (o instanceof Untyped) {
+			((Untyped) o).setFollowersTo(this);
+			return this;
+		}
+		if (o instanceof FunctionType) {
+			domain = domain.unify(((FunctionType) o).domain);
+			range = range.unify(((FunctionType) o).range);
+			return this;
+		}
+		if (o instanceof TupleType){
+			return (FunctionType) o.unify(this);
+		}
+		throw new RuntimeException();
+	}
+
+	public TLAType getDomain() {
+		return domain;
+	}
+
+	public TLAType getRange() {
+		return range;
+	}
+
+	public void setDomain(TLAType domain) {
+		this.domain = domain;
+		if (domain instanceof AbstractHasFollowers) {
+			((AbstractHasFollowers) domain).addFollower(this);
+		}
+	}
+
+	public void setRange(TLAType range) {
+		this.range = range;
+		if (range instanceof AbstractHasFollowers) {
+			((AbstractHasFollowers) range).addFollower(this);
+		}
+	}
+	
+	@Override
+	public String toString() {
+		String res = "POW(" + domain + "*";
+		if (range instanceof TupleType) {
+			res += "(" + range + ")";
+		} else{
+			res += range;
+		}
+		res += ")";
+		return res;
+	}
+
+	@Override
+	public PExpression getBNode() {
+		return new APartialFunctionExpression(domain.getBNode(), range.getBNode());
+	}
+
+}
diff --git a/src/main/java/de/tla2b/types/IType.java b/src/main/java/de/tla2b/types/IType.java
new file mode 100644
index 0000000000000000000000000000000000000000..26c84cae66ddac18cd81f1505192d33eb7fd5c7f
--- /dev/null
+++ b/src/main/java/de/tla2b/types/IType.java
@@ -0,0 +1,17 @@
+package de.tla2b.types;
+
+public interface IType {
+	public final int UNTYPED = 0;
+	public final int INTEGER = 1;
+	public final int BOOL = 2;
+	public final int STRING = 3;
+	public final int MODELVALUE = 4;
+	public final int POW = 5;
+	public final int PAIR = 6;
+	public final int STRUCT = 7;
+	public final int TUPLEORSEQ  =8;
+	public final int STRUCT_OR_FUNCTION = 9;
+	public final int FUNCTION = 10;
+	public final int TUPLE = 11;
+	
+}
diff --git a/src/main/java/de/tla2b/types/IntType.java b/src/main/java/de/tla2b/types/IntType.java
new file mode 100644
index 0000000000000000000000000000000000000000..b5fae0f68e30f0b1c6ea22b1e8cee102a5464f74
--- /dev/null
+++ b/src/main/java/de/tla2b/types/IntType.java
@@ -0,0 +1,62 @@
+package de.tla2b.types;
+
+import de.be4.classicalb.core.parser.node.AIntegerSetExpression;
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.tla2b.exceptions.UnificationException;
+
+public class IntType extends TLAType {
+
+	private static IntType instance = new IntType();
+
+	private IntType() {
+		super(INTEGER);
+	}
+
+	public static IntType getInstance() {
+		return instance;
+	}
+
+	@Override
+	public String toString() {
+		return "INTEGER";
+	}
+
+	@Override
+	public boolean isUntyped() {
+		return false;
+	}
+
+	@Override
+	public boolean compare(TLAType o) {
+		if (o.getKind() == UNTYPED || o.getKind() == INTEGER)
+			return true;
+		else
+			return false;
+	}
+
+	@Override
+	public IntType unify(TLAType o) throws UnificationException {
+		if (o.getKind() == INTEGER) {
+			return this;
+		} else if (o instanceof Untyped) {
+			((Untyped) o).setFollowersTo(this);
+			return this;
+		} else
+			throw new UnificationException();
+	}
+
+	@Override
+	public IntType cloneTLAType() {
+		return this;
+	}
+	
+	@Override
+	public boolean contains(TLAType o) {
+		return false;
+	}
+
+	@Override
+	public PExpression getBNode() {
+		return new AIntegerSetExpression();
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/tla2b/types/ModelValueType.java b/src/main/java/de/tla2b/types/ModelValueType.java
new file mode 100644
index 0000000000000000000000000000000000000000..e196cea10b2ae6ed2799b8ff49a88c466f19090f
--- /dev/null
+++ b/src/main/java/de/tla2b/types/ModelValueType.java
@@ -0,0 +1,63 @@
+package de.tla2b.types;
+
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.tla2b.exceptions.UnificationException;
+
+public class ModelValueType extends TLAType {
+
+	private static ModelValueType instance = new ModelValueType();
+
+	private ModelValueType() {
+		super(MODELVALUE);
+	}
+
+	public static ModelValueType getInstance() {
+		return instance;
+	}
+
+
+	@Override
+	public String toString() {
+		return "ENUM";
+	}
+
+	@Override
+	public boolean isUntyped() {
+		return false;
+	}
+	
+	@Override
+	public boolean compare(TLAType o) {
+		if (o.getKind() == UNTYPED || o.getKind() == MODELVALUE)
+			return true;
+		else
+			return false;
+	}
+	
+	@Override
+	public ModelValueType unify(TLAType o) throws UnificationException {
+		if (o.getKind() == MODELVALUE) {
+			return this;
+		} else if (o instanceof Untyped) {
+			((Untyped) o).setFollowersTo(this);
+			return this;
+		} else
+			throw new UnificationException();
+	}
+
+	@Override
+	public ModelValueType cloneTLAType() {
+		return this;
+	}
+	
+	@Override
+	public boolean contains(TLAType o) {
+		return false;
+	}
+
+	@Override
+	public PExpression getBNode() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/de/tla2b/types/PairType.java b/src/main/java/de/tla2b/types/PairType.java
new file mode 100644
index 0000000000000000000000000000000000000000..29d382d62439aa78fc3dc5fbcfe590113b115f24
--- /dev/null
+++ b/src/main/java/de/tla2b/types/PairType.java
@@ -0,0 +1,140 @@
+package de.tla2b.types;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.be4.classicalb.core.parser.node.ACoupleExpression;
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.tla2b.exceptions.UnificationException;
+
+public class PairType extends AbstractHasFollowers {
+
+	private TLAType first;
+	private TLAType second;
+
+	public PairType() {
+		super(PAIR);
+		setFirst(new Untyped());
+		setSecond(new Untyped());
+	}
+
+	public PairType(TLAType f, TLAType s) {
+		super(PAIR);
+		this.first = f;
+		if (first instanceof AbstractHasFollowers) {
+			AbstractHasFollowers firstHasFollowers = (AbstractHasFollowers) first;
+			firstHasFollowers.addFollower(this);
+		}
+		this.second = s;
+		if (second instanceof AbstractHasFollowers) {
+			AbstractHasFollowers secondHasFollowers = (AbstractHasFollowers) second;
+			secondHasFollowers.addFollower(this);
+		}
+	}
+
+	public TLAType getFirst() {
+		return first;
+	}
+
+	public void setFirst(TLAType f) {
+		this.first = f;
+
+		if (first instanceof AbstractHasFollowers) {
+			AbstractHasFollowers firstHasFollowers = (AbstractHasFollowers) first;
+			firstHasFollowers.addFollower(this);
+		}
+
+		// setting first can leads to a completely typed type
+		if (!this.isUntyped()) {
+			// this type is completely typed
+			this.deleteFollowers();
+		}
+	}
+
+	public TLAType getSecond() {
+		return second;
+	}
+
+	public void setSecond(TLAType s) {
+		this.second = s;
+
+		if (second instanceof AbstractHasFollowers) {
+			AbstractHasFollowers secondHasFollowers = (AbstractHasFollowers) second;
+			secondHasFollowers.addFollower(this);
+		}
+
+		// setting second can leads to a completely typed type
+		if (!this.isUntyped()) {
+			// this type is completely typed
+			this.deleteFollowers();
+		}
+	}
+
+	@Override
+	public boolean isUntyped() {
+		return first.isUntyped() || second.isUntyped();
+	}
+
+	@Override
+	public PairType unify(TLAType o) throws UnificationException {
+		if (!this.compare(o))
+			throw new UnificationException();
+		if (o instanceof AbstractHasFollowers)
+			((AbstractHasFollowers) o).setFollowersTo(this);
+
+		if (o instanceof PairType) {
+			PairType p = (PairType) o;
+			this.first = this.first.unify(p.first);
+			this.second = this.second.unify(p.second);
+			return this;
+		}
+		throw new RuntimeException();
+	}
+
+	@Override
+	public boolean compare(TLAType o) {
+		if (this.contains(o))
+			return false;
+		if (o.getKind() == UNTYPED)
+			return true;
+
+		if (o instanceof PairType) {
+			PairType p = (PairType) o;
+			// test first and second component compatibility
+			return this.first.compare(p.first) && this.second.compare(p.second);
+		} else
+			return false;
+	}
+
+	@Override
+	public PairType cloneTLAType() {
+		return new PairType(this.first.cloneTLAType(),
+				this.second.cloneTLAType());
+	}
+
+	@Override
+	public boolean contains(TLAType o) {
+		return first.equals(o) || first.contains(o) || second.equals(o)
+				|| second.contains(o);
+	}
+
+	@Override
+	public String toString() {
+		String res = first + "*";
+		if (second instanceof PairType) {
+			res += "(" + second + ")";
+		} else
+			res += second;
+		return res;
+
+	}
+
+	@Override
+	public PExpression getBNode() {
+		List<PExpression> list = new ArrayList<PExpression>();
+		list.add(first.getBNode());
+		list.add(second.getBNode());
+		return new ACoupleExpression(list);
+	}
+
+}
diff --git a/src/main/java/de/tla2b/types/SetType.java b/src/main/java/de/tla2b/types/SetType.java
new file mode 100644
index 0000000000000000000000000000000000000000..636aee87ea809ea6379957ceaa1bf7d08cef15c3
--- /dev/null
+++ b/src/main/java/de/tla2b/types/SetType.java
@@ -0,0 +1,110 @@
+package de.tla2b.types;
+
+import de.be4.classicalb.core.parser.node.APowSubsetExpression;
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.tla2b.exceptions.UnificationException;
+
+public class SetType extends AbstractHasFollowers {
+	private TLAType subType;
+
+	public SetType(TLAType t) {
+		super(POW);
+		setSubType(t);
+	}
+
+	public TLAType getSubType() {
+		return subType;
+	}
+
+	public void setSubType(TLAType t) {
+		// if (subType instanceof AbstractHasFollowers) {
+		// // delete old reference
+		// ((AbstractHasFollowers) subType).deleteFollower(this);
+		// }
+
+		if (t instanceof AbstractHasFollowers) {
+			// set new reference
+			((AbstractHasFollowers) t).addFollower(this);
+		}
+		this.subType = t;
+
+		// setting subType can lead to a completely typed type
+		if (!this.isUntyped()) {
+			// this type is completely typed
+			this.deleteFollowers();
+		}
+	}
+
+	public SetType unify(TLAType o) throws UnificationException {
+
+		if (!this.compare(o)|| this.contains(o)) {
+			throw new UnificationException();
+		}
+		// if o has followers than switch pointer to this
+		if (o instanceof AbstractHasFollowers) {
+			((AbstractHasFollowers) o).setFollowersTo(this);
+		}
+		
+		if (o instanceof StructOrFunction){
+			return (SetType)o.unify(this);
+		}
+		if (o instanceof SetType) {
+			SetType p = (SetType) o;
+			this.subType = this.subType.unify(p.subType);
+
+//			if (this.subType instanceof AbstractHasFollowers) {
+//				((AbstractHasFollowers) this.subType).removeFollower(p);
+//			}
+		}
+		return this;
+	}
+
+	@Override
+	public boolean compare(TLAType o) {
+		if(this.contains(o))
+			return false;
+		
+		if (o.getKind() == UNTYPED)
+			return true;
+		
+		if (o instanceof StructOrFunction){
+			return o.compare(this);
+		}
+
+		if (o instanceof SetType) {
+			SetType p = (SetType) o;
+			// test sub types compatibility
+			return this.subType.compare(p.subType);
+		} else
+			return false;
+	}
+
+	@Override
+	public String toString() {
+		String res = "POW(" + this.getSubType() + ")";
+
+		return res;
+	}
+
+	@Override
+	public boolean isUntyped() {
+		return subType.isUntyped();
+	}
+
+	@Override
+	public SetType cloneTLAType() {
+		return new SetType(this.subType.cloneTLAType());
+	}
+
+
+	@Override
+	public boolean contains(TLAType o) {
+		return this.getSubType().equals(o) || this.getSubType().contains(o);
+	}
+
+	@Override
+	public PExpression getBNode() {
+		return new APowSubsetExpression(this.getSubType().getBNode());
+	}
+
+}
diff --git a/src/main/java/de/tla2b/types/StringType.java b/src/main/java/de/tla2b/types/StringType.java
new file mode 100644
index 0000000000000000000000000000000000000000..e66f900a83c7412baa70b3d6f4ac17ccdfb28d49
--- /dev/null
+++ b/src/main/java/de/tla2b/types/StringType.java
@@ -0,0 +1,68 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.types;
+
+import de.be4.classicalb.core.parser.node.AStringSetExpression;
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.tla2b.exceptions.UnificationException;
+
+public class StringType extends TLAType {
+
+	private static StringType instance = new StringType();
+
+	private StringType() {
+		super(STRING);
+	}
+	
+	public static StringType getInstance(){
+		return instance;
+	}
+
+	@Override
+	public String toString() {
+		return "STRING";
+	}
+
+	@Override
+	public boolean compare(TLAType o) {
+		if (o.getKind() == UNTYPED || o.getKind() == STRING)
+			return true;
+		else
+			return false;
+	}
+
+	@Override
+	public boolean isUntyped() {
+		return false;
+	}
+
+	@Override
+	public StringType unify(TLAType o) throws UnificationException {
+		if (o.getKind() == STRING) {
+			return this;
+		} else if (o instanceof Untyped) {
+			((Untyped) o).setFollowersTo(this);
+			((Untyped) o).deleteFollowers();
+			return this;
+		} else
+			throw new UnificationException();
+	}
+
+	@Override
+	public StringType cloneTLAType() {
+		return this;
+	}
+	
+	@Override
+	public boolean contains(TLAType o) {
+		return false;
+	}
+
+	@Override
+	public PExpression getBNode() {
+		return new AStringSetExpression();
+	}
+	
+}
diff --git a/src/main/java/de/tla2b/types/StructOrFunction.java b/src/main/java/de/tla2b/types/StructOrFunction.java
new file mode 100644
index 0000000000000000000000000000000000000000..f62233497737e0307cdf1f8943ddc0b6720ac329
--- /dev/null
+++ b/src/main/java/de/tla2b/types/StructOrFunction.java
@@ -0,0 +1,232 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.types;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.tla2b.exceptions.UnificationException;
+
+
+
+public class StructOrFunction extends AbstractHasFollowers {
+	private LinkedHashMap<String, TLAType> types;
+
+	public StructOrFunction(String name, TLAType type) {
+		super(STRUCT_OR_FUNCTION);
+		types = new LinkedHashMap<String, TLAType>();
+		types.put(name, type);
+	}
+
+	public StructOrFunction() {
+		super(STRUCT_OR_FUNCTION);
+		types = new LinkedHashMap<String, TLAType>();
+	}
+
+	public void setNewType(TLAType old, TLAType New) {
+		Set<Entry<String, TLAType>> set = types.entrySet();
+		Iterator<Entry<String, TLAType>> iterator = set.iterator();
+
+		while (iterator.hasNext()) {
+			Entry<String, TLAType> entry = iterator.next();
+			if (entry.getValue() == old) {
+				String key = entry.getKey();
+				if (New instanceof AbstractHasFollowers) {
+					// set new reference
+					((AbstractHasFollowers) New).addFollower(this);
+				}
+				types.put(key, New);
+			}
+		}
+		testRecord();
+	}
+
+	@Override
+	public String toString() {
+		String res = "StructOrFunction(";
+		for (Iterator<String> keys = types.keySet().iterator(); keys.hasNext();) {
+			String key = keys.next();
+			res += "\""+key + "\" : " + types.get(key);
+			if (keys.hasNext())
+				res += ", ";
+		}
+		res += ")";
+		return res;
+	}
+
+	@Override
+	public boolean compare(TLAType o) {
+		if (this.contains(o) || o.contains(this))
+			return false;
+		if (o.getKind() == UNTYPED)
+			return true;
+		if (o instanceof StructType) {
+			StructType s = (StructType) o;
+			Iterator<String> thisKeys = types.keySet().iterator();
+			while (thisKeys.hasNext()) {
+				String fieldName = (String) thisKeys.next();
+				if (s.getFields().contains(fieldName)) {
+					if (!this.types.get(fieldName)
+							.compare(s.getType(fieldName))) {
+						return false;
+					}
+				}
+			}
+			return true;
+		}
+		if (o instanceof SetType) {
+			SetType p = (SetType) o;
+			TLAType sub = p.getSubType();
+			if (sub.getKind() == UNTYPED)
+				return true;
+
+			if (sub instanceof PairType) {
+				PairType pair = (PairType) sub;
+				if (pair.getFirst().compare(StringType.getInstance())) {
+					for (String key : types.keySet()) {
+						if (!pair.getSecond().compare(types.get(key)))
+							return false;
+					}
+					return true;
+				} else
+					return false;
+			} else
+				return false;
+		}
+
+		if (o instanceof StructOrFunction) {
+			StructOrFunction s = (StructOrFunction) o;
+
+			Iterator<String> thisKeys = types.keySet().iterator();
+			while (thisKeys.hasNext()) {
+				String fieldName = (String) thisKeys.next();
+				if (s.types.containsKey(fieldName)) {
+					if (!this.types.get(fieldName).compare(
+							s.types.get(fieldName))) {
+						return false;
+					}
+				}
+			}
+			return true;
+
+		}
+
+		return false;
+	}
+
+	@Override
+	public boolean contains(TLAType o) {
+		Iterator<String> thisKeys = types.keySet().iterator();
+		while (thisKeys.hasNext()) {
+			String fieldName = (String) thisKeys.next();
+			TLAType type = this.types.get(fieldName);
+			if (type.equals(o) || type.contains(o))
+				return true;
+		}
+		return false;
+	}
+
+	@Override
+	public boolean isUntyped() {
+		return true;
+		// Iterator<BType> itr = types.values().iterator();
+		// while (itr.hasNext()) {
+		// if (itr.next().isUntyped())
+		// return true;
+		// }
+		// return false;
+	}
+
+	@Override
+	public TLAType cloneTLAType() {
+		StructOrFunction res = new StructOrFunction();
+		for (String field : types.keySet()) {
+			res.types.put(field, this.types.get(field));
+		}
+		return res;
+	}
+
+	@Override
+	public TLAType unify(TLAType o) throws UnificationException {
+		if (!this.compare(o))
+			throw new UnificationException();
+
+		if (o instanceof Untyped) {
+			((Untyped) o).setFollowersTo(this);
+			return this;
+		}
+
+		if (o instanceof SetType) {
+			Iterator<TLAType> itr = types.values().iterator();
+			TLAType temp = itr.next();
+			while (itr.hasNext()) {
+				temp = temp.unify(itr.next());
+			}
+			SetType found = new SetType(new PairType(
+					StringType.getInstance(), temp));
+			return found.unify(o);
+		}
+		if (o instanceof StructType) {
+			StructType res = new StructType();
+
+			for (String field : types.keySet()) {
+				res.add(field, this.types.get(field));
+			}
+			return o.unify(res);
+		}
+		if (o instanceof StructOrFunction) {
+			StructOrFunction other = (StructOrFunction) o;
+			for (String field : other.types.keySet()) {
+				TLAType type = other.types.get(field);
+				if (this.types.containsKey(field)) {
+					TLAType res = this.types.get(field).unify(type);
+					this.types.put(field, res);
+				} else {
+					if (type instanceof AbstractHasFollowers) {
+						((AbstractHasFollowers) type).addFollower(this);
+					}
+					this.types.put(field, type);
+				}
+			}
+			TLAType res = testRecord();
+			return res;
+		}
+		return this;
+	}
+
+	private TLAType testRecord() {
+		Iterator<TLAType> itr = types.values().iterator();
+		TLAType temp = itr.next().cloneTLAType();
+		while (itr.hasNext()) {
+			TLAType next = itr.next().cloneTLAType();
+			try {
+				temp.unify(next);
+			} catch (UnificationException e) {
+				StructType res = new StructType();
+				for (String field : this.types.keySet()) {
+					res.add(field, this.types.get(field));
+				}
+				this.setFollowersTo(res);
+				return res;
+			}
+		}
+		return this;
+	}
+
+	public SetType getFunction() {
+		Iterator<TLAType> itr = types.values().iterator();
+		return new SetType(new PairType(StringType.getInstance(),
+				itr.next()));
+	}
+
+	@Override
+	public PExpression getBNode() {
+		return null;
+	}
+
+}
diff --git a/src/main/java/de/tla2b/types/StructType.java b/src/main/java/de/tla2b/types/StructType.java
new file mode 100644
index 0000000000000000000000000000000000000000..34e52e01bfe27a9e01a97b8ad23aaf16d5f1841d
--- /dev/null
+++ b/src/main/java/de/tla2b/types/StructType.java
@@ -0,0 +1,192 @@
+package de.tla2b.types;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import de.be4.classicalb.core.parser.node.ARecEntry;
+import de.be4.classicalb.core.parser.node.AStructExpression;
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.be4.classicalb.core.parser.node.PRecEntry;
+import de.tla2b.exceptions.UnificationException;
+import de.tla2b.pprint.BAstCreator;
+
+
+
+public class StructType extends AbstractHasFollowers {
+	private LinkedHashMap<String, TLAType> types;
+
+	public StructType() {
+		super(STRUCT);
+		types = new LinkedHashMap<String, TLAType>();
+	}
+
+	public TLAType getType(String fieldName) {
+		return types.get(fieldName);
+	}
+
+	public void add(String name, TLAType type) {
+		if (type instanceof AbstractHasFollowers) {
+			// set new reference
+			((AbstractHasFollowers) type).addFollower(this);
+		}
+		types.put(name, type);
+	}
+
+	public void setNewType(TLAType old, TLAType New) {
+		Set<Entry<String, TLAType>> set = types.entrySet();
+		Iterator<Entry<String, TLAType>> iterator = set.iterator();
+
+		while (iterator.hasNext()) {
+			Entry<String, TLAType> entry = iterator.next();
+			if (entry.getValue() == old) {
+				String key = entry.getKey();
+				if (New instanceof AbstractHasFollowers) {
+					// set new reference
+					((AbstractHasFollowers) New).addFollower(this);
+				}
+				types.put(key, New);
+			}
+		}
+	}
+
+	@Override
+	public boolean isUntyped() {
+		Iterator<TLAType> ts = types.values().iterator();
+		while (ts.hasNext()) {
+			TLAType bType = (TLAType) ts.next();
+			if (bType.isUntyped())
+				return true;
+		}
+		return false;
+	}
+
+	public boolean compare(TLAType o) {
+		if(this.contains(o)|| o.contains(this))
+			return false;
+		if (o.getKind() == UNTYPED)
+			return true;
+		
+		if (o instanceof StructOrFunction){
+			return o.compare(this);
+		}
+		if (o instanceof StructType) {
+			StructType s = (StructType) o;
+
+			Iterator<String> thisKeys = types.keySet().iterator();
+			while (thisKeys.hasNext()) {
+				String fieldName = (String) thisKeys.next();
+				if (s.types.containsKey(fieldName)) {
+					if (!this.types.get(fieldName).compare(
+							s.types.get(fieldName))) {
+						return false;
+					}
+				}
+			}
+			return true;
+		}
+		return false;
+	}
+
+	public StructType unify(TLAType o) throws UnificationException {
+		if (!this.compare(o)) {
+			throw new UnificationException();
+		}
+		if (o instanceof AbstractHasFollowers)
+			((AbstractHasFollowers) o).setFollowersTo(this);
+
+		if (o instanceof StructOrFunction){
+			return (StructType) o.unify(this);
+		}
+		
+		if (o instanceof StructType) {
+			StructType s = (StructType) o;
+			Iterator<String> keys = s.types.keySet().iterator();
+			while (keys.hasNext()) {
+				String fieldName = (String) keys.next();
+				TLAType sType = s.types.get(fieldName);
+				if (this.types.containsKey(fieldName)) {
+					TLAType res = this.types.get(fieldName).unify(sType);
+					this.types.put(fieldName, res);
+				} else {
+					if (sType instanceof AbstractHasFollowers) {
+						// set new reference
+						((AbstractHasFollowers) sType).addFollower(this);
+					}
+					this.types.put(fieldName, sType);
+				}
+			}
+			return this;
+		}
+		return this;
+	}
+
+	@Override
+	public StructType cloneTLAType() {
+		StructType clone = new StructType();
+
+		Set<Entry<String, TLAType>> set = this.types.entrySet();
+		Iterator<Entry<String, TLAType>> iterator = set.iterator();
+
+		while (iterator.hasNext()) {
+			Entry<String, TLAType> entry = iterator.next();
+			String field = entry.getKey();
+			TLAType type = entry.getValue().cloneTLAType();
+			clone.add(field, type);
+		}
+
+		return clone;
+	}
+
+	public ArrayList<String> getFields() {
+		ArrayList<String> fields = new ArrayList<String>();
+		Iterator<String> keys = this.types.keySet().iterator();
+		while (keys.hasNext()) {
+			String fieldName = (String) keys.next();
+			fields.add(fieldName);
+		}
+		return fields;
+	}
+
+	@Override
+	public boolean contains(TLAType o) {
+		Iterator<TLAType> ts = types.values().iterator();
+		while (ts.hasNext()) {
+			TLAType bType = (TLAType) ts.next();
+			if (bType.equals(o) || bType.contains(o))
+				return true;
+		}
+		return false;
+	}
+
+	@Override
+	public String toString() {
+		String res = "struct(";
+		Iterator<String> keys = types.keySet().iterator();
+		if(!keys.hasNext())
+			res += "...";
+		while (keys.hasNext()) {
+			String fieldName = (String) keys.next();
+			res += fieldName + ":" + types.get(fieldName);
+			if (keys.hasNext())
+				res += ",";
+		}
+		res += ")";
+		return res;
+	}
+	
+	@Override
+	public PExpression getBNode() {
+		List<PRecEntry> recList = new ArrayList<PRecEntry>();
+		for (Entry<String, TLAType> entry : types.entrySet()) {
+			ARecEntry rec = new ARecEntry();
+			rec.setIdentifier(BAstCreator.createIdentifierNode(entry.getKey()));
+			rec.setValue(entry.getValue().getBNode());
+			recList.add(rec);
+		}
+		return new AStructExpression(recList);
+	}
+}
diff --git a/src/main/java/de/tla2b/types/TLAType.java b/src/main/java/de/tla2b/types/TLAType.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6da56a6623e127a23d08c0946dc5caebca2ac06
--- /dev/null
+++ b/src/main/java/de/tla2b/types/TLAType.java
@@ -0,0 +1,44 @@
+package de.tla2b.types;
+
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.tla2b.exceptions.UnificationException;
+
+
+public abstract class TLAType implements IType {
+	private int kind;
+
+	public TLAType(int t) {
+		this.kind = t;
+	}
+
+	public final int getKind() {
+		return kind;
+	}
+
+	public abstract String toString();
+	
+	public abstract PExpression getBNode();
+
+	public abstract boolean compare(TLAType o);
+	
+	public abstract boolean contains(TLAType o);
+	
+	public abstract boolean isUntyped();
+	
+	public abstract TLAType cloneTLAType();
+
+	public abstract TLAType unify(TLAType o) throws UnificationException;
+	
+	public TLAType unityAll(TLAType[] types) throws UnificationException{
+		TLAType current = this;
+		for (int i = 0; i < types.length; i++) {
+			current = current.unify(types[i]);
+		}
+		return current;
+	}
+
+	public final String printObjectToString() {
+		return super.toString();
+	}
+
+}
diff --git a/src/main/java/de/tla2b/types/TupleType.java b/src/main/java/de/tla2b/types/TupleType.java
new file mode 100644
index 0000000000000000000000000000000000000000..4adcfefc87992f9a345967e97d13fa3bbe3a4980
--- /dev/null
+++ b/src/main/java/de/tla2b/types/TupleType.java
@@ -0,0 +1,210 @@
+package de.tla2b.types;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.be4.classicalb.core.parser.node.ACoupleExpression;
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.tla2b.exceptions.UnificationException;
+
+public class TupleType extends AbstractHasFollowers {
+	private ArrayList<TLAType> types;
+
+	public TupleType(ArrayList<TLAType> typeList) {
+		super(TUPLE);
+		setTypes(typeList);
+	}
+
+	public TupleType(int size) {
+		super(TUPLE);
+		ArrayList<TLAType> list = new ArrayList<TLAType>();
+		for (int i = 0; i < size; i++) {
+			list.add(new Untyped());
+		}
+		setTypes(list);
+	}
+
+	public ArrayList<TLAType> getTypes() {
+		return new ArrayList<TLAType>(types);
+	}
+
+	public void setTypes(ArrayList<TLAType> types) {
+		this.types = types;
+		types = new ArrayList<TLAType>(types);
+		for (TLAType tlaType : types) {
+			if (tlaType instanceof AbstractHasFollowers) {
+				((AbstractHasFollowers) tlaType).addFollower(this);
+			}
+		}
+	}
+
+
+	public void update(TLAType oldType, TLAType newType) {
+		for (int i = 0; i < types.size(); i++) {
+			TLAType t = types.get(i);
+			if (oldType == t) {
+				types.set(i, newType);
+			}
+		}
+		if (oldType instanceof AbstractHasFollowers)
+			((AbstractHasFollowers) oldType).addFollower(this);
+	}
+
+	@Override
+	public boolean compare(TLAType o) {
+		if (this.contains(o))
+			return false;
+		if (o.getKind() == UNTYPED)
+			return true;
+		if (o instanceof TupleType) {
+			TupleType t = (TupleType) o;
+			if (this.types.size() != t.types.size()) {
+				for (int i = 0; i < t.types.size(); i++) {
+					if (!compareToAll(t.types.get(i))) {
+						return false;
+					}
+				}
+				// both are sequences with different lengths
+				return true;
+			}
+			for (int i = 0; i < types.size(); i++) {
+				if (!types.get(i).compare(t.types.get(i)))
+					return false;
+			}
+			return true;
+		}
+		if (o instanceof FunctionType) {
+			//TODO
+			FunctionType func = (FunctionType) o;
+			if (!(func.getDomain() instanceof IntType)) {
+				return false;
+			}
+			TLAType range = func.getRange();
+			for (int i = 0; i < types.size(); i++) {
+				if (types.get(i).compare(range)) {
+					continue;
+				} else {
+					return false;
+				}
+			}
+			return true;
+		}
+		return false;
+	}
+
+	private boolean compareToAll(TLAType other) {
+		for (int i = 0; i < types.size(); i++) {
+			for (int j = i + 1; j < types.size(); j++) {
+				if (!types.get(i).compare(types.get(j)))
+					return false;
+			}
+			if (!types.get(i).compare(other))
+				return false;
+		}
+		return true;
+	}
+
+	@Override
+	public boolean contains(TLAType o) {
+		for (TLAType tlaType : types) {
+			if (tlaType.equals(o) || tlaType.contains(o))
+				return true;
+		}
+		return false;
+	}
+
+	@Override
+	public boolean isUntyped() {
+		for (TLAType tlaType : types) {
+			if (tlaType.isUntyped())
+				return true;
+		}
+		return false;
+	}
+
+	@Override
+	public TLAType cloneTLAType() {
+		ArrayList<TLAType> list = new ArrayList<TLAType>();
+		for (TLAType tlaType : types) {
+			list.add(tlaType.cloneTLAType());
+		}
+		return new TupleType(list);
+	}
+
+	@Override
+	public TLAType unify(TLAType o) throws UnificationException {
+		if (!this.compare(o)) {
+			throw new UnificationException();
+		}
+		if (o instanceof Untyped) {
+			((Untyped) o).setFollowersTo(this);
+			return this;
+		}
+		if (o instanceof TupleType) {
+			TupleType tuple = (TupleType) o;
+			if (this.types.size() != tuple.types.size()) {
+				TLAType t = types.get(0);
+				for (int i = 1; i < types.size(); i++) {
+					t = t.unify(types.get(i));
+				}
+				for (int i = 0; i < tuple.types.size(); i++) {
+					t = t.unify(tuple.types.get(i));
+				}
+				return new FunctionType(IntType.getInstance(), t);
+			} else {
+				for (int i = 0; i < types.size(); i++) {
+					TLAType res = types.get(i).unify(tuple.types.get(i));
+					types.set(i, res);
+					if (res instanceof AbstractHasFollowers)
+						((AbstractHasFollowers) res).addFollower(this);
+				}
+				return this;
+			}
+		}
+		if (o instanceof FunctionType) {
+			//TODO
+			if(compareToAll(new Untyped())){
+				//Function 
+				TLAType t = types.get(0);
+				for (int i = 1; i < types.size(); i++) {
+					t = t.unify(types.get(i));
+				}
+				FunctionType func = new FunctionType(IntType.getInstance(), t);
+				this.setFollowersTo(func);
+				return func.unify(o);
+			}else{
+				TLAType res = types.get(1).unify(((FunctionType) o).getRange());
+				types.set(1, res);
+				return this;
+			}
+			
+		}
+		throw new RuntimeException();
+	}
+	
+	@Override
+	public String toString() {
+		String res = "";
+		for (int i = 0; i < types.size(); i++) {
+			if (types.get(i) instanceof TupleType && i != 0) {
+				res += "(" + types.get(i) + ")";
+			} else
+				res += types.get(i);
+
+			if (i < types.size() - 1) {
+				res += "*";
+			}
+		}
+		return res;
+	}
+
+	@Override
+	public PExpression getBNode() {
+		List<PExpression> list = new ArrayList<PExpression>();
+		for (TLAType t : types) {
+			list.add(t.getBNode());
+		}
+		return new ACoupleExpression(list);
+	}
+
+}
diff --git a/src/main/java/de/tla2b/types/Untyped.java b/src/main/java/de/tla2b/types/Untyped.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b7b36de7952f08c4f026394f725060dedb0b1b6
--- /dev/null
+++ b/src/main/java/de/tla2b/types/Untyped.java
@@ -0,0 +1,54 @@
+package de.tla2b.types;
+
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.tla2b.exceptions.UnificationException;
+
+public class Untyped extends AbstractHasFollowers {
+
+	public Untyped() {
+		super(UNTYPED);
+	}
+
+	public TLAType unify(TLAType o) throws UnificationException {
+		if (!this.compare(o)) {
+			throw new UnificationException();
+		}
+		// u2 contains more or equal type information than untyped (this)
+		this.setFollowersTo(o);
+		//this.deleteFollowers();
+		return o;
+	}
+	
+	@Override
+	public boolean compare(TLAType o){
+		if(o.contains(this)){
+			return false;
+		}
+		return true;
+	}
+	
+	@Override
+	public boolean contains(TLAType o){
+		return false;
+	}
+
+	@Override
+	public String toString() {
+		return "UNTYPED_"+hashCode();
+	}
+
+	@Override
+	public boolean isUntyped() {
+		return true;
+	}
+
+	@Override
+	public Untyped cloneTLAType() {
+		return new Untyped();
+	}
+
+	@Override
+	public PExpression getBNode() {
+		return null;
+	}
+}
diff --git a/src/main/java/de/tla2bAst/TLAParser.java b/src/main/java/de/tla2bAst/TLAParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..32b92ca2db8ee3b76900f44c480223ddd647d818
--- /dev/null
+++ b/src/main/java/de/tla2bAst/TLAParser.java
@@ -0,0 +1,44 @@
+package de.tla2bAst;
+
+import tla2sany.drivers.FrontEndException;
+import tla2sany.drivers.SANY;
+import tla2sany.modanalyzer.SpecObj;
+import tla2sany.semantic.ModuleNode;
+import util.FilenameToStream;
+import util.ToolIO;
+
+public class TLAParser {
+
+	private FilenameToStream filenameToStream;
+	
+	public TLAParser(FilenameToStream filenameToStream) {
+		this.filenameToStream = filenameToStream;
+	}
+	
+	public  ModuleNode parseModule(String moduleName) {
+		SpecObj spec = new SpecObj(moduleName, filenameToStream);
+		try {
+			SANY.frontEndMain(spec, moduleName, ToolIO.out);
+		} catch (FrontEndException e) {
+			// Error in Frontend, should never happens
+			return null;
+		}
+
+		if (spec.parseErrors.isFailure()) {
+		}
+
+		if (spec.semanticErrors.isFailure()) {
+		}
+
+		// RootModule
+		ModuleNode n = spec.getExternalModuleTable().rootModule;
+		if (spec.getInitErrors().isFailure()) {
+			System.err.println(spec.getInitErrors());
+			return null;
+		}
+
+		if (n == null) { // Parse Error
+		}
+		return n;
+	}
+}
diff --git a/src/main/java/de/tla2bAst/Translator.java b/src/main/java/de/tla2bAst/Translator.java
new file mode 100644
index 0000000000000000000000000000000000000000..b5744d7cd451f9c89a064f5f154341725fe8db5f
--- /dev/null
+++ b/src/main/java/de/tla2bAst/Translator.java
@@ -0,0 +1,153 @@
+package de.tla2bAst;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import de.be4.classicalb.core.parser.node.Node;
+import de.tla2b.analysis.InstanceTransformation;
+import de.tla2b.analysis.SpecAnalyser;
+import de.tla2b.analysis.SymbolRenamer;
+import de.tla2b.analysis.SymbolSorter;
+import de.tla2b.analysis.TypeChecker;
+import de.tla2b.config.ConfigfileEvaluator;
+import de.tla2b.config.ModuleOverrider;
+import de.tla2b.exceptions.ConfigFileErrorException;
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.NotImplementedException;
+import de.tla2b.exceptions.SemanticErrorException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.pprint.BAstCreator;
+import de.tla2b.pprint.BMachinePrinter;
+import tla2sany.semantic.ModuleNode;
+import tlc2.tool.ModelConfig;
+import util.FileUtil;
+import util.ToolIO;
+
+public class Translator {
+	private String moduleFileName;
+	private String configFileName;
+	
+	
+	
+	private String moduleName;
+	private ModuleNode moduleNode;
+	private ModelConfig modelConfig;
+
+	public Translator(String moduleFileName, String configFileName) {
+		this.moduleFileName = moduleFileName;
+		this.configFileName	= configFileName;
+		
+		parse();
+	}
+	
+	private void parse(){
+		moduleName = evalFileName(moduleFileName);
+
+		TLAParser tlaParser = new TLAParser(null);
+		moduleNode = tlaParser.parseModule(moduleName);
+
+		modelConfig = null;
+		if (configFileName != null) {
+			modelConfig = new ModelConfig(configFileName, null);
+			modelConfig.parse();
+		}
+	}
+
+	public Translator(String moduleString, String configString, int i) {
+		moduleName = "Testing";
+		File dir = new File("temp/");
+		dir.mkdirs();
+
+		try {
+			File f = new File("temp/" + moduleName + ".tla");
+			f.createNewFile();
+			FileWriter fw = new FileWriter(f);
+			fw.write(moduleString);
+			fw.close();
+			f.deleteOnExit();
+			moduleFileName = f.getAbsolutePath();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		modelConfig = null;
+		if (configString != null) {
+			File f = new File("temp/" + moduleName + ".cfg");
+			
+			try {
+				f.createNewFile();
+				FileWriter fw = new FileWriter(f);
+				fw.write(configString);
+				fw.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			f.deleteOnExit();
+			configFileName = f.getAbsolutePath();
+		}
+		dir.deleteOnExit();
+		
+		parse();
+	}
+
+	public Node translate() throws TLA2BException {
+		InstanceTransformation trans = new InstanceTransformation(moduleNode);
+		trans.start();
+
+		SymbolSorter symbolSorter = new SymbolSorter(moduleNode);
+		symbolSorter.sort();
+
+		SpecAnalyser specAnalyser;
+
+		ConfigfileEvaluator conEval = null;
+		if (modelConfig != null) {
+
+			conEval = new ConfigfileEvaluator(modelConfig, moduleNode);
+			conEval.start();
+
+			ModuleOverrider modOver = new ModuleOverrider(moduleNode, conEval);
+			modOver.start();
+			specAnalyser = new SpecAnalyser(moduleNode, conEval);
+		} else {
+			specAnalyser = new SpecAnalyser(moduleNode);
+		}
+
+		specAnalyser.start();
+
+		TypeChecker typechecker = new TypeChecker(moduleNode, conEval,
+				specAnalyser);
+		typechecker.start();
+
+		specAnalyser.evalIfThenElse();
+
+		SymbolRenamer symRenamer = new SymbolRenamer(moduleNode, specAnalyser);
+		symRenamer.start();
+		BMachinePrinter p = new BMachinePrinter(moduleNode, conEval,
+				specAnalyser);
+		//System.out.println(p.start());
+		BAstCreator bAstCreator = new BAstCreator(moduleNode, conEval,
+				specAnalyser);
+		return bAstCreator.getStartNode();
+	}
+
+	public static String evalFileName(String name) {
+		if (name.toLowerCase().endsWith(".tla")) {
+			name = name.substring(0, name.length() - 4);
+		}
+
+		if (name.toLowerCase().endsWith(".cfg")) {
+			name = name.substring(0, name.length() - 4);
+		}
+
+		String sourceModuleName = name.substring(name
+				.lastIndexOf(FileUtil.separator) + 1);
+
+		String path = name.substring(0,
+				name.lastIndexOf(FileUtil.separator) + 1);
+		if (!path.equals(""))
+			ToolIO.setUserDir(path);
+		return sourceModuleName;
+	}
+
+}
diff --git a/src/test/java/de/tla2b/prettyprintb/BBuiltInsTest.java b/src/test/java/de/tla2b/prettyprintb/BBuiltInsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..93f059306fe65ebe5b6a504711c299a3b9009aa6
--- /dev/null
+++ b/src/test/java/de/tla2b/prettyprintb/BBuiltInsTest.java
@@ -0,0 +1,61 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.prettyprintb;
+
+import static de.tla2b.util.TestUtil.compare;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.util.TestUtil;
+import util.ToolIO;
+
+public class BBuiltInsTest {
+
+	@Test
+	public void testBoolean() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME TRUE \\in BOOLEAN\n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES TRUE : BOOL \n" + "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testString() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME \"abc\" \\in STRING\n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES \"abc\" : STRING \n" + "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testBoolValue() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME TRUE \n" + "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES TRUE = TRUE \n" + "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testBoolValue2() throws Exception {
+		ToolIO.reset();
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME TRUE = FALSE \n"
+				+ "=================================";
+
+		StringBuilder sb = TestUtil.translateString(module);
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES TRUE = FALSE \n" + "END";
+		assertEquals(TestUtil.getBTreeofMachineString(expected), TestUtil.getBTreeofMachineString(sb.toString()));
+	}
+}
diff --git a/src/test/java/de/tla2b/prettyprintb/FunctionTest.java b/src/test/java/de/tla2b/prettyprintb/FunctionTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8846c5719e0ddeddcc363d4ab3e203991fad3ec
--- /dev/null
+++ b/src/test/java/de/tla2b/prettyprintb/FunctionTest.java
@@ -0,0 +1,197 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.prettyprintb;
+
+import static de.tla2b.util.TestUtil.compare;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import de.tla2b.util.TestUtil;
+import util.ToolIO;
+
+public class FunctionTest {
+
+	@Test
+	public void testFunctionConstructor() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = [x \\in {1} |-> TRUE = TRUE] \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = %x.(x : {1}| bool(TRUE = TRUE)) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testFunctionConstructor2() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = [x,y \\in {1} |-> 1] \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = %x,y.(x : {1} & y : {1}| 1) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testFunctionConstructor3() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = [x \\in {1}, y \\in BOOLEAN |-> 1] \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = %x,y.(x : {1} & y : BOOL| 1) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * recursive Function
+	 **********************************************************************/
+
+	@Ignore
+	@Test
+	public void testRecursiveFunction() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "fact[n \\in {1,2}] == IF n = 0 THEN 1 ELSE n+ fact[n-1] \n"
+				+ "ASSUME k = fact /\\ fact[k2] = k3 \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k,k2,k3\n"
+				+ "PROPERTIES k : POW(INTEGER*INTEGER) & k2 : INTEGER & k3 : INTEGER \n"
+				+ " & k = fact & fact(k2) = k3 \n"
+				+ "DEFINITIONS IF_THEN_ELSE(P, a, b) == (%t_.(t_=TRUE & P = TRUE | a )\\/%t_.(t_=TRUE & not(P= TRUE) | b ))(TRUE); \n"
+				+ "fact == %n.(n : {1, 2}| IF_THEN_ELSE(bool(n = 0), 1, n + fact(n - 1))) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * Function call
+	 **********************************************************************/
+	@Test
+	public void testFunctionCall() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = [x,y \\in {1} |-> x+y] /\\ k[1,2] = 1 \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n" + "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = %x,y.(x : {1} & y : {1}| x + y) & k(1, 2) = 1" 
+				+ "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testFunctionCall2() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = [x \\in {1} |-> TRUE] /\\ k[1] \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n" + "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = %x.(x : {1}| TRUE) & k(1) = TRUE\n" + "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testDomain() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = [x \\in {1} |-> x] /\\ DOMAIN k = {1} \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n" + "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = %x.(x : {1}| x) & dom(k) = {1}" + "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testSetOfFunction() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [BOOLEAN -> {1}] \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n" + "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = BOOL --> {1}" 
+				+ "END";
+		compare(expected, module);
+	}
+
+	@Ignore
+	@Test
+	public void testFunctionExcept() throws Exception {
+		ToolIO.reset();
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [k EXCEPT ![TRUE] = 0, ![FALSE] = 0]  \n"
+				+ "=================================";
+
+		StringBuilder sb = TestUtil.translateString(module);
+		final String expected = "MACHINE Testing\n" + "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES " + " k : POW(BOOL*INTEGER)"
+				+ "& k = k <+ {TRUE |-> 0, FALSE |-> 0}" + "END";
+		assertEquals(TestUtil.getBTreeofMachineString(expected), TestUtil.getBTreeofMachineString(sb.toString()));
+	}
+
+	/**********************************************************************
+	 * Record Except @
+	 **********************************************************************/
+	@Ignore
+	@Test
+	public void testFunctionExceptAt() throws Exception {
+		ToolIO.reset();
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [x \\in {1,2} |-> x] /\\ k2 = [k EXCEPT ![1] = @ + 1] \n"
+				+ "=================================";
+
+		StringBuilder sb = TestUtil.translateString(module);
+		System.out.println(sb);
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k, k2\n"
+				+ "PROPERTIES k : POW(INTEGER*INTEGER) &  k2 : POW(INTEGER*INTEGER) & k = %x.(x : {1, 2}| x) & k2 = k <+ {1 |-> k(1) + 1} \n"
+				+ "END";
+		assertEquals(TestUtil.getBTreeofMachineString(expected), TestUtil.getBTreeofMachineString(sb.toString()));
+	}
+	@Ignore
+	@Test
+	public void testFunctionExceptAt2() throws Exception {
+		ToolIO.reset();
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [x,y \\in {1,2} |-> x+y] /\\ k2 = [k EXCEPT ![1,1] = @ + 4] \n"
+				+ "=================================";
+
+		StringBuilder sb = TestUtil.translateString(module);
+		System.out.println(sb);
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k, k2\n"
+				+ "PROPERTIES  k : POW(INTEGER*INTEGER*INTEGER) "
+				+ "&  k2 : POW(INTEGER*INTEGER*INTEGER) "
+				+ "& k = %x,y.(x : {1, 2} & y : {1, 2}| x + y) "
+				+ "& k2 = k <+ {(1, 1) |-> k(1, 1) + 4} \n" + "END";
+		assertEquals(TestUtil.getBTreeofMachineString(expected), TestUtil.getBTreeofMachineString(sb.toString()));
+	}
+}
diff --git a/src/test/java/de/tla2b/prettyprintb/LogicOperatorsTest.java b/src/test/java/de/tla2b/prettyprintb/LogicOperatorsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ae3d6e136fd61c5877aeb079d55303d8d23cce4f
--- /dev/null
+++ b/src/test/java/de/tla2b/prettyprintb/LogicOperatorsTest.java
@@ -0,0 +1,171 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.prettyprintb;
+
+import org.junit.Test;
+
+import de.tla2b.util.TestUtil;
+import static de.tla2b.util.TestUtil.compare;
+import static org.junit.Assert.*;
+
+public class LogicOperatorsTest {
+
+	@Test
+	public void testEquality() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2\n"
+				+ "ASSUME k = (k2 # 1)\n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k, k2\n"
+				+ "PROPERTIES k = bool(k2 /= 1)\n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testEquality2() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = TRUE\n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n" + "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = TRUE \n" + "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testEquality3() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME TRUE\n" + "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES TRUE = TRUE \n" + "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * Logic Operators: \neg, \lnot, \land, \cl, \lor, \dl, \equiv, =>
+	 **********************************************************************/
+	@Test
+	public void testAnd() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2\n"
+				+ "ASSUME k = (FALSE \\land k2) \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k, k2\n"
+				+ "PROPERTIES k = bool(FALSE = TRUE & k2 = TRUE) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testAnd2() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME TRUE /\\ (TRUE \\/ FALSE) \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES TRUE = TRUE & (TRUE = TRUE or FALSE = TRUE) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * Negation: ~, \neg, \lnot
+	 **********************************************************************/
+	@Test
+	public void testNegation() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME \\lnot TRUE \n" + "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES not(TRUE = TRUE) \n" + "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * Implication and Equivalence: =>, \equiv
+	 **********************************************************************/
+
+	@Test
+	public void testImplication() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME TRUE /\\ (TRUE => FALSE) \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES TRUE = TRUE & (TRUE = TRUE => FALSE = TRUE) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testEquivalence() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME TRUE /\\ (TRUE <=> FALSE) \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES TRUE = TRUE & (TRUE = TRUE <=> FALSE = TRUE) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * Quantification: \A x \in S : P or \E x \in S : P
+	 **********************************************************************/
+	@Test
+	public void testUniversalQuantifier() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME \\A x,y \\in {1,2} : x = 0 \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES !x,y.(x : {1, 2} & y : {1, 2} => x = 0) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testExistentialQuantifier() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME \\E x,y \\in {1,2} : x = 0 \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES #x,y.(x : {1, 2} & y : {1, 2} & x = 0) \n"
+				+ "END";
+		compare(expected, module);
+	}
+	
+	@Test
+	public void testAppend() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "ASSUME Append(<<1>>, 2) = <<1,2>> \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES [1] <- 2 = [1,2] \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testQuantifier() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals, Sequences \n"
+				+ "CONSTANTS S \n"
+				+ "ASSUME S = {1,2,3} /\\  \\E u \\in Seq(S) : \\A s \\in S : \\E n \\in 1..Len(u) : u[n] = s \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS S\n"
+				+ "PROPERTIES S = {1, 2, 3} & #u.(u : seq(S) & !s.(s : S => #n.(n : 1 .. size(u) & u(n) = s))) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+}
diff --git a/src/test/java/de/tla2b/prettyprintb/PrecedenceTest.java b/src/test/java/de/tla2b/prettyprintb/PrecedenceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..479f8a55a5d70a7af9846b3cf5613947a2e0b51e
--- /dev/null
+++ b/src/test/java/de/tla2b/prettyprintb/PrecedenceTest.java
@@ -0,0 +1,77 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.prettyprintb;
+
+import static de.tla2b.util.TestUtil.compare;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import de.tla2b.util.TestUtil;
+import util.ToolIO;
+
+public class PrecedenceTest {
+
+	@Test
+	public void testSetConstructor() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "ASSUME {x \\in {1,2,3} : x \\in {1}  \\/ x \\in {2}} = {1,2} \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES {x|x : {1, 2, 3} & (x : {1} or x : {2})} = {1, 2} \n" + "END";
+		compare(expected, module);
+	}
+	
+	@Test
+	public void testPrecedence() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "ASSUME 1 + (2 * 3) = 7 \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES 1 + 2 * 3 = 7 \n" + "END";
+		compare(expected, module);
+	}
+	
+
+	
+	@Test
+	public void testPrecedence2() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "ASSUME (1 + 2) * 3 = 9 \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES (1 + 2) * 3 = 9 \n" + "END";
+		compare(expected, module);
+	}
+	
+	@Test
+	public void testPrecedence3() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "ASSUME (1 + 2) + 3 = 6 \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES 1 + 2 + 3 = 6 \n" + "END";
+		compare(expected, module);
+	}
+	
+	@Test
+	public void testPrecedence4() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "ASSUME 1 + (2 + 3) = 6 \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES 1 + (2 + 3) = 6 \n" + "END";
+		compare(expected, module);
+	}
+
+}
diff --git a/src/test/java/de/tla2b/prettyprintb/SetsTest.java b/src/test/java/de/tla2b/prettyprintb/SetsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b3090c42b87c5aee5beee0e2f3737b34eb08e2ef
--- /dev/null
+++ b/src/test/java/de/tla2b/prettyprintb/SetsTest.java
@@ -0,0 +1,175 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.prettyprintb;
+
+import static de.tla2b.util.TestUtil.compare;
+
+import org.junit.Test;
+
+public class SetsTest {
+
+	@Test
+	public void testSetEnumeration() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = {1,2,3}\n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n" + "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = {1,2,3} \n" + "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testSetEnumeration2() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = {TRUE, 1 = 1}\n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n" + "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = {TRUE, bool(1=1)} \n" + "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * Element of: \in, \notin
+	 **********************************************************************/
+	@Test
+	public void testIn() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME TRUE \\in BOOLEAN \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES TRUE : BOOL \n" + "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testIn2() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME 1 \\in {1,2,3} \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES 1 : {1,2,3} \n" + "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testNotIn() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME 1 \\notin {} \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n" + "PROPERTIES 1 /: {} \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * set operators like difference, union, intersection: \setdiff, \cup, \cap
+	 **********************************************************************/
+	@Test
+	public void testSetDifference() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME {1} = {1,2} \\ {1} \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES {1} = {1,2} - {1} \n" + "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testCup() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME {1,2} = {1} \\cup {2} \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES {1,2} = {1} \\/ {2} \n" + "END";
+		compare(expected, module);
+		}
+
+	@Test
+	public void testCap() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME {1} = {1,2} \\cap {2} \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES {1} = {1,2} /\\ {2} \n" + "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * Subseteq: subset or equal
+	 **********************************************************************/
+	@Test
+	public void testSubsteq() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME TRUE = ({1} \\subseteq {1,2}) \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES TRUE = bool({1} <: {1,2}) \n" + "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * SUBSET: conforms POW in B
+	 **********************************************************************/
+	@Test
+	public void testSubset() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME {{},{1}} = SUBSET {1,2} \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES {{},{1}} = POW({1,2}) \n" + "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * UNION
+	 **********************************************************************/
+	@Test
+	public void testUnion() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME UNION {{1},{2}} = {1,2} \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES union({{1},{2}}) = {1,2} \n" + "END";
+		compare(expected, module);
+	}
+	 
+	/**********************************************************************
+	* Set Constructor
+	 **********************************************************************/
+	@Test
+	public void testConstructor1() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME {x \\in {1,2} : x = 1} = {1} \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES {x | x : {1,2} & x = 1} = {1} \n" + "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testConstructor2() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "ASSUME {1} = {x + y+ 2:  x \\in {1,2}, y \\in {1} } \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES {1} = {t_|#x, y.(x : {1, 2} & y : {1} & t_ = x + y + 2)} \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+}
diff --git a/src/test/java/de/tla2b/prettyprintb/StructTest.java b/src/test/java/de/tla2b/prettyprintb/StructTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..78d0d0f6de7c95c6ba70961aa33400dd821d0aeb
--- /dev/null
+++ b/src/test/java/de/tla2b/prettyprintb/StructTest.java
@@ -0,0 +1,149 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.prettyprintb;
+
+import static de.tla2b.util.TestUtil.compare;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import de.tla2b.util.TestUtil;
+import util.ToolIO;
+
+public class StructTest {
+	static {
+		ToolIO.setMode(ToolIO.TOOL);
+	}
+
+	/**********************************************************************
+	 * Set of Records: [L1 : e1, L2 : e2]
+	 **********************************************************************/
+	@Test
+	public void testStruct() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [a : {1}, b : BOOLEAN] \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = struct(a : {1}, b : BOOL) \n"
+				+ "END";
+		compare(expected, module);
+	}
+	
+	
+	@Test
+	public void testStructExpansion() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME [a: {2}] = [a : {1}, b : BOOLEAN] \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES struct(a : {2},b : BOOL) = struct(a : {1},b : BOOL) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * Record: [L1 |-> e1, L2 |-> e2]
+	 **********************************************************************/
+	@Test
+	public void testRecord() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [a |-> 1, b |-> TRUE] \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = rec(a : 1, b : TRUE) \n"
+				+ "END";
+		compare(expected, module);
+	}
+	
+	
+	@Ignore
+	@Test
+	public void testRecordExpansion() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME [a|-> 2] = [a |-> 1, b |-> \"abc\"] \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES rec(a : 2,b : \"\") = rec(a : 1,b : \"abc\") \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * Record Select: r.c
+	 **********************************************************************/
+	@Test
+	public void testRecordSelect() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [a |-> 1, b |-> TRUE] /\\ k2 = k.a \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k, k2\n"
+				+ "PROPERTIES k = rec(a : 1, b : TRUE) & k2 = k'a \n"
+				+ "END";
+		compare(expected, module);
+	}
+	
+	@Test
+	public void testRecordSelect2() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [a |-> 1, b |-> TRUE] /\\ k.b \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES  k = rec(a : 1, b : TRUE) & k'b = TRUE \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * Record Except
+	 **********************************************************************/
+	@Ignore
+	@Test
+	public void testRecordExcept() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [a |-> 1, b |-> TRUE] /\\ k2 = [k EXCEPT !.a = 2] \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k, k2\n"
+				+ "PROPERTIES k = rec(a : 1, b : TRUE) & k2 = rec(a : 2, b : k'b) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * Record Except @
+	 **********************************************************************/
+	@Ignore
+	@Test
+	public void testRecordExceptAt() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [a |-> 1, b |-> TRUE] /\\ k2 = [k EXCEPT !.a = @ + 1] \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "ABSTRACT_CONSTANTS k, k2\n"
+				+ "PROPERTIES k : struct(a:INTEGER,b:BOOL) &  k2 : struct(a:INTEGER,b:BOOL) & k = rec(a : 1, b : TRUE) & k2 = rec(a : k'a + 1, b : k'b) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+}
diff --git a/src/test/java/de/tla2b/prettyprintb/TupleTest.java b/src/test/java/de/tla2b/prettyprintb/TupleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..507ab4cb2f128d53757a0cada2e117dbc3904f6d
--- /dev/null
+++ b/src/test/java/de/tla2b/prettyprintb/TupleTest.java
@@ -0,0 +1,54 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.prettyprintb;
+
+import static de.tla2b.util.TestUtil.compare;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.util.TestUtil;
+
+
+public class TupleTest {
+	
+	@Test
+	public void testTuple() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = <<TRUE,FALSE,TRUE>>\n"
+				+ "=================================";
+		
+		final String expected = "MACHINE Testing\n" + "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = (TRUE,FALSE,TRUE) \n" + "END";
+		compare(expected, module);
+	}
+	
+	@Test
+	public void testCartesianProduct() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = BOOLEAN \\X {1} \n"
+				+ "=================================";
+		
+		final String expected = "MACHINE Testing\n"+ "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = BOOL*{1} \n" + "END";
+		compare(expected, module);
+	}
+	
+	@Test
+	public void testCartesianProduct2() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = BOOLEAN \\X ({1} \\X BOOLEAN) \n"
+				+ "=================================";
+		
+		final String expected = "MACHINE Testing\n"+ "ABSTRACT_CONSTANTS k\n"
+				+ "PROPERTIES k = BOOL*({1}*BOOL) \n" + "END";
+		compare(expected, module);
+	}
+	
+	
+}
diff --git a/src/test/java/de/tla2b/prettyprintb/VariablesTest.java b/src/test/java/de/tla2b/prettyprintb/VariablesTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..386aa9198e480ff1e38ad7a41ada7ebaa47dc7c2
--- /dev/null
+++ b/src/test/java/de/tla2b/prettyprintb/VariablesTest.java
@@ -0,0 +1,29 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.prettyprintb;
+
+import static de.tla2b.util.TestUtil.compare;
+
+import org.junit.Test;
+
+public class VariablesTest {
+
+	@Test
+	public void testVariables() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "VARIABLES x, y \n"
+				+ "Init == x = 1 /\\ y = 1 \n"
+				+ "=================================";
+		
+		final String expected = "MACHINE Testing\n"
+				+ "VARIABLES x, y\n"
+				+ "INVARIANT x : INTEGER & y : INTEGER \n"
+				+ "INITIALISATION  x, y:(x = 1 & y = 1) \n"
+				+ "END";
+		compare(expected, module);
+	}
+	
+}
diff --git a/src/test/java/de/tla2b/prettyprintb/standardmodules/TestModuleFiniteSets.java b/src/test/java/de/tla2b/prettyprintb/standardmodules/TestModuleFiniteSets.java
new file mode 100644
index 0000000000000000000000000000000000000000..507bfb84d6be5738ac7c201fb9d45e1b0506b27e
--- /dev/null
+++ b/src/test/java/de/tla2b/prettyprintb/standardmodules/TestModuleFiniteSets.java
@@ -0,0 +1,50 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.prettyprintb.standardmodules;
+
+import static de.tla2b.util.TestUtil.compare;
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import de.tla2b.util.TestUtil;
+
+
+public class TestModuleFiniteSets {
+
+	@Test
+	public void testIsFiniteSet() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS FiniteSets \n"
+				+ "ASSUME IsFiniteSet({1,2,3}) \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES {1,2,3} : FIN({1,2,3}) \n" + "END";
+		compare(expected, module);
+	}
+	
+	@Test
+	public void testIsFiniteSet2() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS FiniteSets, Naturals \n"
+				+ "ASSUME IsFiniteSet(Nat) \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES NATURAL : FIN(NATURAL) \n" + "END";
+		compare(expected, module);
+	}
+	
+	@Test
+	public void testCardinality() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS FiniteSets, Naturals \n"
+				+ "ASSUME Cardinality({1,2,3}) = 3 \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES card({1,2,3}) = 3 \n" + "END";
+		compare(expected, module);
+	}
+	
+}
diff --git a/src/test/java/de/tla2b/prettyprintb/standardmodules/TestModuleNaturals.java b/src/test/java/de/tla2b/prettyprintb/standardmodules/TestModuleNaturals.java
new file mode 100644
index 0000000000000000000000000000000000000000..fbd087135098a74165c5a6b969fc7e89a2d6464e
--- /dev/null
+++ b/src/test/java/de/tla2b/prettyprintb/standardmodules/TestModuleNaturals.java
@@ -0,0 +1,99 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.prettyprintb.standardmodules;
+
+import static de.tla2b.util.TestUtil.compare;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.util.TestUtil;
+
+
+public class TestModuleNaturals {
+
+	/**********************************************************************
+	 *  >, <, <=, >=
+	 **********************************************************************/
+	
+	@Test
+	public void testCompareOperators() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "ASSUME 1 < 2 /\\ 2 > 1 /\\ 1 <= 1 /\\ 1 >= 1 \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES 1 < 2 & 2 > 1 & 1 <= 1 & 1 >= 1 \n" + "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testCompareOperators2() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "ASSUME (1 < 2) = (2 > 1) /\\ (1 <= 1) = (1 >= 1) \n"
+				+ "=================================";
+
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES bool(1 < 2) = bool(2 > 1) & bool(1 <= 1) = bool(1 >= 1) \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * Arithmetic operator: +, -, *, \div, %, ^
+	 **********************************************************************/
+	@Test
+	public void testArithmeticOperators() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "ASSUME 1 + 2 = 4-1 /\\ 1 * 2 = 4 \\div 2 /\\  1 ^ 1 = 1 \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES 1 + 2 = 4 - 1 & 1 * 2 = 4 / 2 & 1 ** 1 = 1 \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	/**********************************************************************
+	 * Interval operator: x .. y 
+	 **********************************************************************/
+	@Test
+	public void testDotDot() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "ASSUME 1 \\in 1 .. 2 \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES 1 : 1..2 \n"
+				+ "END";
+		compare(expected, module);
+	}
+
+	@Test
+	public void testNat() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "ASSUME 1 \\in Nat \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES 1 : NATURAL \n"
+				+ "END";
+		compare(expected, module);
+	}
+	
+	@Test
+	public void testMod() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals, Integers \n"
+				+ "ASSUME -3 % 2 = 1 \n"
+				+ "=================================";
+		final String expected = "MACHINE Testing\n"
+				+ "PROPERTIES -3 - 2 * (-3 / 2) = 1 \n"
+				+ "END";
+		compare(expected, module);
+	}
+	
+}
diff --git a/src/test/java/de/tla2b/typechecking/BBuiltInsTest.java b/src/test/java/de/tla2b/typechecking/BBuiltInsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a79f3b65f25528091feb3163d01273fa01d20757
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/BBuiltInsTest.java
@@ -0,0 +1,90 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class BBuiltInsTest {
+
+
+	/**********************************************************************
+	 * BOOLEAN
+	 **********************************************************************/
+	@Test  
+	public void testBoolean() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = BOOLEAN \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL)", t.getConstantType("k"));
+	}
+	
+	@Test (expected = TypeErrorException.class)  
+	public void testBooleanException() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME 1 \\in BOOLEAN \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL)", t.getConstantType("k"));
+	}
+	
+
+	/**********************************************************************
+	 * String
+	 **********************************************************************/
+	@Test  
+	public void testString() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = STRING \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(STRING)", t.getConstantType("k"));
+	}
+	
+	@Test (expected = TypeErrorException.class)
+	public void testUnifyErrorString() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME 1 = STRING \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	/**********************************************************************
+	 * Bool value: TRUE, FALSE
+	 **********************************************************************/
+	@Test  
+	public void testBoolValue() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = TRUE \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getConstantType("k"));
+	}
+	
+	@Test (expected = TypeErrorException.class)
+	public void testUnifyErrorBoolValue() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME 1 = TRUE \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	
+	
+}
diff --git a/src/test/java/de/tla2b/typechecking/ConfigTest.java b/src/test/java/de/tla2b/typechecking/ConfigTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff938d0deb2b08a1810e709968b3a45a6edb8ca8
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/ConfigTest.java
@@ -0,0 +1,42 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class ConfigTest {
+
+	@Test
+	public void TestConAssignment() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n" + "=================================";
+		final String config = "CONSTANTS k = 1";
+		TestTypeChecker t = TestUtil.typeCheckString(module, config);
+		assertEquals("INTEGER", t.getConstantType("k").toString());
+	}
+
+	@Test
+	public void TestConOverride() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "foo == 1\n"
+				+ "ASSUME k2 = k\n"
+				+ "=================================";
+		final String config = "CONSTANTS k <- foo";
+		TestTypeChecker t = TestUtil.typeCheckString(module, config);
+		assertEquals("INTEGER", t.getConstantType("k2").toString());
+	}
+
+	// TODO DefOverriding
+
+}
diff --git a/src/test/java/de/tla2b/typechecking/ConstantTypesTest.java b/src/test/java/de/tla2b/typechecking/ConstantTypesTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f3c7471b068f64a3b257c02bbd740deb9ef89309
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/ConstantTypesTest.java
@@ -0,0 +1,107 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class ConstantTypesTest {
+
+	@Test
+	public void test1() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = 1 /\\ k2 = k\n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void test2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = k2 /\\ k = 1\n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void test3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = k2 /\\ k = k3 /\\ k3 = 1\n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+		assertEquals("INTEGER", t.getConstantType("k3"));
+	}
+
+	@Test
+	public void worstCaseUnification() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS a, b, c, d, e, f, g, h \n"
+				+ "ASSUME a = b \n"
+				+ "ASSUME c = d \n"
+				+ "ASSUME a = c \n"
+				+ "ASSUME e = f \n"
+				+ "ASSUME g = h \n"
+				+ "ASSUME e = g \n"
+				+ "ASSUME a = e \n"
+				+ "ASSUME h = 1 \n" 
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("a"));
+		assertEquals("INTEGER", t.getConstantType("b"));
+		assertEquals("INTEGER", t.getConstantType("c"));
+		assertEquals("INTEGER", t.getConstantType("d"));
+		assertEquals("INTEGER", t.getConstantType("e"));
+		assertEquals("INTEGER", t.getConstantType("f"));
+		assertEquals("INTEGER", t.getConstantType("g"));
+		assertEquals("INTEGER", t.getConstantType("h"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void prime() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "Next ==  1' = 1 \n" + "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void prime2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k\n"
+				+ "foo ==  k' = 1 \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test
+	public void ifThenElse() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2\n"
+				+ "ASSUME k = IF 1 = 1 THEN k2 ELSE 1 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+}
diff --git a/src/test/java/de/tla2b/typechecking/DefinitionsTest.java b/src/test/java/de/tla2b/typechecking/DefinitionsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..954fe821e0418b9b5e1436e88bad89b0e5f525ad
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/DefinitionsTest.java
@@ -0,0 +1,231 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class DefinitionsTest {
+
+	/**********************************************************************
+	 * Definition: foo(a,b) == e
+	 **********************************************************************/
+	@Test
+	public void testDefinition() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "foo(a,b) ==  a = 1 /\\ b = TRUE \n"
+				+ "Next ==  foo(1,TRUE)  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getDefinitionType("foo"));
+		assertEquals("INTEGER", t.getDefinitionParamType("foo", "a"));
+		assertEquals("BOOL", t.getDefinitionParamType("foo", "b"));
+	}
+
+	@Test
+	public void testDefinition2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "foo(a,b) ==  a = k /\\ b = k2 \n"
+				+ "bar == k = 1 /\\ k2 = TRUE \n"
+				+ "ASSUME foo(1,FALSE) /\\ bar \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getDefinitionType("foo"));
+		assertEquals("INTEGER", t.getDefinitionParamType("foo", "a"));
+		assertEquals("BOOL", t.getDefinitionParamType("foo", "b"));
+		assertEquals("BOOL", t.getDefinitionType("bar"));
+
+	}
+
+	@Test
+	public void testDefinition3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "foo ==  k \n"
+				+ "bar == foo = 1 \n"
+				+ "ASSUME bar \n" + "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getDefinitionType("foo"));
+		assertEquals("BOOL", t.getDefinitionType("bar"));
+	}
+
+	@Test
+	public void testDefinition4() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "foo(var, value) ==  var = value \n"
+				+ "ASSUME foo(k,1) /\\ foo(k2,TRUE)  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getDefinitionType("foo"));
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("BOOL", t.getConstantType("k2"));
+	}
+
+	/**********************************************************************
+	 * Definition Call
+	 **********************************************************************/
+
+	@Test
+	public void testDefinitionCall() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "foo(a) ==  TRUE \n"
+				+ "bar == foo(1) \n"
+				+ "ASSUME bar \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getDefinitionType("foo"));
+		assertEquals("BOOL", t.getDefinitionType("bar"));
+	}
+
+	@Test
+	public void testDefinitionCall2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "foo(a) ==  a \n"
+				+ "bar == foo(1) \n"
+				+ "baz == foo(TRUE) \n"
+				+ "ASSUME baz /\\ bar = bar"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertTrue(t.getDefinitionType("foo").startsWith("UNTYPED"));
+		assertEquals("INTEGER", t.getDefinitionType("bar"));
+		assertEquals("BOOL", t.getDefinitionType("baz"));
+	}
+
+	@Test
+	public void testDefinitionCall3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "foo(a) ==  a \n"
+				+ "bar == foo(1) \n"
+				+ "baz == k = foo(k2) /\\ k2 = bar  \n"
+				+ "ASSUME baz \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertTrue(t.getDefinitionType("foo").startsWith("UNTYPED"));
+		assertEquals("INTEGER", t.getDefinitionType("bar"));
+		assertEquals("BOOL", t.getDefinitionType("baz"));
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testDefinitionCall4() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "foo(a,b) ==  a \\cup b \n"
+				+ "bar == foo({1}, k) \n"
+				+ "baz == foo({TRUE}, k2)\n"
+				+ "ASSUME baz = baz /\\ bar = bar"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertTrue(t.getDefinitionType("foo").startsWith("POW(UNTYPED"));
+		assertEquals("POW(INTEGER)", t.getDefinitionType("bar"));
+		assertEquals("POW(BOOL)", t.getDefinitionType("baz"));
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+		assertEquals("POW(BOOL)", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testDefinitionCall5() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "foo(a,b) ==  a = b \n"
+				+ "bar == foo(1,k) \n"
+				+ "ASSUME bar \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getDefinitionType("foo"));
+		assertEquals("INTEGER", t.getConstantType("k"));
+	}
+
+	@Test
+	public void testDefinitionCall6() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "foo(a,b) ==  a = b \n"
+				+ "bar == foo(k, k2) /\\ k2 = 1 \n"
+				+ "ASSUME bar \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getDefinitionType("foo"));
+		assertTrue(t.getDefinitionParamType("foo", "a").startsWith("UNTYPED"));
+		assertTrue(t.getDefinitionParamType("foo", "b").startsWith("UNTYPED"));
+		assertEquals("BOOL", t.getDefinitionType("bar"));
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testDefinitionCall7() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "foo(a,b) ==  a \\cup b \n"
+				+ "bar(x,y) == x = foo(y, k) /\\ y ={1} \n"
+				+ "ASSUME bar(k2,k3) \n" + "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertTrue(t.getDefinitionType("foo").startsWith("POW(UNTYPED"));
+		assertTrue(t.getDefinitionParamType("foo", "a").startsWith(
+				"POW(UNTYPED"));
+		assertTrue(t.getDefinitionParamType("foo", "b").startsWith(
+				"POW(UNTYPED"));
+		assertEquals("BOOL", t.getDefinitionType("bar"));
+		assertEquals("POW(INTEGER)", t.getDefinitionParamType("bar", "x"));
+		assertEquals("POW(INTEGER)", t.getDefinitionParamType("bar", "y"));
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+	}
+
+	@Test
+	public void testDefinitionCall8() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "foo(a) ==  k = a \n"
+				+ "bar == foo(k2)\n"
+				+ "baz == k2 = 1 \n"
+				+ "ASSUME bar /\\ baz \n" + "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+		assertEquals("BOOL", t.getDefinitionType("foo"));
+		assertEquals("BOOL", t.getDefinitionType("bar"));
+		assertEquals("BOOL", t.getDefinitionType("baz"));
+		assertEquals("INTEGER", t.getDefinitionParamType("foo", "a"));
+	}
+
+	@Test
+	public void testDefinitionCall9() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "foo(a,b) ==  a = b \n"
+				+ "ASSUME foo(k, 1) /\\ foo(k2, TRUE) \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("BOOL", t.getConstantType("k2"));
+		assertEquals("BOOL", t.getDefinitionType("foo"));
+		assertTrue(t.getDefinitionParamType("foo", "a").startsWith("UNTYPED"));
+		assertTrue(t.getDefinitionParamType("foo", "b").startsWith("UNTYPED"));
+	}
+
+	@Test
+	public void testDefinitionCall10() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "foo(a,b) ==  a= 1 /\\ b = TRUE \n"
+				+ "ASSUME foo(1, TRUE) \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getDefinitionType("foo"));
+		assertEquals("INTEGER", t.getDefinitionParamType("foo", "a"));
+		assertEquals("BOOL", t.getDefinitionParamType("foo", "b"));
+	}
+}
diff --git a/src/test/java/de/tla2b/typechecking/ExceptTest.java b/src/test/java/de/tla2b/typechecking/ExceptTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce5086df31130834b1a65c9c874c8efae3245c0b
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/ExceptTest.java
@@ -0,0 +1,124 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class ExceptTest {
+
+	@Test
+	public void testFunction() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [k2 EXCEPT ![TRUE] = 0]  \n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL*INTEGER)", t.getConstantType("k"));
+		assertEquals("POW(BOOL*INTEGER)", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testFunctionRecord() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [k EXCEPT ![1] = [a|-> 1, b |-> TRUE], ![1].b = k2 ] "
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*struct(a:INTEGER,b:BOOL))",
+				t.getConstantType("k"));
+		assertEquals("BOOL", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testFunctionRecord2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [k EXCEPT ![1].a = 2, ![1].b = k2 ] /\\ k2 = TRUE \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*struct(a:INTEGER,b:BOOL))",
+				t.getConstantType("k"));
+	}
+
+	@Test
+	public void testRecord() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [k EXCEPT !.a = 2, !.b = TRUE] \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("struct(a:INTEGER,b:BOOL)", t.getConstantType("k")
+				.toString());
+	}
+
+	@Test (expected = TypeErrorException.class)
+	public void testRecordOrFunction() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS a, b \n"
+				+ "ASSUME a = [a EXCEPT !.a = 1, !.b = 1] \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testRecordAtTypeError() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS r, r2\n"
+				+ "ASSUME  r = [a |-> TRUE] \n"
+				+ "/\\ r2 = [r EXCEPT !.a = 1 = @] \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testRecordAtTypeError2() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS r, r2\n"
+				+ "ASSUME  r = [x \\in {1,2}|->TRUE] \n"
+				+ "/\\ r2 = [r EXCEPT ![1] = 1 = @] \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testRecordAtTypeError3() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS r, r2\n"
+				+ "ASSUME  r = [x \\in {1,2}|->TRUE] \n"
+				+ "/\\ r2 = [r EXCEPT ![1] = @ + 1] \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test
+	public void testRecordAt() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = [k EXCEPT ![1] = @ = @] \n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+	}
+
+}
diff --git a/src/test/java/de/tla2b/typechecking/ExtendsTest.java b/src/test/java/de/tla2b/typechecking/ExtendsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..95e7cedf057e1b2d67bb885121f57dd26f1e13c3
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/ExtendsTest.java
@@ -0,0 +1,24 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class ExtendsTest {
+
+	@Test
+	public void TestExtendsCounter() throws Exception {
+		String path = "src/test/resources/typechecking/modules/";
+		TestTypeChecker t = TestUtil.typeCheck(path + "ExtendsCounter.tla");
+		assertEquals("INTEGER", t.getVariableType("x"));
+		assertEquals("INTEGER", t.getConstantType("start"));
+	}
+}
diff --git a/src/test/java/de/tla2b/typechecking/FunctionTest.java b/src/test/java/de/tla2b/typechecking/FunctionTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..419fd9773193e4b2010961ce9099aecbcad29076
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/FunctionTest.java
@@ -0,0 +1,440 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class FunctionTest {
+
+	/**********************************************************************
+	 * Function constructor
+	 **********************************************************************/
+
+	@Test
+	public void testSimpleFunctionConstructor() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [x \\in {1} |-> 1] \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*INTEGER)", t.getConstantType("k"));
+	}
+
+	@Test
+	public void testFunctionConstructor() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, S \n"
+				+ "ASSUME k = [x \\in S |-> x = k2] /\\ k2 = 1 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+		assertEquals("POW(INTEGER)", t.getConstantType("S"));
+	}
+
+	@Test
+	public void testFunctionConstructorTwoVariables() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [x,y \\in {1} |-> TRUE]  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*INTEGER*BOOL)", t.getConstantType("k")
+				.toString());
+	}
+
+	@Test
+	public void testFunctionConstructor2() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [<<x,y>> \\in {<<1,TRUE>>} |-> TRUE]  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL*BOOL)", t.getConstantType("k")
+				.toString());
+	}
+
+	@Test
+	public void testFunctionConstructor6() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [x \\in {1}, <<y,z>> \\in {<<1,TRUE>>} |-> TRUE]  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		//System.out.println(t.getConstantType("k").toString());
+		assertEquals("POW(INTEGER*(INTEGER*BOOL)*BOOL)", t.getConstantType("k")
+				.toString());
+	}
+
+	@Test
+	public void testFunctionConstructorTwoVariables2()
+			throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [x \\in {1}, y \\in BOOLEAN |-> TRUE]  \n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL*BOOL)", t.getConstantType("k")
+				.toString());
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testFunctionConstructorFail() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [<<x,y>> \\in {1}  |-> TRUE]  \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test (expected = TypeErrorException.class)
+	public void testFunctionConstructorFail2() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [<<x,y,z>> \\in ({1} \\times {1}) |-> TRUE]  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		System.out.println(t.getConstantType("k"));
+	}
+
+	@Test
+	public void testFunctionConstructor3() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, S, S2 \n"
+				+ "ASSUME k = [x,y \\in S, z \\in S2 |-> z] /\\ S = BOOLEAN /\\ S2 = {1}  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL*BOOL*INTEGER*INTEGER)", t.getConstantType("k"));
+		assertEquals("POW(BOOL)", t.getConstantType("S"));
+		assertEquals("POW(INTEGER)", t.getConstantType("S2"));
+	}
+
+	@Test
+	public void testFunctionConstructor4() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, S, S2 \n"
+				+ "ASSUME [x \\in S |-> k] = [x \\in S2 |-> x=k2] /\\ k2 = 1  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+		assertEquals("POW(INTEGER)", t.getConstantType("S"));
+		assertEquals("POW(INTEGER)", t.getConstantType("S2"));
+	}
+
+	@Test
+	public void testFunctionConstructor5() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS S, S2 \n"
+				+ "ASSUME [x \\in S, y \\in S2 |-> 1] = [x,y \\in {1} |-> 1]   \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("S"));
+		assertEquals("POW(INTEGER)", t.getConstantType("S2"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testFunctionConstructorException() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, S, S2 \n"
+				+ "ASSUME [x \\in S, y \\in S2 |-> 1] = [x \\in {1} |-> 1]   \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * recursive Function
+	 **********************************************************************/
+	@Test
+	public void testRecursiveFunction() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "fact[n \\in {1,2}] == IF n = 0 THEN 1 ELSE n+ fact[n-1] \n"
+				+ "ASSUME k = fact /\\ fact[k2] = k3 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*INTEGER)", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+		assertEquals("INTEGER", t.getConstantType("k3"));
+	}
+
+	/**********************************************************************
+	 * Function call
+	 **********************************************************************/
+
+	@Test
+	public void testFunctionCall() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k[1] = TRUE \n" + "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+	}
+
+	@Test
+	public void testFunctionCall2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k[1,TRUE,2] = TRUE \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL*INTEGER*BOOL)", t.getConstantType("k"));
+	}
+
+	@Test
+	public void testFunctionCall3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3, S \n"
+				+ "ASSUME k[k2,TRUE] = k3 \n"
+				+ "ASSUME k = [x \\in {1}, y \\in S |-> 1]\n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL*INTEGER)", t.getConstantType("k")
+				.toString());
+		assertEquals("INTEGER", t.getConstantType("k2"));
+		assertEquals("INTEGER", t.getConstantType("k3"));
+		assertEquals("POW(BOOL)", t.getConstantType("S"));
+	}
+
+	@Test
+	public void testFunctionCall4() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k[(TRUE /\\ TRUE)] = 2 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL*INTEGER)", t.getConstantType("k"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testFunctionCallException() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3, S \n"
+				+ "ASSUME k = [x \\in {1} |-> 1]\n"
+				+ "ASSUME k[k2,TRUE] = k3 \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * Domain
+	 **********************************************************************/
+	@Test
+	public void testDomain() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [x \\in {1}, y \\in BOOLEAN |-> 1]\n"
+				+ "ASSUME k2 = DOMAIN k \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL*INTEGER)", t.getConstantType("k")
+				.toString());
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testDomain2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [x \\in {1}, y \\in BOOLEAN |-> 1]\n"
+				+ "ASSUME k2 = DOMAIN k \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL*INTEGER)", t.getConstantType("k")
+				.toString());
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k2"));
+	}
+
+	/**********************************************************************
+	 * Set of Function
+	 **********************************************************************/
+	@Test
+	public void testSetOfFunction() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [BOOLEAN -> {1}] \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(POW(BOOL*INTEGER))", t.getConstantType("k"));
+	}
+
+	@Test
+	public void testSetOfFunction2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS S, S2 \n"
+				+ "ASSUME [x \\in BOOLEAN |-> 1] \\in [S -> S2] \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL)", t.getConstantType("S"));
+		assertEquals("POW(INTEGER)", t.getConstantType("S2"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testSetOfFunctionException() throws FrontEndException,
+			TLA2BException {
+		/*
+		 * A set of tuple is not a function in TLA+
+		 */
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS S, S2 \n"
+				+ "ASSUME {1} \\X BOOLEAN \\in [S -> S2] \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * Except
+	 **********************************************************************/
+	@Test
+	public void testFunctionExcept() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [k2 EXCEPT ![TRUE] = 0]  \n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+
+		assertEquals("POW(BOOL*INTEGER)", t.getConstantType("k"));
+		assertEquals("POW(BOOL*INTEGER)", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testFunctionExcept2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = [k2 EXCEPT ![TRUE,1] = k3] /\\ k3 = 1 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL*INTEGER*INTEGER)", t.getConstantType("k")
+				.toString());
+		assertEquals("POW(BOOL*INTEGER*INTEGER)", t.getConstantType("k2")
+				.toString());
+		assertEquals("INTEGER", t.getConstantType("k3"));
+
+	}
+
+	@Test
+	public void testFunctionExcept3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3, k4, k5 \n"
+				+ "ASSUME k = [k2 EXCEPT ![k3,k4] = k5]\n"
+				+ "ASSUME k2 = [x \\in {1}, y \\in BOOLEAN |-> 1]"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL*INTEGER)", t.getConstantType("k")
+				.toString());
+		assertEquals("POW(INTEGER*BOOL*INTEGER)", t.getConstantType("k2")
+				.toString());
+		assertEquals("INTEGER", t.getConstantType("k3"));
+		assertEquals("BOOL", t.getConstantType("k4"));
+		assertEquals("INTEGER", t.getConstantType("k5"));
+
+	}
+
+	@Test
+	public void testFunctionExcept4() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3, k4, k5 \n"
+				+ "ASSUME k = [k2 EXCEPT ![k3,k4] = k5]\n"
+				+ "ASSUME k = [x \\in {1}, y \\in BOOLEAN |-> 1]"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL*INTEGER)", t.getConstantType("k")
+				.toString());
+		assertEquals("POW(INTEGER*BOOL*INTEGER)", t.getConstantType("k2")
+				.toString());
+		assertEquals("INTEGER", t.getConstantType("k3"));
+		assertEquals("BOOL", t.getConstantType("k4"));
+		assertEquals("INTEGER", t.getConstantType("k5"));
+	}
+
+	@Test
+	public void testFunctionExcept6() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3, k4\n"
+				+ "ASSUME k = [k2 EXCEPT ![k3] = k4, ![1] = TRUE ]\n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k").toString());
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k2").toString());
+		assertEquals("INTEGER", t.getConstantType("k3"));
+		assertEquals("BOOL", t.getConstantType("k4"));
+	}
+
+	@Test
+	public void testFunctionExcept5() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [k2 EXCEPT ![1][1] = 2]\n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*POW(INTEGER*INTEGER))",
+				t.getConstantType("k"));
+		assertEquals("POW(INTEGER*POW(INTEGER*INTEGER))",
+				t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testFunctionExcept7() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [k2 EXCEPT ![<<1,2>>] = 2]\n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*INTEGER*INTEGER)", t.getConstantType("k"));
+	}
+
+	/**********************************************************************
+	 * Except @
+	 **********************************************************************/
+
+	@Test
+	public void testAt2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2,k3 \n"
+				+ "ASSUME k = [k2 EXCEPT ![1] = TRUE, ![2] = @=k3]  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+		assertEquals("BOOL", t.getConstantType("k3"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testAtException() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [k2 EXCEPT ![1] = TRUE, ![2] = @=1]  \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+}
diff --git a/src/test/java/de/tla2b/typechecking/InstanceTest.java b/src/test/java/de/tla2b/typechecking/InstanceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..60fd53e881e6a737e7450caada11d302259d35e8
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/InstanceTest.java
@@ -0,0 +1,67 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+import util.ToolIO;
+
+public class InstanceTest {
+
+	private static String path = "src/test/resources/typechecking/modules/";
+
+	@Test
+	public void TestNamedInstanceCounter() throws Exception {
+		TestTypeChecker t = TestUtil.typeCheck(path + "NamedInstanceCounter.tla");
+		assertEquals("INTEGER", t.getVariableType("c"));
+		assertEquals("INTEGER", t.getConstantType("start"));
+	}
+
+	@Test
+	public void TestNamedInstancePoly() throws Exception {
+		TestTypeChecker t = TestUtil.typeCheck(path + "NamedInstancePoly.tla");
+		assertEquals("INTEGER", t.getVariableType("c"));
+	}
+
+	@Test
+	public void TestNamedInstancePoly2() throws Exception {
+		TestTypeChecker t = TestUtil.typeCheck(path + "NamedInstancePoly2.tla");
+		assertEquals("INTEGER", t.getVariableType("c"));
+	}
+
+	@Test
+	public void TestNamedInstancePoly3() throws Exception {
+		TestTypeChecker t = TestUtil.typeCheck(path + "NamedInstancePoly3.tla");
+		assertEquals("BOOL", t.getVariableType("c"));
+		assertEquals("INTEGER", t.getVariableType("c2"));
+	}
+
+	@Test
+	public void TestNamedInstancePoly4() throws Exception {
+		TestTypeChecker t = TestUtil.typeCheck(path + "NamedInstancePoly4.tla");
+		assertEquals("BOOL", t.getVariableType("c"));
+		assertEquals("INTEGER", t.getConstantType("k"));
+	}
+
+	@Test
+	public void TestInstanceValue() throws Exception {
+		TestTypeChecker t = TestUtil.typeCheck(path + "InstanceValue.tla",
+				"InstanceValue.cfg");
+		assertEquals("INTEGER", t.getConstantType("c2"));
+		assertEquals("INTEGER", t.getConstantType("val2"));
+	}
+
+	@Test
+	public void TestInstanceValue2Times() throws Exception {
+		TestTypeChecker t = TestUtil.typeCheck(path + "InstanceValue2Times.tla");
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("BOOL", t.getConstantType("k2"));
+	}
+
+}
diff --git a/src/test/java/de/tla2b/typechecking/LogicOperatorsTest.java b/src/test/java/de/tla2b/typechecking/LogicOperatorsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f4585bf4dc0ae16d6592ca53c4820478a8c8c153
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/LogicOperatorsTest.java
@@ -0,0 +1,100 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class LogicOperatorsTest {
+	
+	/**********************************************************************
+	 * equality and disequality: =, #,
+	 **********************************************************************/
+	@Test
+	public void testEquality() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2\n"
+				+ "ASSUME k = (k2 = 1)\n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getConstantType("k").toString());
+		assertEquals("INTEGER", t.getConstantType("k2").toString());
+	}
+	
+	@Test (expected = TypeErrorException.class)
+	public void testEqualityError() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME 1 = TRUE\n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	@Test (expected = TypeErrorException.class)
+	public void testEqualityError2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME 1 = (1=1)\n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	
+	
+	/**********************************************************************
+	 * Logic Operators: \neg, \lnot, \land, \cl, \lor, \dl, \equiv, =>
+	 **********************************************************************/
+	@Test
+	public void testLogicOperators() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3\n"
+				+ "ASSUME k = (k2 \\land k3) \n"
+				+ "=================================";
+		
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getConstantType("k").toString());
+		assertEquals("BOOL", t.getConstantType("k2").toString());
+		assertEquals("BOOL", t.getConstantType("k3").toString());
+	}
+	
+	@Test (expected = TypeErrorException.class)
+	public void testLogicOperatorsError() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3\n"
+				+ "ASSUME 1 = (k2 \\land k3) \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	/**********************************************************************
+	 * Quantification: \A x \in S : P or \E x \in S : P.  
+	 **********************************************************************/
+
+	
+	@Test 
+	public void testQuantification() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, S\n"
+				+ "ASSUME k = (\\A x \\in S : x = k2) /\\ k2 = 1 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getConstantType("k").toString());
+		assertEquals("INTEGER", t.getConstantType("k2").toString());
+		assertEquals("POW(INTEGER)", t.getConstantType("S").toString());
+	}
+	
+	@Test(expected = TypeErrorException.class)
+	public void testQuantificationException() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME \\A <<x,y>> \\in {1} : TRUE \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+}
diff --git a/src/test/java/de/tla2b/typechecking/MiscellaneousConstructsTest.java b/src/test/java/de/tla2b/typechecking/MiscellaneousConstructsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..38b627a7299d29f6670e34518b1c2ea8672c52bd
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/MiscellaneousConstructsTest.java
@@ -0,0 +1,109 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class MiscellaneousConstructsTest {
+
+	/**********************************************************************
+	 * IF THEN ELSE
+	 **********************************************************************/
+	@Test
+	public void testIfThenElse() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3, k4 \n"
+				+ "ASSUME k = (IF k2 THEN k3 ELSE k4) /\\ k4 = 1  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER",t.getConstantType("k"));
+		assertEquals("BOOL",t.getConstantType("k2"));
+		assertEquals("INTEGER",t.getConstantType("k3"));
+		assertEquals("INTEGER",t.getConstantType("k4"));
+	}
+	
+
+	/**********************************************************************
+	 * IF THEN ELSE
+	 **********************************************************************/
+	@Test
+	public void testCase() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3, e1, e2 \n"
+				+ "ASSUME k = (CASE k2 -> e1 [] k3 -> e2) /\\ e2 = 1  \n"
+				+ "=================================";
+		TestTypeChecker t =TestUtil.typeCheckString(module);
+		assertEquals("INTEGER",t.getConstantType("k"));
+		assertEquals("BOOL",t.getConstantType("k2"));
+		assertEquals("BOOL",t.getConstantType("k3"));
+		assertEquals("INTEGER",t.getConstantType("e1"));
+		assertEquals("INTEGER",t.getConstantType("e2"));
+	}
+	
+	@Test
+	public void testCase2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3, e1, e2, e3 \n"
+				+ "ASSUME k = (CASE k2 -> e1 [] k3 -> e2 [] OTHER -> e3) /\\ e2 = 1  \n"
+				+ "=================================";
+		TestTypeChecker t =TestUtil.typeCheckString(module);
+		assertEquals("INTEGER",t.getConstantType("k"));
+		assertEquals("BOOL",t.getConstantType("k2"));
+		assertEquals("BOOL",t.getConstantType("k3"));
+		assertEquals("INTEGER",t.getConstantType("e1"));
+		assertEquals("INTEGER",t.getConstantType("e2"));
+		assertEquals("INTEGER",t.getConstantType("e3"));
+	}
+	
+	/**********************************************************************
+	 * LET d == exp IN e
+	 **********************************************************************/
+	@Test
+	public void testLetIn() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = (LET d == k2 IN d = k3) /\\ k2 = 1  \n"
+				+ "=================================";
+		TestTypeChecker t =TestUtil.typeCheckString(module);
+		assertEquals("BOOL",t.getConstantType("k"));
+		assertEquals("INTEGER",t.getConstantType("k2"));
+		assertEquals("INTEGER",t.getConstantType("k3"));
+	}
+	
+	@Test
+	public void testLetIn2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = (LET d == k2 d2 == k3 IN d = d2) /\\ k2 = 1  \n"
+				+ "=================================";
+		TestTypeChecker t =TestUtil.typeCheckString(module);
+		assertEquals("BOOL",t.getConstantType("k"));
+		assertEquals("INTEGER",t.getConstantType("k2"));
+		assertEquals("INTEGER",t.getConstantType("k3"));
+	}
+	
+	@Test
+	public void testLetIn3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3, k4 \n"
+				+ "ASSUME k = (LET d(a,b) == a=k2/\\b=k3 IN d(1,k4)) /\\ k4 = TRUE  \n"
+				+ "=================================";
+		TestTypeChecker t =TestUtil.typeCheckString(module);
+		assertEquals("BOOL",t.getConstantType("k"));
+		assertEquals("INTEGER",t.getConstantType("k2"));
+		assertEquals("BOOL",t.getConstantType("k3"));
+		assertEquals("BOOL",t.getConstantType("k4"));
+	}
+	
+	
+}
diff --git a/src/test/java/de/tla2b/typechecking/OpArgTest.java b/src/test/java/de/tla2b/typechecking/OpArgTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a1c305305020ba7698ce99a88b23921cf5fd1097
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/OpArgTest.java
@@ -0,0 +1,65 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.ConfigFileErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+
+public class OpArgTest {
+
+	@Test
+	public void TestConOverridenByLessOp() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k(_,_), k2 \n"
+				+ "ASSUME k2 = k(1,2)\n" + "=================================";
+		final String config = "CONSTANTS k <- <";
+		TestTypeChecker t = TestUtil.typeCheckString(module, config);
+		assertEquals("BOOL", t.getConstantType("k2"));
+	}
+
+	@Test(expected = ConfigFileErrorException.class)
+	public void TestOverridenConstantWrongArityException() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k(_,_) \n"
+				+ "def == TRUE /\\ FALSE \n"
+				+ "=================================";
+		final String config = "CONSTANTS k <- def";
+		TestUtil.typeCheckString(module, config);
+	}
+
+	@Test(expected = ConfigFileErrorException.class)
+	public void TestOverridenDefWrongArityException() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "foo(a, b) == a /\\ b  \n"
+				+ "def == TRUE /\\ FALSE \n"
+				+ "ASSUME foo(TRUE, FALSE) \n"
+				+ "=================================";
+		final String config = "CONSTANTS foo <- def";
+		TestUtil.typeCheckString(module, config);
+	}
+
+	@Test
+	public void TestOverridenByDef() throws Exception {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k(_,_), k2 \n"
+				+ "def(a,b) == a /\\ b \n"
+				+ "ASSUME k2 = k(TRUE,TRUE)\n"
+				+ "=================================";
+		final String config = "CONSTANTS k <- def";
+		TestTypeChecker t = TestUtil.typeCheckString(module, config);
+		assertEquals("BOOL", t.getConstantType("k2"));
+		System.out.println(t.getDefinitionType("def"));
+		assertEquals("BOOL", t.getDefinitionType("def"));
+		assertEquals("BOOL", t.getDefinitionParamType("def", "a"));
+	}
+}
diff --git a/src/test/java/de/tla2b/typechecking/SetTest.java b/src/test/java/de/tla2b/typechecking/SetTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4fad92a6033832457a2ce1ce105c9abc73de906d
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/SetTest.java
@@ -0,0 +1,506 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+import tla2sany.semantic.AbortException;
+
+public class SetTest {
+
+	/**********************************************************************
+	 * Set Enumeration: {1,2,3}
+	 * 
+	 * @throws AbortException
+	 **********************************************************************/
+
+	@Test
+	public void testSetEnumeration() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3\n"
+				+ "ASSUME k = {k2, k3} /\\ k3 = 1\n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+		assertEquals("INTEGER", t.getConstantType("k3"));
+
+	}
+
+	@Test
+	public void testSetEnumeration2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3\n"
+				+ "ASSUME k = {k2, k3} /\\ k = {1}\n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+		assertEquals("INTEGER", t.getConstantType("k3"));
+	}
+
+	@Test
+	public void testSetEnumeration3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3\n"
+				+ "ASSUME k = {k2,{k3}} /\\ k3 = 1\n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(POW(INTEGER))", t.getConstantType("k"));
+		assertEquals("POW(INTEGER)", t.getConstantType("k2"));
+		assertEquals("INTEGER", t.getConstantType("k3"));
+	}
+
+	@Test
+	public void testSetEnumeration4() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2\n"
+				+ "ASSUME k = {{1},{k2}}\n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(POW(INTEGER))", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testSetEnumerationException() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2\n"
+				+ "ASSUME k = {1, TRUE}\n"
+				+ "=================================";
+
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testSetEnumerationException2() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2\n"
+				+ "ASSUME 1 = {1, 2}\n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * Element of: \in, \notin
+	 **********************************************************************/
+	@Test
+	public void testElementOfSet() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2\n"
+				+ "ASSUME k \\in {k2} /\\ k2 = 1 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testElementOfSet2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2\n"
+				+ "ASSUME k \\in {k2} /\\ k = 1 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testElementOfSet3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k \\in {<<TRUE>>}\n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testElementOfSetError() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME 1 = (1 \\in {1}) \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testElementOfSetError2() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME 1 \\in 1 \n" + "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * set operators like difference, union, intersection
+	 **********************************************************************/
+	@Test
+	public void testSetOperators() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3\n"
+				+ "ASSUME k = (k2 \\cup k3) /\\ k3 = {1} \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER)", t.getConstantType("k2"));
+		assertEquals("POW(INTEGER)", t.getConstantType("k3"));
+	}
+
+	@Test
+	public void testSetOperators2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2\n"
+				+ "ASSUME k = (k \\cup k2) /\\ k2 = {1} \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER)", t.getConstantType("k2"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testSetOperatorsException() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2\n"
+				+ "ASSUME 1 = k \\cup k2 \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testSetOperatorsException2() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = {1} \\cup {TRUE} \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * set constructor: {x \in S : p}.
+	 **********************************************************************/
+	@Test
+	public void testSubsetOf() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, S\n"
+				+ "ASSUME k = {x \\in S : x = 1} \n"
+				+ "=================================";
+		TestTypeChecker t =TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER)", t.getConstantType("S"));
+	}
+
+	@Test
+	public void testSubsetOf2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2\n"
+				+ "ASSUME k = {x \\in {TRUE} : x = k2} \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL)", t.getConstantType("k"));
+		assertEquals("BOOL", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testSubsetOf3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, S, k2\n"
+				+ "ASSUME k = {x \\in S : x = k2} /\\ k2 = TRUE \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL)", t.getConstantType("k"));
+		assertEquals("POW(BOOL)", t.getConstantType("S"));
+		assertEquals("BOOL", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testSubsetOf4() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, S\n"
+				+ "ASSUME k = {x \\in S : TRUE} /\\ k = {TRUE} \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL)", t.getConstantType("k"));
+		assertEquals("POW(BOOL)", t.getConstantType("S"));
+	}
+
+	@Test (expected = TypeErrorException.class)
+	public void testSubsetOfException() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = {<<x,y>> \\in {TRUE} : TRUE} \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testSubsetOfException2() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = {x \\in 1 : TRUE} \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test (expected = TypeErrorException.class)
+	public void testSubsetOfException3() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = {x \\in {} : 1 = 1} \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test 
+	public void testSubsetOfTuple() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k\n"
+				+ "ASSUME k = {<<x,y>> \\in {1} \\times {TRUE} : TRUE} \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+	}
+	
+	@Test 
+	public void testSubsetOfTuple2() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, S, S2\n"
+				+ "ASSUME k = {<<x,y>> \\in S \\times S2 : x = 1 /\\ y = TRUE} \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER)", t.getConstantType("S"));
+		assertEquals("POW(BOOL)", t.getConstantType("S2"));
+	}
+	
+	@Test 
+	public void testSubsetOfTuple3() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, S\n"
+				+ "ASSUME k = {<<x,y>> \\in S : x = 1 /\\ y = TRUE} \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("S"));
+	}
+	
+	/**********************************************************************
+	 * set constructor: {e : x \in S}
+	 **********************************************************************/
+	@Test
+	public void testSetOfAll() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, S, k2\n"
+				+ "ASSUME k = {x = k2 : x \\in S} /\\ k2 = 1  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER)", t.getConstantType("S"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testSetOfAll2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, S\n"
+				+ "ASSUME k = {{x} : x \\in S} /\\ S = {1}  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(POW(INTEGER))", t.getConstantType("k"));
+		assertEquals("POW(INTEGER)", t.getConstantType("S"));
+	}
+
+	@Test
+	public void testSetOfAll3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, S, k2\n"
+				+ "ASSUME k = { x = y /\\ y = k2 : x,y \\in S} /\\ k2 = 1 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER)", t.getConstantType("S"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testSetOfAll4() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, S, S2, k2, k3\n"
+				+ "ASSUME k = { x = k2 /\\ y /\\ z = k3 : x \\in S, y,z \\in S2 } /\\ k2 = TRUE \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL)", t.getConstantType("k"));
+		assertEquals("POW(BOOL)", t.getConstantType("S"));
+		assertEquals("BOOL", t.getConstantType("k2"));
+		assertEquals("BOOL", t.getConstantType("k3"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testSetOfAllException() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, S\n"
+				+ "ASSUME 1 = {x : x \\in S} \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testSetOfAllException2() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, S\n"
+				+ "ASSUME k = {x : x \\in 1} \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testSetOfAllException3() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, S\n"
+				+ "ASSUME k = {x : <<x,y>> \\in S} \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * SUBSET: conforms POW in B
+	 **********************************************************************/
+	@Test
+	public void testSubset() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = SUBSET k2 /\\ k2 = 1 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testSubset2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = SUBSET k2 /\\ k = {1} \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testSubsetException() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME 1 = SUBSET k \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * UNION
+	 **********************************************************************/
+	@Test
+	public void testUnion() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = UNION k2 /\\ k = {1} \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+		assertEquals("POW(POW(INTEGER))", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testUnion2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = UNION k2 /\\ k2 = {{1},{2}} \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+		assertEquals("POW(POW(INTEGER))", t.getConstantType("k2"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testUnionException() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = UNION k2 /\\ k = 1 \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testUnionException2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = UNION k2 /\\ k2 = {1,2} \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * Subseteq: subset or equal
+	 **********************************************************************/
+	@Test
+	public void testSubseteq() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = (k2 \\subseteq k3) /\\ k3 = {1}  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getConstantType("k"));
+		assertEquals("POW(INTEGER)", t.getConstantType("k2"));
+		assertEquals("POW(INTEGER)", t.getConstantType("k3"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testSubseteqException() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = (k2 \\subseteq 1)  \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testSubseteqException2() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME 1 = (k \\subseteq k2)  \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+}
diff --git a/src/test/java/de/tla2b/typechecking/StringTest.java b/src/test/java/de/tla2b/typechecking/StringTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6944edec529ba2bce7e200085971b57440934ef6
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/StringTest.java
@@ -0,0 +1,64 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class StringTest {
+	
+	/**********************************************************************
+	 * a String: "abc"
+	 **********************************************************************/
+
+	@Test
+	public void testAString() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = \"abc\" \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("STRING", t.getConstantType("k").toString());
+	}
+	
+	@Test (expected = TypeErrorException.class)
+	public void testAStringException() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME 1 = \"abc\" \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	
+	/**********************************************************************
+	 * STRING
+	 **********************************************************************/
+	@Test 
+	public void testString() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = STRING \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(STRING)", t.getConstantType("k").toString());
+	}
+	
+	@Test (expected = TypeErrorException.class)
+	public void testStringException() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME 1 = STRING \n"
+				+ "=================================";
+
+		TestUtil.typeCheckString(module);
+	}
+}
diff --git a/src/test/java/de/tla2b/typechecking/StructTest.java b/src/test/java/de/tla2b/typechecking/StructTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..360131c61b56ed09d872b47de8ac0243f8bbe42a
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/StructTest.java
@@ -0,0 +1,277 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+import util.ToolIO;
+
+public class StructTest {
+	static {
+		ToolIO.setMode(ToolIO.TOOL);
+	}
+
+	/**********************************************************************
+	 * Set of Records: [L1 : e1, L2 : e2]
+	 **********************************************************************/
+	@Test
+	public void testStruct() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [a : {1}, b : BOOLEAN] \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(struct(a:INTEGER,b:BOOL))", t.getConstantType("k"));
+	}
+
+	@Test
+	public void testStruct2() throws FrontEndException, TLA2BException {
+
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = [a : k2, b : k3] /\\ k2 = {1} /\\ k3 = BOOLEAN \n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		
+		assertEquals("POW(struct(a:INTEGER,b:BOOL))", t.getConstantType("k"));
+	}
+
+	@Test
+	public void testStruct3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME [a : {1}, b : BOOLEAN] = [a : k, b : k2] \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+		assertEquals("POW(BOOL)", t.getConstantType("k2"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testStructException() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME 1 = [a : 1, b : TRUE] \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testStructException2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME [a : {1}, b : BOOLEAN] = [a : BOOLEAN, b : BOOLEAN] \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testStructException3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME [aa : {1}, b : BOOLEAN] = [a : {1}, b : BOOLEAN] \n"
+				+ "=================================";
+
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * Record: [L1 |-> e1, L2 |-> e2]
+	 **********************************************************************/
+
+	@Test
+	public void testRecord() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [a |-> 1, b |-> TRUE] \n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("struct(a:INTEGER,b:BOOL)", t.getConstantType("k"));
+	}
+
+	@Test
+	public void testRecord2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = [a |-> k2, b |-> k3] /\\ k2 = 1 /\\ k3 = TRUE \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("struct(a:INTEGER,b:BOOL)", t.getConstantType("k"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testRecordException() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "ASSUME 1 = [b |-> 1, a |-> TRUE] \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test
+	public void testRecord3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME [a |-> k, b |-> k2] \\in [a: {1}, b: BOOLEAN]  \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("BOOL", t.getConstantType("k2"));
+	}
+
+	/**********************************************************************
+	 * Record Select: r.c
+	 **********************************************************************/
+
+	@Test
+	public void testRecordSelect() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = [a |-> 1, b |-> TRUE] /\\ k2 = k.a \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("struct(a:INTEGER,b:BOOL)", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testRecordSelect2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k2 = k.a /\\ k = [a |-> 1, b |-> TRUE] \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("struct(a:INTEGER,b:BOOL)", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test
+	public void testRecordSelect3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = [a |-> k2, b |-> k3]  /\\ k.a = 1 /\\ k.b = TRUE \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		
+		assertEquals("struct(a:INTEGER,b:BOOL)", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+		assertEquals("BOOL", t.getConstantType("k3"));
+	}
+
+	@Test
+	public void testRecordSelect4() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k \\in [a : k2, b : k3]  /\\ k.a = 1 /\\ k.b = TRUE \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("struct(a:INTEGER,b:BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER)", t.getConstantType("k2"));
+		assertEquals("POW(BOOL)", t.getConstantType("k3"));
+	}
+
+	@Test
+	public void testRecordSelectException3() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [a |-> 1] /\\ TRUE = k.b \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test
+	public void testRecordSelect5() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME 1 = k.a /\\ TRUE = k.b  /\\ k = [a |-> 1] \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("struct(a:INTEGER,b:BOOL)", t.getConstantType("k"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testRecordSelectException() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME TRUE = k.a  /\\ k = [a |-> 1] \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testRecordSelectException4() throws FrontEndException,
+			TLA2BException {
+
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [a |-> 1] /\\ TRUE = k.a \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * Record Except
+	 **********************************************************************/
+
+	@Test
+	public void testRecordExcept() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3, k4 \n"
+				+ "ASSUME k = [a|-> k2, b|-> k3] /\\ k4 = [k EXCEPT !.a = 1, !.b = TRUE]\n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("struct(a:INTEGER,b:BOOL)", t.getConstantType("k"));
+		assertEquals("struct(a:INTEGER,b:BOOL)", t.getConstantType("k4"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+		assertEquals("BOOL", t.getConstantType("k3"));
+	}
+
+	@Test
+	public void testRecordExcept2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k.a = 1/\\ k2 = [k EXCEPT !.a = 1, !.b = TRUE] /\\ k2 = [a|->2, b |-> FALSE]\n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("struct(a:INTEGER,b:BOOL)", t.getConstantType("k"));
+		assertEquals("struct(a:INTEGER,b:BOOL)", t.getConstantType("k2"));
+	}
+
+	/**********************************************************************
+	 * Record Except @
+	 **********************************************************************/
+
+	@Test
+	public void testRecordExceptAt() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = [a|-> TRUE] /\\ k2 = [k EXCEPT !.a = @ = k3]\n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("struct(a:BOOL)", t.getConstantType("k"));
+		assertEquals("struct(a:BOOL)", t.getConstantType("k2"));
+		assertEquals("BOOL", t.getConstantType("k3"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testRecordExceptAtException() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = [a|-> TRUE] /\\ k2 = [k EXCEPT !.a = @ = 1]\n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+}
diff --git a/src/test/java/de/tla2b/typechecking/TupleTest.java b/src/test/java/de/tla2b/typechecking/TupleTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6671f089ace2e6be874f68568d0ba27d6bfdc2ea
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/TupleTest.java
@@ -0,0 +1,171 @@
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class TupleTest {
+
+	@Test
+	public void testSimpleTuple() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = <<1,TRUE>> \n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER*BOOL", t.getConstantType("k").toString());
+	}
+
+	@Test
+	public void testTuple3Components() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = <<1,TRUE,1>> \n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER*BOOL*INTEGER", t.getConstantType("k").toString());
+	}
+	
+	@Test
+	public void testTuple3Components2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = <<1,1,1>> \n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER*INTEGER*INTEGER", t.getConstantType("k").toString());
+	}
+
+	@Test
+	public void testTupleComponentsOfTheSameType() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = <<1,1>> \n" + "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER*INTEGER", t.getConstantType("k").toString());
+	}
+
+	@Test
+	public void testTuple1() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = <<1,k2>> /\\ k2 = TRUE \n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER*BOOL", t.getConstantType("k").toString());
+		assertEquals("BOOL", t.getConstantType("k2").toString());
+	}
+
+	@Test
+	public void testCartesianProduct() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = {1} \\times BOOLEAN \n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k").toString());
+	}
+
+	@Test
+	public void testTupleSingleElement() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = <<TRUE>> \n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k").toString());
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testTuple2Elements() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = <<k2, k3>> /\\ k3 = TRUE \n"
+				+ "=================================";
+
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test
+	public void testUnifyTuple3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = <<k2, <<k3>> >> /\\ k3 = TRUE /\\ k2 = 1\n"
+				+ "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER*POW(INTEGER*BOOL)", t.getConstantType("k")
+				.toString());
+		assertEquals("INTEGER", t.getConstantType("k2").toString());
+		assertEquals("BOOL", t.getConstantType("k3").toString());
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testUnifyTuple4() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k \\in <<TRUE>>\n"
+				+ "=================================";
+
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * Cartesian Product
+	 **********************************************************************/
+	@Test
+	public void testCartesianProduct2() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = BOOLEAN \\X {1} \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL*INTEGER)", t.getConstantType("k").toString());
+	}
+
+	@Test
+	public void testCartesianProduct3() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME BOOLEAN \\X {1} = k \\X k2 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(BOOL)", t.getConstantType("k").toString());
+		assertEquals("POW(INTEGER)", t.getConstantType("k2").toString());
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testCartesianProductException() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = BOOLEAN \\X 1 \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+}
diff --git a/src/test/java/de/tla2b/typechecking/TupleVsSequenceTest.java b/src/test/java/de/tla2b/typechecking/TupleVsSequenceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..24cf8a104acb0a11d248f9d22b619725d70986fd
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/TupleVsSequenceTest.java
@@ -0,0 +1,50 @@
+package de.tla2b.typechecking;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class TupleVsSequenceTest {
+
+	@Test  
+	public void testTupleVsSequence() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = Append(<<>>, TRUE) \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+	}
+	
+	@Test  
+	public void testTupleVsSequence2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = Append(<<1,2,3>>, k2) \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*INTEGER)", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+	
+	@Test  
+	public void testTupleVsSequence3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS a, b, c\n"
+				+ "ASSUME <<1,2,3,4>> = <<a,b,c>> \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("a"));
+		assertEquals("INTEGER", t.getConstantType("b"));
+		assertEquals("INTEGER", t.getConstantType("c"));
+	}
+	
+}
diff --git a/src/test/java/de/tla2b/typechecking/TypeConflictsTest.java b/src/test/java/de/tla2b/typechecking/TypeConflictsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e4a1b9b25c0987732c4293ce3316cf0e9cf205ed
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/TypeConflictsTest.java
@@ -0,0 +1,79 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+import util.ToolIO;
+
+public class TypeConflictsTest {
+
+	@Test(expected = TypeErrorException.class)
+	public void testTypeConflict1() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = {k} \n"
+				+ "=================================";
+
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testTypeConflict2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME {k} = k  \n"
+				+ "=================================";
+
+		TestUtil.typeCheckString(module);
+	}
+	
+	@Test(expected = TypeErrorException.class)
+	public void testTypeConflict3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME {{k}} = k  \n"
+				+ "=================================";
+
+		TestUtil.typeCheckString(module);
+	}
+	
+	@Test(expected = TypeErrorException.class)
+	public void testTypeConflict4() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [a |-> k]  \n"
+				+ "=================================";
+
+		TestUtil.typeCheckString(module);
+	}
+	
+	@Test(expected = TypeErrorException.class)
+	public void testTypeConflict5() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Integers \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = [x \\in {} |-> k]  \n"
+				+ "=================================";
+
+		TestUtil.typeCheckString(module);
+	}
+	
+	@Test(expected = TypeErrorException.class)
+	public void testTypeConflict6() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "CONSTANTS a,b \n"
+				+ "ASSUME a = [x|->1] /\\ b = [y|->a, x|->1] /\\ a=b  \n"
+				+ "=================================";
+
+		TestUtil.typeCheckString(module);
+	}
+}
diff --git a/src/test/java/de/tla2b/typechecking/standardmodules/TestModuleFiniteSets.java b/src/test/java/de/tla2b/typechecking/standardmodules/TestModuleFiniteSets.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa93e1d0fc72c34dfb059497b22d5a21a0e4f639
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/standardmodules/TestModuleFiniteSets.java
@@ -0,0 +1,120 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking.standardmodules;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class TestModuleFiniteSets {
+
+	/**********************************************************************
+	 * IsFiniteSet
+	 **********************************************************************/
+	@Test
+	public void unifyIsFiniteSet() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS FiniteSets \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = IsFiniteSet({1,2,3}) \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getConstantType("k"));
+	}
+
+	@Test
+	public void unifyIsFiniteSet2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS FiniteSets \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = IsFiniteSet(k2) /\\ k2 = {1} \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getConstantType("k"));
+		assertEquals("POW(INTEGER)", t.getConstantType("k2"));
+
+	}
+
+	@Test
+	public void unifyIsFiniteSet3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS FiniteSets \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = IsFiniteSet({}) \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getConstantType("k"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void unifyErrorIsFiniteSet() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS FiniteSets \n"
+				+ "ASSUME IsFiniteSet(1)\n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void unifyErrorIsFiniteSet2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS FiniteSets \n"
+				+ "ASSUME 1 = IsFiniteSet({1})\n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * Cardinality
+	 **********************************************************************/
+	@Test
+	public void unifyCardinality() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS FiniteSets \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = Cardinality({1,2,3}) \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+	}
+
+	@Test
+	public void unifyCardinality2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS FiniteSets \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = Cardinality(k2) /\\ k2 = {1} \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("POW(INTEGER)", t.getConstantType("k2"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void unifyErrorCardinality() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS FiniteSets \n"
+				+ "ASSUME Cardinality(1)\n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void unifyErrorCardinality2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS FiniteSets \n"
+				+ "ASSUME TRUE = Cardinality({1})\n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+}
diff --git a/src/test/java/de/tla2b/typechecking/standardmodules/TestModuleIntegers.java b/src/test/java/de/tla2b/typechecking/standardmodules/TestModuleIntegers.java
new file mode 100644
index 0000000000000000000000000000000000000000..b658435a201b03a406568fd6e7dcbcb6265650b8
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/standardmodules/TestModuleIntegers.java
@@ -0,0 +1,67 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking.standardmodules;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class TestModuleIntegers {
+
+	/**********************************************************************
+	 * Int
+	 **********************************************************************/
+	@Test
+	public void unifyInt() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Integers \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = Int \n" + "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void unifyErrorInt() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Integers \n"
+				+ "ASSUME TRUE \\in Int \n"
+				+ "=================================";
+
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * unary minus: -x
+	 **********************************************************************/
+	@Test
+	public void unifyUnaryMinus() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Integers \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = -k2 \n" + "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void unifyErrorUnaryMinus() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Integers \n"
+				+ "ASSUME TRUE = -1 \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+}
diff --git a/src/test/java/de/tla2b/typechecking/standardmodules/TestModuleNaturals.java b/src/test/java/de/tla2b/typechecking/standardmodules/TestModuleNaturals.java
new file mode 100644
index 0000000000000000000000000000000000000000..3fa055da24b9cc519bc546bd8f7bcc7b36833c24
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/standardmodules/TestModuleNaturals.java
@@ -0,0 +1,124 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking.standardmodules;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class TestModuleNaturals {
+
+	/**********************************************************************
+	 * Relational operators: >, <, <=, >=
+	 **********************************************************************/
+	@Test
+	public void testRelationalOperators() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = (k2 > k3) \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testRelationalOperatorsException() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME 1 = (2 > 1) \n" + "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * Arithmetic operator: +, -, *, /, mod, exp
+	 **********************************************************************/
+	@Test
+	public void testArithmeticOperators() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = k2 + k3 \n" + "=================================";
+
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+		assertEquals("INTEGER", t.getConstantType("k3"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testArithmeticOperatorsException() throws FrontEndException,
+			TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME TRUE = 1 + 1 \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * Interval operator: x .. y
+	 **********************************************************************/
+
+	@Test
+	public void testDotDot() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = k2 .. k3 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+		assertEquals("INTEGER", t.getConstantType("k2"));
+		assertEquals("INTEGER", t.getConstantType("k3"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void testDotDotException() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS  k2, k3 \n"
+				+ "ASSUME TRUE \\in  k2 .. k3 \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	/**********************************************************************
+	 * Nat
+	 **********************************************************************/
+	@Test
+	public void testNat() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = Nat \n" + "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER)", t.getConstantType("k"));
+	}
+
+	@Test(expected = TypeErrorException.class)
+	public void unifyErrorNat() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Naturals \n"
+				+ "ASSUME TRUE \\in Nat \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+}
diff --git a/src/test/java/de/tla2b/typechecking/standardmodules/TestModuleSequences.java b/src/test/java/de/tla2b/typechecking/standardmodules/TestModuleSequences.java
new file mode 100644
index 0000000000000000000000000000000000000000..0ae160faef029bcd572d77ab1cada3a7c3685481
--- /dev/null
+++ b/src/test/java/de/tla2b/typechecking/standardmodules/TestModuleSequences.java
@@ -0,0 +1,356 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.typechecking.standardmodules;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.exceptions.TypeErrorException;
+import de.tla2b.util.TestTypeChecker;
+import de.tla2b.util.TestUtil;
+
+
+public class TestModuleSequences {
+
+	/**********************************************************************
+	 * Seq(S): The set of all sequences of elements in S.
+	 **********************************************************************/
+	@Test  
+	public void testSeq() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = Seq({TRUE}) \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(POW(INTEGER*BOOL))", t.getConstantType("k"));
+	}
+	
+	@Test  
+	public void testSeq2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME <<k>> \\in Seq({TRUE}) \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("BOOL", t.getConstantType("k"));
+	}
+	
+	
+	
+	@Test (expected = TypeErrorException.class)
+	public void testSeqException() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "ASSUME 1 = Seq({1}) \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+
+	@Test (expected = TypeErrorException.class)
+	public void testSeqException2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = Seq(1) \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	
+	/**********************************************************************
+	 * Len(S)
+	 **********************************************************************/
+	@Test  
+	public void testLen() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = Len(<<1,2,3>>) \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+	}
+	
+	@Test (expected = TypeErrorException.class)
+	public void testLenException() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME TRUE = Len(<<1,2,3>>) \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	@Test (expected = TypeErrorException.class)
+	public void testLenException2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME 3 = Len({1,2,3}) \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	@Test (expected = TypeErrorException.class)
+	public void testUnifyErrorLen2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME 1 = Len(1) \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	
+	/**********************************************************************
+	 * s \o s2 - concatenation of s and s2
+	 **********************************************************************/
+	@Test  
+	public void testUnifyConcatenation() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = k2 \\o <<TRUE>> \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k2"));
+	}
+	
+	@Test  
+	public void testUnifyConcatenation2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME <<TRUE>> = k \\o k2 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k2"));
+	}
+	
+	@Test  
+	public void testUnifyConcatenation3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k= k2 \\o k3 /\\ k3 = <<TRUE>> \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k2"));
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k3"));
+	}
+	
+	@Test (expected = TypeErrorException.class)
+	public void testUnifyErrorConcatenation() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2  \n"
+				+ "ASSUME k = 1 \\o k2 \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	@Test (expected = TypeErrorException.class)
+	public void testUnifyErrorConcatenation2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2  \n"
+				+ "ASSUME 1 = k \\o k2 \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	@Test (expected = TypeErrorException.class)
+	public void testUnifyErrorConcatenation3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2  \n"
+				+ "ASSUME <<TRUE>> = <<1>> \\o <<2>> \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	
+	/**********************************************************************
+	 * Append(s, e)
+	 **********************************************************************/
+	@Test  
+	public void testUnifyAppend() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = Append(k2, k3) /\\ k3 = TRUE \n"
+				+ "=================================";
+	
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k2"));
+		assertEquals("BOOL", t.getConstantType("k3"));
+	}
+	
+	@Test  
+	public void testUnifyAppend2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = Append(k2, k3) /\\ k = <<TRUE>> \n"
+				+ "=================================";
+	
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k2"));
+		assertEquals("BOOL", t.getConstantType("k3"));
+	}
+	
+	@Test  
+	public void testUnifyAppend3() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = Append(k2, 1) \n"
+				+ "=================================";
+	
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*INTEGER)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER*INTEGER)", t.getConstantType("k2"));
+	}
+
+	
+	@Test (expected = TypeErrorException.class)
+	public void testUnifyErrorAppend() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2, k3 \n"
+				+ "ASSUME k = Append(1, k3) \n"
+				+ "=================================";
+	
+		TestUtil.typeCheckString(module);
+	}
+	
+
+	/**********************************************************************
+	 * Head(s): the first element of the seq
+	 **********************************************************************/
+	@Test  
+	public void testUnifyHead() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = Head(k2) /\\ k2 = <<1>> \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("POW(INTEGER*INTEGER)", t.getConstantType("k2"));
+	}
+	
+	@Test  
+	public void testUnifyHead2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = Head(k2) /\\ k = 1 \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("INTEGER", t.getConstantType("k"));
+		assertEquals("POW(INTEGER*INTEGER)", t.getConstantType("k2"));
+	}
+	
+	@Test (expected = TypeErrorException.class) 
+	public void testUnifyErrorHead() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = Head(1) \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	/**********************************************************************
+	 * Tail(s): the sequence without the first element
+	 **********************************************************************/
+	@Test  
+	public void testUnifyTail() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = Tail(k2) /\\ k = <<TRUE>> \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k2"));
+	}
+	
+	@Test  
+	public void testUnifyTail2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2 \n"
+				+ "ASSUME k = Tail(k2) /\\ k2 = <<TRUE>> \n"
+				+ "=================================";
+	
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k2"));
+	}
+	
+	@Test (expected = TypeErrorException.class)  
+	public void testUnifyErrorTail() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k \n"
+				+ "ASSUME k = Tail(1) \n"
+				+ "=================================";
+		TestUtil.typeCheckString(module);
+	}
+	
+	/**********************************************************************
+	 * SubSeq(s,m,n): The sequence <<s[m], s[m+1], ... , s[n]>>
+	 **********************************************************************/
+	@Test  
+	public void testUnifySubSeq() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2, m, n \n"
+				+ "ASSUME k = SubSeq(k2, m, n) /\\ k = <<TRUE>> \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k2"));
+		assertEquals("INTEGER", t.getConstantType("m"));
+		assertEquals("INTEGER", t.getConstantType("n"));
+	}
+	
+	@Test  
+	public void testUnifySubSeq2() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2, m, n \n"
+				+ "ASSUME k = SubSeq(k2, m, n) /\\ k2= <<TRUE>> \n"
+				+ "=================================";
+		TestTypeChecker t = TestUtil.typeCheckString(module);
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k"));
+		assertEquals("POW(INTEGER*BOOL)", t.getConstantType("k2"));
+		assertEquals("INTEGER", t.getConstantType("m"));
+		assertEquals("INTEGER", t.getConstantType("n"));
+	}
+	
+	@Test (expected = TypeErrorException.class)
+	public void testUnifyErrorSubSeq() throws FrontEndException, TLA2BException {
+		final String module = "-------------- MODULE Testing ----------------\n"
+				+ "EXTENDS Sequences \n"
+				+ "CONSTANTS k, k2, m, n \n"
+				+ "ASSUME k = SubSeq(1, m, n) \n"
+				+ "=================================";
+	
+		TestUtil.typeCheckString(module);
+	}
+}
diff --git a/src/test/java/de/tla2b/util/Ast2String.java b/src/test/java/de/tla2b/util/Ast2String.java
new file mode 100644
index 0000000000000000000000000000000000000000..2fb20951b48d533fd1cf178399c657b817d06dd0
--- /dev/null
+++ b/src/test/java/de/tla2b/util/Ast2String.java
@@ -0,0 +1,67 @@
+package de.tla2b.util;
+
+import de.be4.classicalb.core.parser.analysis.ExtendedDFAdapter;
+import de.be4.classicalb.core.parser.node.Node;
+import de.be4.classicalb.core.parser.node.Start;
+import de.be4.classicalb.core.parser.node.Token;
+
+public class Ast2String extends ExtendedDFAdapter {
+	private final StringBuilder builder = new StringBuilder();
+
+	@Override
+	public String toString() {
+		return builder.toString();
+	}
+
+	@Override
+	public void defaultIn(final Node node) {
+		super.defaultIn(node);
+		builder.append(node.getClass().getSimpleName());
+		builder.append("(");
+	}
+
+	@Override
+	public void defaultCase(final Node node) {
+		super.defaultCase(node);
+		if (node instanceof Token) {
+			builder.append(((Token) node).getText());
+		} else {
+			builder.append(node.toString());
+		}
+
+	}
+
+	@Override
+	public void defaultOut(final Node node) {
+		super.defaultOut(node);
+		builder.append(")");
+	}
+
+	@Override
+	public void beginList(final Node parent) {
+		builder.append('[');
+	}
+
+	@Override
+	public void betweenListElements(final Node parent) {
+		builder.append(',');
+	}
+
+	@Override
+	public void endList(final Node parent) {
+		builder.append(']');
+	}
+
+	@Override
+	public void betweenChildren(final Node parent) {
+		builder.append(',');
+	}
+
+	@Override
+	public void caseStart(final Start node) {
+		inStart(node);
+		node.getPParseUnit().apply(this);
+		node.getEOF().apply(this);
+		outStart(node);
+	}
+}
diff --git a/src/test/java/de/tla2b/util/TestTypeChecker.java b/src/test/java/de/tla2b/util/TestTypeChecker.java
new file mode 100644
index 0000000000000000000000000000000000000000..f858a8646930b01aa8f8f65de3f0809b6efd370c
--- /dev/null
+++ b/src/test/java/de/tla2b/util/TestTypeChecker.java
@@ -0,0 +1,127 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.util;
+
+import java.util.Hashtable;
+
+import de.tla2b.analysis.TypeChecker;
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.global.TranslationGlobals;
+import de.tla2b.translation.Tla2BTranslator;
+import de.tla2b.types.TLAType;
+
+import tla2sany.semantic.FormalParamNode;
+import tla2sany.semantic.ModuleNode;
+import tla2sany.semantic.OpDeclNode;
+import tla2sany.semantic.OpDefNode;
+
+public class TestTypeChecker implements TranslationGlobals {
+
+	public ModuleNode moduleNode;
+	public final int toolId = 5;
+	private Hashtable<String, TLAType> constants;
+	private Hashtable<String, TLAType> variables;
+	private Hashtable<String, DefCon> definitions;
+
+	public TestTypeChecker() {
+		constants = new Hashtable<String, TLAType>();
+		variables = new Hashtable<String, TLAType>();
+		definitions = new Hashtable<String, DefCon>();
+	}
+
+	public void startTest(String moduleString, String configString)
+			throws FrontEndException, TLA2BException {
+		Tla2BTranslator translator = new Tla2BTranslator();
+		translator.startTest(moduleString, configString);
+		translator.translate();
+		moduleNode = translator.getModuleNode();
+		init();
+	}
+	
+	public void start(String moduleFileName, String configFileName)
+			throws FrontEndException, TLA2BException {
+		Tla2BTranslator translator = new Tla2BTranslator();
+		translator.start(moduleFileName, configFileName);
+		translator.translate();
+		moduleNode = translator.getModuleNode();
+		init();
+	}
+
+	private void init() {
+		for (int i = 0; i < moduleNode.getConstantDecls().length; i++) {
+			OpDeclNode con = moduleNode.getConstantDecls()[i];
+			constants.put(con.getName().toString(),
+					(TLAType) con.getToolObject(toolId));
+		}
+
+		for (int i = 0; i < moduleNode.getVariableDecls().length; i++) {
+			OpDeclNode var = moduleNode.getVariableDecls()[i];
+			variables.put(var.getName().toString(),
+					(TLAType) var.getToolObject(toolId));
+		}
+
+		for (int i = 0; i < moduleNode.getOpDefs().length; i++) {
+			OpDefNode def = moduleNode.getOpDefs()[i];
+			DefCon defCon = new DefCon((TLAType) def.getToolObject(5));
+			if (defCon.getType() == null)
+				continue;
+
+			if (STANDARD_MODULES.contains(def
+					.getOriginallyDefinedInModuleNode().getName().toString())
+					|| STANDARD_MODULES.contains(def.getSource()
+							.getOriginallyDefinedInModuleNode().getName()
+							.toString())) {
+				continue;
+			}
+
+			for (int j = 0; j < def.getParams().length; j++) {
+				FormalParamNode p = def.getParams()[j];
+				defCon.parameters.put(p.getName().toString(),
+						(TLAType) p.getToolObject(toolId));
+			}
+			definitions.put(def.getName().toString(), defCon);
+		}
+	}
+
+	
+	public String getConstantType(String conName) {
+		return constants.get(conName).toString();
+	}
+	
+	public String getVariableType(String varName){
+		return variables.get(varName).toString();
+	}
+
+	public String getDefinitionType(String defName){
+		return definitions.get(defName).getType().toString();
+	}
+
+	public String getDefinitionParamType(String defName, String paramName){
+		return definitions.get(defName).getParams().get(paramName).toString();
+	}
+
+	public class DefCon {
+		private Hashtable<String, TLAType> parameters;
+		private TLAType type;
+
+		private DefCon(TLAType t) {
+			parameters = new Hashtable<String, TLAType>();
+			type = t;
+		}
+
+		public Hashtable<String, TLAType> getParams() {
+			return parameters;
+		}
+
+		public TLAType getType() {
+			return type;
+		}
+
+		public void setType(TLAType type) {
+			this.type = type;
+		}
+	}
+}
diff --git a/src/test/java/de/tla2b/util/TestUtil.java b/src/test/java/de/tla2b/util/TestUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..d8f7b1d17b5d5a653e5359d9467b9411f072d41a
--- /dev/null
+++ b/src/test/java/de/tla2b/util/TestUtil.java
@@ -0,0 +1,149 @@
+/**
+ * @author Dominik Hansen <Dominik.Hansen at hhu.de>
+ **/
+
+package de.tla2b.util;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+
+import de.be4.classicalb.core.parser.BParser;
+import de.be4.classicalb.core.parser.exceptions.BException;
+import de.be4.classicalb.core.parser.node.Node;
+import de.be4.classicalb.core.parser.node.Start;
+import de.tla2b.exceptions.FrontEndException;
+import de.tla2b.exceptions.TLA2BException;
+import de.tla2b.translation.Tla2BTranslator;
+import de.tla2bAst.Translator;
+import tla2sany.semantic.AbortException;
+import util.FileUtil;
+import util.ToolIO;
+
+public class TestUtil {
+
+	public static StringBuilder translateString(String moduleString)
+			throws FrontEndException, TLA2BException, AbortException {
+		ToolIO.setMode(ToolIO.TOOL);
+		ToolIO.reset();
+		Tla2BTranslator translator = new Tla2BTranslator();
+		translator.startTest(moduleString, null);
+		return translator.translate();
+	}
+	
+	public static void compare(String bMachine, String tlaModule) throws BException, TLA2BException{
+		ToolIO.setMode(ToolIO.TOOL);
+		String expected = getBTreeofMachineString(bMachine);
+		System.out.println(expected);
+		
+		Translator trans = new Translator(tlaModule, null, 1);
+		Node resultNode = trans.translate();
+		String result = getTreeAsString(resultNode);
+		System.out.println(result);
+		assertEquals(expected, result);
+	}
+	
+	public static String getTreeAsString(Node node){
+		final Ast2String ast2String = new Ast2String();
+		node.apply(ast2String);
+		return ast2String.toString();
+	}
+	
+
+	public static StringBuilder translateString(String moduleString, String configString)
+			throws FrontEndException, TLA2BException, AbortException {
+		ToolIO.setMode(ToolIO.TOOL);
+		ToolIO.reset();
+		Tla2BTranslator translator = new Tla2BTranslator();
+		translator.startTest(moduleString, configString);
+		return translator.translate();
+	}
+	
+	
+	public static StringBuilder translate(String moduleFileName)
+			throws FrontEndException, TLA2BException, AbortException {
+		ToolIO.setMode(ToolIO.TOOL);
+		ToolIO.reset();
+		moduleFileName = moduleFileName.replace('/', FileUtil.separatorChar);
+		Tla2BTranslator translator = new Tla2BTranslator();
+		translator.start(moduleFileName, null);
+		StringBuilder res = translator.translate();
+		return res;
+	}
+	
+	public static StringBuilder translate(String moduleFileName, String configFileName)
+			throws FrontEndException, TLA2BException {
+		ToolIO.setMode(ToolIO.TOOL);
+		ToolIO.reset();
+		moduleFileName = moduleFileName.replace('/', FileUtil.separatorChar);
+		configFileName = configFileName.replace('/', FileUtil.separatorChar);
+		Tla2BTranslator translator = new Tla2BTranslator();
+		translator.start(moduleFileName, configFileName);
+		return translator.translate();
+	}
+	
+	
+	public static TestTypeChecker typeCheckString(String moduleString) throws FrontEndException, TLA2BException{
+		ToolIO.setMode(ToolIO.TOOL);
+		ToolIO.reset();
+		TestTypeChecker testTypeChecker = new TestTypeChecker();
+		testTypeChecker.startTest(moduleString, null);
+		return testTypeChecker;
+		
+	}
+	
+	public static TestTypeChecker typeCheckString(String moduleString, String configString) throws FrontEndException, TLA2BException{
+		ToolIO.setMode(ToolIO.TOOL);
+		ToolIO.reset();
+		TestTypeChecker testTypeChecker = new TestTypeChecker();
+		testTypeChecker.startTest(moduleString, configString);
+		return testTypeChecker;
+	}
+	
+	public static TestTypeChecker typeCheck(String moduleFileName) throws FrontEndException, TLA2BException{
+		ToolIO.setMode(ToolIO.TOOL);
+		ToolIO.reset();
+		moduleFileName = moduleFileName.replace('/', FileUtil.separatorChar);
+		TestTypeChecker testTypeChecker = new TestTypeChecker();
+		testTypeChecker.start(moduleFileName, null);
+		return testTypeChecker;
+	}
+	
+	public static TestTypeChecker typeCheck(String moduleFileName, String configFileName) throws FrontEndException, TLA2BException{
+		ToolIO.setMode(ToolIO.TOOL);
+		ToolIO.reset();
+		moduleFileName = moduleFileName.replace('/', FileUtil.separatorChar);
+		configFileName = configFileName.replace('/', FileUtil.separatorChar);
+		TestTypeChecker testTypeChecker = new TestTypeChecker();
+		testTypeChecker.start(moduleFileName, configFileName);
+		return testTypeChecker;
+	}
+
+
+	public static String fileToString(String fileName) throws IOException {
+		StringBuilder res = new StringBuilder();
+		BufferedReader in = new BufferedReader(new FileReader(fileName));
+		String str;
+		while ((str = in.readLine()) != null) {
+			res.append(str + "\n");
+		}
+		in.close();
+		return res.toString();
+	}
+
+
+	public static String getBTreeofMachineString(final String testMachine)
+			throws BException {
+		final BParser parser = new BParser("testcase");
+		final Start startNode = parser.parse(testMachine, false);
+	
+		final Ast2String ast2String = new Ast2String();
+		startNode.apply(ast2String);
+		final String string = ast2String.toString();
+		return string;
+	}
+	
+	
+}
diff --git a/src/test/resources/examples/AsynchInterface/AsynchInterface.cfg b/src/test/resources/examples/AsynchInterface/AsynchInterface.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..4a45c4c6914fb06480b45c400ebd4c445ce8ae93
--- /dev/null
+++ b/src/test/resources/examples/AsynchInterface/AsynchInterface.cfg
@@ -0,0 +1,3 @@
+INIT Init
+NEXT Next
+INVARIANTS TypeInvariant
\ No newline at end of file
diff --git a/src/test/resources/examples/AsynchInterface/AsynchInterface.mch b/src/test/resources/examples/AsynchInterface/AsynchInterface.mch
new file mode 100644
index 0000000000000000000000000000000000000000..b15fa61cbb52d4a8ff4113e35f1fe357d841d675
--- /dev/null
+++ b/src/test/resources/examples/AsynchInterface/AsynchInterface.mch
@@ -0,0 +1,33 @@
+MACHINE AsynchInterface
+ABSTRACT_CONSTANTS Data
+PROPERTIES
+ Data : POW(INTEGER)
+ & Data = 0 .. 7
+DEFINITIONS
+ TypeInvariant == val : Data
+	 & rdy : {0, 1}
+	 & ack : {0, 1}
+VARIABLES val, rdy, ack
+INVARIANT
+ val : INTEGER
+ & rdy : INTEGER
+ & ack : INTEGER
+ & TypeInvariant
+INITIALISATION
+ val, rdy, ack:(val : Data
+ & rdy : {0, 1}
+ & ack = rdy)
+OPERATIONS
+ Snd_Op = ANY val_n, rdy_n
+	WHERE val_n : INTEGER & rdy_n : INTEGER & rdy = ack
+	 & val_n : Data
+	 & rdy_n = 1 - rdy
+	 & TRUE = TRUE
+	THEN val, rdy := val_n, rdy_n END;
+
+ Rcv_Op = ANY ack_n
+	WHERE ack_n : INTEGER & rdy /= ack
+	 & ack_n = 1 - ack
+	 & TRUE = TRUE
+	THEN ack := ack_n END
+END
diff --git a/src/test/resources/examples/AsynchInterface/AsynchInterface.tla b/src/test/resources/examples/AsynchInterface/AsynchInterface.tla
new file mode 100644
index 0000000000000000000000000000000000000000..3eddf863b771b07b5adfa998826363cc45a7f9ed
--- /dev/null
+++ b/src/test/resources/examples/AsynchInterface/AsynchInterface.tla
@@ -0,0 +1,25 @@
+----- MODULE AsynchInterface -----
+EXTENDS Naturals
+CONSTANTS Data
+ASSUME Data = 0..7 (* added to avoid having to give Data a value in .cfg file *)
+VARIABLES val, rdy, ack
+TypeInvariant == /\ val \in Data
+                 /\ rdy \in {0,1}
+                 /\ ack \in {0,1}
+----------------------
+Init == /\ val \in Data
+        /\ rdy \in {0,1}
+        /\ ack = rdy
+Snd  == /\ rdy=ack
+        /\ val' \in Data
+        /\ rdy' = 1-rdy
+        /\ UNCHANGED ack
+Rcv  == /\ rdy # ack
+        /\ ack' = 1-ack
+        /\ UNCHANGED <<val,rdy>>
+Next == Snd \/ Rcv
+Spec == Init /\ [] [Next]_<<val,rdy,ack>>
+----------------------
+THEOREM Spec => [] TypeInvariant  (* this defines the invariant; not yet automatically detected by TLA2B *)
+=======================
+
diff --git a/src/test/resources/examples/Channel/Channel.cfg b/src/test/resources/examples/Channel/Channel.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..dbaae4075b4171db16d9b608eba70fe121c7e4fb
--- /dev/null
+++ b/src/test/resources/examples/Channel/Channel.cfg
@@ -0,0 +1,5 @@
+CONSTANTS
+Data = {d1,d2}
+INIT Init
+NEXT Next
+INVARIANTS TypeInvariant
\ No newline at end of file
diff --git a/src/test/resources/examples/Channel/Channel.mch b/src/test/resources/examples/Channel/Channel.mch
new file mode 100644
index 0000000000000000000000000000000000000000..99d83b20501aba325a5dbe7a72343ac5b96bc50f
--- /dev/null
+++ b/src/test/resources/examples/Channel/Channel.mch
@@ -0,0 +1,30 @@
+MACHINE Channel
+SETS
+ ENUM1 = {d1, d2}
+ABSTRACT_CONSTANTS Data
+PROPERTIES
+ Data = ENUM1
+DEFINITIONS
+ TypeInvariant == chan : struct(val : Data,rdy : {0, 1},ack : {0, 1});
+
+ Send(d) == chan'rdy = chan'ack
+	 & chan_n = rec(val : d, rdy : 1 - chan'rdy, ack : chan'ack)
+VARIABLES chan
+INVARIANT
+ chan : struct(val:ENUM1,rdy:INTEGER,ack:INTEGER)
+ & TypeInvariant
+INITIALISATION
+ chan:(TypeInvariant
+ & chan'ack = chan'rdy)
+OPERATIONS
+ Send_Op(d) = ANY chan_n
+	WHERE d : Data & 
+	 chan_n : struct(val:ENUM1,rdy:INTEGER,ack:INTEGER) & Send(d)
+	THEN chan := chan_n END;
+
+ Rcv_Op = ANY chan_n
+	WHERE chan_n : struct(val:ENUM1,rdy:INTEGER,ack:INTEGER) & chan'rdy /= chan'ack
+	 & chan_n = rec(val : chan'val, rdy : chan'rdy, ack : 1 - chan'ack)
+	THEN chan := chan_n END
+END
+
diff --git a/src/test/resources/examples/Channel/Channel.tla b/src/test/resources/examples/Channel/Channel.tla
new file mode 100644
index 0000000000000000000000000000000000000000..3ac12470f4efb0ff91f590f61dee2f0db5b74673
--- /dev/null
+++ b/src/test/resources/examples/Channel/Channel.tla
@@ -0,0 +1,20 @@
+-------------------------- MODULE Channel -----------------------------
+EXTENDS Naturals
+CONSTANT Data
+VARIABLE chan
+
+TypeInvariant  ==  chan \in [val : Data,  rdy : {0, 1},  ack : {0, 1}]
+-----------------------------------------------------------------------
+Init  ==  /\ TypeInvariant
+          /\ chan.ack = chan.rdy 
+Send(d) ==  /\ chan.rdy = chan.ack
+            /\ chan' = [chan EXCEPT !.val = d, !.rdy = 1 - @]
+
+Rcv     ==  /\ chan.rdy # chan.ack
+            /\ chan' = [chan EXCEPT !.ack = 1 - @]
+            
+Next  ==  (\E d \in Data : Send(d)) \/ Rcv
+Spec == Init /\ [] [Next]_<<chan>>
+----------------------
+THEOREM Spec => [] TypeInvariant  (* this defines the invariant; not yet automatically detected by TLA2B *)
+=======================================================================
diff --git a/src/test/resources/examples/Club/Club.cfg b/src/test/resources/examples/Club/Club.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..2f57580b8191246f34e4691675619b0af85f3b86
--- /dev/null
+++ b/src/test/resources/examples/Club/Club.cfg
@@ -0,0 +1,4 @@
+INIT Init
+NEXT Next
+CONSTANTS
+NAME = {n1,n2,n3}
diff --git a/src/test/resources/examples/Club/Club.mch b/src/test/resources/examples/Club/Club.mch
new file mode 100644
index 0000000000000000000000000000000000000000..d81f1bfa5706cc598fbc32b0e9377960d673800b
--- /dev/null
+++ b/src/test/resources/examples/Club/Club.mch
@@ -0,0 +1,39 @@
+MACHINE Club
+SETS
+ ENUM1 = {n1, n2, n3}
+ABSTRACT_CONSTANTS capacity, NAME, total
+PROPERTIES
+ capacity : INTEGER
+ & NAME = ENUM1
+ & total : INTEGER
+ & capacity : NATURAL & capacity = 2
+ & card(NAME) > capacity
+ & total : NATURAL & total > 2
+DEFINITIONS
+ join_queue(nn) == nn /: member & nn /: waiting & card(waiting) < total & waiting_n = waiting \/ {nn} & TRUE = TRUE;
+
+ join(nn) == nn : waiting & card(member) < capacity & member_n = member \/ {nn} & waiting_n = waiting - {nn};
+
+ remove(nn) == nn : member & member_n = member - {nn} & TRUE = TRUE
+VARIABLES member, waiting
+INVARIANT
+ member : POW(ENUM1)
+ & waiting : POW(ENUM1)
+INITIALISATION
+ member, waiting:(member = {} & waiting = {})
+OPERATIONS
+ join_queue_Op(nn) = ANY waiting_n
+	WHERE nn : NAME & 
+	 waiting_n : POW(ENUM1) & join_queue(nn)
+	THEN waiting := waiting_n END;
+
+ join_Op(nn) = ANY member_n, waiting_n
+	WHERE nn : NAME & 
+	 member_n : POW(ENUM1) & waiting_n : POW(ENUM1) & join(nn)
+	THEN member, waiting := member_n, waiting_n END;
+
+ remove_Op(nn) = ANY member_n
+	WHERE nn : NAME & 
+	 member_n : POW(ENUM1) & remove(nn)
+	THEN member := member_n END
+END
diff --git a/src/test/resources/examples/Club/Club.tla b/src/test/resources/examples/Club/Club.tla
new file mode 100644
index 0000000000000000000000000000000000000000..905b0ac493bf0e07438e80ce03c0f457ed0046a0
--- /dev/null
+++ b/src/test/resources/examples/Club/Club.tla
@@ -0,0 +1,31 @@
+------------------------------ MODULE Club ------------------------------- 
+EXTENDS Naturals, FiniteSets
+CONSTANTS capacity, NAME, total
+ASSUME capacity \in Nat /\ capacity = 2
+ASSUME Cardinality(NAME) > capacity
+ASSUME total \in Nat /\ total > 2
+
+VARIABLES member, waiting
+----------------------------------------------------------------------------
+Inv == member \subseteq NAME /\ waiting \subseteq NAME
+	/\ member \cup waiting = {}
+	/\ Cardinality(member) \leq 4096
+	/\ Cardinality(waiting) \leq total
+
+Init == member = {} /\ waiting = {}
+----------------------------------------------------------------------------
+
+join_queue(nn) == nn \notin member /\ nn \notin waiting 
+	/\ Cardinality(waiting) < total /\ waiting' = waiting \cup {nn}
+	/\ UNCHANGED member
+
+join(nn) == nn \in waiting /\ Cardinality(member) < capacity
+	/\ member' = member \cup {nn} /\ waiting' = waiting\{nn} 
+
+remove(nn) == nn \in member /\ member' = member\{nn} /\ UNCHANGED waiting
+
+
+Next == \/ (\E nn \in NAME: join_queue(nn))
+	\/ (\E nn \in NAME: join(nn))
+	\/ (\E nn \in NAME: remove(nn))
+=============================================================================
diff --git a/src/test/resources/examples/Counter/Counter.cfg b/src/test/resources/examples/Counter/Counter.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..c2c935a8c9abab6cadd624ad796e68ced5cf767a
--- /dev/null
+++ b/src/test/resources/examples/Counter/Counter.cfg
@@ -0,0 +1,4 @@
+INIT Init
+NEXT Next
+CONSTANTS
+k = 10
\ No newline at end of file
diff --git a/src/test/resources/examples/Counter/Counter.mch b/src/test/resources/examples/Counter/Counter.mch
new file mode 100644
index 0000000000000000000000000000000000000000..4e14b6b3049b1b69b6ae420875357230ed082f72
--- /dev/null
+++ b/src/test/resources/examples/Counter/Counter.mch
@@ -0,0 +1,18 @@
+MACHINE Counter
+ABSTRACT_CONSTANTS k
+PROPERTIES
+ k = 10
+VARIABLES a
+INVARIANT
+ a : INTEGER
+INITIALISATION
+ a:(a = 0)
+OPERATIONS
+ Inc_Op = ANY a_n
+	WHERE a_n : INTEGER & a < k & a_n = a + 1
+	THEN a := a_n END;
+
+ Dec_Op = ANY a_n
+	WHERE a_n : INTEGER & a > 0 & a_n = a - 1
+	THEN a := a_n END
+END
diff --git a/src/test/resources/examples/Counter/Counter.tla b/src/test/resources/examples/Counter/Counter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..42bd73e75f3091951825706e13424488b4433a81
--- /dev/null
+++ b/src/test/resources/examples/Counter/Counter.tla
@@ -0,0 +1,13 @@
+------------------------------ MODULE Counter ------------------------------- 
+EXTENDS Naturals
+CONSTANTS k
+
+VARIABLES a
+
+Init == a = 0
+
+Inc ==  a < k /\ a' = a+1
+Dec == a > 0 /\ a' = a-1
+Next == Inc \/ Dec
+
+=============================================================================
\ No newline at end of file
diff --git a/src/test/resources/examples/DefCapture/DefCapture.mch b/src/test/resources/examples/DefCapture/DefCapture.mch
new file mode 100644
index 0000000000000000000000000000000000000000..643c7fff3b40fe6be59a0be8c867eb6c7666f23d
--- /dev/null
+++ b/src/test/resources/examples/DefCapture/DefCapture.mch
@@ -0,0 +1,10 @@
+MACHINE DefCapture
+PROPERTIES
+ Double(2)
+ & NotDouble(3)
+ & {x|x : {2, 3} & NotDouble(x)} = {3}
+DEFINITIONS
+ Double(y) == #x_1.(x_1 : 1 .. 10 & x_1 + x_1 = y);
+
+ NotDouble(y) == not(Double(y))
+END
diff --git a/src/test/resources/examples/DefCapture/DefCapture.tla b/src/test/resources/examples/DefCapture/DefCapture.tla
new file mode 100644
index 0000000000000000000000000000000000000000..7aa53cc4b90354d9c2be1b201caa5df3b9ae503d
--- /dev/null
+++ b/src/test/resources/examples/DefCapture/DefCapture.tla
@@ -0,0 +1,15 @@
+-------------------------------- MODULE DefCapture --------------------------------
+EXTENDS Naturals
+
+Double(y) == \E x \in 1..10 :(x+x=y)
+
+NotDouble(y) == \neg Double(y)
+
+ASSUME Double(2)
+
+ASSUME NotDouble(3)
+
+ASSUME {x \in {2,3} : NotDouble(x)} = {3}
+
+=======================
+
diff --git a/src/test/resources/examples/DieHard/DieHard.cfg b/src/test/resources/examples/DieHard/DieHard.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..08aa2418b9aa2ed935c9a2eff7293c55a2b15681
--- /dev/null
+++ b/src/test/resources/examples/DieHard/DieHard.cfg
@@ -0,0 +1,3 @@
+INIT Init
+NEXT Next
+INVARIANTS TypeOK NotSolved
diff --git a/src/test/resources/examples/DieHard/DieHard.mch b/src/test/resources/examples/DieHard/DieHard.mch
new file mode 100644
index 0000000000000000000000000000000000000000..b65ad6e09ef0c59c6f6c8a7b1dffadfd49115de6
--- /dev/null
+++ b/src/test/resources/examples/DieHard/DieHard.mch
@@ -0,0 +1,49 @@
+MACHINE DieHard
+DEFINITIONS
+ IF_THEN_ELSE(P, a, b) == (%t_.(t_ = TRUE & P = TRUE | a )\/%t_.(t_= TRUE & not(P= TRUE) | b ))(TRUE);
+ TypeOK == small : 0 .. 3
+	 & big : 0 .. 5;
+
+ Min(m,n) == IF_THEN_ELSE(bool(m < n), m, n);
+
+ NotSolved == big /= 4
+VARIABLES big, small
+INVARIANT
+ big : INTEGER
+ & small : INTEGER
+ & TypeOK
+ & NotSolved
+INITIALISATION
+ big, small:(big = 0
+ & small = 0)
+OPERATIONS
+ FillSmallJug_Op = ANY big_n, small_n
+	WHERE big_n : INTEGER & small_n : INTEGER & small_n = 3
+	 & big_n = big
+	THEN big, small := big_n, small_n END;
+
+ FillBigJug_Op = ANY big_n, small_n
+	WHERE big_n : INTEGER & small_n : INTEGER & big_n = 5
+	 & small_n = small
+	THEN big, small := big_n, small_n END;
+
+ EmptySmallJug_Op = ANY big_n, small_n
+	WHERE big_n : INTEGER & small_n : INTEGER & small_n = 0
+	 & big_n = big
+	THEN big, small := big_n, small_n END;
+
+ EmptyBigJug_Op = ANY big_n, small_n
+	WHERE big_n : INTEGER & small_n : INTEGER & big_n = 0
+	 & small_n = small
+	THEN big, small := big_n, small_n END;
+
+ SmallToBig_Op = ANY big_n, small_n
+	WHERE big_n : INTEGER & small_n : INTEGER & big_n = Min(big + small, 5)
+	 & small_n = small - (big_n - big)
+	THEN big, small := big_n, small_n END;
+
+ BigToSmall_Op = ANY big_n, small_n
+	WHERE big_n : INTEGER & small_n : INTEGER & small_n = Min(big + small, 3)
+	 & big_n = big - (small_n - small)
+	THEN big, small := big_n, small_n END
+END
diff --git a/src/test/resources/examples/DieHard/DieHard.tla b/src/test/resources/examples/DieHard/DieHard.tla
new file mode 100644
index 0000000000000000000000000000000000000000..0447532ccd6c21e6d42c16ce99b31b63cdea0b20
--- /dev/null
+++ b/src/test/resources/examples/DieHard/DieHard.tla
@@ -0,0 +1,129 @@
+------------------------------ MODULE DieHard ------------------------------- 
+(***************************************************************************)
+(* In the movie Die Hard 3, the heros must obtain exactly 4 gallons of     *)
+(* water using a 5 gallon jug, a 3 gallon jug, and a water faucet.  Our    *)
+(* goal: to get TLC to solve the problem for us.                           *)
+(*                                                                         *)
+(* First, we write a spec that describes all allowable behaviors of our    *)
+(* heros.                                                                  *)
+(***************************************************************************)
+EXTENDS Naturals
+  (*************************************************************************)
+  (* This statement imports the definitions of the ordinary operators on   *)
+  (* natural numbers, such as +.                                           *)
+  (*************************************************************************)
+  
+(***************************************************************************)
+(* We next declare the specification's variables.                          *)
+(***************************************************************************)
+VARIABLES big,   \* The number of gallons of water in the 5 gallon jug.
+          small  \* The number of gallons of water in the 3 gallon jug.
+
+
+(***************************************************************************)
+(* We now define TypeOK to be the type invariant, asserting that the value *)
+(* of each variable is an element of the appropriate set.  A type          *)
+(* invariant like this is not part of the specification, but it's          *)
+(* generally a good idea to include it because it helps the reader         *)
+(* understand the spec.  Moreover, having TLC check that it is an          *)
+(* invariant of the spec catches errors that, in a typed language, are     *)
+(* caught by type checking.                                                *)
+(*                                                                         *)
+(* Note: TLA+ uses the convention that a list of formulas bulleted by /\   *)
+(* or \/ denotes the conjunction or disjunction of those formulas.         *)
+(* Indentation of subitems is significant, allowing one to eliminate lots  *)
+(* of parentheses.  This makes a large formula much easier to read.        *)
+(* However, it does mean that you have to be careful with your indentation.*)
+(***************************************************************************)
+TypeOK == /\ small \in 0..3 
+          /\ big   \in 0..5
+
+
+(***************************************************************************)
+(* Now we define of the initial predicate, that specifies the initial      *)
+(* values of the variables.  I like to name this predicate Init, but the   *)
+(* name doesn't matter.                                                    *)
+(***************************************************************************)
+Init == /\ big = 0 
+        /\ small = 0
+
+(***************************************************************************)
+(* Now we define the actions that our hero can perform.  There are three   *)
+(* things they can do:                                                     *)
+(*                                                                         *)
+(*   - Pour water from the faucet into a jug.                              *)
+(*                                                                         *)
+(*   - Pour water from a jug onto the ground.                              *)
+(*                                                                         *)
+(*   - Pour water from one jug into another                                *)
+(*                                                                         *)
+(* We now consider the first two.  Since the jugs are not calibrated,      *)
+(* partially filling or partially emptying a jug accomplishes nothing.     *)
+(* So, the first two possibilities yield the following four possible       *)
+(* actions.                                                                *)
+(***************************************************************************)
+FillSmallJug  == /\ small' = 3 
+                 /\ big' = big
+
+FillBigJug    == /\ big' = 5 
+                 /\ small' = small
+
+EmptySmallJug == /\ small' = 0 
+                 /\ big' = big
+
+EmptyBigJug   == /\ big' = 0 
+                 /\ small' = small
+
+(***************************************************************************)
+(* We now consider pouring water from one jug into another.  Again, since  *)
+(* the jugs are not callibrated, when pouring from jug A to jug B, it      *)
+(* makes sense only to either fill B or empty A. And there's no point in   *)
+(* emptying A if this will cause B to overflow, since that could be        *)
+(* accomplished by the two actions of first filling B and then emptying A. *)
+(* So, pouring water from A to B leaves B with the lesser of (i) the water *)
+(* contained in both jugs and (ii) the volume of B. To express this        *)
+(* mathematically, we first define Min(m,n) to equal the minimum of the    *)
+(* numbers m and n.                                                        *)
+(***************************************************************************)
+Min(m,n) == IF m < n THEN m ELSE n
+
+(***************************************************************************)
+(* Now we define the last two pouring actions.  From the observation       *)
+(* above, these definitions should be clear.                               *)
+(***************************************************************************)
+SmallToBig == /\ big'   = Min(big + small, 5)
+              /\ small' = small - (big' - big)
+
+BigToSmall == /\ small' = Min(big + small, 3) 
+              /\ big'   = big - (small' - small)
+
+(***************************************************************************)
+(* We define the next-state relation, which I like to call Next.  A Next   *)
+(* step is a step of one of the six actions defined above.  Hence, Next is *)
+(* the disjunction of those actions.                                       *)
+(***************************************************************************)
+Next ==  \/ FillSmallJug 
+         \/ FillBigJug    
+         \/ EmptySmallJug 
+         \/ EmptyBigJug    
+         \/ SmallToBig    
+         \/ BigToSmall    
+
+-----------------------------------------------------------------------------
+
+(***************************************************************************)
+(* Remember that our heros must measure out 4 gallons of water.            *)
+(* Obviously, those 4 gallons must be in the 5 gallon jug.  So, they have  *)
+(* solved their problem when they reach a state with big = 4.  So, we      *)
+(* define NotSolved to be the predicate asserting that big # 4.            *)
+(***************************************************************************)
+NotSolved == big # 4
+
+(***************************************************************************)
+(* We find a solution by having TLC check if NotSolved is an invariant,    *)
+(* which will cause it to print out an "error trace" consisting of a       *)
+(* behavior ending in a states where NotSolved is false.  Such a           *)
+(* behavior is the desired solution.  (Because TLC uses a breadth-first    *)
+(* search, it will find the shortest solution.)                            *)
+(***************************************************************************)
+=============================================================================
diff --git a/src/test/resources/examples/DieHard/DieHarder.cfg b/src/test/resources/examples/DieHard/DieHarder.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..7d9d78bce48c7e2a77fb26d922f50cb56aae20c5
--- /dev/null
+++ b/src/test/resources/examples/DieHard/DieHarder.cfg
@@ -0,0 +1,7 @@
+INIT Init
+NEXT Next
+INVARIANT NotSolved
+CONSTANTS
+Goal = 4
+Jug <- MCJug
+Capacity <- MCCapacity
\ No newline at end of file
diff --git a/src/test/resources/examples/DieHard/DieHarder.mch b/src/test/resources/examples/DieHard/DieHarder.mch
new file mode 100644
index 0000000000000000000000000000000000000000..fbb17293bacc05ea51b0941f0cad06aacebce1c8
--- /dev/null
+++ b/src/test/resources/examples/DieHard/DieHarder.mch
@@ -0,0 +1,44 @@
+MACHINE DieHarder
+ABSTRACT_CONSTANTS Goal
+PROPERTIES
+ Goal = 4
+ & MCCapacity : MCJug --> {n|n : NATURAL & n > 0}
+ & Goal : NATURAL
+DEFINITIONS
+ IF_THEN_ELSE(P, a, b) == (%t_.(t_ = TRUE & P = TRUE | a )\/%t_.(t_= TRUE & not(P= TRUE) | b ))(TRUE);
+ MCJug == {"j1", "j2"};
+
+ MCCapacity == %j_1.(j_1 : MCJug| (%t_.(t_ = 0 & j_1 = "j1" | 3) \/ %t_.(t_ = 0 & j_1 = "j2" | 5))(0));
+
+ Min(m,n) == IF_THEN_ELSE(bool(m < n), m, n);
+
+ FillJug(j) == contents_n = contents <+ {j |-> MCCapacity(j)};
+
+ EmptyJug(j) == contents_n = contents <+ {j |-> 0};
+
+ amountPoured(j, k) == Min(contents(j), MCCapacity(k) - contents(k));
+ JugToJug(j,k) == contents_n = contents <+ {j |-> contents(j) - amountPoured(j, k), k |-> contents(k) + amountPoured(j, k)};
+
+ NotSolved == !j.(j : MCJug => contents(j) /= Goal)
+VARIABLES contents
+INVARIANT
+ contents : POW(STRING*INTEGER)
+ & NotSolved
+INITIALISATION
+ contents:(contents = %j.(j : MCJug| 0))
+OPERATIONS
+ FillJug_Op(j) = ANY contents_n
+	WHERE j : MCJug & 
+	 contents_n : POW(STRING*INTEGER) & FillJug(j)
+	THEN contents := contents_n END;
+
+ EmptyJug_Op(j) = ANY contents_n
+	WHERE j : MCJug & 
+	 contents_n : POW(STRING*INTEGER) & EmptyJug(j)
+	THEN contents := contents_n END;
+
+ JugToJug_Op(j, k) = ANY contents_n
+	WHERE j : MCJug & k : MCJug - {j} & 
+	 contents_n : POW(STRING*INTEGER) & JugToJug(j, k)
+	THEN contents := contents_n END
+END
\ No newline at end of file
diff --git a/src/test/resources/examples/DieHard/DieHarder.tla b/src/test/resources/examples/DieHard/DieHarder.tla
new file mode 100644
index 0000000000000000000000000000000000000000..27f329aff260fb7bf990765ef97afc4b7bd6cb78
--- /dev/null
+++ b/src/test/resources/examples/DieHard/DieHarder.tla
@@ -0,0 +1,104 @@
+----------------------------- MODULE DieHarder ------------------------------ 
+(***************************************************************************)
+(* We now generalize the problem from Die Hard into one with an arbitrary  *)
+(* number of jugs, each holding some specified amount of water.            *)
+(***************************************************************************)
+EXTENDS Naturals
+
+(***************************************************************************)
+(* We now declare two constant parameters.                                 *)
+(***************************************************************************)
+
+CONSTANT Jug,      \* The set of all jugs.
+         Capacity, \* A function, where Capacity[j] is the capacity of jug j.
+         Goal      \* The quantity of water our heros must measure.
+(***************************************************************************)
+(* We make an assumption about these constants--namely, that Capacity is a *)
+(* function from jugs to positive integers, and Goal is a natural number.  *)
+(***************************************************************************)
+ASSUME /\ Capacity \in [Jug -> {n \in Nat : n > 0}]
+       /\ Goal \in Nat
+
+
+(***************************************************************************)
+(* Configfile replacements						   *)
+(* Jug      <- MCJug 							   *)
+(* Capacity <- MCCapacity 						   *)
+MCJug == {"j1", "j2"}
+ 
+MCCapacity ==
+  [j \in MCJug |-> CASE j = "j1" -> 3
+                     [] j = "j2" -> 5 ]
+(***************************************************************************)
+(* We are going to need the Min operator again, so let's define it here.   *)
+(* (I prefer defining constant operators like this in the part of the      *)
+(* spec where constants are declared.                                      *)
+(***************************************************************************)
+Min(m,n) == IF m < n THEN m ELSE n
+-----------------------------------------------------------------------------
+(***************************************************************************)
+(* We declare the specification's single variable and define its type      *)
+(* invariant and initial predicate.                                        *)
+(***************************************************************************)
+VARIABLE contents \* contents[j] is the amount of water in jug j
+
+TypeOK == contents \in [Jug -> Nat]
+
+Init == contents = [j \in Jug |-> 0]
+-----------------------------------------------------------------------------
+(***************************************************************************)
+(* Now we define the actions that can be performed.  They are the obvious  *)
+(* generalizations of the ones from the simple DieHard spec.  First come   *)
+(* the actions of filling and emptying jug j, then the action of           *)
+(* pouring water from jug j to jug k.                                      *)
+(*                                                                         *)
+(* Note: The definitions use the TLA+ notation                             *)
+(*                                                                         *)
+(*          [f EXCEPT ![c]=e]                                              *)
+(*                                                                         *)
+(* which is the function g that is the same as f except g[c]=e.  In the    *)
+(* expression e, the symbol @ stands for f[c].  This has the more general  *)
+(* form                                                                    *)
+(*                                                                         *)
+(*         [f EXCEPT ![c1] = e1, ... , ![ck] = ek]                         *)
+(*                                                                         *)
+(* that has the expected meaning.                                          *)
+(***************************************************************************)
+FillJug(j)  == contents' = [contents EXCEPT ![j] = Capacity[j]]
+
+EmptyJug(j) == contents' = [contents EXCEPT ![j] = 0]
+  
+JugToJug(j, k) == 
+  LET amountPoured == Min(contents[j], Capacity[k]-contents[k])
+  IN  contents' = [contents EXCEPT ![j] = @ - amountPoured,
+                                   ![k] = @ + amountPoured]
+
+(***************************************************************************)
+(* As usual, the next-state relation Next is the disjunction of all        *)
+(* possible actions, where existential quantification is a general form of *)
+(* disjunction.                                                            *)
+(***************************************************************************)
+Next ==  \E j \in Jug : \/ FillJug(j)
+                        \/ EmptyJug(j)
+                        \/ \E k \in Jug \ {j} : JugToJug(j, k)
+
+(***************************************************************************)
+(* We define the formula Spec to be the complete specification, asserting  *)
+(* of a behavior that it begins in a state satisfying Init, and that every *)
+(* step either satisfies Next or else leaves contents unchanged.           *)
+(***************************************************************************)
+Spec == Init /\ [][Next]_contents
+-----------------------------------------------------------------------------
+(***************************************************************************)
+(* We define NotSolved to be true of a state iff no jug contains Goal      *)
+(* gallons of water.                                                       *)
+(***************************************************************************)
+NotSolved == \A j \in Jug : contents[j] # Goal
+
+(***************************************************************************)
+(* We find a solution by having TLC check if NotSolved is an invariant,    *)
+(* which will cause it to print out an "error trace" consisting of a       *)
+(* behavior ending in a states where NotSolved is false.  Such a           *)
+(* behavior is the desired solution.                                       *)
+(***************************************************************************)
+=============================================================================
diff --git a/src/test/resources/examples/Doors/Doors.cfg b/src/test/resources/examples/Doors/Doors.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..3cae8360b34554c2ab9e1645c5118898db10cb37
--- /dev/null
+++ b/src/test/resources/examples/Doors/Doors.cfg
@@ -0,0 +1,8 @@
+INIT Init
+NEXT Next
+CONSTANTS
+DOOR = {D1,D2,D3}
+open = open
+closed = closed
+INVARIANT
+Inv
\ No newline at end of file
diff --git a/src/test/resources/examples/Doors/Doors.mch b/src/test/resources/examples/Doors/Doors.mch
new file mode 100644
index 0000000000000000000000000000000000000000..c515edcb75be9b66375a7cbb06441b817c6d77c4
--- /dev/null
+++ b/src/test/resources/examples/Doors/Doors.mch
@@ -0,0 +1,31 @@
+MACHINE Doors
+SETS
+ ENUM1 = {D1, D2, D3}; ENUM2 = {open, closed}
+ABSTRACT_CONSTANTS DOOR, POSITION
+PROPERTIES
+ DOOR = ENUM1
+ & POSITION : POW(ENUM2)
+ & POSITION = {open, closed}
+DEFINITIONS
+ Inv == position : DOOR --> POSITION;
+
+ opening(dd) == dd : DOOR & position_n = position <+ {dd |-> open};
+
+ closedoor(dd) == dd : DOOR & position_n = position <+ {dd |-> closed}
+VARIABLES position
+INVARIANT
+ position : POW(ENUM1*ENUM2)
+ & Inv
+INITIALISATION
+ position:(position = %x.(x : DOOR| closed))
+OPERATIONS
+ opening_Op(dd) = ANY position_n
+	WHERE dd : DOOR & 
+	 position_n : POW(ENUM1*ENUM2) & opening(dd)
+	THEN position := position_n END;
+
+ closedoor_Op(dd) = ANY position_n
+	WHERE dd : DOOR & 
+	 position_n : POW(ENUM1*ENUM2) & closedoor(dd)
+	THEN position := position_n END
+END
diff --git a/src/test/resources/examples/Doors/Doors.tla b/src/test/resources/examples/Doors/Doors.tla
new file mode 100644
index 0000000000000000000000000000000000000000..4c42a68c8654ec445d3ee7ab747ff299e002eac3
--- /dev/null
+++ b/src/test/resources/examples/Doors/Doors.tla
@@ -0,0 +1,15 @@
+------------------------------ MODULE Doors ------------------------------- 
+EXTENDS Naturals
+CONSTANTS DOOR, POSITION, open, closed
+ASSUME POSITION = {open,closed}
+VARIABLES position
+
+Inv == position \in [DOOR -> POSITION]
+Init == position = [x \in DOOR |-> closed] 
+
+opening(dd)== dd \in DOOR /\ position' = [position EXCEPT ![dd] = open ]
+
+closedoor(dd)== dd \in DOOR /\  position' =  [position EXCEPT ![dd] = closed ]
+
+Next == \E dd \in DOOR : opening(dd) \/ closedoor(dd)
+=============================================================================
\ No newline at end of file
diff --git a/src/test/resources/examples/FastPaxos/FastPaxos.tla b/src/test/resources/examples/FastPaxos/FastPaxos.tla
new file mode 100644
index 0000000000000000000000000000000000000000..f2494dffbae85a751c3936fa54f393442ff9c00b
--- /dev/null
+++ b/src/test/resources/examples/FastPaxos/FastPaxos.tla
@@ -0,0 +1,210 @@
+------------------------------ MODULE FastPaxos -----------------------------
+CONSTANTS PVal, Acceptor, FastNum, ClassicNum, Quorum(_), _\prec_, NextNum(_)
+
+i \preceq j == (i \prec j) \/ (i = j)
+
+Max(S) == CHOOSE i \in S : \A j \in S : j \preceq i
+
+RNum == FastNum \cup ClassicNum
+
+ASSUME 
+  /\ FastNum \cap ClassicNum = {}
+  /\ \A i, j, k \in RNum : (i \prec j) /\ (j \prec k) => (i \prec k)
+  /\ \A i \in RNum : ~(i \prec i)
+  /\ \A i, j \in RNum : (i \preceq j) \/ (j \preceq i)
+  /\ (0 \notin RNum) /\ \A i \in RNum : 0 \prec i
+  /\ \A i \in FastNum : NextNum(i) \in RNum => 
+                          ~\E j \in RNum : (i \prec j) /\ (j \prec NextNum(i))
+
+R3 ==   \A i, j \in RNum : 
+          \A Q \in Quorum(i), R \in Quorum(j) : Q \cap R # {}
+R5b ==   \A i, j \in RNum :     
+             (j \in FastNum) => \A Q \in Quorum(i), R1, R2 \in Quorum(j) : 
+                                   Q \cap R1 \cap R2 # {}
+
+ASSUME
+  /\ \A i \in RNum : Quorum(i) \subseteq SUBSET Acceptor
+  /\ R3 /\ R5b
+
+any == CHOOSE v : v \notin PVal
+
+Message ==
+       [type : {"propose"}, pval : PVal]
+  \cup [type : {"phase1a"}, rnd : RNum]
+  \cup [type : {"phase1b"}, rnd : RNum, vrnd : RNum \cup {0}, 
+         pval : PVal \cup {any}, acc : Acceptor]
+  \cup [type : {"phase2a"}, rnd : RNum, pval : PVal \cup {any}]
+  \cup [type : {"phase2b"}, rnd : RNum, pval : PVal, acc : Acceptor]
+
+
+VARIABLES rnd, vrnd, pval, sentMsg, learned
+vars == <<rnd, vrnd, pval, sentMsg, learned>>
+
+TypeOK == 
+  /\ rnd  \in [Acceptor -> RNum \cup {0}]
+  /\ vrnd \in [Acceptor -> RNum \cup {0}]
+  /\ pval \in [Acceptor -> PVal \cup {any}]
+  /\ sentMsg  \in SUBSET Message
+  /\ learned  \in SUBSET PVal
+
+Init ==
+  /\ rnd  = [a \in Acceptor |-> 0]
+  /\ vrnd = [a \in Acceptor |-> 0]
+  /\ pval = [a \in Acceptor |-> any]
+  /\ sentMsg  = {}
+  /\ learned  = {}
+-----------------------------------------------------------------------------
+Send(m) == sentMsg' = sentMsg \cup {m}
+
+Propose(v) ==  
+  /\ Send([type |-> "propose", pval |-> v])
+  /\ UNCHANGED <<rnd, vrnd, pval, learned>>
+  
+Phase1a(i) == 
+  /\ Send([type |-> "phase1a", rnd |-> i])
+  /\ UNCHANGED <<rnd, vrnd, pval, learned>>
+
+Phase1b(a, i) ==
+  /\ rnd[a] \prec i
+  /\ \E m \in sentMsg : (m.type = "phase1a") /\ (m.rnd = i)
+  /\ rnd' = [rnd EXCEPT ![a] = i]
+  /\ Send([type |-> "phase1b", rnd |-> i, vrnd |-> vrnd[a], pval |-> pval[a], 
+           acc |-> a])
+  /\ UNCHANGED <<vrnd, pval, learned>>
+
+P1bMsg(Q, i) == 
+   {m \in sentMsg : (m.type = "phase1b") /\ (m.acc \in Q) /\ (m.rnd = i)}
+
+SafeSet(M, Q, i) ==
+    LET k  == Max({m.vrnd : m \in M})
+        Vk == {m.pval : m \in {mm \in M : mm.vrnd = k}}
+        Only(v) == \/ Vk = {v}
+                   \/ /\ k \in FastNum
+                      /\ \E R \in Quorum(k) : 
+                           \A a \in Q \cap R :
+                             \E m \in M : /\ m.vrnd = k
+                                          /\ m.pval = v
+                                          /\ m.acc = a
+    IN  IF k = 0 
+          THEN PVal
+          ELSE IF \E v \in Vk : Only(v)
+                 THEN {CHOOSE v \in Vk : Only(v)}
+                 ELSE PVal                     
+
+Phase2a(i, va) ==
+  /\ ~\E m \in sentMsg : (m.type = "phase2a") /\ (m.rnd = i)
+  /\ \E Q \in Quorum(i) : 
+       /\ \A a \in Q : \E m \in sentMsg : /\ m.type = "phase1b"
+                                          /\ m.rnd  = i
+                                          /\ m.acc  = a
+       /\ \/ /\ va \in SafeSet(P1bMsg(Q,i), Q, i)
+             /\ \E m \in sentMsg : /\ m.type \in {"propose", "phase1b"} 
+                                   /\ m.pval = va
+          \/ /\ SafeSet(P1bMsg(Q,i), Q, i) = PVal
+             /\ i \in FastNum
+             /\ va = any
+  /\ Send([type |-> "phase2a", rnd |-> i, pval |-> va])
+  /\ UNCHANGED <<rnd, vrnd, pval, learned>>
+
+Phase2b(i, a, v) ==
+  /\ rnd[a] \preceq i
+  /\ vrnd[a] \prec i
+  /\ \E m \in sentMsg : 
+       /\ m.type = "phase2a"
+       /\ m.rnd = i
+       /\ \/ m.pval = v
+          \/ /\ m.pval = any
+             /\ \E mm \in sentMsg  : (mm.type = "propose") /\ (mm.pval = v)
+  /\ rnd' = [rnd EXCEPT ![a] = i]
+  /\ vrnd'  = [vrnd  EXCEPT ![a] = i]
+  /\ pval' = [pval EXCEPT ![a] = v]
+  /\ Send([type |-> "phase2b", rnd |-> i, pval |-> v, acc |-> a])
+  /\ UNCHANGED learned
+
+Learn(v) ==
+  /\ \E i \in RNum :
+       \E Q \in Quorum(i) : 
+         \A a \in Q : 
+           \E m \in sentMsg : /\ m.type = "phase2b"
+                              /\ m.rnd = i
+                              /\ m.pval = v
+                              /\ m.acc  = a
+  /\ learned' = learned \cup {v}
+  /\ UNCHANGED <<rnd, vrnd, pval, sentMsg>>
+-----------------------------------------------------------------------------
+P2bToP1b(Q, i) ==
+  LET iMsg == 
+        {m \in sentMsg : (m.type = "phase2b") /\ (m.rnd = i) /\ (m.acc \in Q)}
+  IN  {[type |-> "phase1b", rnd |-> NextNum(i), vrnd |-> i, 
+           pval |-> m.pval, acc |-> m.acc] : m \in iMsg}
+
+LeaderRecovery(i, v) ==
+  /\ ~\E m \in sentMsg : (m.type = "phase2a") /\ (m.rnd = NextNum(i))
+  /\ \E Q \in Quorum(i) : 
+        /\ \A a \in Q : \E m \in P2bToP1b(Q, i) : m.acc  = a
+        /\ v \in SafeSet(P2bToP1b(Q, i), Q, NextNum(i))
+        /\ \E m \in P2bToP1b(Q, i) : m.pval = v
+  /\ Send([type |-> "phase2a", rnd |-> NextNum(i), pval |-> v])
+  /\ UNCHANGED <<rnd, vrnd, pval, learned>>
+
+LeaderlessRecovery(i, a, v) ==  
+  /\ NextNum(i) \in FastNum
+  /\ rnd[a] = i
+  /\ vrnd[a] = i
+  /\ \E Q \in Quorum(i) : 
+        /\ \A b \in Q : \E m \in P2bToP1b(Q, i) : m.acc  = b
+        /\ v \in SafeSet(P2bToP1b(Q, i), Q, NextNum(i))
+        /\ \E m \in P2bToP1b(Q, i): m.pval = v
+  /\ rnd' = [rnd EXCEPT ![a] = NextNum(i)]
+  /\ vrnd'  = [vrnd  EXCEPT ![a] = NextNum(i)]
+  /\ pval' = [pval EXCEPT ![a] = v]
+  /\ Send([type |-> "phase2b", rnd |-> NextNum(i), pval |-> v, acc |-> a])
+  /\ UNCHANGED learned
+
+
+-----------------------------------------------------------------------------
+Next ==
+  \/ \E v \in PVal : Propose(v) \/  Learn(v)
+  \/ \E i \in RNum : \/ Phase1a(i)
+                     \/ \E a \in Acceptor : \/ Phase1b(a, i)
+                                            \/ \E v \in PVal : Phase2b(i, a, v)
+                     \/ \E va \in PVal \cup {any} : Phase2a(i, va)
+  (*\/ \E i \in FastNum, v \in PVal : 
+         \/ LeaderRecovery(i, v)
+         \/ \E a \in Acceptor :LeaderlessRecovery(i, a, v)*)
+
+Spec == Init /\ [][Next]_vars
+
+VotedForIn(a, v, i) ==
+  \E m \in sentMsg : /\ m.type = "phase2b"
+                     /\ m.acc  = a
+                     /\ m.pval = v
+                     /\ m.rnd = i
+
+VotedorAbstainedIn(a, i) ==
+  \/ \E v \in PVal : VotedForIn(a, v, i)
+  \/ i \prec rnd[a] 
+
+R1 == \A m \in sentMsg : 
+        (m.type = "phase2b") => \E mm \in sentMsg : /\ mm.type = "propose"
+                                                    /\ mm.pval = m.pval
+
+R2 == \A a \in Acceptor, v1, v2 \in PVal, i \in RNum :
+         VotedForIn(a, v1, i) /\ VotedForIn(a, v2, i) => (v1 = v2)
+
+ChooseableIn(v, i) == 
+  \E Q \in Quorum(i) : 
+    \A a \in Q : (~ VotedorAbstainedIn(a, i)) \/ VotedForIn(a, v, i)
+  
+NOC(v, i) == \A w \in PVal : ChooseableIn(w, i) => (w = v)
+
+SafeIn(v, i) == \A j \in RNum : (j \prec i) => NOC(v, j)
+
+R4 == \A a \in Acceptor, v \in PVal, i \in RNum :
+        VotedForIn(a, v, i) => SafeIn(v, i)
+
+R5a == \A j \in ClassicNum :
+         \A a1, a2 \in Acceptor :
+           \A v1, v2 \in PVal :
+              VotedForIn(a1, v1, j) /\ VotedForIn(a2, v2, j) => (v1 = v2)
+=============================================================================
diff --git a/src/test/resources/examples/FastPaxos/MCFastPaxos.cfg b/src/test/resources/examples/FastPaxos/MCFastPaxos.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..7988268bf808945b1ee5c763df8f5d3b7def732d
--- /dev/null
+++ b/src/test/resources/examples/FastPaxos/MCFastPaxos.cfg
@@ -0,0 +1,13 @@
+CONSTANTS
+  ClassicNum = {1,3}
+  FastNum    = {2}
+  Acceptor   = {a1,a2,a3}
+  PVal       = {v1,v2}
+  Quorum <- MCQuorum
+  any =[FastPaxos] any
+  a1=a1 a2=a2 a3=a3  v1=v1 v2=v2
+
+SPECIFICATION Spec
+INVARIANT TypeOK Correctness \* R1 R2 R4 R5a
+
+
diff --git a/src/test/resources/examples/FastPaxos/MCFastPaxos.tla b/src/test/resources/examples/FastPaxos/MCFastPaxos.tla
new file mode 100644
index 0000000000000000000000000000000000000000..e1cd84b489711c5ebaf80f45be6b2145a426eed4
--- /dev/null
+++ b/src/test/resources/examples/FastPaxos/MCFastPaxos.tla
@@ -0,0 +1,25 @@
+----------------------------- MODULE MCFastPaxos ----------------------------
+EXTENDS FiniteSets, Naturals 
+
+CONSTANTS PVal, Acceptor, FastNum, ClassicNum, Quorum(_) \* , _\prec_
+VARIABLES rnd, vrnd, pval, sentMsg, learned
+
+NextNum(a) == IF a+1 \in FastNum \cup ClassicNum THEN a+1 ELSE 0
+
+INSTANCE FastPaxos WITH \prec <- <
+CONSTANTS a1, a2, a3, v1, v2
+
+MCQuorum(i) == IF i \in ClassicNum THEN {{a1,a2}, {a1,a3}, {a2, a3}}
+                                   ELSE {{a1,a2,a3}}
+Correctness == 
+ /\ Cardinality(learned) \leq 1
+ /\ \A v \in learned : \E m \in sentMsg : /\ m.type = "propose"
+                                          /\ m.pval = v
+TSpec == Init /\  [][Next]_vars
+
+(*
+TInit ==
+
+TSpec == TInit /\ [][Next]_vars
+*)
+=============================================================================
diff --git a/src/test/resources/examples/GraphIso/GraphIso.cfg b/src/test/resources/examples/GraphIso/GraphIso.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..f4de133b686366e3e6ac5098eb8d2734d459ddd3
--- /dev/null
+++ b/src/test/resources/examples/GraphIso/GraphIso.cfg
@@ -0,0 +1,2 @@
+INIT Init
+NEXT Solve
\ No newline at end of file
diff --git a/src/test/resources/examples/GraphIso/GraphIso.mch b/src/test/resources/examples/GraphIso/GraphIso.mch
new file mode 100644
index 0000000000000000000000000000000000000000..325180a9bfb31f3a9dd9bec034697e4bb0ef1cbb
--- /dev/null
+++ b/src/test/resources/examples/GraphIso/GraphIso.mch
@@ -0,0 +1,24 @@
+MACHINE GraphIso
+VARIABLES g1, g2, p, n, solved
+INVARIANT
+ g1 : POW(INTEGER*INTEGER)
+ & g2 : POW(INTEGER*INTEGER)
+ & p : POW(INTEGER*INTEGER)
+ & n : INTEGER
+ & solved : INTEGER
+INITIALISATION
+ g1, g2, p, n, solved:(n = 9
+ & g1 = %i.(i : 1 .. n| i) <+ {1 |-> 3, 2 |-> 3, 3 |-> 6, 4 |-> 6, 5 |-> 6, 8 |-> 9, 9 |-> 8}
+ & g2 = %i.(i : 1 .. n| i) <+ {2 |-> 5, 3 |-> 5, 4 |-> 5, 6 |-> 4, 7 |-> 4, 1 |-> 9, 9 |-> 1}
+ & p = %i.(i : 1 .. n| 0)
+ & solved = 0)
+OPERATIONS
+ Solve_Op = ANY p_n, solved_n
+	WHERE p_n : POW(INTEGER*INTEGER) & solved_n : INTEGER & solved = 0
+	 & solved_n = 1
+	 & p_n : 1 .. n --> 1 .. n
+	 & !i.(i : 1 .. n => #j.(j : 1 .. n & p_n(j) = i))
+	 & !i.(i : 1 .. n => p_n(g1(i)) = g2(p_n(i)))
+	 & TRUE = TRUE
+	THEN p, solved := p_n, solved_n END
+END
diff --git a/src/test/resources/examples/GraphIso/GraphIso.tla b/src/test/resources/examples/GraphIso/GraphIso.tla
new file mode 100644
index 0000000000000000000000000000000000000000..f09eaeecab33af03b66974ab7b6de25db39b91fa
--- /dev/null
+++ b/src/test/resources/examples/GraphIso/GraphIso.tla
@@ -0,0 +1,24 @@
+---- MODULE GraphIso ----
+
+EXTENDS Naturals, FiniteSets
+VARIABLE g1, g2, p, n, solved
+----
+Init == /\ n = 9
+        /\ g1 = [[i\in 1..n|->i] EXCEPT ![1]=3,![2]=3,![3]=6,![4]=6,![5]=6,![8]=9,![9]=8]
+        /\ g2 = [[i\in 1..n|->i] EXCEPT ![2]=5,![3]=5,![4]=5,![6]=4,![7]=4,![1]=9,![9]=1]
+        /\ p = [i \in 1..n |-> 0]
+        /\ solved = 0
+Solve == /\ solved = 0
+         /\ solved' = 1
+         /\ p' \in [1..n -> 1..n]
+         /\ \A i \in 1..n : (\E j \in 1..n : p'[j]=i)
+         /\ \A i \in 1..n : (p'[g1[i]] = g2[p'[i]])
+         /\ UNCHANGED <<g1,g2,n>>
+====
+\* Generated at Wed Jul 21 15:51:20 CEST 2010
+\*         /\ \A i \in 1..n : (p'[g1[i]] = g2[p'[i]])
+\* trying to encode graph isomporphism in TLA for graphs with exactly one successor
+\* ProB takes 0.06 seconds for first solution; 0.1 second for all 8 solutions
+\* TLC starts at  21:28:18
+\* finds permutation <<6, 7, 4, 2, 3, 5, 8, 1, 9>>   at 23:34:46  (2h 6mins 28secs)
+\* same as first permutation found by ProB in 0.06 seconds
\ No newline at end of file
diff --git a/src/test/resources/examples/HourClock/HourClock.cfg b/src/test/resources/examples/HourClock/HourClock.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..7f032c783b822cd13c760106166328f13ae6e64a
--- /dev/null
+++ b/src/test/resources/examples/HourClock/HourClock.cfg
@@ -0,0 +1,3 @@
+INIT HCini
+NEXT HCnxt
+INVARIANTS HCini
\ No newline at end of file
diff --git a/src/test/resources/examples/HourClock/HourClock.mch b/src/test/resources/examples/HourClock/HourClock.mch
new file mode 100644
index 0000000000000000000000000000000000000000..b696afa4b38e572cb2bf8066b601ea0dcdf04a51
--- /dev/null
+++ b/src/test/resources/examples/HourClock/HourClock.mch
@@ -0,0 +1,15 @@
+MACHINE HourClock
+DEFINITIONS
+ IF_THEN_ELSE(P, a, b) == (%t_.(t_ = TRUE & P = TRUE | a )\/%t_.(t_= TRUE & not(P= TRUE) | b ))(TRUE);
+ HCini == hr : 1 .. 12
+VARIABLES hr
+INVARIANT
+ hr : INTEGER
+ & HCini
+INITIALISATION
+ hr:(hr : 1 .. 12)
+OPERATIONS
+ HCnxt_Op = ANY hr_n
+	WHERE hr_n : INTEGER & hr_n = IF_THEN_ELSE(bool(hr /= 12), hr + 1, 1)
+	THEN hr := hr_n END
+END
diff --git a/src/test/resources/examples/HourClock/HourClock.tla b/src/test/resources/examples/HourClock/HourClock.tla
new file mode 100644
index 0000000000000000000000000000000000000000..253eea2af2ed0ab6fe81e03791c6aa5de01fb17b
--- /dev/null
+++ b/src/test/resources/examples/HourClock/HourClock.tla
@@ -0,0 +1,9 @@
+---------------------- MODULE HourClock ----------------------
+EXTENDS Naturals
+VARIABLE hr
+HCini  ==  hr \in (1 .. 12)
+HCnxt == hr' = IF hr #12 THEN hr+1 ELSE 1
+HC  ==  HCini /\ [] [HCnxt]_hr
+--------------------------------------------------------------
+THEOREM HC => []HCini
+==============================================================
diff --git a/src/test/resources/examples/Jukebox/Jukebox.cfg b/src/test/resources/examples/Jukebox/Jukebox.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..edf388f92669546052fc55cd316adfaf814c64e5
--- /dev/null
+++ b/src/test/resources/examples/Jukebox/Jukebox.cfg
@@ -0,0 +1,5 @@
+INIT Init
+NEXT Next
+INVARIANT Inv
+CONSTANTS
+TRACK = {t1,t2,t3}
\ No newline at end of file
diff --git a/src/test/resources/examples/Jukebox/Jukebox.mch b/src/test/resources/examples/Jukebox/Jukebox.mch
new file mode 100644
index 0000000000000000000000000000000000000000..bd120d8fc316e8bce4b0d4cfdf69861c37e6ff09
--- /dev/null
+++ b/src/test/resources/examples/Jukebox/Jukebox.mch
@@ -0,0 +1,48 @@
+MACHINE Jukebox
+SETS
+ ENUM1 = {t1, t2, t3}
+ABSTRACT_CONSTANTS TRACK, limit
+PROPERTIES
+ TRACK = ENUM1
+ & limit : INTEGER
+ & limit : NATURAL & limit > 0
+DEFINITIONS
+ IF_THEN_ELSE(P, a, b) == (%t_.(t_ = TRUE & P = TRUE | a )\/%t_.(t_= TRUE & not(P= TRUE) | b ))(TRUE);
+ Inv == credit : NATURAL & credit <= limit & playset <: TRACK;
+
+ minimum(a,b) == IF_THEN_ELSE(bool(a < b), a, b);
+
+ pay(cc) == cc > 0 & credit_n = minimum(credit + cc, limit);
+
+ select(tt) == credit > 0 & (credit_n = credit - 1 or credit_n = credit) & playset_n = playset \/ {tt}
+VARIABLES credit, playset
+INVARIANT
+ credit : INTEGER
+ & playset : POW(ENUM1)
+ & Inv
+INITIALISATION
+ credit, playset:(credit = 0 & playset = {})
+OPERATIONS
+ pay_Op(cc) = ANY credit_n, playset_n
+	WHERE cc : NATURAL & 
+	 credit_n : INTEGER & playset_n : POW(ENUM1) & pay(cc)
+	THEN credit, playset := credit_n, playset_n END;
+
+ select_Op(tt) = ANY credit_n, playset_n
+	WHERE tt : TRACK & 
+	 credit_n : INTEGER & playset_n : POW(ENUM1) & select(tt)
+	THEN credit, playset := credit_n, playset_n END;
+
+ play_Op = ANY playset_n
+	WHERE playset_n : POW(ENUM1) & playset /= {} & #tr.(tr : playset & playset_n = playset - {tr}) & TRUE = TRUE
+	THEN playset := playset_n END;
+
+ removeCredit_Op = ANY credit_n
+	WHERE credit_n : INTEGER & credit > 0 & credit_n = credit - 1 & TRUE = TRUE
+	THEN credit := credit_n END;
+
+ dropTrack_Op(tt) = ANY playset_n
+	WHERE tt : playset & 
+	 playset_n : POW(ENUM1) & playset_n = playset - {tt} & TRUE = TRUE
+	THEN playset := playset_n END
+END
diff --git a/src/test/resources/examples/Jukebox/Jukebox.tla b/src/test/resources/examples/Jukebox/Jukebox.tla
new file mode 100644
index 0000000000000000000000000000000000000000..7e187bfb5e6d8b1e7c635fbcf65e07550fa0f077
--- /dev/null
+++ b/src/test/resources/examples/Jukebox/Jukebox.tla
@@ -0,0 +1,48 @@
+-------------------------- MODULE Jukebox -----------------------------
+EXTENDS Naturals
+CONSTANT TRACK, limit
+ASSUME limit \in Nat /\ limit > 0
+
+VARIABLE credit, playset
+Init == credit = 0 /\ playset = {}
+Inv  ==  credit \in Nat /\ credit \leq limit /\ playset \subseteq TRACK
+-----------------------------------------------------------------------
+
+(* A user can purchase some credits to make some selections from the
+jukebox. The limit cannot be exceeded.  *)
+
+minimum(a,b) == IF a < b THEN a ELSE b
+pay(cc) ==  cc > 0 /\ credit' = minimum(credit + cc, limit)
+
+
+(* The select action occasionally provides free selections.  The
+intention is that this should occur occasionally, and randomly.  Note that even a free selection can only be made if the credit total is positive. *)
+
+select(tt) == credit > 0 /\ (credit' = credit - 1 \/ credit' = credit)
+	 /\ playset' = playset \cup {tt}
+
+
+(* Any track that is currently in the set to be played can be output
+by this action. *)
+
+play == playset # {} /\ (\E tr \in playset: playset' = playset\{tr}) /\ UNCHANGED credit
+
+
+(* the penalty action, invoked when the jukebox is mistreated,
+either removes a credit if there are any left, or drops a tack from
+the playset, if there are any left.  If both are possible, then it can
+do either of these.*)
+
+removeCredit == credit > 0 /\ credit' = credit -1 /\ UNCHANGED playset
+dropTrack == \E tt \in playset: playset' = playset\{tt} /\ UNCHANGED credit
+penalty == removeCredit \/ dropTrack
+
+
+(* Disjunction of all actions *)
+
+Next == \/ (\E cc \in Nat: pay(cc))
+	\/ (\E tt \in TRACK: select(tt))
+	\/ play
+	\/ penalty
+
+=======================================================================
diff --git a/src/test/resources/examples/MySequence/MySequence.tla b/src/test/resources/examples/MySequence/MySequence.tla
new file mode 100644
index 0000000000000000000000000000000000000000..e84c3eecf7fee1018e36fce89e1fa1889de6a194
--- /dev/null
+++ b/src/test/resources/examples/MySequence/MySequence.tla
@@ -0,0 +1,9 @@
+----- MODULE MySequence-----
+EXTENDS Sequences
+VARIABLE q
+Init == q = <<1, 2, 3>>
+Next ==
+  /\ q # <<>>
+  /\ q' = Tail(q)
+Spec == Init /\ [][Next]_q
+=======================
diff --git a/src/test/resources/examples/Queens/Queens.cfg b/src/test/resources/examples/Queens/Queens.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..f4de133b686366e3e6ac5098eb8d2734d459ddd3
--- /dev/null
+++ b/src/test/resources/examples/Queens/Queens.cfg
@@ -0,0 +1,2 @@
+INIT Init
+NEXT Solve
\ No newline at end of file
diff --git a/src/test/resources/examples/Queens/Queens.mch b/src/test/resources/examples/Queens/Queens.mch
new file mode 100644
index 0000000000000000000000000000000000000000..fafa8565590097078c66768b2b607e6083eb9293
--- /dev/null
+++ b/src/test/resources/examples/Queens/Queens.mch
@@ -0,0 +1,19 @@
+MACHINE Queens
+VARIABLES q, n, solved
+INVARIANT
+ q : POW(INTEGER*INTEGER)
+ & n : INTEGER
+ & solved : INTEGER
+INITIALISATION
+ q, n, solved:(q = %i.(i : 1 .. 2| 0)
+ & n = 7
+ & solved = 0)
+OPERATIONS
+ Solve_Op = ANY q_n, n_n, solved_n
+	WHERE q_n : POW(INTEGER*INTEGER) & n_n : INTEGER & solved_n : INTEGER & solved = 0
+	 & q_n : 1 .. n --> 1 .. n
+	 & !i.(i : 1 .. n => !j.(j : 2 .. n => (i < j => q_n(i) /= q_n(j) & q_n(i) + (i - j) /= q_n(j) & q_n(i) - i + j /= q_n(j))))
+	 & solved_n = 1
+	 & n_n = n
+	THEN q, n, solved := q_n, n_n, solved_n END
+END
diff --git a/src/test/resources/examples/Queens/Queens.tla b/src/test/resources/examples/Queens/Queens.tla
new file mode 100644
index 0000000000000000000000000000000000000000..5edd6010acb4c53d4e775760c360b428f42c5900
--- /dev/null
+++ b/src/test/resources/examples/Queens/Queens.tla
@@ -0,0 +1,22 @@
+---- MODULE Queens ----
+
+EXTENDS Naturals, FiniteSets
+
+VARIABLE q, n, solved
+----
+
+Init == /\ q=[i \in 1..2 |-> 0]
+        /\ n=7
+        /\ solved = 0
+
+Solve == /\ solved=0
+         /\ q' \in [1..n -> 1..n]
+         /\ \A i \in 1..n : (\A j \in 2..n : i<j => q'[i] # q'[j] /\ q'[i]+i-j # q'[j] /\ q'[i]-i+j # q'[j])
+         /\ solved'=1
+         /\ n'=n
+Spec == Init /\ [] [Solve]_<<n,q>>
+=======
+\* Generated at Tue Jun 22 21:06:17 CEST 2010
+\* Takes 2 seconds for n-6, 12 seconds to solve for n=7 and 4 minutes 9 seconds for n=8, 1h45min47sec for n=9
+\* ProB takes 0.01 seconds for n=8, both on MacBook Pro 3.06 GHz
+\*         /\ \A i \in 1..n : (\E j \in 1..n : q'[j]=i)
\ No newline at end of file
diff --git a/src/test/resources/examples/Queens/Queens2.cfg b/src/test/resources/examples/Queens/Queens2.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..ac11778eb3b8b6b8991288bc9e419219926ae0c8
--- /dev/null
+++ b/src/test/resources/examples/Queens/Queens2.cfg
@@ -0,0 +1,5 @@
+INIT Init
+NEXT PlaceQueen
+INVARIANT TypeInvariant Invariant
+CONSTANTS
+N =5
\ No newline at end of file
diff --git a/src/test/resources/examples/Queens/Queens2.mch b/src/test/resources/examples/Queens/Queens2.mch
new file mode 100644
index 0000000000000000000000000000000000000000..8809b151a45874482857aedfca558676dc2a65c9
--- /dev/null
+++ b/src/test/resources/examples/Queens/Queens2.mch
@@ -0,0 +1,44 @@
+MACHINE Queens2
+ABSTRACT_CONSTANTS N
+PROPERTIES
+ N = 5
+ & N : NATURAL - {0}
+DEFINITIONS
+ Attacks(queens,i,j) == queens(i) = queens(j)
+	 or queens(i) - queens(j) = i - j
+	 or queens(j) - queens(i) = i - j;
+
+ IsSolution(queens) == !i.(i : 1 .. size(queens) - 1 => !j.(j : i + 1 .. size(queens) => not(Attacks(queens, i, j))));
+
+ Solutions == {queens|queens : 1 .. N --> 1 .. N & IsSolution(queens)};
+
+ TypeInvariant == todo : POW(seq(1 .. N)) & !s.(s : todo => size(s) < N)
+	 & (sols : POW(seq(1 .. N)) & !s.(s : sols => size(s) = N));
+
+ Invariant == sols <: Solutions
+	 & (todo = {} => Solutions <: sols);
+
+ nxtQ == size(queens) + 1;
+ cols == {c|c : 1 .. N & not(#i.(i : 1 .. size(queens) & Attacks(queens <- c, i, nxtQ)))};
+ exts == {t_|#c.(c : cols & t_ = queens <- c)};
+
+VARIABLES todo, sols
+INVARIANT
+ todo : POW(POW(INTEGER*INTEGER))
+ & sols : POW(POW(INTEGER*INTEGER))
+ & TypeInvariant
+ & Invariant
+INITIALISATION
+ todo, sols:(todo = {[]}
+ & sols = {})
+OPERATIONS
+ PlaceQueen_Op(queens) = ANY todo_n, sols_n
+	WHERE queens : todo & 
+	 todo_n : POW(POW(INTEGER*INTEGER)) & sols_n : POW(POW(INTEGER*INTEGER)) & (nxtQ = N 
+	  => todo_n = todo - {queens}
+	  & sols_n = sols \/ exts) 
+	 & (not(nxtQ = N) 
+	  => todo_n = todo - {queens} \/ exts
+	  & sols_n = sols)
+	THEN todo, sols := todo_n, sols_n END
+END
diff --git a/src/test/resources/examples/Queens/Queens2.tla b/src/test/resources/examples/Queens/Queens2.tla
new file mode 100644
index 0000000000000000000000000000000000000000..0c466eaf9a2ff44745b1910d733404371e3cb178
--- /dev/null
+++ b/src/test/resources/examples/Queens/Queens2.tla
@@ -0,0 +1,85 @@
+------------------------------- MODULE Queens2 -------------------------------
+EXTENDS Naturals, Sequences
+(***************************************************************************)
+(* Formulation of the N-queens problem and an iterative algorithm to solve *)
+(* the problem in TLA+. Since there must be exactly one queen in every row *)
+(* we represent placements of queens as functions of the form              *)
+(*    queens \in [ 1..N -> 1..N ]                                          *)
+(* where queens[i] gives the column of the queen in row i. Note that such  *)
+(* a function is just a sequence of length N.                              *)
+(* We will also consider partial solutions, also represented as sequences  *)
+(* of length \leq N.                                                       *)
+(***************************************************************************)
+
+CONSTANT N              \** number of queens and size of the board
+ASSUME N \in Nat \ {0}
+
+(* The following predicate determines if queens i and j attack each other
+   in a placement of queens (represented by a sequence as above). *)
+Attacks(queens,i,j) ==
+  \/ queens[i] = queens[j]                 \** same column
+  \/ queens[i] - queens[j] = i - j         \** first diagonal
+  \/ queens[j] - queens[i] = i - j         \** second diagonal
+
+(* A placement represents a (partial) solution if no two different queens
+   attack each other in it. *)
+IsSolution(queens) ==
+  \A i \in 1 .. Len(queens)-1 : \A j \in i+1 .. Len(queens) : 
+       ~ Attacks(queens,i,j) 
+
+(* Compute the set of solutions of the N-queens problem. *)
+Solutions == { queens \in [1..N -> 1..N] : IsSolution(queens) }
+
+(***************************************************************************)
+(* We now describe an algorithm that iteratively computes the set of       *)
+(* solutions of the N-queens problem by successively placing queens.       *)
+(* The current state of the algorithm is given by two variables:           *)
+(* - todo contains a set of partial solutions,                             *)
+(* - sols contains the set of full solutions found so far.                 *)
+(* At every step, the algorithm picks some partial solution and computes   *)
+(* all possible extensions by the next queen. If N queens have been placed *)
+(* these extensions are in fact full solutions, otherwise they are added   *)
+(* to the set todo.                                                        *)
+(***************************************************************************)
+
+VARIABLES todo, sols
+
+Init == /\ todo = { << >> }   \** << >> is a partial (but not full) solution
+        /\ sols = {}          \** no full solution found so far
+
+PlaceQueen == \E queens \in todo :
+  \** extend some partial solution by placing the next queen
+  LET nxtQ == Len(queens) + 1   \** number of queen to place
+      cols == \** set of columns on which queen can be placed without any
+              \** conflict with some queen already placed
+              { c \in 1..N : ~ \E i \in 1 .. Len(queens) :
+                                  Attacks( Append(queens, c), i, nxtQ ) }
+      exts == { Append(queens, c) : c \in cols }  \** possible extensions
+  IN  IF nxtQ = N  \** completed solution
+      THEN /\ todo' = todo \ {queens}
+           /\ sols' = sols \union exts
+      ELSE /\ todo' = (todo \ {queens}) \union exts
+           /\ sols' = sols
+
+vars == <<todo,sols>>
+Spec == Init /\ [][PlaceQueen]_vars /\ WF_vars(PlaceQueen)
+
+TypeInvariant ==
+  /\ todo \in SUBSET Seq(1 .. N) /\ \A s \in todo : Len(s) < N
+  /\ sols \in SUBSET Seq(1 .. N) /\ \A s \in sols : Len(s) = N
+
+(* The set of sols contains only solutions, and contains all solutions
+   when todo is empty. *)
+Invariant ==
+  /\ sols \subseteq Solutions
+  /\ todo = {} => Solutions \subseteq sols
+
+Termination == <>(todo = {})
+
+(* Assert that no solutions are ever computed so that TLC displays one *)
+NoSolutions == sols = {}
+
+=============================================================================
+\* Modification History
+\* Last modified Sat Dec 11 09:58:48 CET 2010 by merz
+\* Created Sat Dec 11 08:50:24 CET 2010 by merz
diff --git a/src/test/resources/examples/RecursiveFunction/RecursiveFunction.mch b/src/test/resources/examples/RecursiveFunction/RecursiveFunction.mch
new file mode 100644
index 0000000000000000000000000000000000000000..4f24de357d3586b3298c7c9bcbb7e291ecac7c53
--- /dev/null
+++ b/src/test/resources/examples/RecursiveFunction/RecursiveFunction.mch
@@ -0,0 +1,11 @@
+MACHINE RecursiveFunction
+ABSTRACT_CONSTANTS k, k2, k3, fact
+PROPERTIES
+ k : INTEGER
+ & k2 : INTEGER
+ & k3 : INTEGER
+ & k = fact(0) & k2 = fact(3) & k3 = fact(4)
+ & fact = %n.(n : NATURAL & n = 0 | 1) \/ %n.(n : NATURAL & not(n = 0) | n * fact(n - 1))
+DEFINITIONS
+ IF_THEN_ELSE(P, a, b) == (%t_.(t_ = TRUE & P = TRUE | a )\/%t_.(t_= TRUE & not(P= TRUE) | b ))(TRUE)
+END
diff --git a/src/test/resources/examples/RecursiveFunction/RecursiveFunction.tla b/src/test/resources/examples/RecursiveFunction/RecursiveFunction.tla
new file mode 100644
index 0000000000000000000000000000000000000000..958c71a1be9f6f155df4d1c517a4cc99335e1145
--- /dev/null
+++ b/src/test/resources/examples/RecursiveFunction/RecursiveFunction.tla
@@ -0,0 +1,7 @@
+----- MODULE RecursiveFunction -----
+EXTENDS Naturals
+CONSTANTS k, k2, k3
+fact[n \in Nat] == IF n = 0 THEN 1 ELSE n * fact[n-1]
+ASSUME k = fact[0] /\ k2 = fact[3] /\ k3 = fact[4]
+=======================
+
diff --git a/src/test/resources/examples/Relations.tla b/src/test/resources/examples/Relations.tla
new file mode 100644
index 0000000000000000000000000000000000000000..a9a1bc1e0f5c3c8fc88150450a8c35d948f19437
--- /dev/null
+++ b/src/test/resources/examples/Relations.tla
@@ -0,0 +1,66 @@
+----------------------------- MODULE Relations -----------------------------
+
+EXTENDS TLC, Sequences, Naturals, FiniteSets, Integers
+
+domain(r) == {x[1]: x \in r}
+range(r) == {x[2]: x \in r}
+id(S) == {<<x,x>>: x \in S}
+set_of_relations(x,y) == SUBSET (x \times y) 
+domain_restriction(S, r) == {x \in r: x[1] \in S}
+domain_substraction(S, r) == {x \in r: x[1] \notin S}
+range_restriction(S, r) == {x \in r: x[2] \in S}
+range_substraction(S, r) == {x \in r: x[2] \notin S}
+
+rel_inverse(r) == {<<x[2],x[1]>>: x\in r}
+relational_image(r, S) =={y[2] :y \in {x \in r: x[1] \in S}}
+relational_overriding(r, r2) == {x \in r: x[1] \notin domain(r2)} \cup r2
+
+
+direct_product(r1, r2) == {<<x, u>> \in (domain(r1)\cup domain(r2)) \times (range(r1) \times range(r2)):
+     u[1] \in relational_image(r1, {x}) /\ u[2] \in relational_image(r2,{x})}
+direct_product2(r1, r2) == {u \in (domain(r1)\cup domain(r2)) \times (range(r1) \times range(r2)):
+     <<u[1],u[2][1]>> \in r1 /\ <<u[1],u[2][2]>> \in r2}
+
+relational_composition(r1, r2) == {<<u[1][1],u[2][2]>> : u \in
+    {x \in range_restriction(domain(r2),r1) \times domain_restriction(range(r1),r2): x[1][2] = x[2][1]}
+        }
+
+prj1(E, F) == {u \in E \times F \times E: u[1] = u[3]}
+prj2(E, F) == {u \in E \times F \times F: u[2] = u[3]}
+
+
+RECURSIVE iterate(_,_)
+iterate(r, n) == CASE  n = 0 -> id(domain(r)\cup range(r))
+                [] n = 1 -> r
+                [] OTHER -> iterate(relational_composition(r,r), n-1)
+
+RECURSIVE closure1(_)
+closure1(R) == IF relational_composition(R,R) \R # {}
+                THEN R \cup closure1(relational_composition(R,R)) 
+                ELSE R
+
+closure(R) == closure1( R \cup {<<x[1],x[1]>>: x \in R} \cup {<<x[2],x[2]>>: x \in R})
+
+relational_call(r, x) == (CHOOSE y \in r: y[1] = x)[2]
+
+
+is_partial_func(f) == \A x \in domain(f): Cardinality(relational_image(f, {x})) <= 1
+is_partial_func2(f, S, S2) == /\ \A x \in f: x[1] \in S /\ x[2] \in S2 /\  relational_image(f, {x[1]}) = {x[2]}
+
+partial_func(S, S2) == {x \in (SUBSET (S \times S2)): is_partial_func(x)}
+
+is_func(f) == \A x \in domain(f): Cardinality(relational_image(f, {x})) < 2
+total_func(S, S2) == {x \in (SUBSET (S \times S2)): is_func(x) /\ domain(x)= S}
+
+is_total_func(f, S, S2) == domain(f) = S /\ \A x \in f: x[1] \in S /\ x[2] \in S2 /\  relational_image(f, {x[1]}) = {x[2]}
+
+is_injectiv_func(f) == \A x \in range(f): Cardinality(relational_image(rel_inverse(f), {x})) <= 1 
+total_injection(S, S2) == {x \in (SUBSET (S \times S2)): is_func(x) /\ domain(x)= S /\ is_injectiv_func(x) }
+partial_injection(S, S2) == {x \in (SUBSET (S \times S2)): is_func(x) /\ is_injectiv_func(x) }
+
+total_surjection(S, S2) == {x \in (SUBSET (S \times S2)): is_func(x)/\ domain(x)= S /\ S2 = range(x)}
+partial_surjection(S, S2) == {x \in (SUBSET (S \times S2)): is_func(x)/\ S2 = range(x)}
+
+total_bijection(S, S2) == {x \in (SUBSET (S \times S2)): is_func(x) /\ domain(x) = S /\ is_injectiv_func(x) /\ S2 = range(x)}
+
+=============================================================================
\ No newline at end of file
diff --git a/src/test/resources/examples/Scheduler/Scheduler.cfg b/src/test/resources/examples/Scheduler/Scheduler.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..5d1dbd39ff05ef5075420c2f426df29f659b6dfe
--- /dev/null
+++ b/src/test/resources/examples/Scheduler/Scheduler.cfg
@@ -0,0 +1,5 @@
+INIT Init
+NEXT Next
+INVARIANT Inv
+CONSTANTS
+PID = {p1,p2,p3,p4,p5,p6,p7}
diff --git a/src/test/resources/examples/Scheduler/Scheduler.mch b/src/test/resources/examples/Scheduler/Scheduler.mch
new file mode 100644
index 0000000000000000000000000000000000000000..7bb32cbd8c3997cdef1a7c61990d0442b5e5ef42
--- /dev/null
+++ b/src/test/resources/examples/Scheduler/Scheduler.mch
@@ -0,0 +1,48 @@
+MACHINE Scheduler
+SETS
+ ENUM1 = {p1, p2, p3, p4, p5, p6, p7}
+ABSTRACT_CONSTANTS PID
+PROPERTIES
+ PID = ENUM1
+DEFINITIONS
+ Inv == active : POW(PID) & ready : POW(PID) & waiting : POW(PID) & active <: PID & ready <: PID & waiting <: PID & ready /\ waiting = {} & card(active) <= 1 & (active = {} => ready = {});
+
+ new(pp) == pp /: active & pp /: ready \/ waiting & waiting_n = waiting \/ {pp} & TRUE = TRUE;
+
+ del(pp) == pp : waiting & waiting_n = waiting - {pp} & TRUE = TRUE;
+
+ ready_(rr) == rr : waiting & waiting_n = waiting - {rr} & ((active = {} 
+	  => active_n = {rr} & ready_n = ready) 
+	 & (not(active = {}) 
+	  => ready_n = ready \/ {rr} & active_n = active))
+VARIABLES active, ready, waiting
+INVARIANT
+ active : POW(ENUM1)
+ & ready : POW(ENUM1)
+ & waiting : POW(ENUM1)
+ & Inv
+INITIALISATION
+ active, ready, waiting:(active = {} & ready = {} & waiting = {})
+OPERATIONS
+ new_Op(pp) = ANY waiting_n
+	WHERE pp : PID & 
+	 waiting_n : POW(ENUM1) & new(pp)
+	THEN waiting := waiting_n END;
+
+ del_Op(pp) = ANY waiting_n
+	WHERE pp : PID & 
+	 waiting_n : POW(ENUM1) & del(pp)
+	THEN waiting := waiting_n END;
+
+ ready__Op(rr) = ANY active_n, ready_n, waiting_n
+	WHERE rr : PID & 
+	 active_n : POW(ENUM1) & ready_n : POW(ENUM1) & waiting_n : POW(ENUM1) & ready_(rr)
+	THEN active, ready, waiting := active_n, ready_n, waiting_n END;
+
+ swap_Op = ANY active_n, ready_n, waiting_n
+	WHERE active_n : POW(ENUM1) & ready_n : POW(ENUM1) & waiting_n : POW(ENUM1) & active /= {} & waiting_n = waiting \/ active & ((ready = {} 
+	  => active_n = {} & ready_n = ready) 
+	 & (not(ready = {}) 
+	  => #pp.(pp : ready & (active_n = {pp} & ready_n = ready - {pp}))))
+	THEN active, ready, waiting := active_n, ready_n, waiting_n END
+END
diff --git a/src/test/resources/examples/Scheduler/Scheduler.tla b/src/test/resources/examples/Scheduler/Scheduler.tla
new file mode 100644
index 0000000000000000000000000000000000000000..f93545ac3ffba7e5f97646eb10d33032f4d6b4bb
--- /dev/null
+++ b/src/test/resources/examples/Scheduler/Scheduler.tla
@@ -0,0 +1,29 @@
+------------------------------ MODULE Scheduler ------------------------------- 
+EXTENDS Naturals, FiniteSets
+CONSTANTS PID
+VARIABLES active, ready, waiting
+Inv == active \in SUBSET(PID) /\ ready \in SUBSET(PID) /\ waiting \in SUBSET(PID)
+	 /\ active \subseteq PID /\ ready \subseteq PID /\ waiting \subseteq PID
+	/\ (ready \cap waiting) = {} /\ Cardinality(active) \leq 1
+	/\ (active = {} => ready = {})
+Init == active = {} /\ ready = {} /\ waiting = {}
+------------------------------------------------------------------------------
+new(pp) == pp \notin active /\ pp \notin (ready \cup waiting) /\ waiting' = waiting \cup {pp} /\ UNCHANGED <<ready,active>>
+
+del(pp) == pp \in waiting /\ waiting' = waiting\{pp} /\ UNCHANGED <<ready,active>>
+
+ready_(rr) == rr \in waiting /\ waiting' =  waiting\{rr} /\
+	IF active = {} THEN active' = {rr} /\ UNCHANGED ready
+	ELSE ready' = ready \cup {rr} /\ UNCHANGED active
+
+swap == active # {} /\ waiting' = waiting \cup active 
+	/\ IF ready = {} THEN active' = {} /\ UNCHANGED ready
+	ELSE \E pp \in ready: active' ={pp} /\ ready' = ready\{pp}
+
+
+
+Next ==  \/ (\E pp \in PID : new(pp))
+	\/ (\E pp \in PID : del(pp))
+	\/ (\E rr \in PID : ready_(rr))
+	\/ swap
+=============================================================================
diff --git a/src/test/resources/examples/SecCtx.cfg b/src/test/resources/examples/SecCtx.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..d9bdb0b9b1707d86c7a668bc84dfa3d5759b8f0e
--- /dev/null
+++ b/src/test/resources/examples/SecCtx.cfg
@@ -0,0 +1,8 @@
+INIT SecCtx_Init
+NEXT SecCtx_Next
+INVARIANT Inv
+CONSTANTS
+usr_lst_cnt = 2
+REG_USR = {0,1}
+NAT = {0,1,2,3}
+INT = {0,1,2,3}
\ No newline at end of file
diff --git a/src/test/resources/examples/SecCtx.tla b/src/test/resources/examples/SecCtx.tla
new file mode 100644
index 0000000000000000000000000000000000000000..a31684ddcf69f96b1eaa4388fa8e5b4e8ae223cf
--- /dev/null
+++ b/src/test/resources/examples/SecCtx.tla
@@ -0,0 +1,475 @@
+------------------------------- MODULE SecCtx -------------------------------
+EXTENDS Naturals, Integers, Relations
+CONSTANTS usr_lst_cnt, REG_USR, INT, NAT
+ASSUME usr_lst_cnt \in Nat\{0} /\ REG_USR = 0..(usr_lst_cnt-1)
+
+min(S) == CHOOSE x \in S : \A i \in S: x \leq i
+
+VARIABLES
+    flg_comm_active,            (* communicating *)
+    flg_got_cli_nonce,          (* Client Nonce received *)
+    flg_sent_serv_nonce,        (* Server Nonce sent *)
+    flg_sent_cert,              (* Server certificate sent *)
+    flg_got_premaster,          (* premaster secret received from client *)
+    flg_set_cmn_key,            (* session common key set *)
+    flg_done_hs_verify,         (* Data for verifying a Handshake message checked *)
+    flg_sent_hs_verify,         (* Data for verifying a Handshake message sent *)
+    flg_cipher_on,              (* Applied encryption to communication data *)
+    
+    flg_allow_user_auth,        (* the propriety user authenticating user *)
+    flg_done_user_auth,         (* user authenticated flag *)
+    flg_allow_user_data,        (* the propriety sending and receiving user data flag *)
+    
+    flg_tx_msg_encoded,         (* encryption of sending data flag *)
+    flg_tx_add_mac,             (* Given MAC  of sending data flag *)
+    flg_allow_send_data,        (* Permission of sending TCP data flag*)
+    
+    flg_rx_msg_decoded,         (* encryption of receiviing data flag *)
+    flg_rx_chk_mac,             (* Given MAC  of receiviing data flag *)
+    flg_allow_recv_data,        (* Permission of giving application software received data flag*)
+    
+    auth_fail_cnt,              (* consecutive unsuccessful authentication attempts for each user *)
+    recent_auth_tim             (* previous time of authentication attempts for each user for each user *)
+
+Inv == (* Definition of type *)
+    (* -------------------------------------------------------- *)
+    flg_comm_active \in BOOLEAN /\
+    flg_got_cli_nonce \in BOOLEAN /\
+    flg_sent_serv_nonce \in BOOLEAN /\
+    flg_sent_cert \in BOOLEAN /\
+    flg_got_premaster \in BOOLEAN /\
+    flg_set_cmn_key \in BOOLEAN /\
+    flg_done_hs_verify \in BOOLEAN /\
+    flg_sent_hs_verify \in BOOLEAN /\
+    flg_cipher_on \in BOOLEAN /\
+    
+    flg_allow_user_auth \in BOOLEAN /\
+    flg_done_user_auth \in BOOLEAN /\
+    flg_allow_user_data \in BOOLEAN /\
+    
+    flg_tx_msg_encoded \in BOOLEAN /\
+    flg_tx_add_mac \in BOOLEAN /\
+    flg_allow_send_data \in BOOLEAN /\
+    
+    flg_rx_msg_decoded \in BOOLEAN /\
+    flg_rx_chk_mac \in BOOLEAN /\
+    flg_allow_recv_data \in BOOLEAN /\
+    
+    is_total_func(auth_fail_cnt, REG_USR, NAT) /\ (*   auth_fail_cnt : REG_USR +-> NAT & dom(auth_fail_cnt)=REG_USR &*)
+    is_total_func(recent_auth_tim, REG_USR, INT) /\ (*recent_auth_tim : REG_USR +-> INT & dom(recent_auth_tim)=REG_USR &*)
+    
+    (flg_sent_serv_nonce=TRUE => flg_got_cli_nonce=TRUE) /\
+    (flg_sent_cert=TRUE => flg_sent_serv_nonce=TRUE) /\
+    (flg_got_premaster=TRUE => flg_sent_cert=TRUE) /\
+    (flg_sent_hs_verify=TRUE => flg_got_premaster=TRUE) /\
+    (flg_allow_user_auth = TRUE
+        => (flg_sent_cert = TRUE) /\ (flg_got_premaster=TRUE) /\ (flg_sent_hs_verify=TRUE))
+    
+   /\     (flg_allow_user_data = TRUE
+        => (flg_sent_cert = TRUE) /\ (flg_got_premaster=TRUE) /\ (flg_sent_hs_verify=TRUE))
+  
+  /\      
+        (* Encryption of user data:Prevent eavesdropping *)
+    ( flg_cipher_on=TRUE => flg_set_cmn_key=TRUE) /\ 
+    ( flg_allow_user_auth=TRUE => flg_cipher_on=TRUE) /\
+    ( flg_done_user_auth=TRUE => flg_allow_user_auth=TRUE) /\
+    ( flg_allow_send_data=TRUE => (flg_allow_user_data=TRUE)/\(flg_tx_msg_encoded=TRUE) ) /\ 
+    ( flg_allow_recv_data=TRUE => (flg_allow_user_data=TRUE)/\(flg_rx_msg_decoded=TRUE) ) /\    
+        
+        
+        (* Make the unique common key for every session:Prevent replying *)
+    ( flg_allow_user_auth=TRUE => flg_done_hs_verify=TRUE ) /\
+    ( flg_allow_user_auth=TRUE => flg_sent_hs_verify=TRUE ) /\
+    ( flg_cipher_on=TRUE => flg_got_cli_nonce=TRUE ) /\
+    ( flg_cipher_on=TRUE => flg_sent_serv_nonce=TRUE ) /\
+    ( flg_comm_active=FALSE => flg_set_cmn_key=FALSE) /\
+    
+    (* Make hash:Prevent Prevent falsifying(contain adding messages, 
+    deleting messages and replacing an order of a message ) and replying *)
+    ( flg_allow_send_data=TRUE => (flg_allow_user_data=TRUE)/\(flg_tx_add_mac=TRUE) ) /\ 
+    ( flg_allow_recv_data=TRUE => (flg_allow_user_data=TRUE)/\(flg_rx_chk_mac=TRUE) ) /\
+    
+    (* Authenticate User:Prevent masquerading as an user *)
+    ( flg_allow_user_auth = TRUE => flg_cipher_on = TRUE ) /\
+    ( flg_allow_user_data = TRUE => flg_done_user_auth = TRUE )
+       
+        
+SecCtx_Init ==
+    flg_comm_active = FALSE /\
+    flg_got_cli_nonce = FALSE /\
+    flg_sent_serv_nonce = FALSE /\
+    flg_sent_cert = FALSE /\
+    flg_got_premaster = FALSE /\
+    flg_set_cmn_key = FALSE /\
+    flg_done_hs_verify = FALSE /\
+    flg_sent_hs_verify = FALSE /\
+    flg_cipher_on = FALSE /\
+    flg_allow_user_auth = FALSE /\
+    flg_done_user_auth = FALSE /\
+    flg_allow_user_data = FALSE /\
+    
+    flg_tx_msg_encoded = FALSE /\
+    flg_tx_add_mac = FALSE /\
+    flg_allow_send_data = FALSE /\
+    
+    flg_rx_msg_decoded = FALSE /\
+    flg_rx_chk_mac = FALSE /\
+    flg_allow_recv_data = FALSE /\
+    
+    auth_fail_cnt = REG_USR \times {0} /\
+    recent_auth_tim = (REG_USR \times {-1})
+        
+        
+        
+            (* Set flag operations *)
+SetFlgCommActive == 
+        /\ flg_comm_active = FALSE
+        /\ flg_comm_active' = TRUE
+        /\ UNCHANGED << flg_got_cli_nonce,flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key, flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth, flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded, flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim >>
+        
+SetFlgGotCliNonce == 
+        /\ flg_got_cli_nonce' = TRUE        
+        /\ UNCHANGED <<flg_comm_active, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+SetFlgSentServNonce == 
+        /\ flg_got_cli_nonce = TRUE
+        /\ flg_sent_serv_nonce' = TRUE
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+                
+SetFlgSentCert ==
+        /\ flg_sent_serv_nonce = TRUE
+        /\ flg_sent_cert' = TRUE
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+                
+SetFlgGotPremaster  == 
+        /\ flg_sent_cert = TRUE
+        /\ flg_got_premaster' = TRUE
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+        
+SetFlgCmnKey ==
+        /\ (flg_comm_active = TRUE)
+        /\ (flg_got_premaster = TRUE)
+        /\ (flg_got_cli_nonce = TRUE)
+        /\ (flg_sent_serv_nonce = TRUE)
+        /\ flg_set_cmn_key' = TRUE
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+    
+SetFlgCipherOn == 
+        /\ (flg_got_premaster = TRUE)
+        /\ (flg_got_cli_nonce = TRUE)
+        /\ (flg_sent_serv_nonce = TRUE)
+        /\ (flg_set_cmn_key = TRUE)
+        /\ flg_cipher_on' = TRUE 
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+                   
+        
+SetFlgDoneHsVerify  ==
+        /\ flg_done_hs_verify' = TRUE
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+        
+        
+SetFlgSentHsVerify == 
+        /\ flg_got_premaster = TRUE
+        /\ flg_sent_hs_verify' = TRUE 
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+        
+        
+SetFlgAllowUserAuth == 
+        /\ (flg_cipher_on = TRUE)
+        /\ (flg_done_hs_verify = TRUE)
+        /\ (flg_sent_hs_verify = TRUE)
+        /\ flg_allow_user_auth' = TRUE 
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+        
+SetFlgDoneUserAuth  == 
+        /\  flg_allow_user_auth = TRUE
+        /\ flg_done_user_auth' = TRUE
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+
+        
+SetSuccessUserAuth(usr, tim) ==
+        /\ usr \in INT /\ usr \in REG_USR /\ tim \in INT
+        /\    flg_allow_user_auth = TRUE
+            
+        /\  flg_done_user_auth' = TRUE
+        /\  auth_fail_cnt'= relational_overriding(auth_fail_cnt, {<<usr,0>>}) 
+        /\  recent_auth_tim' = relational_overriding(recent_auth_tim, {<<usr, tim>>})    
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data>>    
+        
+SetFailUserAuth(usr, tim) ==
+        /\ usr \in INT /\ usr \in REG_USR /\ tim \in INT  
+        /\    flg_done_user_auth' = FALSE
+        /\    flg_allow_user_data' = FALSE 
+        /\    flg_allow_send_data' = FALSE 
+        /\    flg_allow_recv_data' = FALSE
+        /\    auth_fail_cnt' = relational_overriding(auth_fail_cnt, {<<usr,min({relational_call(auth_fail_cnt,usr)+1, 3})>>})
+        /\    recent_auth_tim' = relational_overriding(recent_auth_tim, {<<usr, tim>>})      
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth, flg_tx_msg_encoded,flg_tx_add_mac,flg_rx_msg_decoded,flg_rx_chk_mac>>    
+        
+ SetFlgAllowUserData == 
+        /\  (flg_sent_cert = TRUE) 
+        /\ (flg_got_premaster=TRUE)
+        /\ (flg_sent_hs_verify = TRUE)
+        /\ (flg_cipher_on = TRUE)
+        /\ (flg_done_user_auth = TRUE)
+        /\ flg_allow_user_data' = TRUE 
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+                
+SetFlgTxMsgEncoded ==
+        /\ flg_tx_msg_encoded' = TRUE
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+    
+SetFlgTxAddMac  ==
+        /\ flg_tx_add_mac' = TRUE
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+         
+    
+SetFlgAllowSendData == 
+        /\ (flg_allow_user_data=TRUE)
+        /\ (flg_tx_msg_encoded = TRUE)
+        /\ (flg_tx_add_mac = TRUE)
+        /\ flg_allow_send_data' = TRUE 
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+         
+
+SetFlgRxMsgDecoded  ==
+        /\ flg_rx_msg_decoded' = TRUE
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+
+SetFlgRxChkMac  ==
+        /\ flg_rx_chk_mac' = TRUE
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+
+
+SetFlgAllowRecvData == 
+        /\ flg_cipher_on = TRUE
+        /\ (flg_allow_user_data = TRUE)
+        /\ (flg_rx_msg_decoded = TRUE)
+        /\ (flg_rx_chk_mac = TRUE)
+        /\ flg_allow_recv_data' = TRUE 
+        /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,auth_fail_cnt,recent_auth_tim>>    
+        
+    (* Complete Handshake  *)
+SetFlgsHndshkCompleteSts == 
+        flg_comm_active' = TRUE /\
+        flg_got_cli_nonce' = TRUE /\
+        flg_sent_serv_nonce' = TRUE /\
+        flg_sent_cert' = TRUE /\
+        flg_got_premaster' = TRUE /\
+        flg_set_cmn_key' = TRUE /\
+        flg_done_hs_verify' = TRUE /\
+        flg_sent_hs_verify' = TRUE /\
+        flg_cipher_on' = TRUE /\
+        flg_allow_user_auth' = TRUE
+        /\ UNCHANGED  <<flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+    (* Reset Handshake Status *)
+ResetFlgsHndshkCompleteSts == 
+    /\ flg_allow_user_data = FALSE
+    
+    /\  flg_comm_active' = FALSE /\
+        flg_got_cli_nonce' = FALSE /\
+        flg_sent_serv_nonce' = FALSE /\
+        flg_sent_cert' = FALSE /\
+        flg_got_premaster' = FALSE /\
+        flg_set_cmn_key' = FALSE /\
+        flg_done_hs_verify' = FALSE /\
+        flg_sent_hs_verify' = FALSE /\
+        flg_cipher_on' = FALSE /\
+        flg_allow_user_auth' = FALSE /\
+        flg_done_user_auth' =FALSE
+    /\ UNCHANGED <<flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+    (* Complete user authentication *)
+SetFlgsAuthCompleteSts ==
+    /\ flg_allow_user_auth = TRUE
+    /\
+        flg_done_user_auth' = TRUE  /\
+        flg_allow_user_data' = TRUE
+    /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+    (* Reset user authentication status *)
+ResetFlgsAuthCompleteSts == 
+    /\
+        flg_done_user_auth' = FALSE /\
+        flg_allow_user_data' = FALSE /\
+        
+        flg_allow_send_data' = FALSE /\
+        flg_allow_recv_data' = FALSE
+    /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth, flg_tx_msg_encoded,flg_tx_add_mac,flg_rx_msg_decoded,flg_rx_chk_mac,auth_fail_cnt,recent_auth_tim>>    
+          
+
+    (* Complete https_acp successfully *)
+SetFlgsAcpCompleteSts == 
+    /\
+        flg_comm_active' = TRUE /\
+        flg_got_cli_nonce' = TRUE /\
+        flg_sent_serv_nonce' = TRUE /\
+        flg_sent_cert' = TRUE /\
+        flg_got_premaster' = TRUE /\
+        flg_set_cmn_key' = TRUE /\
+        flg_done_hs_verify' = TRUE /\
+        flg_sent_hs_verify' = TRUE /\
+        flg_cipher_on' = TRUE /\
+        flg_allow_user_auth' = TRUE /\
+        flg_done_user_auth' = TRUE  /\
+        flg_allow_user_data' = TRUE
+    /\ UNCHANGED <<flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+
+    (* Reset https_acp status *)
+ResetFlgsAcpCompleteSts == 
+    /\
+        flg_comm_active' = FALSE /\
+        flg_got_cli_nonce' = FALSE /\
+        flg_sent_serv_nonce' = FALSE /\
+        flg_sent_cert' = FALSE /\
+        flg_got_premaster' = FALSE /\
+        flg_set_cmn_key' = FALSE /\
+        flg_done_hs_verify' = FALSE /\
+        flg_sent_hs_verify' = FALSE /\
+        flg_cipher_on' = FALSE /\
+        flg_allow_user_auth' = FALSE /\
+        flg_done_user_auth' = FALSE /\
+        flg_allow_user_data' = FALSE /\
+        
+        flg_allow_send_data' = FALSE /\
+        flg_allow_recv_data' = FALSE
+    /\ UNCHANGED <<flg_tx_msg_encoded,flg_tx_add_mac,flg_rx_msg_decoded,flg_rx_chk_mac,auth_fail_cnt,recent_auth_tim>>    
+        
+(* Set status of user data receiving  *)
+SetFlgRx == 
+    /\ flg_allow_user_data = TRUE /\
+        flg_allow_recv_data '= TRUE /\
+        flg_rx_msg_decoded' = TRUE /\
+        flg_rx_chk_mac' = TRUE
+    /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,auth_fail_cnt,recent_auth_tim>>    
+        
+    
+    
+ResetFlgRx == 
+    /\
+        flg_allow_recv_data' = FALSE /\
+        flg_rx_msg_decoded' = FALSE /\
+        flg_rx_chk_mac' = FALSE
+    /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,auth_fail_cnt,recent_auth_tim>>    
+        
+    
+    (* Set status of user data transmitting  *)
+SetFlgTx == 
+    /\ flg_allow_user_data = TRUE /\
+        flg_allow_send_data' = TRUE /\
+        flg_tx_msg_encoded' = TRUE /\
+        flg_tx_add_mac' = TRUE
+    /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+        
+ResetFlgTx == 
+    /\
+        flg_allow_send_data' = FALSE /\
+        flg_tx_msg_encoded' = FALSE /\
+        flg_tx_add_mac' = FALSE
+    /\ UNCHANGED  <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+              
+    
+SetAuthInf(usr, tim, cnt) ==
+    /\ usr \in INT /\ usr \in REG_USR /\ tim \in INT /\ cnt \in NAT
+    /\
+        auth_fail_cnt'= relational_overriding(auth_fail_cnt, {<<usr,cnt>>}) /\
+        recent_auth_tim' = relational_overriding(recent_auth_tim, {<<usr, tim>>})  
+    /\ UNCHANGED <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data>>    
+            
+        
+(* set https_acp complete status and reset the count of unsuccessful authentication attemps *)
+SetAuthSuccessSts(usr, cnt, tim) == 
+    /\ usr \in INT /\ usr \in REG_USR /\ cnt \in NAT /\ tim \in INT
+    /\
+        flg_comm_active' = TRUE /\
+        flg_got_cli_nonce' = TRUE /\
+        flg_sent_serv_nonce' = TRUE /\
+        flg_sent_cert' = TRUE /\
+        flg_got_premaster' = TRUE /\
+        flg_set_cmn_key' = TRUE /\
+        flg_done_hs_verify' = TRUE /\
+        flg_sent_hs_verify' = TRUE /\
+        flg_cipher_on' = TRUE /\
+        flg_allow_user_auth' = TRUE /\
+        flg_done_user_auth' = TRUE  /\
+        flg_allow_user_data' = TRUE /\
+        
+        auth_fail_cnt'= relational_overriding(auth_fail_cnt, {<<usr,cnt>>}) /\
+        recent_auth_tim' = relational_overriding(recent_auth_tim, {<<usr, tim>>})   
+    /\ UNCHANGED <<flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data>>    
+                 
+    (* Reset https_acp status and count up unsuccessful authentication attemps *)
+SetAuthFailSts(usr, cnt, tim) == 
+    /\ usr \in INT /\ usr \in REG_USR /\ cnt \in NAT /\ tim \in INT
+    /\
+        flg_comm_active' = FALSE /\
+        flg_got_cli_nonce' = FALSE /\
+        flg_sent_serv_nonce' = FALSE /\
+        flg_sent_cert' = FALSE /\
+        flg_got_premaster' = FALSE /\
+        flg_set_cmn_key' = FALSE /\
+        flg_done_hs_verify' = FALSE /\
+        flg_sent_hs_verify' = FALSE /\
+        flg_cipher_on' = FALSE /\
+        flg_allow_user_auth' = FALSE /\
+        flg_done_user_auth' = FALSE /\
+        flg_allow_user_data' = FALSE /\
+        
+        flg_allow_send_data' = FALSE /\
+        flg_allow_recv_data' = FALSE /\
+        
+        auth_fail_cnt'= relational_overriding(auth_fail_cnt, {<<usr,cnt>>}) /\
+        recent_auth_tim' = relational_overriding(recent_auth_tim, {<<usr, tim>>})       
+    /\ UNCHANGED <<flg_tx_msg_encoded,flg_tx_add_mac,flg_rx_msg_decoded,flg_rx_chk_mac>>    
+                   
+        
+        
+allVars == <<flg_comm_active, flg_got_cli_nonce, flg_sent_serv_nonce, flg_sent_cert,flg_got_premaster,flg_set_cmn_key,flg_done_hs_verify,flg_sent_hs_verify,flg_cipher_on, flg_allow_user_auth,flg_done_user_auth,flg_allow_user_data, flg_tx_msg_encoded,flg_tx_add_mac,flg_allow_send_data,flg_rx_msg_decoded,flg_rx_chk_mac,flg_allow_recv_data,auth_fail_cnt,recent_auth_tim>>    
+             
+             
+              
+SecCtx_Next == 
+        \/ SetFlgCommActive    
+        \/ SetFlgGotCliNonce
+        \/ SetFlgSentServNonce
+        \/ SetFlgSentCert
+        \/ SetFlgGotPremaster
+        \/ SetFlgCmnKey
+        \/ SetFlgCipherOn
+        \/ SetFlgDoneHsVerify
+        \/ SetFlgSentHsVerify
+        \/ SetFlgAllowUserAuth
+        \/ SetFlgDoneUserAuth
+        \/ \E usr \in REG_USR, tim \in INT: SetSuccessUserAuth(usr, tim)
+        \/ \E usr \in REG_USR, tim \in INT: SetFailUserAuth(usr, tim)
+        \/ SetFlgAllowUserData
+        \/ SetFlgTxMsgEncoded
+        \/ SetFlgTxAddMac
+        \/ SetFlgAllowSendData
+        \/ SetFlgRxMsgDecoded
+        \/ SetFlgRxChkMac
+        \/ SetFlgAllowRecvData
+        \/ SetFlgsHndshkCompleteSts
+        \/ ResetFlgsHndshkCompleteSts
+        \/ SetFlgsAuthCompleteSts
+        \/ SetFlgsAcpCompleteSts
+        \/ ResetFlgsAcpCompleteSts
+        \/ SetFlgRx
+        \/ ResetFlgRx
+        \/ SetFlgTx
+        \/ ResetFlgTx
+        \/ \E usr \in REG_USR, tim \in INT, cnt \in NAT: SetAuthInf(usr, tim, cnt)
+        \/ \E usr \in REG_USR, tim \in INT, cnt \in NAT: SetAuthSuccessSts(usr, cnt, tim)
+        \/ \E usr \in REG_USR, tim \in INT, cnt \in NAT: SetAuthFailSts(usr, cnt, tim)
+
+=============================================================================
diff --git a/src/test/resources/examples/SimpleSATProblem/SimpleSATProblem.mch b/src/test/resources/examples/SimpleSATProblem/SimpleSATProblem.mch
new file mode 100644
index 0000000000000000000000000000000000000000..19cf45e03afd8684c953eb13553566c7f032b81c
--- /dev/null
+++ b/src/test/resources/examples/SimpleSATProblem/SimpleSATProblem.mch
@@ -0,0 +1,27 @@
+MACHINE SimpleSATProblem
+ABSTRACT_CONSTANTS x1, x2, x3, x4, x5, x6, x7
+PROPERTIES
+ x1 : BOOL
+ & x2 : BOOL
+ & x3 : BOOL
+ & x4 : BOOL
+ & x5 : BOOL
+ & x6 : BOOL
+ & x7 : BOOL
+ & x1 : BOOL & x2 : BOOL & x3 : BOOL
+ & (x4 : BOOL & x5 : BOOL & x6 : BOOL & x7 : BOOL)
+ & (x1 = TRUE or x2 = TRUE or x5 = TRUE or x4 = TRUE)
+ & (x1 = TRUE or x2 = TRUE or not(x5 = TRUE) or x4 = TRUE)
+ & (x3 = TRUE or x6 = TRUE)
+ & (not(x4 = TRUE) or x7 = TRUE or x1 = TRUE)
+ & (not(x4 = TRUE) or not(x7 = TRUE) or x2 = TRUE)
+VARIABLES r
+INVARIANT
+ r : BOOL*BOOL*BOOL*BOOL*BOOL*BOOL*BOOL
+INITIALISATION
+ r:(r = (TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE))
+OPERATIONS
+ Set_Op = ANY r_n
+	WHERE r_n : BOOL*BOOL*BOOL*BOOL*BOOL*BOOL*BOOL & r_n = (x1, x2, x3, x4, x5, x6, x7)
+	THEN r := r_n END
+END
diff --git a/src/test/resources/examples/SimpleSATProblem/SimpleSATProblem.tla b/src/test/resources/examples/SimpleSATProblem/SimpleSATProblem.tla
new file mode 100644
index 0000000000000000000000000000000000000000..3e7e797170d8f973ee268e59f9e9b60edce809d7
--- /dev/null
+++ b/src/test/resources/examples/SimpleSATProblem/SimpleSATProblem.tla
@@ -0,0 +1,18 @@
+----- MODULE SimpleSATProblem -----
+EXTENDS Naturals
+CONSTANTS x1,x2,x3,x4,x5,x6,x7
+ASSUME 
+  /\ x1 \in BOOLEAN /\ x2 \in BOOLEAN /\ x3 \in BOOLEAN
+  /\ x4 \in BOOLEAN /\ x5 \in BOOLEAN /\ x6 \in BOOLEAN /\ x7 \in BOOLEAN
+  /\ (x1 \/ x2 \/ x5 \/ x4)
+  /\ (x1 \/ x2 \/ ~x5 \/ x4)
+  /\ (x3 \/ x6)
+  /\ (~x4 \/ x7 \/ x1)
+  /\ (~x4 \/ ~x7 \/ x2)
+ \* 60 different solutions exist
+VARIABLES r
+Init == r = <<TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE>>
+Set ==  r'= <<x1,x2,x3,x4,x5,x6,x7>>
+Next == Set
+=======================
+
diff --git a/src/test/resources/examples/SumAndProduct/SumAndProductTransition.tla b/src/test/resources/examples/SumAndProduct/SumAndProductTransition.tla
new file mode 100644
index 0000000000000000000000000000000000000000..94feee1746e078d07522b4f368ef216e61fd5c39
--- /dev/null
+++ b/src/test/resources/examples/SumAndProduct/SumAndProductTransition.tla
@@ -0,0 +1,96 @@
+------------------------- MODULE SumAndProductTransition ---------------------
+(****************************************************************************)
+(* This module formalizes the "sum and product" puzzle, due to Freudenthal  *)
+(* (1969), and which goes as follows:                                       *)
+(* J says to S and P: I have chosen two integers x and y such that          *)
+(* 1 < x <= y < 100. In a moment, I will inform S only of the sum x+y       *)
+(* and P only of the product x*y. These announcements remain private.       *)
+(* You are required to determine the pair (x,y). He acts as said.           *)
+(* The following conversation now takes place:                              *)
+(* 1. P says: "I don't know it."                                            *)
+(* 2. S says: "I knew you didn't."                                          *)
+(* 3. P says: "Now I know it."                                              *)
+(* 4. S says: "I now also know it."                                         *)
+(* Determine the pair (x,y).                                                *)
+(*                                                                          *)
+(* The following TLA+ module represents the puzzle as a transition system   *)
+(* where the two values are picked arbitrarily, then the feasibility of the *)
+(* above dialogue is verified, with S and P adapting their beliefs at each  *)
+(* step.                                                                    *)
+(* In fact, the first announcement is implied by the second one, so we do   *)
+(* not have to represent it explicitly.                                     *)
+(****************************************************************************)
+
+EXTENDS Naturals, FiniteSets
+
+VARIABLES x, y,     \* the numbers chosen by J
+  beliefP, beliefS, \* the pairs considered possible by P and S
+  step              \* next announcement in the conversation
+
+Pairs == { <<i,j>> \in (2 .. 99) \X (2 .. 99) : i <= j }
+
+(* Set of pairs that are equivalent from the point of view of P or S with a pair (i,j).
+   In particular, possibleP(x,y) denotes the set of pairs that P considers possible
+   given her initial knowledge. *)
+possibleP(i,j) == { <<u,v>> \in Pairs : u*v = i*j }
+possibleS(i,j) == { <<u,v>> \in Pairs : u+v = i+j }
+
+(* Given a set B of beliefs (pairs of numbers), an agent knows the pair if B 
+   is a singleton. For example, P knows the pair if knows(beliefP) holds. *)
+knows(B) == Cardinality(B) = 1
+
+(* Given a set B of beliefs, one knows that P knows the pair, if for every
+   belief b in B, P knows the result based on what it considers compatible
+   with b. For example, S knows that P knows if knows_knowsP(beliefS) holds. *)
+knows_knowsP(B) == \A <<i,j>> \in B : knows(possibleP(i,j))
+
+(* Similarly, given B, one knows that P doesn't know if there is no pair in B
+   for which P knows. *)
+knows_not_knowsP(B) == \A <<i,j>> \in B : ~ knows(possibleP(i,j))
+
+Init ==
+  /\ x \in 2 .. 99 /\ y \in 2 .. 99 /\ x <= y
+(* uncomment the following conjunct to check uniqueness of solution *)
+\*  /\ ~ (x=4 /\ y=13)
+  /\ beliefP = possibleP(x,y)
+  /\ beliefS = possibleS(x,y)
+  /\ step = 2
+
+(* The following actions correspond to the different steps in the conversation. *)
+Step2 ==
+  /\ step = 2
+  /\ ~ knows(beliefP)   \* logically redundant, but speeds up verification
+  /\ knows_not_knowsP(beliefS)
+  /\ beliefP' = beliefP \ { <<i,j>> \in beliefP : ~ knows_not_knowsP(possibleS(i,j)) }
+  /\ step' = 3
+  /\ UNCHANGED <<x,y,beliefS>>
+
+Step3 ==
+  /\ step = 3
+  /\ knows(beliefP)
+  /\ beliefS' = beliefS \ { <<i,j>> \in beliefS : 
+                            LET P == possibleP(i,j)
+                            IN  ~ knows(P \ {<<u,v>> \in P : ~ knows_not_knowsP(possibleS(u,v))}) }
+  /\ step' = 4
+  /\ UNCHANGED <<x,y,beliefP>>
+
+Step4 ==
+  /\ step = 4
+  /\ knows(beliefS)
+  /\ step' = 5
+  /\ UNCHANGED <<x,y,beliefP,beliefS>>
+
+Next == Step2 \/ Step3 \/ Step4
+
+vars == <<x,y,beliefP,beliefS>>
+
+SumProduct == Init /\ [][Next]_vars
+
+(* The following assertion says that the protocol cannot finish. Try to verify it
+   in order to find the solution of the puzzle (disable deadlock checking). *)
+Impossible == step # 5
+
+=============================================================================
+\* Modification History
+\* Last modified Mon Apr 22 12:17:12 CEST 2013 by merz
+\* Created Fri Apr 19 18:30:06 CEST 2013 by merz
diff --git a/src/test/resources/examples/uf50_02.tla b/src/test/resources/examples/uf50_02.tla
new file mode 100644
index 0000000000000000000000000000000000000000..060850f9bae725c21dc3f7bb452c86243e457bd6
--- /dev/null
+++ b/src/test/resources/examples/uf50_02.tla
@@ -0,0 +1,245 @@
+----- MODULE uf50_02 -----
+(* CNF Translated to TLA *)
+(* A SATLIB Problem with 50 variables *)
+(* Can be solved very quickly by ProB *)
+VARIABLES
+   x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, 
+   x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, 
+   x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, 
+   x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, 
+   x41, x42, x43, x44, x45, x46, x47, x48, x49, x50
+TypeInv == 
+    x1 \in BOOLEAN /\ x2 \in BOOLEAN /\ x3 \in BOOLEAN /\ x4 \in BOOLEAN /\ x5 \in BOOLEAN /\
+    x6 \in BOOLEAN /\ x7 \in BOOLEAN /\ x8 \in BOOLEAN /\ x9 \in BOOLEAN /\ x10 \in BOOLEAN /\
+    x11 \in BOOLEAN /\ x12 \in BOOLEAN /\ x13 \in BOOLEAN /\ x14 \in BOOLEAN /\ x15 \in BOOLEAN /\
+    x16 \in BOOLEAN /\ x17 \in BOOLEAN /\ x18 \in BOOLEAN /\ x19 \in BOOLEAN /\ x20 \in BOOLEAN /\
+    x21 \in BOOLEAN /\ x22 \in BOOLEAN /\ x23 \in BOOLEAN /\ x24 \in BOOLEAN /\ x25 \in BOOLEAN /\
+    x26 \in BOOLEAN /\ x27 \in BOOLEAN /\ x28 \in BOOLEAN /\ x29 \in BOOLEAN /\ x30 \in BOOLEAN /\
+    x31 \in BOOLEAN /\ x32 \in BOOLEAN /\ x33 \in BOOLEAN /\ x34 \in BOOLEAN /\ x35 \in BOOLEAN /\
+    x36 \in BOOLEAN /\ x37 \in BOOLEAN /\ x38 \in BOOLEAN /\ x39 \in BOOLEAN /\ x40 \in BOOLEAN /\
+    x41 \in BOOLEAN /\ x42 \in BOOLEAN /\ x43 \in BOOLEAN /\ x44 \in BOOLEAN /\ x45 \in BOOLEAN /\
+    x46 \in BOOLEAN /\ x47 \in BOOLEAN /\ x48 \in BOOLEAN /\ x49 \in BOOLEAN /\ x50\in BOOLEAN
+Sol == 
+   (  x42  \/  x28  \/  x33  ) /\ 
+   (  x1  \/  ~x12  \/  x2  ) /\ 
+   (  ~x15  \/  ~x38  \/  ~x12  ) /\ 
+   (  ~x40  \/  x8  \/  x9  ) /\ 
+   (  x32  \/  x14  \/  x30  ) /\ 
+   (  x38  \/  x47  \/  ~x21  ) /\ 
+   (  ~x7  \/  ~x14  \/  ~x28  ) /\ 
+   (  x44  \/  x27  \/  ~x3  ) /\ 
+   (  ~x15  \/  ~x26  \/  x42  ) /\ 
+   (  ~x22  \/  ~x45  \/  x36  ) /\ 
+   (  ~x14  \/  x47  \/  x1  ) /\ 
+   (  ~x10  \/  ~x8  \/  x17  ) /\ 
+   (  ~x27  \/  x31  \/  ~x33  ) /\ 
+   (  x12  \/  x19  \/  x26  ) /\ 
+   (  ~x10  \/  x31  \/  x1  ) /\ 
+   (  ~x49  \/  x19  \/  ~x48  ) /\ 
+   (  x2  \/  ~x12  \/  ~x8  ) /\ 
+   (  x23  \/  ~x25  \/  x5  ) /\ 
+   (  x14  \/  x48  \/  ~x30  ) /\ 
+   (  ~x27  \/  ~x37  \/  x21  ) /\ 
+   (  x11  \/  ~x36  \/  x18  ) /\ 
+   (  x25  \/  ~x42  \/  x37  ) /\ 
+   (  ~x47  \/  ~x10  \/  x14  ) /\ 
+   (  ~x14  \/  ~x36  \/  ~x49  ) /\ 
+   (  ~x8  \/  x28  \/  x21  ) /\ 
+   (  x47  \/  ~x31  \/  ~x44  ) /\ 
+   (  x34  \/  ~x19  \/  x20  ) /\ 
+   (  ~x29  \/  ~x38  \/  x16  ) /\ 
+   (  x12  \/  ~x1  \/  ~x40  ) /\ 
+   (  x44  \/  x38  \/  ~x9  ) /\ 
+   (  x23  \/  ~x13  \/  x9  ) /\ 
+   (  x45  \/  ~x11  \/  x21  ) /\ 
+   (  ~x20  \/  x9  \/  ~x50  ) /\ 
+   (  ~x39  \/  x14  \/  x38  ) /\ 
+   (  x9  \/  ~x16  \/  x6  ) /\ 
+   (  x46  \/  x3  \/  x34  ) /\ 
+   (  ~x7  \/  ~x14  \/  x21  ) /\ 
+   (  ~x40  \/  ~x47  \/  x10  ) /\ 
+   (  x27  \/  ~x20  \/  ~x25  ) /\ 
+   (  ~x32  \/  x6  \/  ~x13  ) /\ 
+   (  ~x9  \/  x19  \/  x45  ) /\ 
+   (  x3  \/  x30  \/  x27  ) /\ 
+   (  ~x25  \/  ~x47  \/  ~x1  ) /\ 
+   (  x46  \/  ~x13  \/  ~x1  ) /\ 
+   (  ~x18  \/  ~x8  \/  ~x4  ) /\ 
+   (  x23  \/  ~x5  \/  x45  ) /\ 
+   (  x31  \/  x50  \/  x48  ) /\ 
+   (  x11  \/  ~x48  \/  ~x50  ) /\ 
+   (  ~x42  \/  ~x28  \/  x48  ) /\ 
+   (  ~x41  \/  ~x16  \/  ~x32  ) /\ 
+   (  x21  \/  ~x19  \/  ~x31  ) /\ 
+   (  ~x33  \/  x17  \/  x27  ) /\ 
+   (  ~x34  \/  x48  \/  ~x45  ) /\ 
+   (  x8  \/  ~x17  \/  x29  ) /\ 
+   (  ~x21  \/  ~x14  \/  ~x17  ) /\ 
+   (  x29  \/  ~x49  \/  ~x21  ) /\ 
+   (  ~x33  \/  ~x11  \/  ~x10  ) /\ 
+   (  x31  \/  ~x28  \/  x38  ) /\ 
+   (  x18  \/  x13  \/  x3  ) /\ 
+   (  x44  \/  x24  \/  x36  ) /\ 
+   (  x45  \/  x50  \/  ~x18  ) /\ 
+   (  x1  \/  x38  \/  x10  ) /\ 
+   (  ~x4  \/  x1  \/  ~x32  ) /\ 
+   (  x15  \/  x28  \/  ~x42  ) /\ 
+   (  x39  \/  x44  \/  ~x18  ) /\ 
+   (  x43  \/  x47  \/  ~x39  ) /\ 
+   (  x9  \/  x12  \/  x32  ) /\ 
+   (  x23  \/  x26  \/  x3  ) /\ 
+   (  x34  \/  ~x30  \/  ~x41  ) /\ 
+   (  ~x19  \/  x36  \/  ~x34  ) /\ 
+   (  x27  \/  x3  \/  ~x34  ) /\ 
+   (  ~x9  \/  ~x22  \/  ~x7  ) /\ 
+   (  ~x41  \/  x13  \/  x4  ) /\ 
+   (  x6  \/  ~x50  \/  ~x46  ) /\ 
+   (  ~x44  \/  ~x32  \/  x20  ) /\ 
+   (  x6  \/  x43  \/  ~x40  ) /\ 
+   (  x29  \/  x27  \/  x41  ) /\ 
+   (  x9  \/  ~x28  \/  ~x23  ) /\ 
+   (  x7  \/  x44  \/  ~x42  ) /\ 
+   (  x39  \/  ~x11  \/  x19  ) /\ 
+   (  x14  \/  x47  \/  x2  ) /\ 
+   (  ~x37  \/  x46  \/  ~x33  ) /\ 
+   (  x46  \/  x22  \/  x26  ) /\ 
+   (  x10  \/  ~x29  \/  ~x14  ) /\ 
+   (  x38  \/  ~x19  \/  ~x42  ) /\ 
+   (  x15  \/  ~x41  \/  ~x29  ) /\ 
+   (  x22  \/  x31  \/  x42  ) /\ 
+   (  ~x3  \/  x4  \/  ~x27  ) /\ 
+   (  x49  \/  ~x31  \/  x29  ) /\ 
+   (  ~x43  \/  x19  \/  x28  ) /\ 
+   (  ~x17  \/  x38  \/  ~x46  ) /\ 
+   (  ~x42  \/  ~x25  \/  ~x21  ) /\ 
+   (  x39  \/  x32  \/  x31  ) /\ 
+   (  ~x15  \/  x9  \/  x32  ) /\ 
+   (  ~x2  \/  ~x13  \/  x31  ) /\ 
+   (  ~x35  \/  x15  \/  ~x43  ) /\ 
+   (  ~x20  \/  ~x2  \/  ~x21  ) /\ 
+   (  ~x18  \/  ~x25  \/  ~x32  ) /\ 
+   (  ~x50  \/  x5  \/  ~x32  ) /\ 
+   (  ~x50  \/  ~x32  \/  ~x26  ) /\ 
+   (  ~x14  \/  x44  \/  x22  ) /\ 
+   (  x13  \/  ~x6  \/  ~x38  ) /\ 
+   (  x20  \/  x16  \/  x19  ) /\ 
+   (  ~x18  \/  x11  \/  ~x9  ) /\ 
+   (  x45  \/  ~x8  \/  ~x10  ) /\ 
+   (  x50  \/  ~x1  \/  ~x33  ) /\ 
+   (  ~x39  \/  x6  \/  ~x41  ) /\ 
+   (  ~x14  \/  ~x28  \/  x48  ) /\ 
+   (  ~x41  \/  x13  \/  x14  ) /\ 
+   (  ~x27  \/  ~x8  \/  x30  ) /\ 
+   (  x26  \/  ~x27  \/  x17  ) /\ 
+   (  ~x44  \/  x37  \/  x15  ) /\ 
+   (  x17  \/  x26  \/  ~x50  ) /\ 
+   (  ~x17  \/  ~x48  \/  x8  ) /\ 
+   (  ~x1  \/  x23  \/  x28  ) /\ 
+   (  x46  \/  ~x35  \/  ~x31  ) /\ 
+   (  ~x21  \/  x36  \/  ~x15  ) /\ 
+   (  x9  \/  ~x37  \/  x4  ) /\ 
+   (  x3  \/  ~x16  \/  x8  ) /\ 
+   (  x31  \/  ~x46  \/  ~x26  ) /\ 
+   (  ~x13  \/  ~x21  \/  x19  ) /\ 
+   (  ~x22  \/  ~x4  \/  x47  ) /\ 
+   (  x14  \/  x48  \/  x3  ) /\ 
+   (  ~x28  \/  x9  \/  x18  ) /\ 
+   (  x38  \/  x50  \/  ~x9  ) /\ 
+   (  x49  \/  x20  \/  ~x5  ) /\ 
+   (  x28  \/  x35  \/  ~x40  ) /\ 
+   (  ~x41  \/  x35  \/  ~x27  ) /\ 
+   (  x46  \/  x29  \/  x40  ) /\ 
+   (  ~x27  \/  x2  \/  x8  ) /\ 
+   (  x19  \/  ~x13  \/  ~x35  ) /\ 
+   (  ~x10  \/  ~x8  \/  x32  ) /\ 
+   (  x29  \/  x24  \/  ~x37  ) /\ 
+   (  ~x36  \/  x12  \/  ~x17  ) /\ 
+   (  ~x34  \/  ~x1  \/  ~x33  ) /\ 
+   (  ~x6  \/  ~x4  \/  ~x10  ) /\ 
+   (  x38  \/  ~x36  \/  ~x48  ) /\ 
+   (  x23  \/  x14  \/  x4  ) /\ 
+   (  x47  \/  ~x5  \/  x31  ) /\ 
+   (  ~x45  \/  x13  \/  ~x7  ) /\ 
+   (  ~x24  \/  ~x9  \/  x46  ) /\ 
+   (  x24  \/  x38  \/  ~x8  ) /\ 
+   (  x1  \/  ~x30  \/  x7  ) /\ 
+   (  x24  \/  ~x35  \/  x29  ) /\ 
+   (  x11  \/  x43  \/  x22  ) /\ 
+   (  x9  \/  ~x43  \/  ~x34  ) /\ 
+   (  ~x26  \/  x49  \/  ~x20  ) /\ 
+   (  ~x27  \/  x21  \/  ~x7  ) /\ 
+   (  ~x8  \/  x48  \/  ~x30  ) /\ 
+   (  x45  \/  ~x13  \/  ~x21  ) /\ 
+   (  x41  \/  ~x38  \/  x31  ) /\ 
+   (  ~x7  \/  ~x16  \/  x5  ) /\ 
+   (  x4  \/  x25  \/  x44  ) /\ 
+   (  ~x5  \/  x16  \/  x17  ) /\ 
+   (  ~x12  \/  x47  \/  x31  ) /\ 
+   (  x21  \/  ~x4  \/  ~x47  ) /\ 
+   (  x8  \/  x35  \/  x3  ) /\ 
+   (  ~x36  \/  ~x16  \/  ~x27  ) /\ 
+   (  x48  \/  x30  \/  x50  ) /\ 
+   (  x33  \/  x25  \/  x48  ) /\ 
+   (  x24  \/  ~x27  \/  ~x15  ) /\ 
+   (  x8  \/  ~x36  \/  ~x27  ) /\ 
+   (  ~x12  \/  x34  \/  ~x3  ) /\ 
+   (  x22  \/  x11  \/  x8  ) /\ 
+   (  x22  \/  x8  \/  x46  ) /\ 
+   (  ~x31  \/  x44  \/  x28  ) /\ 
+   (  x37  \/  ~x21  \/  ~x41  ) /\ 
+   (  x50  \/  ~x43  \/  ~x22  ) /\ 
+   (  ~x31  \/  x3  \/  x46  ) /\ 
+   (  x8  \/  x45  \/  ~x28  ) /\ 
+   (  ~x4  \/  ~x45  \/  x42  ) /\ 
+   (  ~x37  \/  x26  \/  x28  ) /\ 
+   (  ~x39  \/  ~x49  \/  x38  ) /\ 
+   (  x21  \/  x32  \/  ~x18  ) /\ 
+   (  x16  \/  x49  \/  x19  ) /\ 
+   (  ~x8  \/  x5  \/  ~x4  ) /\ 
+   (  x23  \/  ~x35  \/  ~x17  ) /\ 
+   (  ~x49  \/  x39  \/  ~x20  ) /\ 
+   (  x10  \/  x49  \/  ~x9  ) /\ 
+   (  x33  \/  x2  \/  x12  ) /\ 
+   (  x23  \/  ~x29  \/  x26  ) /\ 
+   (  x43  \/  x22  \/  x33  ) /\ 
+   (  ~x2  \/  x1  \/  ~x35  ) /\ 
+   (  x1  \/  x17  \/  ~x35  ) /\ 
+   (  x1  \/  ~x22  \/  x42  ) /\ 
+   (  ~x24  \/  ~x10  \/  ~x44  ) /\ 
+   (  ~x15  \/  x22  \/  x3  ) /\ 
+   (  ~x12  \/  x27  \/  ~x15  ) /\ 
+   (  x22  \/  ~x18  \/  x1  ) /\ 
+   (  ~x36  \/  ~x35  \/  ~x42  ) /\ 
+   (  ~x43  \/  x10  \/  x38  ) /\ 
+   (  x18  \/  x24  \/  x39  ) /\ 
+   (  ~x35  \/  ~x32  \/  x41  ) /\ 
+   (  ~x33  \/  x49  \/  x26  ) /\ 
+   (  ~x3  \/  x39  \/  ~x46  ) /\ 
+   (  x23  \/  ~x8  \/  ~x41  ) /\ 
+   (  x28  \/  ~x12  \/  ~x22  ) /\ 
+   (  x31  \/  x17  \/  ~x23  ) /\ 
+   (  x29  \/  ~x49  \/  x48  ) /\ 
+   (  x15  \/  ~x35  \/  x40  ) /\ 
+   (  ~x41  \/  x2  \/  x14  ) /\ 
+   (  x29  \/  x40  \/  x19  ) /\ 
+   (  x42  \/  x37  \/  ~x17  ) /\ 
+   (  x14  \/  ~x36  \/  x31  ) /\ 
+   (  x13  \/  x4  \/  ~x47  ) /\ 
+   (  x8  \/  ~x3  \/  ~x28  ) /\ 
+   (  ~x28  \/  x12  \/  ~x30  ) /\ 
+   (  x48  \/  x3  \/  ~x22  ) /\ 
+   (  ~x47  \/  ~x31  \/  x14  ) /\ 
+   (  ~x41  \/  x5  \/  x7  ) /\ 
+   (  ~x13  \/  ~x14  \/  x22  ) /\ 
+   (  x30  \/  x13  \/  ~x15  ) /\ 
+   (  x44  \/  x7  \/  ~x29  ) /\ 
+   (  x44  \/  ~x18  \/  x26  ) /\ 
+   (  x11  \/  x36  \/  ~x22  ) /\ 
+   (  x36  \/  x35  \/  ~x43  ) /\ 
+   (  ~x11  \/  x4  \/  ~x39  ) /\ 
+   (  ~x2  \/  x6  \/  x5  ) /\ 
+    TRUE
+Init == TypeInv /\ Sol
+DLK == 1=2 /\ x1'=x1 (* always deadlocks *)
+Next == DLK
+ =======================
diff --git a/src/test/resources/main/Counter.tla b/src/test/resources/main/Counter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..52482d3053e73d2f5b55d80b836c4e58ec1ff3d6
--- /dev/null
+++ b/src/test/resources/main/Counter.tla
@@ -0,0 +1,10 @@
+-------------------------- MODULE Counter -----------------------------
+EXTENDS Naturals
+CONSTANTS start
+VARIABLE x
+-----------------------------------------------------------------------
+Init  ==  x = start
+Inc == x' = x + 1
+Dec == x' = x - 1
+Next  ==  Inc \/ Dec
+=======================================================================
diff --git a/src/test/resources/main/Counter_tla.mch b/src/test/resources/main/Counter_tla.mch
new file mode 100644
index 0000000000000000000000000000000000000000..4044c9e4da676bd72c8b5c5cba42628e387ce0b6
--- /dev/null
+++ b/src/test/resources/main/Counter_tla.mch
@@ -0,0 +1,21 @@
+/*@ generated by TLA2B 1.0.7 Fri Mar 07 11:03:11 CET 2014 */
+MACHINE Counter
+ABSTRACT_CONSTANTS
+start
+PROPERTIES
+ start : INTEGER
+VARIABLES
+ x
+INVARIANT
+ x : INTEGER
+INITIALISATION
+ x:(x = start)
+OPERATIONS
+ Inc_Op = ANY x_n
+	WHERE x_n : INTEGER & x_n = x + 1
+	THEN x := x_n END;
+
+ Dec_Op = ANY x_n
+	WHERE x_n : INTEGER & x_n = x - 1
+	THEN x := x_n END
+END
\ No newline at end of file
diff --git a/src/test/resources/main/Test.cfg b/src/test/resources/main/Test.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..8b6cfcba421df1370704ac1a8ae8fe807d7a6a57
--- /dev/null
+++ b/src/test/resources/main/Test.cfg
@@ -0,0 +1,2 @@
+INIT Init
+NEXT Next
\ No newline at end of file
diff --git a/src/test/resources/main/Test.tla b/src/test/resources/main/Test.tla
new file mode 100644
index 0000000000000000000000000000000000000000..ca1faca54d9cf99f8c5e2cde3e9790f73945fb41
--- /dev/null
+++ b/src/test/resources/main/Test.tla
@@ -0,0 +1,10 @@
+-------------------------- MODULE Test -----------------------------
+EXTENDS Naturals
+CONSTANTS start
+VARIABLE x
+-----------------------------------------------------------------------
+Init  ==  x = start
+Inc == x' = x + 1
+Dec == x' = x - 1
+Next  ==  Inc \/ Dec
+=======================================================================
diff --git a/src/test/resources/main/TypeError.tla b/src/test/resources/main/TypeError.tla
new file mode 100644
index 0000000000000000000000000000000000000000..bd182b1d0e88d7baac77415b9e8d00c236e708dc
--- /dev/null
+++ b/src/test/resources/main/TypeError.tla
@@ -0,0 +1,3 @@
+---- MODULE TypeError ----
+ASSUME 1 = TRUE
+======
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/BBuildIns/BBuildIns.tla b/src/test/resources/prettyprint/BBuildIns/BBuildIns.tla
new file mode 100644
index 0000000000000000000000000000000000000000..2874304ba44656de7f8f18c9af1a8b626a6d56d8
--- /dev/null
+++ b/src/test/resources/prettyprint/BBuildIns/BBuildIns.tla
@@ -0,0 +1,3 @@
+--------- MODULE BBuildIns ---------
+POW1(S) == (SUBSET S) \ {} 
+==============================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/BBuildIns/Pow1.tla b/src/test/resources/prettyprint/BBuildIns/Pow1.tla
new file mode 100644
index 0000000000000000000000000000000000000000..2079e5f38e9d8b483f3fe55479d68f2c68d7b4b7
--- /dev/null
+++ b/src/test/resources/prettyprint/BBuildIns/Pow1.tla
@@ -0,0 +1,4 @@
+---- MODULE Pow1 ----
+EXTENDS BBuildIns
+ASSUME {{1}} = POW1({1})
+======
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/constantWithArgs/Counter.tla b/src/test/resources/prettyprint/constantWithArgs/Counter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..bdc49ce5f29f253a510dd071d8cedd9f4f4e904e
--- /dev/null
+++ b/src/test/resources/prettyprint/constantWithArgs/Counter.tla
@@ -0,0 +1,9 @@
+-------------------------- MODULE Counter -----------------------------
+EXTENDS Naturals
+CONSTANTS start, _\prec_
+VARIABLE x
+-----------------------------------------------------------------------
+Init  ==  x = start
+val == 1
+Next  ==  1 \prec 2 /\  x' = x + val
+=======================================================================
diff --git a/src/test/resources/prettyprint/constantWithArgs/InstanceCounter.mch b/src/test/resources/prettyprint/constantWithArgs/InstanceCounter.mch
new file mode 100644
index 0000000000000000000000000000000000000000..47967bf450665d0756cf20e0b5cfba63600d1179
--- /dev/null
+++ b/src/test/resources/prettyprint/constantWithArgs/InstanceCounter.mch
@@ -0,0 +1,15 @@
+MACHINE InstanceCounter
+DEFINITIONS
+ prec(a, b) == a < b;
+
+ val == 1
+VARIABLES c
+INVARIANT
+ c : INTEGER
+INITIALISATION
+ c:(c = 0)
+OPERATIONS
+ Next_Op = ANY c_n
+	WHERE c_n : INTEGER & prec(1, 2) & c_n = c + val
+	THEN c := c_n END
+END
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/constantWithArgs/InstanceCounter.tla b/src/test/resources/prettyprint/constantWithArgs/InstanceCounter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..29b05182ffe9cb685c93158a5f848f3158cee616
--- /dev/null
+++ b/src/test/resources/prettyprint/constantWithArgs/InstanceCounter.tla
@@ -0,0 +1,6 @@
+-------------- MODULE InstanceCounter ----------------
+EXTENDS Naturals
+VARIABLES c
+a \prec b == a < b
+INSTANCE Counter WITH x <- c, start <- 0, \prec <- \prec
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/defOverriding/Counter.tla b/src/test/resources/prettyprint/defOverriding/Counter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..21b60bf30d1a78649117bfe7d0114b457cd97b7e
--- /dev/null
+++ b/src/test/resources/prettyprint/defOverriding/Counter.tla
@@ -0,0 +1,9 @@
+-------------------------- MODULE Counter -----------------------------
+EXTENDS Naturals
+CONSTANTS start, foo(_)
+VARIABLE x
+-----------------------------------------------------------------------
+Init  ==  x = start
+val == foo(1)
+Next  ==  x' = x + val
+=======================================================================
diff --git a/src/test/resources/prettyprint/defOverriding/DefOverriding.cfg b/src/test/resources/prettyprint/defOverriding/DefOverriding.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..03ac00882f2c3cecfe405c6b927ef18091c0f5b8
--- /dev/null
+++ b/src/test/resources/prettyprint/defOverriding/DefOverriding.cfg
@@ -0,0 +1,2 @@
+CONSTANTS
+foo <- bar
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/defOverriding/InstanceDefOverriding.cfg b/src/test/resources/prettyprint/defOverriding/InstanceDefOverriding.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..1e8b350dc77bc05843ca9b8c0b407a624fb13a30
--- /dev/null
+++ b/src/test/resources/prettyprint/defOverriding/InstanceDefOverriding.cfg
@@ -0,0 +1,4 @@
+INIT Init
+NEXT Next
+CONSTANTS
+foo <- bar
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/extends/Counter.tla b/src/test/resources/prettyprint/extends/Counter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..addaef7e755a413ee720c9a43733071d439679c9
--- /dev/null
+++ b/src/test/resources/prettyprint/extends/Counter.tla
@@ -0,0 +1,9 @@
+-------------------------- MODULE Counter -----------------------------
+EXTENDS Naturals
+CONSTANTS start
+VARIABLE x
+-----------------------------------------------------------------------
+Init  ==  x = start
+val == 1
+Next  ==  x' = x + val
+=======================================================================
diff --git a/src/test/resources/prettyprint/extends/ExtendsCounter.cfg b/src/test/resources/prettyprint/extends/ExtendsCounter.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..0209aca647b51caf2210cd783361933e3d6e5d7e
--- /dev/null
+++ b/src/test/resources/prettyprint/extends/ExtendsCounter.cfg
@@ -0,0 +1,4 @@
+INIT Init
+NEXT Next
+CONSTANTS
+start = 2
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/extends/ExtendsCounter.mch b/src/test/resources/prettyprint/extends/ExtendsCounter.mch
new file mode 100644
index 0000000000000000000000000000000000000000..efbedb91c45df59c016e4e852d485bfd31ed789b
--- /dev/null
+++ b/src/test/resources/prettyprint/extends/ExtendsCounter.mch
@@ -0,0 +1,16 @@
+MACHINE ExtendsCounter
+ABSTRACT_CONSTANTS start
+PROPERTIES
+ start = 2
+DEFINITIONS
+ val == 1
+VARIABLES x
+INVARIANT
+ x : INTEGER
+INITIALISATION
+ x:(x = start)
+OPERATIONS
+ Next_Op = ANY x_n
+	WHERE x_n : INTEGER & x_n = x + val
+	THEN x := x_n END
+END
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/extends/ExtendsCounter.tla b/src/test/resources/prettyprint/extends/ExtendsCounter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..37137860beebfb718d868a26ab0366c9e99cafa1
--- /dev/null
+++ b/src/test/resources/prettyprint/extends/ExtendsCounter.tla
@@ -0,0 +1,3 @@
+-------------- MODULE ExtendsCounter ----------------
+EXTENDS Counter
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/extends/ExtendsCounter2.cfg b/src/test/resources/prettyprint/extends/ExtendsCounter2.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..6b25f9936a8770c60dcc76d86df7a452a75367b5
--- /dev/null
+++ b/src/test/resources/prettyprint/extends/ExtendsCounter2.cfg
@@ -0,0 +1,4 @@
+INIT Init
+NEXT Next
+CONSTANTS
+start = [Counter] 2
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/extends/ExtendsCounter2.mch b/src/test/resources/prettyprint/extends/ExtendsCounter2.mch
new file mode 100644
index 0000000000000000000000000000000000000000..efbedb91c45df59c016e4e852d485bfd31ed789b
--- /dev/null
+++ b/src/test/resources/prettyprint/extends/ExtendsCounter2.mch
@@ -0,0 +1,16 @@
+MACHINE ExtendsCounter
+ABSTRACT_CONSTANTS start
+PROPERTIES
+ start = 2
+DEFINITIONS
+ val == 1
+VARIABLES x
+INVARIANT
+ x : INTEGER
+INITIALISATION
+ x:(x = start)
+OPERATIONS
+ Next_Op = ANY x_n
+	WHERE x_n : INTEGER & x_n = x + val
+	THEN x := x_n END
+END
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/Counter/Counter.tla b/src/test/resources/prettyprint/instance/Counter/Counter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..addaef7e755a413ee720c9a43733071d439679c9
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/Counter.tla
@@ -0,0 +1,9 @@
+-------------------------- MODULE Counter -----------------------------
+EXTENDS Naturals
+CONSTANTS start
+VARIABLE x
+-----------------------------------------------------------------------
+Init  ==  x = start
+val == 1
+Next  ==  x' = x + val
+=======================================================================
diff --git a/src/test/resources/prettyprint/instance/Counter/InstanceDefinition.mch b/src/test/resources/prettyprint/instance/Counter/InstanceDefinition.mch
new file mode 100644
index 0000000000000000000000000000000000000000..688146d036fac93fdd9ed749cca16db291bd37a4
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/InstanceDefinition.mch
@@ -0,0 +1,13 @@
+MACHINE InstanceDefinition
+DEFINITIONS
+ val == 5
+VARIABLES c
+INVARIANT
+ c : INTEGER
+INITIALISATION
+ c:(c = 0)
+OPERATIONS
+ Next_Op = ANY c_n
+	WHERE c_n : INTEGER & c_n = c + val
+	THEN c := c_n END
+END
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/Counter/InstanceDefinition.tla b/src/test/resources/prettyprint/instance/Counter/InstanceDefinition.tla
new file mode 100644
index 0000000000000000000000000000000000000000..303d8b59e063b0550108b125949b6943ec2d4f4b
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/InstanceDefinition.tla
@@ -0,0 +1,5 @@
+-------------- MODULE InstanceDefinition ----------------
+VARIABLES c
+val == 5 (* the val definition of the Counter module will be automatically overriden by SANY  *)
+INSTANCE Counter WITH x <- c, start <- 0
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/Counter/InstanceNoName.mch b/src/test/resources/prettyprint/instance/Counter/InstanceNoName.mch
new file mode 100644
index 0000000000000000000000000000000000000000..ad110dca9e20e37494cfdf54fe03a6569d974b29
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/InstanceNoName.mch
@@ -0,0 +1,18 @@
+MACHINE InstanceNoName
+ABSTRACT_CONSTANTS start
+PROPERTIES
+ start : INTEGER
+DEFINITIONS
+ Init == c = start;
+
+ val == 1
+VARIABLES c
+INVARIANT
+ c : INTEGER
+INITIALISATION
+ c:(Init)
+OPERATIONS
+ Next_Op = ANY c_n
+	WHERE c_n : INTEGER & c_n = c + val
+	THEN c := c_n END
+END
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/Counter/InstanceNoName.tla b/src/test/resources/prettyprint/instance/Counter/InstanceNoName.tla
new file mode 100644
index 0000000000000000000000000000000000000000..b2e5e4d0d3b1562d88e5b9e5cf43f7d857126f64
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/InstanceNoName.tla
@@ -0,0 +1,6 @@
+-------------- MODULE InstanceNoName ----------------
+CONSTANTS start
+VARIABLES c
+INSTANCE Counter WITH x <- c
+Spec == Init /\ [][Next]_c
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/Counter/ModConstantAssignment.cfg b/src/test/resources/prettyprint/instance/Counter/ModConstantAssignment.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..e4eda93e3f0fcbb23080a8e7dc29081ce42ffe76
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/ModConstantAssignment.cfg
@@ -0,0 +1,3 @@
+INIT Init
+NEXT Next
+CONSTANTS val = [Counter] 7
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/Counter/ModConstantAssignment.mch b/src/test/resources/prettyprint/instance/Counter/ModConstantAssignment.mch
new file mode 100644
index 0000000000000000000000000000000000000000..73115303fa5b849795a8bf7d78e4962e013a7776
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/ModConstantAssignment.mch
@@ -0,0 +1,13 @@
+MACHINE ModConstantAssignment
+DEFINITIONS
+ val == 7
+VARIABLES c
+INVARIANT
+ c : INTEGER
+INITIALISATION
+ c:(c = 0)
+OPERATIONS
+ Next_Op = ANY c_n
+	WHERE c_n : INTEGER & c_n = c + val
+	THEN c := c_n END
+END
diff --git a/src/test/resources/prettyprint/instance/Counter/ModConstantAssignment.tla b/src/test/resources/prettyprint/instance/Counter/ModConstantAssignment.tla
new file mode 100644
index 0000000000000000000000000000000000000000..59009a98f2468d1364464f2a9f8f85efe41b7f43
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/ModConstantAssignment.tla
@@ -0,0 +1,4 @@
+-------------- MODULE ModConstantAssignment ----------------
+VARIABLES c
+INSTANCE Counter WITH x <- c, start <- 0
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/Counter/OneInstanced.mch b/src/test/resources/prettyprint/instance/Counter/OneInstanced.mch
new file mode 100644
index 0000000000000000000000000000000000000000..0a7a02dad5d328d1f245e4bdd03d6b7f3264577c
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/OneInstanced.mch
@@ -0,0 +1,19 @@
+MACHINE OneInstanced
+ABSTRACT_CONSTANTS start
+PROPERTIES
+ start : INTEGER
+DEFINITIONS
+ count_Init == c = start;
+
+ count_val == 1;
+
+VARIABLES c
+INVARIANT
+ c : INTEGER
+INITIALISATION
+ c:(count_Init)
+OPERATIONS
+ count_Next_Op = ANY c_n
+	WHERE c_n : INTEGER & c_n = c + count_val
+	THEN c := c_n END
+END
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/Counter/OneInstanced.tla b/src/test/resources/prettyprint/instance/Counter/OneInstanced.tla
new file mode 100644
index 0000000000000000000000000000000000000000..69cca02f78c9a06ca1990a479ae13df5a6a11b43
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/OneInstanced.tla
@@ -0,0 +1,8 @@
+-------------- MODULE OneInstanced ----------------
+CONSTANTS start
+VARIABLES c
+count == INSTANCE Counter WITH x <- c
+Init == count!Init
+Next == count!Next
+=================================
+		
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/Counter/TwoInstance.mch b/src/test/resources/prettyprint/instance/Counter/TwoInstance.mch
new file mode 100644
index 0000000000000000000000000000000000000000..d23db8b678843cd223a8bac4cceb4fe0d07c3fb8
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/TwoInstance.mch
@@ -0,0 +1,32 @@
+MACHINE TwoInstanced
+ABSTRACT_CONSTANTS start
+PROPERTIES
+ start : INTEGER
+DEFINITIONS
+ count_Init == c = start;
+
+ count_val == 1;
+
+ count_Next == c_n = c + count_val;
+
+ count2_Init == c2 = 0;
+
+ count2_val == 1;
+
+ count2_Next == c2_n = c2 + count2_val;
+
+VARIABLES c, c2
+INVARIANT
+ c : INTEGER
+ & c2 : INTEGER
+INITIALISATION
+ c, c2:(count_Init & count2_Init)
+OPERATIONS
+ Next1_Op = ANY c_n
+	WHERE c_n : INTEGER & count_Next & TRUE = TRUE
+	THEN c := c_n END;
+
+ Next2_Op = ANY c2_n
+	WHERE c2_n : INTEGER & count2_Next & TRUE = TRUE
+	THEN c2 := c2_n END
+END
diff --git a/src/test/resources/prettyprint/instance/Counter/TwoInstance.tla b/src/test/resources/prettyprint/instance/Counter/TwoInstance.tla
new file mode 100644
index 0000000000000000000000000000000000000000..5939e9dcb2ab565f85bc6844159d0a6a7414ded8
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/TwoInstance.tla
@@ -0,0 +1,9 @@
+-------------- MODULE TwoInstanced --------------
+CONSTANTS start
+VARIABLES c, c2
+count == INSTANCE Counter WITH x <- c
+count2 == INSTANCE Counter WITH x <- c2, start <- 0
+Init == count!Init /\ count2!Init
+Next == 	\/ (count!Next /\ UNCHANGED c2)
+			\/ (count2!Next /\ UNCHANGED c)
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/Counter/TwoInstanced.mch b/src/test/resources/prettyprint/instance/Counter/TwoInstanced.mch
new file mode 100644
index 0000000000000000000000000000000000000000..d23db8b678843cd223a8bac4cceb4fe0d07c3fb8
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/TwoInstanced.mch
@@ -0,0 +1,32 @@
+MACHINE TwoInstanced
+ABSTRACT_CONSTANTS start
+PROPERTIES
+ start : INTEGER
+DEFINITIONS
+ count_Init == c = start;
+
+ count_val == 1;
+
+ count_Next == c_n = c + count_val;
+
+ count2_Init == c2 = 0;
+
+ count2_val == 1;
+
+ count2_Next == c2_n = c2 + count2_val;
+
+VARIABLES c, c2
+INVARIANT
+ c : INTEGER
+ & c2 : INTEGER
+INITIALISATION
+ c, c2:(count_Init & count2_Init)
+OPERATIONS
+ Next1_Op = ANY c_n
+	WHERE c_n : INTEGER & count_Next & TRUE = TRUE
+	THEN c := c_n END;
+
+ Next2_Op = ANY c2_n
+	WHERE c2_n : INTEGER & count2_Next & TRUE = TRUE
+	THEN c2 := c2_n END
+END
diff --git a/src/test/resources/prettyprint/instance/Counter/TwoInstanced.tla b/src/test/resources/prettyprint/instance/Counter/TwoInstanced.tla
new file mode 100644
index 0000000000000000000000000000000000000000..5939e9dcb2ab565f85bc6844159d0a6a7414ded8
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/Counter/TwoInstanced.tla
@@ -0,0 +1,9 @@
+-------------- MODULE TwoInstanced --------------
+CONSTANTS start
+VARIABLES c, c2
+count == INSTANCE Counter WITH x <- c
+count2 == INSTANCE Counter WITH x <- c2, start <- 0
+Init == count!Init /\ count2!Init
+Next == 	\/ (count!Next /\ UNCHANGED c2)
+			\/ (count2!Next /\ UNCHANGED c)
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/OpArg/OpArg.tla b/src/test/resources/prettyprint/instance/OpArg/OpArg.tla
new file mode 100644
index 0000000000000000000000000000000000000000..60a318106bbc6e701b724430bdb0a27c879d2035
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/OpArg/OpArg.tla
@@ -0,0 +1,7 @@
+-------------- MODULE OpArg ----------------
+EXTENDS Naturals
+CONSTANTS k(_,_)
+VARIABLES c
+Init == c = 1 
+Next == c' = c + k(1, 2)
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/OpArg/OpArgInstanced.mch b/src/test/resources/prettyprint/instance/OpArg/OpArgInstanced.mch
new file mode 100644
index 0000000000000000000000000000000000000000..a9e7cf31d3ead0f7a3936d849ad61bd5310d9150
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/OpArg/OpArgInstanced.mch
@@ -0,0 +1,14 @@
+MACHINE OpArgInstanced
+DEFINITIONS
+ foo(a,b) == a + b;
+
+VARIABLES c
+INVARIANT
+ c : INTEGER
+INITIALISATION
+ c:(c = 1)
+OPERATIONS
+ Next_Op = ANY c_n
+	WHERE c_n : INTEGER & c_n = c + foo(1,2)
+	THEN c := c_n END
+END
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/OpArg/OpArgInstanced.tla b/src/test/resources/prettyprint/instance/OpArg/OpArgInstanced.tla
new file mode 100644
index 0000000000000000000000000000000000000000..07e36d098a26749032f3c488f1daabf76e3eab9e
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/OpArg/OpArgInstanced.tla
@@ -0,0 +1,6 @@
+-------------- MODULE OpArgInstanced --------------
+EXTENDS Naturals
+VARIABLES c
+foo(a,b) == a + b
+INSTANCE OpArg WITH k <- foo
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/configOverride/Counter.tla b/src/test/resources/prettyprint/instance/configOverride/Counter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..addaef7e755a413ee720c9a43733071d439679c9
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/configOverride/Counter.tla
@@ -0,0 +1,9 @@
+-------------------------- MODULE Counter -----------------------------
+EXTENDS Naturals
+CONSTANTS start
+VARIABLE x
+-----------------------------------------------------------------------
+Init  ==  x = start
+val == 1
+Next  ==  x' = x + val
+=======================================================================
diff --git a/src/test/resources/prettyprint/instance/configOverride/InstanceCounter.cfg b/src/test/resources/prettyprint/instance/configOverride/InstanceCounter.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..3471675f8ebd5b9b1474da75830d4a8fe9c3a5bc
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/configOverride/InstanceCounter.cfg
@@ -0,0 +1,4 @@
+INIT Init
+NEXT Next
+CONSTANTS 
+val =[Counter] 4
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/configOverride/InstanceCounter.mch b/src/test/resources/prettyprint/instance/configOverride/InstanceCounter.mch
new file mode 100644
index 0000000000000000000000000000000000000000..5b0c40aab287f28cbea784919bd1b0e12479680a
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/configOverride/InstanceCounter.mch
@@ -0,0 +1,16 @@
+MACHINE InstanceCounter
+ABSTRACT_CONSTANTS start
+PROPERTIES
+ start : INTEGER
+DEFINITIONS
+ val == 4
+VARIABLES x
+INVARIANT
+ x : INTEGER
+INITIALISATION
+ x:(x = start)
+OPERATIONS
+ Next_Op = ANY x_n
+	WHERE x_n : INTEGER & x_n = x + val
+	THEN x := x_n END
+END
diff --git a/src/test/resources/prettyprint/instance/configOverride/InstanceCounter.tla b/src/test/resources/prettyprint/instance/configOverride/InstanceCounter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..de92f0f504ca2bdaf151bcc0ae87dd43f01dcf7c
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/configOverride/InstanceCounter.tla
@@ -0,0 +1,5 @@
+-------------- MODULE InstanceCounter ----------------
+CONSTANTS start 
+VARIABLES x
+INSTANCE Counter
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/configOverride/InstanceCounterException.cfg b/src/test/resources/prettyprint/instance/configOverride/InstanceCounterException.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..efebca9fc0b6e5d9309a96fc72fd7a0695c0c2f7
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/configOverride/InstanceCounterException.cfg
@@ -0,0 +1,4 @@
+INIT Init
+NEXT Next
+CONSTANTS
+start <-[Counter] foo
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/configOverride/InstanceCounterException.tla b/src/test/resources/prettyprint/instance/configOverride/InstanceCounterException.tla
new file mode 100644
index 0000000000000000000000000000000000000000..268aa31239fdcc8d64990010afda015c70795a52
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/configOverride/InstanceCounterException.tla
@@ -0,0 +1,6 @@
+-------------- MODULE InstanceCounterException ----------------
+CONSTANTS start
+VARIABLES x
+INSTANCE Counter 
+foo == 11
+==========================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/constantSubstitution/InstanceInstanceOpArg.cfg b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceInstanceOpArg.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..ff2050f0405ec0c0440ed7fc8ee2ac72d4c8ff1e
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceInstanceOpArg.cfg
@@ -0,0 +1 @@
+CONSTANTS foo3 <- bazz
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/constantSubstitution/InstanceInstanceOpArg.tla b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceInstanceOpArg.tla
new file mode 100644
index 0000000000000000000000000000000000000000..52ffeda8a2e77e841a1ac85e538fcb3e47b980cb
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceInstanceOpArg.tla
@@ -0,0 +1,7 @@
+-------------- MODULE InstanceInstanceOpArg ----------------
+EXTENDS Naturals
+CONSTANTS c3, foo3(_,_)
+bazz(a,b) == a + b
+INSTANCE InstanceOpArg WITH c2 <- c3, foo2 <- foo3
+ASSUME def /\ c3 = 3 
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArg.tla b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArg.tla
new file mode 100644
index 0000000000000000000000000000000000000000..74d8d2c25c59d1c9b9d1c732ccbd2ae9980075b8
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArg.tla
@@ -0,0 +1,5 @@
+-------------------------- MODULE InstanceOpArg -----------------------------
+CONSTANTS c2, foo2(_,_)
+INSTANCE OpArg WITH c <- c2, foo <- foo2
+
+=======================================================================
diff --git a/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArg2.tla b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArg2.tla
new file mode 100644
index 0000000000000000000000000000000000000000..72a3bb64df1b6e79622182987c51c3f11e23209c
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArg2.tla
@@ -0,0 +1,7 @@
+-------------- MODULE InstanceOpArg2 ----------------
+EXTENDS Naturals
+CONSTANTS c2
+bar(a,b) == a + b 
+INSTANCE OpArg WITH c <- c2, foo <- bar
+ASSUME def /\ c2 = 3 
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArg3.cfg b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArg3.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..016dd9c9c87a0fb70651f40e8af1d3e3da0bc30d
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArg3.cfg
@@ -0,0 +1 @@
+CONSTANTS bar <- bazz
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArg3.tla b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArg3.tla
new file mode 100644
index 0000000000000000000000000000000000000000..7b37512bf2d05d014722c0b7dc9db29b0f51ceb1
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArg3.tla
@@ -0,0 +1,7 @@
+-------------- MODULE InstanceOpArg3 ----------------
+EXTENDS Naturals
+CONSTANTS c2, bar(_,_)
+bazz(a,b) == a + b
+INSTANCE OpArg WITH c <- c2, foo <- bar
+ASSUME def /\ c2 = 3
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArgException.tla b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArgException.tla
new file mode 100644
index 0000000000000000000000000000000000000000..0d79faacfda771f54fd5385e3a7415b914b9594c
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceOpArgException.tla
@@ -0,0 +1,6 @@
+-------------- MODULE InstanceOpArgException ----------------
+EXTENDS Naturals
+CONSTANTS c2, bar(_,_)
+INSTANCE OpArg WITH c <- c2, foo <- bar
+ASSUME def /\ c2 = 3 
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/constantSubstitution/InstanceValue.tla b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceValue.tla
new file mode 100644
index 0000000000000000000000000000000000000000..1b29c5f56f7706acc5b3a362389689431dae235c
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceValue.tla
@@ -0,0 +1,6 @@
+-------------- MODULE InstanceValue ----------------
+EXTENDS Naturals
+CONSTANTS c
+INSTANCE Value WITH val <- 1+1
+ASSUME def
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/constantSubstitution/InstanceValue2.tla b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceValue2.tla
new file mode 100644
index 0000000000000000000000000000000000000000..a6e649e164c07842e2d71c67dc25d838f4ac823b
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/constantSubstitution/InstanceValue2.tla
@@ -0,0 +1,6 @@
+-------------- MODULE InstanceValue2 ----------------
+EXTENDS Naturals
+CONSTANTS c, val2
+INSTANCE Value WITH val <- val2
+ASSUME def /\ val2 = 1
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/constantSubstitution/OpArg.tla b/src/test/resources/prettyprint/instance/constantSubstitution/OpArg.tla
new file mode 100644
index 0000000000000000000000000000000000000000..d129ef51a7e4112c0c1d9165f48d3416b9b6882c
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/constantSubstitution/OpArg.tla
@@ -0,0 +1,5 @@
+-------------------------- MODULE OpArg -----------------------------
+CONSTANTS c, foo(_,_)
+def == c = foo(1,2)
+
+=======================================================================
diff --git a/src/test/resources/prettyprint/instance/constantSubstitution/Value.tla b/src/test/resources/prettyprint/instance/constantSubstitution/Value.tla
new file mode 100644
index 0000000000000000000000000000000000000000..366f450e641cc29eb1f8b52fb6033aa8c6a007c8
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/constantSubstitution/Value.tla
@@ -0,0 +1,6 @@
+-------------------------- MODULE Value -----------------------------
+EXTENDS Naturals
+CONSTANTS c, val
+def == c = val
+
+=======================================================================
diff --git a/src/test/resources/prettyprint/instance/let/InstanceLet.mch b/src/test/resources/prettyprint/instance/let/InstanceLet.mch
new file mode 100644
index 0000000000000000000000000000000000000000..39f7baa86628f762aa896dc57e8d51e5e12aee8e
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/let/InstanceLet.mch
@@ -0,0 +1,26 @@
+MACHINE InstanceLet
+DEFINITIONS
+ inst_Init == c = 1;
+
+ inst_val == 4;
+
+ inst_foo(p) == 1 + e + p;
+ inst_Next == #e.(e : {1, 2} & c_n = c + inst_foo(3) + inst_val);
+
+ inst2_Init == c2 = 1;
+
+ inst2_val == 4;
+
+ inst2_foo(p) == 1 + e + p;
+ inst2_Next == #e.(e : {1, 2} & c2_n = c2 + inst2_foo(3) + inst2_val)
+VARIABLES c, c2
+INVARIANT
+ c : INTEGER
+ & c2 : INTEGER
+INITIALISATION
+ c, c2:(inst_Init & inst2_Init)
+OPERATIONS
+ Next_Op = ANY c_n, c2_n
+	WHERE c_n : INTEGER & c2_n : INTEGER & inst_Next & inst2_Next
+	THEN c, c2 := c_n, c2_n END
+END
diff --git a/src/test/resources/prettyprint/instance/let/InstanceLet.tla b/src/test/resources/prettyprint/instance/let/InstanceLet.tla
new file mode 100644
index 0000000000000000000000000000000000000000..91f6f079b2169857c61d0a0321ecefe927eb2c59
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/let/InstanceLet.tla
@@ -0,0 +1,7 @@
+-------------- MODULE InstanceLet ----------------
+VARIABLES c, c2
+inst == INSTANCE Let WITH x <- c
+inst2 == INSTANCE Let WITH x <- c2
+Init == inst!Init /\ inst2!Init
+Next == inst!Next /\ inst2!Next
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/instance/let/Let.tla b/src/test/resources/prettyprint/instance/let/Let.tla
new file mode 100644
index 0000000000000000000000000000000000000000..e715e11af7b1ae46c0fbcff449d9e923ca0f812b
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/let/Let.tla
@@ -0,0 +1,14 @@
+---------------------------- MODULE Let -------------------------------
+EXTENDS Naturals
+VARIABLES x
+-----------------------------------------------------------------------------
+Init == x = 1
+val == 4
+Next ==  
+	\E e \in {1,2}:
+	LET
+		foo(p) == 1 + e + p
+	IN
+		x' =  x + foo(3) + val
+=============================================================================
+
diff --git a/src/test/resources/prettyprint/instance/twoInstanced/first.tla b/src/test/resources/prettyprint/instance/twoInstanced/first.tla
new file mode 100644
index 0000000000000000000000000000000000000000..3a03509da1cd4b153600b0dd37de4a89a9a39b72
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/twoInstanced/first.tla
@@ -0,0 +1,5 @@
+-------------------------- MODULE first -----------------------------
+EXTENDS Naturals
+CONSTANTS c2
+INSTANCE second WITH c1 <- c2
+=======================================================================
diff --git a/src/test/resources/prettyprint/instance/twoInstanced/second.tla b/src/test/resources/prettyprint/instance/twoInstanced/second.tla
new file mode 100644
index 0000000000000000000000000000000000000000..d41e27a04046fe739ec5bbee89ee0be663fbafca
--- /dev/null
+++ b/src/test/resources/prettyprint/instance/twoInstanced/second.tla
@@ -0,0 +1,6 @@
+-------------------------- MODULE first -----------------------------
+EXTENDS Naturals
+CONSTANTS c1
+
+val == c1 + 1
+=======================================================================
diff --git a/src/test/resources/prettyprint/realworld/FastPaxos.cfg b/src/test/resources/prettyprint/realworld/FastPaxos.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..abc34f264e9817eac70466647bbf4e109f3fa4d5
--- /dev/null
+++ b/src/test/resources/prettyprint/realworld/FastPaxos.cfg
@@ -0,0 +1,11 @@
+INIT Init
+NEXT Next
+CONSTANTS
+  ClassicNum = {1,3}
+  FastNum    = {2}
+  Acceptor   = {a1,a2,a3}
+  PVal       = {v1,v2}
+  any = any
+  a1=a1 a2=a2 a3=a3  v1=v1 v2=v2
+  Max <- MaxOfSet
+INVARIANT TypeOK
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/realworld/FastPaxos.tla b/src/test/resources/prettyprint/realworld/FastPaxos.tla
new file mode 100644
index 0000000000000000000000000000000000000000..1b7faa5424bb1afbdc7071dc347360787b15d677
--- /dev/null
+++ b/src/test/resources/prettyprint/realworld/FastPaxos.tla
@@ -0,0 +1,178 @@
+------------------------------ MODULE FastPaxos -----------------------------
+EXTENDS Naturals
+CONSTANTS PVal, Acceptor, FastNum, ClassicNum, a1, a2, a3, v1, v2
+
+NextNum(a) == IF a+1 \in FastNum \cup ClassicNum THEN a+1 ELSE 0
+
+RNum == FastNum \cup ClassicNum
+
+any == CHOOSE v : v \notin PVal
+
+i \prec j == i < j 
+i \preceq j == (i \prec j) \/ (i = j)
+
+MaxOfSet(S) == CHOOSE p \in S: \A n \in S: p \geq n
+Max(S) == CHOOSE i \in S : \A j \in S : j \preceq i
+Message ==
+       [type : {"propose"}, pval : PVal]
+  \cup [type : {"phase1a"}, rnd : RNum]
+  \cup [type : {"phase1b"}, rnd : RNum, vrnd : RNum \cup {0}, 
+         pval : PVal \cup {any}, acc : Acceptor]
+  \cup [type : {"phase2a"}, rnd : RNum, pval : PVal \cup {any}]
+  \cup [type : {"phase2b"}, rnd : RNum, pval : PVal, acc : Acceptor]
+
+Quorum(i) == IF i \in ClassicNum THEN {{a1,a2}, {a1,a3}, {a2, a3}}
+                                   ELSE {{a1,a2,a3}}
+
+
+
+ASSUME 
+  /\ FastNum \cap ClassicNum = {}
+  /\ \A i, j, k \in RNum : (i \prec j) /\ (j \prec k) => (i \prec k)
+  /\ \A i \in RNum : ~(i \prec i)
+  /\ \A i, j \in RNum : (i \preceq j) \/ (j \preceq i)
+  /\ (0 \notin RNum) /\ \A i \in RNum : 0 \prec i
+  /\ \A i \in FastNum : NextNum(i) \in RNum => 
+                          ~\E j \in RNum : (i \prec j) /\ (j \prec NextNum(i))
+                          
+                          
+
+VARIABLES rnd, vrnd, pval, sentMsg, learned
+vars == <<rnd, vrnd, pval, sentMsg, learned>>
+
+TypeOK == 
+  /\ rnd  \in [Acceptor -> RNum \cup {0}]
+  /\ vrnd \in [Acceptor -> RNum \cup {0}]
+  /\ pval \in [Acceptor -> PVal \cup {any}]
+  /\ sentMsg  \in SUBSET Message
+  /\ learned  \in SUBSET PVal
+
+Init ==
+  /\ rnd  = [a \in Acceptor |-> 0]
+  /\ vrnd = [a \in Acceptor |-> 0]
+  /\ pval = [a \in Acceptor |-> any]
+  /\ sentMsg  = {}
+  /\ learned  = {}
+-----------------------------------------------------------------------------
+Send(m) == sentMsg' = sentMsg \cup {m}
+
+Propose(v) ==  
+  /\ Send([type |-> "propose", pval |-> v])
+  /\ UNCHANGED <<rnd, vrnd, pval, learned>>
+  
+Phase1a(i) == 
+  /\ Send([type |-> "phase1a", rnd |-> i])
+  /\ UNCHANGED <<rnd, vrnd, pval, learned>>
+
+Phase1b(a, i) ==
+  /\ rnd[a] \prec i
+  /\ \E m \in sentMsg : (m.type = "phase1a") /\ (m.rnd = i)
+  /\ rnd' = [rnd EXCEPT ![a] = i]
+  /\ Send([type |-> "phase1b", rnd |-> i, vrnd |-> vrnd[a], pval |-> pval[a], 
+           acc |-> a])
+  /\ UNCHANGED <<vrnd, pval, learned>>
+
+P1bMsg(Q, i) == 
+   {m \in sentMsg : (m.type = "phase1b") /\ (m.acc \in Q) /\ (m.rnd = i)}
+
+SafeSet(M, Q, i) ==
+    LET k  == Max({m.vrnd : m \in M})
+        Vk == {m.pval : m \in {mm \in M : mm.vrnd = k}}
+        Only(v) == \/ Vk = {v}
+                   \/ /\ k \in FastNum
+                      /\ \E R \in Quorum(k) : 
+                           \A a \in Q \cap R :
+                             \E m \in M : /\ m.vrnd = k
+                                          /\ m.pval = v
+                                          /\ m.acc = a
+    IN  IF k = 0 
+          THEN PVal
+          ELSE IF \E v \in  Vk : Only(v)
+                 THEN {CHOOSE v \in {v1}(*Vk*) : Only(v)}
+                 ELSE PVal                     
+
+Phase2a(i, va) ==
+  /\ ~\E m \in sentMsg : (m.type = "phase2a") /\ (m.rnd = i)
+  /\ \E Q \in Quorum(i) : 
+       /\ \A a \in Q : \E m \in sentMsg : /\ m.type = "phase1b"
+                                          /\ m.rnd  = i
+                                          /\ m.acc  = a
+       /\ \/ /\ va \in SafeSet(P1bMsg(Q,i), Q, i)
+             /\ \E m \in sentMsg : /\ m.type \in {"propose", "phase1b"} 
+                                   /\ m.pval = va
+          \/ /\ SafeSet(P1bMsg(Q,i), Q, i) = PVal
+             /\ i \in FastNum
+             /\ va = any
+  /\ Send([type |-> "phase2a", rnd |-> i, pval |-> va])
+  /\ UNCHANGED <<rnd, vrnd, pval, learned>>
+
+Phase2b(i, a, v) ==
+  /\ rnd[a] \preceq i
+  /\ vrnd[a] \prec i
+  /\ \E m \in sentMsg : 
+       /\ m.type = "phase2a"
+       /\ m.rnd = i
+       /\ \/ m.pval = v
+          \/ /\ m.pval = any
+             /\ \E mm \in sentMsg  : (mm.type = "propose") /\ (mm.pval = v)
+  /\ rnd' = [rnd EXCEPT ![a] = i]
+  /\ vrnd'  = [vrnd  EXCEPT ![a] = i]
+  /\ pval' = [pval EXCEPT ![a] = v]
+  /\ Send([type |-> "phase2b", rnd |-> i, pval |-> v, acc |-> a])
+  /\ UNCHANGED learned
+
+Learn(v) ==
+  /\ \E i \in RNum :
+       \E Q \in Quorum(i) : 
+         \A a \in Q : 
+           \E m \in sentMsg : /\ m.type = "phase2b"
+                              /\ m.rnd = i
+                              /\ m.pval = v
+                              /\ m.acc  = a
+  /\ learned' = learned \cup {v}
+  /\ UNCHANGED <<rnd, vrnd, pval, sentMsg>>
+-----------------------------------------------------------------------------
+P2bToP1b(Q, i) ==
+  LET iMsg == 
+        {m \in sentMsg : (m.type = "phase2b") /\ (m.rnd = i) /\ (m.acc \in Q)}
+  IN  {[type |-> "phase1b", rnd |-> NextNum(i), vrnd |-> i, 
+           pval |-> m.pval, acc |-> m.acc] : m \in iMsg}
+
+LeaderRecovery(i, v) ==
+  /\ ~\E m \in sentMsg : (m.type = "phase2a") /\ (m.rnd = NextNum(i))
+  /\ \E Q \in Quorum(i) : 
+        /\ \A a \in Q : \E m \in P2bToP1b(Q, i) : m.acc  = a
+        /\ v \in SafeSet(P2bToP1b(Q, i), Q, NextNum(i))
+        /\ \E m \in P2bToP1b(Q, i) : m.pval = v
+  /\ Send([type |-> "phase2a", rnd |-> NextNum(i), pval |-> v])
+  /\ UNCHANGED <<rnd, vrnd, pval, learned>>
+
+LeaderlessRecovery(i, a, v) ==  
+  /\ NextNum(i) \in FastNum
+  /\ rnd[a] = i
+  /\ vrnd[a] = i
+  /\ \E Q \in Quorum(i) : 
+        /\ \A b \in Q : \E m \in P2bToP1b(Q, i) : m.acc  = b
+        /\ v \in SafeSet(P2bToP1b(Q, i), Q, NextNum(i))
+        /\ \E m \in P2bToP1b(Q, i): m.pval = v
+  /\ rnd' = [rnd EXCEPT ![a] = NextNum(i)]
+  /\ vrnd'  = [vrnd  EXCEPT ![a] = NextNum(i)]
+  /\ pval' = [pval EXCEPT ![a] = v]
+  /\ Send([type |-> "phase2b", rnd |-> NextNum(i), pval |-> v, acc |-> a])
+  /\ UNCHANGED learned
+
+
+-----------------------------------------------------------------------------
+Next ==
+  \/ \E v \in PVal : Propose(v) \/  Learn(v)
+  \/ \E i \in RNum : \/ Phase1a(i)
+                     \/ \E a \in Acceptor : \/ Phase1b(a, i)
+                                            \/ \E v \in PVal : Phase2b(i, a, v)
+                     \/ \E va \in PVal \cup {any} : Phase2a(i, va)
+  \/ \E i \in FastNum, v \in PVal : 
+         \/ LeaderRecovery(i, v)
+         \/ \E a \in Acceptor :LeaderlessRecovery(i, a, v)
+
+
+
+=============================================================================
diff --git a/src/test/resources/prettyprint/realworld/ManyAssumes.tla b/src/test/resources/prettyprint/realworld/ManyAssumes.tla
new file mode 100644
index 0000000000000000000000000000000000000000..64d96f930c9bd6268f40a9cb4821098b58b65536
--- /dev/null
+++ b/src/test/resources/prettyprint/realworld/ManyAssumes.tla
@@ -0,0 +1,518 @@
+----- MODULE ManyAssumes -----
+CONSTANTS a, b, c, d
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+ASSUME a = 1 /\ b = 1 /\ c = 1 /\ d = 1
+
+
+
+
+==========
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/realworld/fowler.mch b/src/test/resources/prettyprint/realworld/fowler.mch
new file mode 100644
index 0000000000000000000000000000000000000000..7b52dd004d45604ce2eebca929c6dc8abd8b97a1
--- /dev/null
+++ b/src/test/resources/prettyprint/realworld/fowler.mch
@@ -0,0 +1,55 @@
+MACHINE fowler
+DEFINITIONS
+ Init == state = "idle"
+	 & light = "off"
+	 & draw = "closed"
+	 & door = "unlocked"
+	 & panel = "locked"
+VARIABLES state, light, draw, panel, door
+INVARIANT
+ state : STRING
+ & light : STRING
+ & draw : STRING
+ & panel : STRING
+ & door : STRING
+INITIALISATION
+ state, light, draw, panel, door:(Init)
+OPERATIONS
+ CloseDoor_Op = ANY state_n, door_n
+	WHERE state_n : STRING & door_n : STRING & door = "unlocked"
+	 & door_n = "locked"
+	 & state_n = "active"
+	 & TRUE = TRUE
+	THEN state, door := state_n, door_n END;
+
+ LightOn_Op = ANY state_n, light_n, panel_n, door_n
+	WHERE state_n : STRING & light_n : STRING & panel_n : STRING & door_n : STRING & light = "off"
+	 & light_n = "on"
+	 & ((draw = "opened" 
+	  => state_n = "unlockedPanel" & panel_n = "unlocked" & door_n = "locked") 
+	 & (not(draw = "opened") 
+	  => state_n = "waitingForDraw"
+	  & panel_n = panel & door_n = door))
+	  & TRUE = TRUE
+	THEN state, light, panel, door := state_n, light_n, panel_n, door_n END;
+
+ OpenDraw_Op = ANY state_n, draw_n, panel_n, door_n
+	WHERE state_n : STRING & draw_n : STRING & panel_n : STRING & door_n : STRING & draw = "closed"
+	 & draw_n = "opened"
+	 & ((light = "on" 
+	  => state_n = "unlockedPanel" & panel_n = "unlocked" & door_n = "locked") 
+	 & (not(light = "on") 
+	  => state_n = "waitingForLight"
+	  & panel_n = panel & door_n = door))
+	  & TRUE = TRUE
+	THEN state, draw, panel, door := state_n, draw_n, panel_n, door_n END;
+
+ ClosePanel_Op = ANY state_n, light_n, draw_n, panel_n, door_n
+	WHERE state_n : STRING & light_n : STRING & draw_n : STRING & panel_n : STRING & door_n : STRING & panel = "unlocked"
+	 & panel_n = "locked"
+	 & light_n = "off"
+	 & draw_n = "closed"
+	 & door_n = "unlocked"
+	 & state_n = "idle"
+	THEN state, light, draw, panel, door := state_n, light_n, draw_n, panel_n, door_n END
+END
diff --git a/src/test/resources/prettyprint/realworld/fowler.tla b/src/test/resources/prettyprint/realworld/fowler.tla
new file mode 100644
index 0000000000000000000000000000000000000000..09288eb98665a0bfbf2880c807f3cf255d73c8a5
--- /dev/null
+++ b/src/test/resources/prettyprint/realworld/fowler.tla
@@ -0,0 +1,120 @@
+---------------------------- MODULE fowler ------------------------------------
+(*****************************************************************************)
+(* Controller of the secret compartment of Mrs. H, who loves secrets!        *)
+(* Following the example of M. Fowler,                                       *)
+(* which can be found at: `^http://martinfowler.com/^'                       *)
+(*****************************************************************************)
+
+(*****************************************************************************)
+(* Variables                                                                 *)
+(*****************************************************************************)
+VARIABLE 
+  state, \* the state for display, only to be compliant with Fowler 
+  light, \* state of the light     
+  draw,  \* state of the draw
+  panel, \* state of the secret panel
+  door   \* state of the entry door
+
+(*****************************************************************************)
+(* Type invariance                                                           *)
+(*****************************************************************************)
+TypeInv == 
+  /\ state \in { "idle", "active", "waitingForDraw", 
+                 "waitingForLight", "unlockedPanel" }
+  /\ light \in { "on", "off" }
+  /\ draw \in { "opened", "closed" }
+  /\ door \in { "locked", "unlocked"}
+  /\ panel \in { "locked", "unlocked" }
+(*****************************************************************************)
+(* Initial state                                                             *)
+(*****************************************************************************)
+Init == 
+  /\ state = "idle"
+  /\ light = "off"
+  /\ draw  = "closed"
+  /\ door  = "unlocked"
+  /\ panel = "locked"
+------------------------------------------------------------------------------- 
+(*****************************************************************************)
+(* Action definition.                                                        *)
+(* Note that the state variable is not                                       *)
+(* used for the determination of the                                         *)
+(* actual state, but only for display.                                       *)
+(* This shows that this variable                                             *)
+(* is not required in TLA+                                                   *)
+(*****************************************************************************)
+  
+(*****************************************************************************)
+(* Closes the door, to activate                                              *)
+(*****************************************************************************)
+CloseDoor == 
+  /\ door = "unlocked"
+  /\ door' = "locked"
+  /\ state' = "active"
+  /\ UNCHANGED << panel, light, draw >>
+(*****************************************************************************)
+(* Switch on the light, if the draw is                                       *)
+(* opened, this opens the secret panel                                       *)
+(*****************************************************************************)
+LightOn == 
+  /\ light = "off"
+  /\ light' = "on"
+  /\ IF draw = "opened" THEN 
+       /\ state' = "unlockedPanel"
+	   /\ panel' = "unlocked"
+	   /\ door' = "locked"
+	 ELSE 
+	   /\ state' = "waitingForDraw"
+	   /\ UNCHANGED << panel, door >>
+  /\ UNCHANGED << draw >>
+(*****************************************************************************)
+(* Open the draw, if the light is on,                                        *)
+(* this opens the secret panel                                               *)
+(*****************************************************************************)
+OpenDraw ==
+  /\ draw = "closed"
+  /\ draw' = "opened"
+  /\ IF light = "on" THEN 
+       /\ state' = "unlockedPanel"
+	   /\ panel' = "unlocked"
+	   /\ door' = "locked"
+	 ELSE 
+	   /\ state' = "waitingForLight"
+	   /\ UNCHANGED << panel, door >>
+  /\ UNCHANGED << light >>
+(*****************************************************************************)
+(* Closes the secret panel and move the                                      *)
+(* system to initial state                                                   *)
+(*****************************************************************************)
+ClosePanel ==
+  /\ panel = "unlocked"
+  /\ panel' = "locked"
+  /\ light' = "off"
+  /\ draw' = "closed"
+  /\ door' = "unlocked"
+  /\ state' = "idle"
+-------------------------------------------------------------------------------
+(*****************************************************************************)
+(* All possible actions                                                      *)
+(*****************************************************************************)
+Next == 
+  \/ CloseDoor 
+  \/ LightOn 
+  \/ OpenDraw 
+  \/ ClosePanel
+(*****************************************************************************)
+(* Specification of the entire system                                        *)
+(*****************************************************************************)
+Spec == Init /\ [][Next]_<< panel, light, draw, door, state >>
+
+(*****************************************************************************)
+(* Specification never violates the type invariance                          *)
+(*****************************************************************************)
+THEOREM Spec => []TypeInv
+(*****************************************************************************)
+(* The panel and door are never both unlocked in the same time               *)
+(*****************************************************************************)
+Inv == 
+  \/ panel = "unlocked" => door = "locked"  
+  \/ door = "unlocked" => panel = "locked" 
+===============================================================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/realworld/microwave.cfg b/src/test/resources/prettyprint/realworld/microwave.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..97359debc947e0aa4856f7b06f9e06cce96b35fa
--- /dev/null
+++ b/src/test/resources/prettyprint/realworld/microwave.cfg
@@ -0,0 +1,2 @@
+SPECIFICATION Spec
+INVARIANT Door_Locked_When_Heating
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/realworld/microwave.mch b/src/test/resources/prettyprint/realworld/microwave.mch
new file mode 100644
index 0000000000000000000000000000000000000000..9a31d390f00429985df08f9d5946dfa82c35a097
--- /dev/null
+++ b/src/test/resources/prettyprint/realworld/microwave.mch
@@ -0,0 +1,94 @@
+MACHINE microwave
+DEFINITIONS
+ Init == magnetron_running = FALSE
+	 & door_open = FALSE
+	 & button_locked = FALSE
+	 & error = FALSE
+	 & time = 0;
+
+ Action_Start == error = FALSE
+	 & magnetron_running = FALSE
+	 & door_open = FALSE
+	 & time /= 0
+	 & magnetron_running_n = TRUE
+	 & button_locked_n = TRUE
+	 & door_open_n = door_open & time_n = time & error_n = error;
+
+ Action_Stop == magnetron_running = TRUE
+	 & magnetron_running_n = FALSE
+	 & button_locked_n = FALSE
+	 & time_n = 0
+	 & door_open_n = door_open & error_n = error;
+
+ Door_Locked_When_Heating == (magnetron_running = TRUE => door_open = FALSE)
+	 & (magnetron_running = TRUE => button_locked = TRUE);
+
+VARIABLES magnetron_running, door_open, button_locked, time, error
+INVARIANT
+ magnetron_running : BOOL
+ & door_open : BOOL
+ & button_locked : BOOL
+ & time : INTEGER
+ & error : BOOL
+ & Door_Locked_When_Heating
+INITIALISATION
+ magnetron_running, door_open, button_locked, time, error:(Init)
+OPERATIONS
+ Action_Open_Door_Op = ANY door_open_n
+	WHERE door_open_n : BOOL & button_locked = FALSE
+	 & magnetron_running = FALSE
+	 & door_open = FALSE
+	 & door_open_n = TRUE
+	 & TRUE = TRUE
+	THEN door_open := door_open_n END;
+
+ Action_Close_Door_Op = ANY door_open_n
+	WHERE door_open_n : BOOL & door_open = TRUE
+	 & door_open_n = FALSE
+	 & TRUE = TRUE
+	THEN door_open := door_open_n END;
+
+ Action_Change_Time_Op = ANY time_n
+	WHERE time_n : INTEGER & magnetron_running = FALSE
+	 & (time = 180
+	 & time_n = 120
+	 or (time = 120
+	 & time_n = 90)
+	 or (time = 90
+	 & time_n = 60)
+	 or (time = 60
+	 & time_n = 30)
+	 or (time = 30
+	 & time_n = 15)
+	 or (time = 15
+	 & time_n = 180)
+	 or (time = 0
+	 & time_n = 180))
+	 & TRUE = TRUE
+	THEN time := time_n END;
+
+ Action_Button_S_Op = ANY magnetron_running_n, door_open_n, button_locked_n, time_n, error_n
+	WHERE magnetron_running_n : BOOL & door_open_n : BOOL & button_locked_n : BOOL & time_n : INTEGER & error_n : BOOL & (magnetron_running = FALSE 
+	  => Action_Start) 
+	 & (not(magnetron_running = FALSE) 
+	  => Action_Stop)
+	THEN magnetron_running, door_open, button_locked, time, error := magnetron_running_n, door_open_n, button_locked_n, time_n, error_n END;
+
+ Action_Error_Op = ANY magnetron_running_n, error_n
+	WHERE magnetron_running_n : BOOL & error_n : BOOL & error_n = TRUE
+	 & magnetron_running_n = FALSE
+	 & TRUE = TRUE
+	THEN magnetron_running, error := magnetron_running_n, error_n END;
+
+ Action_Tick_Op = ANY magnetron_running_n, door_open_n, button_locked_n, time_n, error_n
+	WHERE magnetron_running_n : BOOL & door_open_n : BOOL & button_locked_n : BOOL & time_n : INTEGER & error_n : BOOL & magnetron_running = TRUE
+	 & ((time /= 1 
+	  => time_n = time - 1
+	  & door_open_n = door_open & magnetron_running_n = magnetron_running & button_locked_n = button_locked & error_n = error) 
+	 & (not(time /= 1) 
+	  => time_n = 0
+	  & magnetron_running_n = FALSE
+	  & button_locked_n = FALSE
+	  & door_open_n = door_open & error_n = error))
+	THEN magnetron_running, door_open, button_locked, time, error := magnetron_running_n, door_open_n, button_locked_n, time_n, error_n END
+END
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/realworld/microwave.tla b/src/test/resources/prettyprint/realworld/microwave.tla
new file mode 100644
index 0000000000000000000000000000000000000000..e6962e4928806644cb098f1a35c0559ea5046752
--- /dev/null
+++ b/src/test/resources/prettyprint/realworld/microwave.tla
@@ -0,0 +1,175 @@
+---- MODULE microwave ----
+EXTENDS Naturals
+
+VARIABLES
+magnetron_running,
+door_open,
+button_locked,
+time,
+error
+
+allvars == <<magnetron_running, door_open, button_locked, time, error>>
+
+\* Initialisierung - die Mikrowelle ist aus, die Tuer geschlossen
+Init ==
+    /\ magnetron_running = FALSE
+    /\ door_open = FALSE
+    /\ button_locked = FALSE
+    /\ error = FALSE
+    /\ time = 0
+
+\* Repraesentiert den Benutzer, der die Tuer oeffnet
+Action_Open_Door ==
+    /\ button_locked = FALSE
+    /\ magnetron_running = FALSE
+    /\ door_open = FALSE
+    /\ door_open' = TRUE
+    /\ UNCHANGED <<magnetron_running, button_locked, time, error>>
+   
+\* Repraesentiert den Benutzer, der die Tuer schliesst
+Action_Close_Door ==
+    /\ door_open = TRUE
+    /\ door_open' = FALSE
+    /\ UNCHANGED <<magnetron_running, button_locked, time, error>>
+    
+\* Setzt die Zeit auf die (festen) Werte
+\* Wenn die Mikrowelle gestoppt wird, ist die Zeit wieder Null
+Action_Change_Time ==
+    /\ magnetron_running = FALSE
+    /\ \/ /\ time = 180
+          /\ time' = 120
+       \/ /\ time = 120
+          /\ time' = 90
+       \/ /\ time = 90
+          /\ time' = 60
+       \/ /\ time = 60
+          /\ time' = 30
+       \/ /\ time = 30
+          /\ time' = 15
+       \/ /\ time = 15
+          /\ time' = 180
+       \/ /\ time = 0
+          /\ time' = 180
+    /\ UNCHANGED <<magnetron_running, door_open, button_locked, error>>
+    
+\* Starten der Mikrowelle: Magnetron an, Knopf gesperrt
+Action_Start ==
+    /\ error = FALSE                        \* Kein Fehlerzustand    
+    /\ magnetron_running = FALSE
+    /\ door_open = FALSE                    \* Die Tuer muss geschlossen sein
+    /\ time /= 0
+    /\ magnetron_running' = TRUE
+    /\ button_locked' = TRUE
+    /\ UNCHANGED <<door_open, time, error>>
+
+\* Stoppen der Mikrowelle: Magnetron aus, Sperre loesen   
+Action_Stop ==
+    /\ magnetron_running = TRUE             \* Nur wenn eingeschaltet
+    /\ magnetron_running' = FALSE
+    /\ button_locked' = FALSE
+    /\ time' = 0
+    /\ UNCHANGED <<door_open, error>>
+    
+\* Wenn die Mikrowelle laeuft, stoppt Knopf S sie,
+\* wenn sie nicht laeuft, startet S
+Action_Button_S ==
+    IF magnetron_running = FALSE
+    THEN Action_Start
+    ELSE Action_Stop
+    
+\* Ein Fehler tritt auf. Einschalten soll nicht mehr moeglich sein.
+\* Fehlerzustand kann nur durch Neustart des Modells verlassen werden
+Action_Error ==
+    /\ error' = TRUE
+    /\ magnetron_running' = FALSE
+    /\ UNCHANGED <<door_open, button_locked, time>>
+    
+\* Tick: Eine Sekunde vergeht
+Action_Tick ==
+    /\ magnetron_running = TRUE
+    /\ IF time /= 1
+       THEN /\ time' = time - 1
+            /\ UNCHANGED <<door_open, magnetron_running, button_locked, error>>
+       ELSE /\ time' = 0                    \* Wenn der Timer 0 erreicht,
+            /\ magnetron_running' = FALSE   \* Mikrowelle abschalten
+            /\ button_locked' = FALSE       \* Und Sperre loesen
+            /\ UNCHANGED <<door_open, error>>
+        
+Next ==
+    \/ Action_Open_Door
+    \/ Action_Close_Door
+    \/ Action_Change_Time
+    \/ Action_Button_S
+    \/ Action_Error
+    \/ Action_Tick
+
+\* Typinvariante
+TypeInvariant ==
+    /\ magnetron_running \in BOOLEAN
+    /\ door_open \in BOOLEAN
+    /\ button_locked \in BOOLEAN
+    /\ error \in BOOLEAN
+    /\ time \in 0..180
+
+\* Die Spezifikation
+\* Start mit Init, dann unendlich viele Next-Schritte
+\* - Die ersten drei Fairness Angaben repraesentieren den Benutzer,
+\*   der die Mikrowelle verwendet (noetig fuer Liveness Beweise)
+\* - Das letzte Fairness Statement bedeutet, dass das Tick-Ereignis
+\*   ausgefuehrt werden muss (die Zeit darf nicht stehen bleiben)
+Spec == 
+    /\ Init
+    /\ [][Next]_allvars
+    /\ SF_allvars (Action_Change_Time)
+    /\ SF_allvars (Action_Button_S)
+    /\ SF_allvars (Action_Close_Door)
+    /\ SF_allvars (Action_Tick)
+    
+----
+THEOREM Spec => []TypeInvariant
+----
+\* Die folgenden Statements werden per Modelcheck geprueft
+
+\* Wenn das Magnetron laeuft, ist die Tuer geschlossen
+\* und der Knopf gesperrt
+Door_Locked_When_Heating == 
+    /\ magnetron_running = TRUE => door_open = FALSE
+    /\ magnetron_running = TRUE => button_locked = TRUE
+    
+\* Die Zeit kann nur geaendert werden, wenn die Mikrowelle nicht laeuft
+Only_Change_Time_When_Off ==
+    magnetron_running = TRUE => \neg ENABLED Action_Change_Time
+    
+\* Die Mirkowelle laeuft nicht dauerhaft
+Not_Constantly_Heating ==
+    [] <> (magnetron_running = FALSE)
+    
+\* Wenn ein Fehler auftritt, heizt die Mikrowelle nicht (mehr)
+No_Heating_Error_State ==
+    error = TRUE => magnetron_running = FALSE
+    
+\* Die Mikrowelle kann immer gestoppt werden, wenn sie laeuft
+Stopable_At_All_Times ==
+    magnetron_running = TRUE => ENABLED Action_Stop
+    
+\* Wenn die Mikrowelle heizt, ist die Zeit nicht Null
+Heating_Time_Not_Zero ==
+    magnetron_running = TRUE => time /= 0
+    
+\* Wenn der Knopf gedrueckt wird beginnt das heizen
+\* Wenn der Knopf aktiviert ist wird er irgendwann gedrueckt (Fairness)
+button1 == 
+    /\ magnetron_running = FALSE
+    /\ ENABLED Action_Button_S
+    /\ error = FALSE
+    => [] <> (magnetron_running = TRUE)
+\* Der Knopf ist die einzige Moeglichkeit, das Magnetron zu aktivieren   
+button2 ==
+    [] (\neg ENABLED Action_Start) => [] (magnetron_running = FALSE)
+    
+\* Liveness: Es gibt immer einen Punkt in der Zukunft,
+\*           an dem die Mikrowelle heizt.
+\* (es sei denn, ein Fehler tritt auf)
+Alive ==
+    [] <> (magnetron_running = TRUE \/ error = TRUE)
+====
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/standardModules/MinOfSet.tla b/src/test/resources/prettyprint/standardModules/MinOfSet.tla
new file mode 100644
index 0000000000000000000000000000000000000000..808f1cdd3a89fbacc36f42e96b5a9bae75a2b635
--- /dev/null
+++ b/src/test/resources/prettyprint/standardModules/MinOfSet.tla
@@ -0,0 +1,4 @@
+-------------- MODULE MinOfSet ----------------
+EXTENDS TLA2B
+ASSUME MinOfSet({1,2,3}) = 1
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/standardModules/PermutedSequences.tla b/src/test/resources/prettyprint/standardModules/PermutedSequences.tla
new file mode 100644
index 0000000000000000000000000000000000000000..3b4df8bd58b070db68b8903203aeb6fa93aae36d
--- /dev/null
+++ b/src/test/resources/prettyprint/standardModules/PermutedSequences.tla
@@ -0,0 +1,4 @@
+-------------- MODULE PermutedSequences ----------------
+EXTENDS TLA2B
+ASSUME PermutedSequences({1,2}) = {<<1,2>>,<<2,1>>}
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/standardModules/SetProduct.tla b/src/test/resources/prettyprint/standardModules/SetProduct.tla
new file mode 100644
index 0000000000000000000000000000000000000000..e3efb9532de40ad829a75c6581ee3558aa11760a
--- /dev/null
+++ b/src/test/resources/prettyprint/standardModules/SetProduct.tla
@@ -0,0 +1,4 @@
+-------------- MODULE SetProduct ----------------
+EXTENDS TLA2B
+ASSUME SetProduct({1,2,3}) = 6
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/standardModules/SetSummation.tla b/src/test/resources/prettyprint/standardModules/SetSummation.tla
new file mode 100644
index 0000000000000000000000000000000000000000..e8bae967f7281ac7603f071ae1cb7c93f9bb792b
--- /dev/null
+++ b/src/test/resources/prettyprint/standardModules/SetSummation.tla
@@ -0,0 +1,4 @@
+------------- MODULE SetSummation ----------------
+EXTENDS TLA2B
+ASSUME SetSummation({1,2,3}) = 6
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/standardModules/TLA2B.tla b/src/test/resources/prettyprint/standardModules/TLA2B.tla
new file mode 100644
index 0000000000000000000000000000000000000000..c4d1b5d2f962ca06b608c4ab482115a2cf895aeb
--- /dev/null
+++ b/src/test/resources/prettyprint/standardModules/TLA2B.tla
@@ -0,0 +1,9 @@
+--------- MODULE TLA2B ---------
+LOCAL INSTANCE Naturals
+LOCAL INSTANCE Sequences
+MinOfSet(S) == CHOOSE p \in S: \A n \in S: p \leq n
+MaxOfSet(S) == CHOOSE p \in S: \A n \in S: p \geq n
+SetProduct(S)  == S
+SetSummation(S) == S
+PermutedSequences(S) == S
+==============================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/unchanged/OneUnchangedVariable.mch b/src/test/resources/prettyprint/unchanged/OneUnchangedVariable.mch
new file mode 100644
index 0000000000000000000000000000000000000000..01eac55e9633c9630b66afc119ab898e4bfc282b
--- /dev/null
+++ b/src/test/resources/prettyprint/unchanged/OneUnchangedVariable.mch
@@ -0,0 +1,12 @@
+MACHINE OneUnchangedVariable
+VARIABLES a, b
+INVARIANT
+ a : INTEGER
+ & b : INTEGER
+INITIALISATION
+ a, b:(a = 0 & b = 0)
+OPERATIONS
+ Next_Op = ANY a_n
+	WHERE a_n : INTEGER & a = 1 & TRUE = TRUE
+	THEN a := a_n END
+END
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/unchanged/OneUnchangedVariable.tla b/src/test/resources/prettyprint/unchanged/OneUnchangedVariable.tla
new file mode 100644
index 0000000000000000000000000000000000000000..e96976aca605b20721773ed685d8d06198c4beae
--- /dev/null
+++ b/src/test/resources/prettyprint/unchanged/OneUnchangedVariable.tla
@@ -0,0 +1,5 @@
+-----MODULE OneUnchangedVariable -----
+VARIABLES a, b
+Init == a= 0 /\ b = 0
+Next == a = 1 /\ UNCHANGED b
+=================================
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/unchanged/SeveralUnchangedVariables.mch b/src/test/resources/prettyprint/unchanged/SeveralUnchangedVariables.mch
new file mode 100644
index 0000000000000000000000000000000000000000..9d5d58e93578d2ff7c4384b4f24ba6a90c040029
--- /dev/null
+++ b/src/test/resources/prettyprint/unchanged/SeveralUnchangedVariables.mch
@@ -0,0 +1,15 @@
+MACHINE SeveralUnchangedVariables
+VARIABLES a, b, c, d, e
+INVARIANT
+ a : INTEGER
+ & b : INTEGER
+ & c : INTEGER
+ & d : INTEGER
+ & e : INTEGER
+INITIALISATION
+ a, b, c, d, e:(a = 0 & b = 0 & c = 0 & d = 0 & e = 0)
+OPERATIONS
+ Next_Op = ANY a_n
+	WHERE a_n : INTEGER & a = 1 & TRUE = TRUE
+	THEN a := a_n END
+END
\ No newline at end of file
diff --git a/src/test/resources/prettyprint/unchanged/SeveralUnchangedVariables.tla b/src/test/resources/prettyprint/unchanged/SeveralUnchangedVariables.tla
new file mode 100644
index 0000000000000000000000000000000000000000..4bc2e367fbcf4f092a894391a027466db81b1c59
--- /dev/null
+++ b/src/test/resources/prettyprint/unchanged/SeveralUnchangedVariables.tla
@@ -0,0 +1,5 @@
+ ----- MODULE SeveralUnchangedVariables -----
+VARIABLES a,b,c,d,e
+Init == a= 0 /\ b = 0 /\ c = 0 /\ d = 0 /\ e = 0
+Next == a = 1 /\ UNCHANGED <<b,c,d,e>>
+=================================
\ No newline at end of file
diff --git a/src/test/resources/typechecking/modules/Counter.tla b/src/test/resources/typechecking/modules/Counter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..52482d3053e73d2f5b55d80b836c4e58ec1ff3d6
--- /dev/null
+++ b/src/test/resources/typechecking/modules/Counter.tla
@@ -0,0 +1,10 @@
+-------------------------- MODULE Counter -----------------------------
+EXTENDS Naturals
+CONSTANTS start
+VARIABLE x
+-----------------------------------------------------------------------
+Init  ==  x = start
+Inc == x' = x + 1
+Dec == x' = x - 1
+Next  ==  Inc \/ Dec
+=======================================================================
diff --git a/src/test/resources/typechecking/modules/Counter2.tla b/src/test/resources/typechecking/modules/Counter2.tla
new file mode 100644
index 0000000000000000000000000000000000000000..2dd5137a1f1f4d3037c43842a6982cf26b90edfa
--- /dev/null
+++ b/src/test/resources/typechecking/modules/Counter2.tla
@@ -0,0 +1,10 @@
+-------------------------- MODULE Counter2 -----------------------------
+EXTENDS Naturals
+CONSTANTS start
+VARIABLE x
+-----------------------------------------------------------------------
+Init  ==  x = start
+plus(a,b) == a + b
+Inc == x' = plus(x, 2)
+Next  ==  Inc
+=======================================================================
diff --git a/src/test/resources/typechecking/modules/ExtendsCounter.tla b/src/test/resources/typechecking/modules/ExtendsCounter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..224a5f096b79157393b654f41a8051c909514e02
--- /dev/null
+++ b/src/test/resources/typechecking/modules/ExtendsCounter.tla
@@ -0,0 +1,3 @@
+-------------- MODULE ExtendsCounter ----------------
+EXTENDS Counter
+=================================
diff --git a/src/test/resources/typechecking/modules/InstCounter.tla b/src/test/resources/typechecking/modules/InstCounter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..a79c0aeca4fc2564b0ba525da66e42fd6e612ce4
--- /dev/null
+++ b/src/test/resources/typechecking/modules/InstCounter.tla
@@ -0,0 +1,11 @@
+-------------------------- MODULE InstCounter -----------------------------
+EXTENDS Naturals
+CONSTANTS k
+VARIABLE u
+bar == 1
+inst == INSTANCE Counter WITH x <- u, start <- bar + k
+inst2 == INSTANCE Counter WITH x <- u, start <- bar + inst!val
+Init == inst!Init
+
+-----------------------------------------------------------------------
+=======================================================================
\ No newline at end of file
diff --git a/src/test/resources/typechecking/modules/InstanceValue.cfg b/src/test/resources/typechecking/modules/InstanceValue.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..266984b5d884ea42cf0766103c69fb7a19d3aa90
--- /dev/null
+++ b/src/test/resources/typechecking/modules/InstanceValue.cfg
@@ -0,0 +1 @@
+CONSTANTS c2 = 1
\ No newline at end of file
diff --git a/src/test/resources/typechecking/modules/InstanceValue.tla b/src/test/resources/typechecking/modules/InstanceValue.tla
new file mode 100644
index 0000000000000000000000000000000000000000..2e9335379f0e026861ae317e4dc180b88307f882
--- /dev/null
+++ b/src/test/resources/typechecking/modules/InstanceValue.tla
@@ -0,0 +1,5 @@
+-------------- MODULE InstanceValue ----------------
+CONSTANTS c2, val2
+INSTANCE Value WITH val <- val2, c <- c2
+ASSUME def
+=================================
\ No newline at end of file
diff --git a/src/test/resources/typechecking/modules/InstanceValue2Times.tla b/src/test/resources/typechecking/modules/InstanceValue2Times.tla
new file mode 100644
index 0000000000000000000000000000000000000000..949f9ad1668c2532dc184b9257f9cb6aeeac5067
--- /dev/null
+++ b/src/test/resources/typechecking/modules/InstanceValue2Times.tla
@@ -0,0 +1,6 @@
+ -------------- MODULE InstanceValue2Times ----------------
+CONSTANTS k, k2
+Inst == INSTANCE Value WITH val <- 1, c <- k
+Inst2 == INSTANCE Value WITH val <- TRUE, c <- k2
+ASSUME Inst!def /\ Inst2!def
+=================================
\ No newline at end of file
diff --git a/src/test/resources/typechecking/modules/InstanceValues2Times.tla b/src/test/resources/typechecking/modules/InstanceValues2Times.tla
new file mode 100644
index 0000000000000000000000000000000000000000..949f9ad1668c2532dc184b9257f9cb6aeeac5067
--- /dev/null
+++ b/src/test/resources/typechecking/modules/InstanceValues2Times.tla
@@ -0,0 +1,6 @@
+ -------------- MODULE InstanceValue2Times ----------------
+CONSTANTS k, k2
+Inst == INSTANCE Value WITH val <- 1, c <- k
+Inst2 == INSTANCE Value WITH val <- TRUE, c <- k2
+ASSUME Inst!def /\ Inst2!def
+=================================
\ No newline at end of file
diff --git a/src/test/resources/typechecking/modules/NamedInstanceCounter.tla b/src/test/resources/typechecking/modules/NamedInstanceCounter.tla
new file mode 100644
index 0000000000000000000000000000000000000000..7d242f88d24195b6e5630dae50ca0ff00909bdb6
--- /dev/null
+++ b/src/test/resources/typechecking/modules/NamedInstanceCounter.tla
@@ -0,0 +1,7 @@
+-------------- MODULE NamedInstanceCounter ----------------
+CONSTANTS start
+VARIABLES c
+count == INSTANCE Counter WITH x <- c
+Init == count!Init
+Next == count!Next
+=================================
\ No newline at end of file
diff --git a/src/test/resources/typechecking/modules/NamedInstancePoly.tla b/src/test/resources/typechecking/modules/NamedInstancePoly.tla
new file mode 100644
index 0000000000000000000000000000000000000000..bb4b9b3a6c9f580f32fc34271007bd57c025b533
--- /dev/null
+++ b/src/test/resources/typechecking/modules/NamedInstancePoly.tla
@@ -0,0 +1,5 @@
+-------------- MODULE NamedInstancePoly ----------------
+VARIABLES c
+count == INSTANCE Poly WITH x <- c
+Init == count!foo = 1
+=================================
\ No newline at end of file
diff --git a/src/test/resources/typechecking/modules/NamedInstancePoly2.tla b/src/test/resources/typechecking/modules/NamedInstancePoly2.tla
new file mode 100644
index 0000000000000000000000000000000000000000..85944c43bb260107065ab8cd7e85d9d4804a9b32
--- /dev/null
+++ b/src/test/resources/typechecking/modules/NamedInstancePoly2.tla
@@ -0,0 +1,5 @@
+-------------- MODULE NamedInstancePoly2 ----------------
+VARIABLES c
+count == INSTANCE Poly WITH x <- c
+Init == count!bar(1)
+=================================
\ No newline at end of file
diff --git a/src/test/resources/typechecking/modules/NamedInstancePoly3.tla b/src/test/resources/typechecking/modules/NamedInstancePoly3.tla
new file mode 100644
index 0000000000000000000000000000000000000000..77e062761ac7671415347a04be0ae4f8efa0248b
--- /dev/null
+++ b/src/test/resources/typechecking/modules/NamedInstancePoly3.tla
@@ -0,0 +1,8 @@
+----------- MODULE NamedInstancePoly3 ----------------
+VARIABLES c, c2
+count == INSTANCE Poly WITH x <- c
+count2 == INSTANCE Poly WITH x <- c2
+foo == count!foo = TRUE
+foo2 == count2!foo = 1
+Init == foo /\ foo2
+=================================
\ No newline at end of file
diff --git a/src/test/resources/typechecking/modules/NamedInstancePoly4.tla b/src/test/resources/typechecking/modules/NamedInstancePoly4.tla
new file mode 100644
index 0000000000000000000000000000000000000000..7ac2ec82c584a3bb0a23510e792a49b17213b63f
--- /dev/null
+++ b/src/test/resources/typechecking/modules/NamedInstancePoly4.tla
@@ -0,0 +1,7 @@
+-------------- MODULE NamedInstancePoly4 ----------------
+CONSTANTS k
+VARIABLES c
+poly == INSTANCE Poly WITH x <- c
+Init == poly!foo = TRUE
+ASSUME poly!baz(1,k)
+=================================
\ No newline at end of file
diff --git a/src/test/resources/typechecking/modules/Poly.tla b/src/test/resources/typechecking/modules/Poly.tla
new file mode 100644
index 0000000000000000000000000000000000000000..b4d1d8121ea07062557e4375e25525538bc929c3
--- /dev/null
+++ b/src/test/resources/typechecking/modules/Poly.tla
@@ -0,0 +1,7 @@
+-------------------------- MODULE Poly -----------------------------
+VARIABLE x
+-----------------------------------------------------------------------
+foo  ==  x
+bar(a) == x = a
+baz(a,b) == a = b
+=======================================================================
diff --git a/src/test/resources/typechecking/modules/Value.tla b/src/test/resources/typechecking/modules/Value.tla
new file mode 100644
index 0000000000000000000000000000000000000000..85a2df253e2e0e08fa356d589057b5422232710e
--- /dev/null
+++ b/src/test/resources/typechecking/modules/Value.tla
@@ -0,0 +1,5 @@
+-------------------------- MODULE Value -----------------------------
+CONSTANTS c, val
+def == c = val
+
+=======================================================================
diff --git a/src/test/resources/typechecking/modules/ext.tla b/src/test/resources/typechecking/modules/ext.tla
new file mode 100644
index 0000000000000000000000000000000000000000..68c7e74cd63fe6b97117aff2451ba70f9c7e04a5
--- /dev/null
+++ b/src/test/resources/typechecking/modules/ext.tla
@@ -0,0 +1,9 @@
+-------------------------- MODULE ext-----------------------------
+EXTENDS Naturals
+-----------------------------------------------------------------------
+
+ext1 == 1
+ext2 == 1
+ext5 == 1
+ext3 == 1
+=======================================================================
diff --git a/src/test/resources/typechecking/modules/test.tla b/src/test/resources/typechecking/modules/test.tla
new file mode 100644
index 0000000000000000000000000000000000000000..53debdc3b0700c5ebcf810ca420c0b7720dd80ad
--- /dev/null
+++ b/src/test/resources/typechecking/modules/test.tla
@@ -0,0 +1,5 @@
+-------------------------- MODULE test-----------------------------
+cc == INSTANCE ext
+-----------------------------------------------------------------------
+test == 1
+=======================================================================