diff --git a/src/main/java/de/b2tla/B2TLA.java b/src/main/java/de/b2tla/B2TLA.java
index bb0655a2de9aed0dfbe80f56fc2222bfac219b47..09df230e3fbd0f6cbe105808851188fda78f4a3f 100644
--- a/src/main/java/de/b2tla/B2TLA.java
+++ b/src/main/java/de/b2tla/B2TLA.java
@@ -35,6 +35,7 @@ public class B2TLA {
 	private B2TlaTranslator translator;
 	private TLCOutputInfo tlcOutputInfo;
 	private String ltlFormula;
+	private String constantsSetup;
 
 	public static void main(String[] args) throws IOException {
 		B2TLA b2tla = new B2TLA();
@@ -70,6 +71,7 @@ public class B2TLA {
 			throws IOException {
 		B2TLAGlobals.resetGlobals();
 		B2TLAGlobals.setDeleteOnExit(deleteFiles);
+		// B2TLAGlobals.setCleanup(true);
 		B2TLA b2tla = new B2TLA();
 		try {
 			b2tla.progress(args);
@@ -159,7 +161,7 @@ public class B2TLA {
 
 			} else if (args[index].toLowerCase().equals("-del")) {
 				B2TLAGlobals.setDeleteOnExit(true);
-			}else if (args[index].toLowerCase().equals("-workers")) {
+			} else if (args[index].toLowerCase().equals("-workers")) {
 				index = index + 1;
 				if (index == args.length) {
 					throw new B2TLAIOException(
@@ -167,8 +169,14 @@ public class B2TLA {
 				}
 				int workers = Integer.parseInt(args[index]);
 				B2TLAGlobals.setWorkers(workers);
-			}
-			else if (args[index].toLowerCase().equals("-ltlformula")) {
+			} else if (args[index].toLowerCase().equals("-constantssetup")) {
+				index = index + 1;
+				if (index == args.length) {
+					throw new B2TLAIOException(
+							"Error: String requiered after option '-constantsetup'.");
+				}
+				constantsSetup = args[index];
+			} else if (args[index].toLowerCase().equals("-ltlformula")) {
 				index = index + 1;
 				if (index == args.length) {
 					throw new B2TLAIOException(
@@ -202,7 +210,7 @@ public class B2TLA {
 			StopWatch.start("Parsing");
 			translator = new B2TlaTranslator(
 					machineFileNameWithoutFileExtension, getFile(),
-					this.ltlFormula);
+					this.ltlFormula, this.constantsSetup);
 			StopWatch.stop("Parsing");
 			StopWatch.start("Pure");
 			translator.translate();
diff --git a/src/main/java/de/b2tla/B2TLAGlobals.java b/src/main/java/de/b2tla/B2TLAGlobals.java
index 233b7cec3b07f8a20b3720e06aeb8a4b0b640fc5..8b1589d95d6b3ce0d0195345ec11e5b800357cec 100644
--- a/src/main/java/de/b2tla/B2TLAGlobals.java
+++ b/src/main/java/de/b2tla/B2TLAGlobals.java
@@ -16,6 +16,8 @@ public class B2TLAGlobals {
 	private static boolean translate;
 	private static boolean hideTLCConsoleOutput;
 	private static boolean createTraceFile;
+	
+	private static boolean cleanup;
 
 	private static int workers;
 	
@@ -36,6 +38,8 @@ public class B2TLAGlobals {
 		checkInvariant = true;
 		checkLTL = true;
 
+		setCleanup(true);
+		
 		workers = 1;
 		
 		// for debugging purposes
@@ -162,5 +166,13 @@ public class B2TLAGlobals {
 	public static int getWorkers(){
 		return B2TLAGlobals.workers;
 	}
+
+	public static boolean isCleanup() {
+		return cleanup;
+	}
+
+	public static void setCleanup(boolean cleanup) {
+		B2TLAGlobals.cleanup = cleanup;
+	}
 	
 }
diff --git a/src/main/java/de/b2tla/B2TlaTranslator.java b/src/main/java/de/b2tla/B2TlaTranslator.java
index b1f484c07729a0b5010674bf95bc16bd7547fcd2..e717c22239140f60646a3fcd72021ffb8679ea30 100644
--- a/src/main/java/de/b2tla/B2TlaTranslator.java
+++ b/src/main/java/de/b2tla/B2TlaTranslator.java
@@ -9,6 +9,7 @@ import de.b2tla.analysis.ConstantsEliminator;
 import de.b2tla.analysis.ConstantsEvaluator;
 import de.b2tla.analysis.DefinitionsAnalyser;
 import de.b2tla.analysis.MachineContext;
+import de.b2tla.analysis.NotSupportedConstructs;
 import de.b2tla.analysis.UnchangedVariablesFinder;
 import de.b2tla.analysis.PrecedenceCollector;
 import de.b2tla.analysis.PrimedNodesMarker;
@@ -24,6 +25,8 @@ import de.b2tla.tlc.TLCOutputInfo;
 import de.b2tla.util.StopWatch;
 import de.be4.classicalb.core.parser.BParser;
 import de.be4.classicalb.core.parser.exceptions.BException;
+import de.be4.classicalb.core.parser.node.APredicateParseUnit;
+import de.be4.classicalb.core.parser.node.PPredicate;
 import de.be4.classicalb.core.parser.node.Start;
 import de.be4.ltl.core.parser.node.TYesterday;
 
@@ -35,6 +38,7 @@ public class B2TlaTranslator {
 	private String configString;
 	private String machineName;
 	private String ltlFormula;
+	private PPredicate constantsSetup;
 	private ArrayList<STANDARD_MODULES> usedStandardModules;
 	private TLCOutputInfo tlcOutputInfo;
 
@@ -46,8 +50,9 @@ public class B2TlaTranslator {
 		start.apply(ast2String2);
 		System.out.println(ast2String2.toString());
 	}
-	
-	public B2TlaTranslator(String machineString, String ltlFormula) throws BException {
+
+	public B2TlaTranslator(String machineString, String ltlFormula)
+			throws BException {
 		this.machineString = machineString;
 		this.ltlFormula = ltlFormula;
 		BParser parser = new BParser("Testing");
@@ -57,30 +62,49 @@ public class B2TlaTranslator {
 		System.out.println(ast2String2.toString());
 	}
 
-	public B2TlaTranslator(String machineName, File machineFile, String ltlFormula)
+	public B2TlaTranslator(String machineName, File machineFile, String ltlFormula, String constantSetup)
 			throws IOException, BException {
 		this.machineName = machineName;
 		this.ltlFormula = ltlFormula;
+		
 		BParser parser = new BParser(machineName);
 		start = parser.parseFile(machineFile, false);
-		final Ast2String ast2String2 = new Ast2String();
+
+		
+		if(constantSetup!= null){
+			BParser con = new BParser("Constants");
+			Start start2 = con.parse("#FORMULA " + constantSetup, false);
+			APredicateParseUnit parseUnit = (APredicateParseUnit) start2.getPParseUnit();
+			this.constantsSetup = parseUnit.getPredicate();
+			
+			final Ast2String ast2String2 = new Ast2String();
+			start2.apply(ast2String2);
+			System.out.println(ast2String2.toString());
+		}
+		
+	    final Ast2String ast2String2 = new Ast2String();
 		start.apply(ast2String2);
-		// System.out.println(ast2String2.toString());
+		System.out.println(ast2String2.toString());
 	}
 
 	public void translate() {
 		DefinitionsEliminator defEliminator = new DefinitionsEliminator(start);
-		
-		MachineContext machineContext = new MachineContext(machineName, start, ltlFormula);
+
+		new NotSupportedConstructs(start);
+
+		MachineContext machineContext = new MachineContext(machineName, start,
+				ltlFormula, constantsSetup);
 		this.machineName = machineContext.getMachineName();
-		
+
 		Typechecker typechecker = new Typechecker(machineContext);
-		UnchangedVariablesFinder unchangedVariablesFinder = new UnchangedVariablesFinder(machineContext);
-		
+		UnchangedVariablesFinder unchangedVariablesFinder = new UnchangedVariablesFinder(
+				machineContext);
+
 		PrecedenceCollector precedenceCollector = new PrecedenceCollector(
 				start, typechecker.getTypes());
 
-		ConstantsEliminator constantsEliminator  = new ConstantsEliminator(machineContext);
+		ConstantsEliminator constantsEliminator = new ConstantsEliminator(
+				machineContext);
 		constantsEliminator.start();
 
 		ConstantsEvaluator constantsEvaluator = new ConstantsEvaluator(
@@ -92,7 +116,7 @@ public class B2TlaTranslator {
 				typeRestrictor);
 		start.apply(usedModules);
 		usedStandardModules = usedModules.getUsedModules();
-		
+
 		DefinitionsAnalyser deferredSetSizeCalculator = new DefinitionsAnalyser(
 				machineContext);
 
@@ -105,7 +129,7 @@ public class B2TlaTranslator {
 		PrimedNodesMarker primedNodesMarker = new PrimedNodesMarker(generator
 				.getTlaModule().getOperations(), machineContext);
 		primedNodesMarker.start();
-		
+
 		Renamer renamer = new Renamer(machineContext);
 		TLAPrinter printer = new TLAPrinter(machineContext, typechecker,
 				unchangedVariablesFinder, precedenceCollector, usedModules,
diff --git a/src/main/java/de/b2tla/TLCRunner.java b/src/main/java/de/b2tla/TLCRunner.java
index cf31a410dfee6c52c5e9f8186bac8e982037705e..b82a1ea8a5774f4fd22d1dc917b1cb347f71fe2e 100644
--- a/src/main/java/de/b2tla/TLCRunner.java
+++ b/src/main/java/de/b2tla/TLCRunner.java
@@ -67,6 +67,10 @@ public class TLCRunner {
 		if (!B2TLAGlobals.isDeadlockCheck()) {
 			list.add("-deadlock");
 		}
+		
+		if(B2TLAGlobals.isCheckltl()){
+			list.add("-cleanup");
+		}
 		// list.add("-coverage");
 		// list.add("1");
 
diff --git a/src/main/java/de/b2tla/analysis/AssignedVariablesFinder.java b/src/main/java/de/b2tla/analysis/AssignedVariablesFinder.java
index f2a8d0b144e1a1e64ce4fb2d9c28ff8a83cae152..934a5c61f4362316d3a69281bdd1592cb842db01 100644
--- a/src/main/java/de/b2tla/analysis/AssignedVariablesFinder.java
+++ b/src/main/java/de/b2tla/analysis/AssignedVariablesFinder.java
@@ -10,12 +10,14 @@ import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter;
 import de.be4.classicalb.core.parser.node.AAssignSubstitution;
 import de.be4.classicalb.core.parser.node.ABecomesElementOfSubstitution;
 import de.be4.classicalb.core.parser.node.ABecomesSuchSubstitution;
+import de.be4.classicalb.core.parser.node.ABlockSubstitution;
 import de.be4.classicalb.core.parser.node.AChoiceOrSubstitution;
 import de.be4.classicalb.core.parser.node.AChoiceSubstitution;
 import de.be4.classicalb.core.parser.node.ADefinitionSubstitution;
 import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause;
 import de.be4.classicalb.core.parser.node.AFunctionExpression;
 import de.be4.classicalb.core.parser.node.AIdentifierExpression;
+import de.be4.classicalb.core.parser.node.AIfElsifSubstitution;
 import de.be4.classicalb.core.parser.node.AIfSubstitution;
 import de.be4.classicalb.core.parser.node.AInitialisationMachineClause;
 import de.be4.classicalb.core.parser.node.AOperation;
@@ -72,6 +74,15 @@ public class AssignedVariablesFinder extends DepthFirstAdapter {
 		}
 	}
 
+	@Override
+	public void caseABlockSubstitution(ABlockSubstitution node) {
+		inABlockSubstitution(node);
+		if (node.getSubstitution() != null) {
+			node.getSubstitution().apply(this);
+		}
+		outABlockSubstitution(node);
+	}
+
 	@Override
 	public void caseAOperation(AOperation node) {
 		node.getOperationBody().apply(this);
@@ -150,7 +161,7 @@ public class AssignedVariablesFinder extends DepthFirstAdapter {
 			list.add(identifier);
 		}
 		assignedVariablesTable.put(node, list);
-		defaultCase(node);
+		defaultOut(node);
 	}
 
 	@Override
@@ -195,6 +206,16 @@ public class AssignedVariablesFinder extends DepthFirstAdapter {
 		defaultOut(node);
 	}
 
+	@Override
+	public void caseAIfElsifSubstitution(AIfElsifSubstitution node) {
+		HashSet<Node> list = new HashSet<Node>();
+		node.getThenSubstitution().apply(this);
+		list.addAll(getVariableList(node.getThenSubstitution()));
+
+		assignedVariablesTable.put(node, list);
+		defaultOut(node);
+	}
+
 	@Override
 	public void caseAParallelSubstitution(AParallelSubstitution node) {
 		List<PSubstitution> copy = new ArrayList<PSubstitution>(
diff --git a/src/main/java/de/b2tla/analysis/MachineContext.java b/src/main/java/de/b2tla/analysis/MachineContext.java
index ad7153a6f99510dd252cf6203103b29f4457afd7..bab46a8730e83a9d6fcfd1e8cb7a50e9437f428d 100644
--- a/src/main/java/de/b2tla/analysis/MachineContext.java
+++ b/src/main/java/de/b2tla/analysis/MachineContext.java
@@ -21,6 +21,7 @@ import de.be4.classicalb.core.parser.node.AAssertionsMachineClause;
 import de.be4.classicalb.core.parser.node.AAssignSubstitution;
 import de.be4.classicalb.core.parser.node.AComprehensionSetExpression;
 import de.be4.classicalb.core.parser.node.AConcreteVariablesMachineClause;
+import de.be4.classicalb.core.parser.node.AConjunctPredicate;
 import de.be4.classicalb.core.parser.node.AConstantsMachineClause;
 import de.be4.classicalb.core.parser.node.AConstraintsMachineClause;
 import de.be4.classicalb.core.parser.node.ADeferredSetSet;
@@ -76,6 +77,7 @@ public class MachineContext extends DepthFirstAdapter {
 	private final Start start;
 	private final Hashtable<String, MachineContext> machineContextsTable;
 	private ArrayList<LTLFormulaVisitor> ltlVisitors;
+	private PPredicate constantSetup;
 
 	// machine identifier
 	private final LinkedHashMap<String, Node> setParameter;
@@ -131,9 +133,10 @@ public class MachineContext extends DepthFirstAdapter {
 	// start.apply(this);
 	// }
 
-	public MachineContext(String machineName, Start start, String ltlFormula) {
+	public MachineContext(String machineName, Start start, String ltlFormula, PPredicate constantSetup) {
 		this.start = start;
 		this.machineName = machineName;
+		this.constantSetup = constantSetup;
 		this.referencesTable = new Hashtable<Node, Node>();
 		this.ltlVisitors = new ArrayList<LTLFormulaVisitor>();
 
@@ -564,7 +567,12 @@ public class MachineContext extends DepthFirstAdapter {
 	@Override
 	public void caseAPropertiesMachineClause(APropertiesMachineClause node) {
 		this.propertiesMachineClause = node;
-
+		
+		if(constantSetup != null){
+			AConjunctPredicate and = new AConjunctPredicate(constantSetup, node.getPredicates());
+			node.setPredicates(and);
+		}
+		
 		/**
 		 * check identifier scope in properties clauses
 		 */
diff --git a/src/main/java/de/b2tla/analysis/NotSupportedConstructs.java b/src/main/java/de/b2tla/analysis/NotSupportedConstructs.java
new file mode 100644
index 0000000000000000000000000000000000000000..44af9247865862dd842abcb1c1ac9a5f87011c0b
--- /dev/null
+++ b/src/main/java/de/b2tla/analysis/NotSupportedConstructs.java
@@ -0,0 +1,25 @@
+package de.b2tla.analysis;
+
+import de.b2tla.exceptions.NotSupportedException;
+import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter;
+import de.be4.classicalb.core.parser.node.ACaseSubstitution;
+import de.be4.classicalb.core.parser.node.AWhileSubstitution;
+import de.be4.classicalb.core.parser.node.Start;
+
+public class NotSupportedConstructs extends DepthFirstAdapter{
+	
+	public NotSupportedConstructs(Start start){
+		start.apply(this);
+	}
+	
+    public void inAWhileSubstitution(AWhileSubstitution node)
+    {
+    	throw new NotSupportedException("While substitutions are currently not supported.");
+    }
+    
+    public void inACaseSubstitution(ACaseSubstitution node)
+    {
+    	throw new NotSupportedException("Case substitutions are currently not supported.");
+    }
+
+}
diff --git a/src/main/java/de/b2tla/analysis/Typechecker.java b/src/main/java/de/b2tla/analysis/Typechecker.java
index d26f33afbf446bb92f27f24167f8bc8f706eedd5..afba565867bee66997820a7dbf6fed59b67a0180 100644
--- a/src/main/java/de/b2tla/analysis/Typechecker.java
+++ b/src/main/java/de/b2tla/analysis/Typechecker.java
@@ -540,6 +540,13 @@ public class Typechecker extends DepthFirstAdapter implements ITypechecker {
 		}
 	}
 
+	@Override
+	public void caseAIfElsifSubstitution(AIfElsifSubstitution node) {
+		setType(node.getCondition(), BoolType.getInstance());
+		node.getCondition().apply(this);
+		node.getThenSubstitution().apply(this);
+	}
+
 	@Override
 	public void caseAAssignSubstitution(AAssignSubstitution node) {
 		List<PExpression> copy = new ArrayList<PExpression>(
diff --git a/src/main/java/de/b2tla/analysis/UnchangedVariablesFinder.java b/src/main/java/de/b2tla/analysis/UnchangedVariablesFinder.java
index 863a18bcb950de5ff9c8de91e33f56e66ebd8a50..cdfd2753e0e9d077df6618ef76f5aae227705439 100644
--- a/src/main/java/de/b2tla/analysis/UnchangedVariablesFinder.java
+++ b/src/main/java/de/b2tla/analysis/UnchangedVariablesFinder.java
@@ -10,11 +10,13 @@ import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter;
 import de.be4.classicalb.core.parser.node.AAnySubstitution;
 import de.be4.classicalb.core.parser.node.AAssertionSubstitution;
 import de.be4.classicalb.core.parser.node.AAssignSubstitution;
+import de.be4.classicalb.core.parser.node.ABecomesElementOfSubstitution;
 import de.be4.classicalb.core.parser.node.ABecomesSuchSubstitution;
 import de.be4.classicalb.core.parser.node.ABlockSubstitution;
 import de.be4.classicalb.core.parser.node.AChoiceOrSubstitution;
 import de.be4.classicalb.core.parser.node.AChoiceSubstitution;
 import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause;
+import de.be4.classicalb.core.parser.node.AIfElsifSubstitution;
 import de.be4.classicalb.core.parser.node.AIfSubstitution;
 import de.be4.classicalb.core.parser.node.AInitialisationMachineClause;
 import de.be4.classicalb.core.parser.node.ALetSubstitution;
@@ -51,10 +53,10 @@ public class UnchangedVariablesFinder extends DepthFirstAdapter {
 
 	private final Hashtable<Node, HashSet<Node>> unchangedVariablesNull;
 
-	public HashSet<Node> getUnchangedVariables(Node node){
+	public HashSet<Node> getUnchangedVariables(Node node) {
 		return unchangedVariablesTable.get(node);
 	}
-	
+
 	public HashSet<Node> getUnchangedVariablesNull(Node node) {
 		return unchangedVariablesNull.get(node);
 	}
@@ -129,6 +131,12 @@ public class UnchangedVariablesFinder extends DepthFirstAdapter {
 		check(node);
 	}
 
+	@Override
+	public void caseABecomesElementOfSubstitution(
+			ABecomesElementOfSubstitution node) {
+		check(node);
+	}
+
 	@Override
 	public void caseAParallelSubstitution(AParallelSubstitution node) {
 		check(node);
@@ -201,7 +209,6 @@ public class UnchangedVariablesFinder extends DepthFirstAdapter {
 	@Override
 	public void caseAIfSubstitution(AIfSubstitution node) {
 		check(node);
-
 		// Separating variables and output parameters
 		HashSet<Node> foundIdentifiers = assignedIdentifiersTable.get(node);
 		HashSet<Node> foundVariables = new HashSet<Node>(foundIdentifiers);
@@ -233,6 +240,15 @@ public class UnchangedVariablesFinder extends DepthFirstAdapter {
 
 	}
 
+	@Override
+	public void caseAIfElsifSubstitution(AIfElsifSubstitution node) {
+		expectedOutputParametersTable.put(node.getThenSubstitution(),
+				expectedOutputParametersTable.get(node));
+		expectedVariablesTable.put(node.getThenSubstitution(),
+				expectedVariablesTable.get(node));
+		node.getThenSubstitution().apply(this);
+	}
+
 	@Override
 	public void caseAPreconditionSubstitution(APreconditionSubstitution node) {
 		// check(node);
diff --git a/src/main/java/de/b2tla/exceptions/NotSupportedException.java b/src/main/java/de/b2tla/exceptions/NotSupportedException.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d7abb93602c5eae37387990425d4536b20bd66f
--- /dev/null
+++ b/src/main/java/de/b2tla/exceptions/NotSupportedException.java
@@ -0,0 +1,15 @@
+package de.b2tla.exceptions;
+
+@SuppressWarnings("serial")
+public class NotSupportedException extends B2tlaException{
+
+	
+	public NotSupportedException(String e){
+		super(e);
+	}
+
+	@Override
+	public String getError() {
+		return "NotSupportedException";
+	}
+}
diff --git a/src/main/java/de/b2tla/prettyprint/TLAPrinter.java b/src/main/java/de/b2tla/prettyprint/TLAPrinter.java
index aa3d7f33ee474221bdbae4b8245819a0ac84b31f..d2505674eae1b2373860f056307f1f18e0927966 100644
--- a/src/main/java/de/b2tla/prettyprint/TLAPrinter.java
+++ b/src/main/java/de/b2tla/prettyprint/TLAPrinter.java
@@ -134,17 +134,17 @@ public class TLAPrinter extends DepthFirstAdapter {
 		tlaModuleString.append("))");
 
 	}
-	
+
 	public void printWeakFairnessWithParameter(String s) {
 		Node operation = machineContext.getOperations().get(s.trim());
-		
+
 		tlaModuleString.append("([]<><<");
 		printOperationCall(operation);
 		tlaModuleString.append(">>_vars \\/  []<>~ENABLED(");
 		printOperationCall(operation);
 		tlaModuleString.append(") \\/ []<> ENABLED(");
 		printOperationCall(operation);
-		tlaModuleString.append(" /\\ ");	
+		tlaModuleString.append(" /\\ ");
 		printVarsStuttering();
 		tlaModuleString.append("))");
 
@@ -661,6 +661,10 @@ public class TLAPrinter extends DepthFirstAdapter {
 
 	@Override
 	public void caseAIfSubstitution(AIfSubstitution node) {
+		if(node.getElsifSubstitutions().size() > 0){
+			printElseIFSubsitution(node);
+			return;
+		}
 		tlaModuleString.append("(IF ");
 		node.getCondition().apply(this);
 		tlaModuleString.append(" THEN ");
@@ -680,6 +684,37 @@ public class TLAPrinter extends DepthFirstAdapter {
 		tlaModuleString.append(")");
 		printUnchangedVariables(node, true);
 	}
+	
+	private void printElseIFSubsitution(AIfSubstitution node){
+		tlaModuleString.append("(CASE ");
+		node.getCondition().apply(this);
+		tlaModuleString.append(" -> ");
+		node.getThen().apply(this);
+		List<PSubstitution> copy = new ArrayList<PSubstitution>(
+				node.getElsifSubstitutions());
+		for (PSubstitution e : copy) {
+			tlaModuleString.append(" [] ");
+			e.apply(this);
+		}
+		tlaModuleString.append(" [] OTHER -> ");
+		if (node.getElse() != null) {
+			node.getElse().apply(this);
+		} else {
+			printUnchangedVariablesNull(node, false);
+		}
+		tlaModuleString.append(")");
+		printUnchangedVariables(node, true);
+		
+	}
+
+	@Override
+	public void caseAIfElsifSubstitution(AIfElsifSubstitution node) {
+		node.getCondition().apply(this);
+		tlaModuleString.append(" -> ");
+		node.getThenSubstitution().apply(this);
+		printUnchangedVariables(node, true);
+		
+	}
 
 	public void printUnchangedVariablesNull(Node node, boolean printAnd) {
 		HashSet<Node> unchangedVariablesSet = missingVariableFinder
@@ -2546,18 +2581,17 @@ public class TLAPrinter extends DepthFirstAdapter {
 	public void caseAGeneralConcatExpression(AGeneralConcatExpression node) {
 		BType result = typechecker.getType(node.getExpression());
 
-		if (result instanceof FunctionType && ((FunctionType) result).getRange() instanceof FunctionType) {
+		if (result instanceof FunctionType
+				&& ((FunctionType) result).getRange() instanceof FunctionType) {
 
-		}else{
-			BType expected2 = new SetType(new PairType(IntegerType.getInstance(),
-					new SetType(new PairType(IntegerType.getInstance(),
-							new UntypedType()))));
+		} else {
+			BType expected2 = new SetType(new PairType(
+					IntegerType.getInstance(), new SetType(new PairType(
+							IntegerType.getInstance(), new UntypedType()))));
 			typechecker.unify(expected2, result, node);
 		}
 
-		
-		printSequenceOrRelation(node,
-				SEQUENCE_GENERAL_CONCATINATION,
+		printSequenceOrRelation(node, SEQUENCE_GENERAL_CONCATINATION,
 				REL_SEQUENCE_GENERAL_CONCATINATION, node.getExpression(), null);
 	}
 
@@ -2613,7 +2647,8 @@ public class TLAPrinter extends DepthFirstAdapter {
 
 	@Override
 	public void caseACartesianProductExpression(ACartesianProductExpression node) {
-		inACartesianProductExpression(node); //TODO cartesianproduct vs AMultOrCartExpression
+		inACartesianProductExpression(node); // TODO cartesianproduct vs
+												// AMultOrCartExpression
 		node.getLeft().apply(this);
 		tlaModuleString.append(" \\times ");
 		node.getRight().apply(this);
diff --git a/src/test/java/de/b2tla/prettyprint/SetTest.java b/src/test/java/de/b2tla/prettyprint/SetTest.java
index c1cbb5df128eea9b624cb34e3bc1bde601a5d8ae..85d68569c4d0b39d5e8f7411598977902963e538 100644
--- a/src/test/java/de/b2tla/prettyprint/SetTest.java
+++ b/src/test/java/de/b2tla/prettyprint/SetTest.java
@@ -3,7 +3,6 @@ package de.b2tla.prettyprint;
 import static de.b2tla.util.TestUtil.*;
 import static org.junit.Assert.*;
 
-import org.junit.Ignore;
 import org.junit.Test;
 
 public class SetTest {
@@ -48,16 +47,6 @@ public class SetTest {
 		compare(expected, machine);
 	}
 	
-	@Ignore
-	@Test
-	public void testSetComprehension3() throws Exception {
-		String machine = "MACHINE test\n"
-				+ "PROPERTIES (1,TRUE,2) : {a,b,c | (a,b,c) : {1} * {TRUE} * {2} } \n" + "END";
-		String expected = "---- MODULE test----\n" + "EXTENDS Integers\n"
-				+ "ASSUME {1} = {x \\in {1}: 1 = 1 } \n"
-				+ "======";
-	}
-	
 	
 	@Test
 	public void testPowerSet() throws Exception {
diff --git a/src/test/java/de/b2tla/prettyprint/SubstitutionsTest.java b/src/test/java/de/b2tla/prettyprint/SubstitutionsTest.java
index f45c8511742a4d6fbdbbe34385bf084c0c4d0811..83708cefc72222ec2bb85f4ef08609c565060a43 100644
--- a/src/test/java/de/b2tla/prettyprint/SubstitutionsTest.java
+++ b/src/test/java/de/b2tla/prettyprint/SubstitutionsTest.java
@@ -2,6 +2,7 @@ package de.b2tla.prettyprint;
 
 import static de.b2tla.util.TestUtil.compare;
 
+import org.junit.Ignore;
 import org.junit.Test;
 
 public class SubstitutionsTest {
@@ -94,4 +95,25 @@ public class SubstitutionsTest {
 				+ "====";
 		compare(expected, machine);
 	}
+	
+	@Test
+	public void testIFElseIFSubstitution() throws Exception {
+		String machine = "MACHINE test\n" 
+				+ "VARIABLES x\n"
+				+ "INVARIANT x = 1\n" 
+				+ "INITIALISATION IF 1=1 THEN x:= 1 ELSIF 1=2 THEN x:= 2 ELSE x:= 4 END \n"
+				+ "END";
+		
+		String expected = "---- MODULE test ----\n"
+				+ "EXTENDS Naturals \n"
+				+ "VARIABLES x \n"
+				+ "Invariant == x = 1\n"
+				+ "Init == (CASE 1 = 1 -> x = 1 [] 1 = 2 -> x = 2 [] OTHER -> x = 4)\n"
+				+ "Next == 1 = 2 /\\ UNCHANGED <<x>>\n"
+				+ "====";
+		compare(expected, machine);
+	}
+	
+	
+	
 }
diff --git a/src/test/java/de/b2tla/tlc/integration/BasicsTest.java b/src/test/java/de/b2tla/tlc/integration/BasicsTest.java
index b1ae13553db19f260e1e5174d001db9b3d636e74..d1849faa00f9d8a9739a6cfd9c7dbd8d9b48b669 100644
--- a/src/test/java/de/b2tla/tlc/integration/BasicsTest.java
+++ b/src/test/java/de/b2tla/tlc/integration/BasicsTest.java
@@ -10,7 +10,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import de.b2tla.B2TLA;
-import de.b2tla.B2TLAGlobals;
 import de.b2tla.tlc.TLCOutput.TLCResult;
 import de.b2tla.util.AbstractParseMachineTest;
 import de.b2tla.util.PolySuite;
diff --git a/src/test/java/de/b2tla/tlc/integration/ErrorTest.java b/src/test/java/de/b2tla/tlc/integration/ErrorTest.java
index 5bcebb7bfb1321adc85c45101af6db79a493eee4..f086bdc2e88cf1f62ad9f6d8129d48385c7fc7e6 100644
--- a/src/test/java/de/b2tla/tlc/integration/ErrorTest.java
+++ b/src/test/java/de/b2tla/tlc/integration/ErrorTest.java
@@ -3,12 +3,10 @@ package de.b2tla.tlc.integration;
 import static de.b2tla.tlc.TLCOutput.TLCResult.*;
 import static org.junit.Assert.*;
 
-import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 
 import de.b2tla.B2TLA;
-import de.b2tla.B2TLAGlobals;
 
 public class ErrorTest {
 
diff --git a/src/test/java/de/b2tla/typechecking/TestTypechecker.java b/src/test/java/de/b2tla/typechecking/TestTypechecker.java
index 533ec05451da468df9ee96331cda7365a54c5587..83c4b6ef5381f88861dda8c1a0996fe0f6c813ab 100644
--- a/src/test/java/de/b2tla/typechecking/TestTypechecker.java
+++ b/src/test/java/de/b2tla/typechecking/TestTypechecker.java
@@ -26,7 +26,7 @@ public class TestTypechecker {
 		final Ast2String ast2String2 = new Ast2String();
 		start.apply(ast2String2);
 		System.out.println(ast2String2.toString());
-		MachineContext c = new MachineContext(null, start, null);
+		MachineContext c = new MachineContext(null, start, null, null);
 		Typechecker t = new Typechecker(c);
 
 		for (String name : c.getSetParamter().keySet()) {
diff --git a/src/test/resources/basics/SetsTest.mch b/src/test/resources/basics/SetsTest.mch
index 120edd4cadf1f92e96592253b45045ca3ed2c759..66aca591201ba865a2dd06e3fcdc8a2cc7ed7d2e 100644
--- a/src/test/resources/basics/SetsTest.mch
+++ b/src/test/resources/basics/SetsTest.mch
@@ -3,4 +3,6 @@ PROPERTIES
  union({{},{1},{1},{2},{2,3},{4}}) = {1,2,3,4}
 & union({}) = {}
 & UNION(x).(x :{2,4} | {y | y : 0..x}) = {0, 1, 2, 3, 4}
+& (1,TRUE,2) : {a,b,c | (a,b,c) : {1} * {TRUE} * {2} }
+& UNION(z).(z: {1,2} & 1 = 1| {z}) = {1,2}
 END
\ No newline at end of file
diff --git a/src/test/resources/laws/SetLaws.mch b/src/test/resources/laws/SetLaws.mch
new file mode 100644
index 0000000000000000000000000000000000000000..1870a3384307f5852adea62f4c2ed1d4015c3de0
--- /dev/null
+++ b/src/test/resources/laws/SetLaws.mch
@@ -0,0 +1,174 @@
+MACHINE SetLaws
+
+SETS
+  setX = {el1,el2,el3}
+
+VARIABLES
+   SS, TT, VV
+
+DEFINITIONS
+ /*GOAL == (FIN1(SS)) = (FIN(SS)-{{}});*/
+ law1 ==  (SS \/ SS = SS  &  SS = SS \/ {}  &  SS = SS /\ SS  &  SS = SS \ {});
+ law2 == (SS /\ {} = {} & {} = SS \ SS &  ({} \ SS = {}));
+ law3 == (SS \/ TT = TT \/ SS   &  SS /\ TT = TT /\ SS); 
+ law4 == (( SS \/ (TT \/ VV) = (SS \/TT) \/ VV) & ( SS /\ (TT /\ VV) = (SS /\ TT) /\ VV));
+ law5 == ( SS \/ (TT /\ VV) = (SS \/ TT) /\ (SS \/ VV));
+ law6 == ( SS /\ (TT \/ VV) = (SS /\ TT) \/ (SS /\ VV));
+ law7 == ( (SS /\ TT) \/ (SS \ TT) = SS);
+ law8 == ((SS \ TT) /\ TT = {});
+ law9 == (SS \ (TT \ VV) = (SS \ TT) \/ (SS /\ VV));
+ law10 == ((SS \ TT) \ VV = (SS \ (TT \/ VV)));
+ law11 == (SS \/ (TT \ VV) = (SS \/ TT) \ (VV \ SS));
+ law12 == (SS /\ (TT \ VV) = (SS /\ TT) \ VV);
+ law13 == ((SS \/ TT) \ VV = (SS \ VV) \/ (TT \ VV));
+ law14 == (SS \ (TT /\ VV) = ( SS \ TT) \/ (SS \ VV));
+
+ orderlaw1 == (SS <: SS \/ TT & TT <: SS \/ TT);
+ orderlaw2 == ( ( SS <: VV & TT <: VV) => (SS\/TT <: VV));
+ orderlaw3 == (SS /\ TT <: SS & SS /\ TT <: TT);
+ orderlaw4 == ( (VV <: SS & VV <: TT) => (VV <: SS /\ TT));
+
+ setcomprlaw1 == ( {xx | xx: SS & xx:TT} = SS /\ TT);
+ setcomprlaw2 == ( {xx | xx: setX & (xx: SS or xx:TT)} = SS \/ TT);
+ setcomprlaw3 == ( {xx | xx: setX & xx: SS & (xx: TT or xx:VV)} = SS /\ (VV \/TT));
+ setcomprlaw4 == ( {xx | xx: SS & not(xx:TT)} = SS \ TT);
+
+ foralllaw1 == (!xx.(xx:SS & xx:TT => xx: SS /\ TT));
+ foralllaw2 == (!xx.(xx:SS & not(xx:TT) => (xx: SS \ TT & xx /: TT)));
+
+ existslaw1 == (#xx.(xx:SS & xx:TT & xx:VV) => not(SS /\ TT /\ VV = {}));
+ existslaw2 == (#xx.(xx:SS & xx/:TT) => not(SS \/ TT = TT) & not(SS \ TT = {}));
+
+
+ /* laws for <<:, <:, /<: and /<<: */
+ orderlaw5 == ( SS <<: VV  or SS /<<: VV );
+ orderlaw6 == ( (VV <<: SS & SS <: TT) => (VV <<: TT));
+ orderlaw7 == ( (VV <: SS & SS <<: TT) => (VV <<: TT));
+ orderlaw8 == ( SS <: VV  or SS /<: VV );
+ orderlaw9 == ( SS : POW(TT)  or SS /: POW(TT) );
+
+ otherlaw1 == ( (SS <: VV & SS /<<: VV) => SS = VV);
+ otherlaw1b ==(  SS <: VV => (SS /= VV  <=> SS <<: VV));
+ otherlaw2 == ( (SS <<: VV ) => (SS /= VV & card(VV)>0));
+ otherlaw3 == ( (SS = VV ) => SS /<<: VV);
+ otherlaw4 == ( SS <<: VV  => SS <: VV);
+ otherlaw5 == ( SS <<: VV => #xx.(xx:VV & xx/:SS));
+ otherlaw6 == ( SS <: VV <=> !x.(x:SS => x:VV) );
+
+ cardlaw1 == (SS <<: VV => (card(SS) < card(VV)));
+ cardlaw2 == (SS <: VV => (card(SS) <= card(VV)));
+ cardlaw3 == (card(SS) < card(VV) => (VV /<: SS));
+ cardlaw4 == (card(SS \/ VV) <= (card(SS) + card(VV)));
+ cardlaw5 == (card(SS) = card(VV) => (VV /<<: SS));
+ cardlaw6 == (card(SS) <= card(VV) => (VV /<<: SS));
+ cardlaw7 == (SS = VV => (card(SS) = card(VV)));
+ cardlaw8 == (card(SS /\ VV) <= card(SS) & card(SS /\ VV) <= card(VV));
+
+ difflaw1 == (SS /\ VV = {}  <=> SS <: setX - VV);
+ difflaw2 == (SS \ VV = SS-VV);
+ difflaw3 == (VV-SS = VV\SS)
+
+INVARIANT
+  SS : POW(setX) & TT : POW(setX) & VV : POW(setX) &
+   law1 & law2 & law3 & law4 & law5 & law6 & law7 & law8 &
+   law9 & law10 & law11 & law12 & law13 & law14 &
+   orderlaw1  & orderlaw2 & orderlaw3 & orderlaw4 &
+   setcomprlaw1  & setcomprlaw2 & setcomprlaw3 & setcomprlaw4 &
+   foralllaw1 & foralllaw2 & existslaw1 & existslaw2 &
+
+   orderlaw5 & orderlaw6 & orderlaw7 & 
+   orderlaw8 & orderlaw9 &
+   otherlaw1 & otherlaw1b & otherlaw2 & otherlaw3 & otherlaw4 & otherlaw5 & otherlaw6 &
+
+   cardlaw1 & cardlaw2 & cardlaw3 & cardlaw4 & cardlaw5 & cardlaw6 & cardlaw7 & cardlaw8
+   &
+   difflaw1 & difflaw2
+   &
+   difflaw3 &
+
+   (SS<<:VV or not(SS<<:VV)) & not(SS<<:VV & not(SS<<:VV)) &
+   (SS<:VV or not(SS<:VV)) & not(SS<:VV & not(SS<:VV)) &
+    /* */
+   (SS/<<:VV or not(SS/<<:VV)) & not(SS/<<:VV & not(SS/<<:VV)) &
+   (SS/<:VV or not(SS/<:VV)) & not(SS/<:VV & not(SS/<:VV)) &
+   (SS/:POW(TT) or not(SS/:POW(TT))) & not(SS/:POW(TT) & not(SS/:POW(TT))) &
+   (SS:POW(TT) or not(SS:POW(TT))) & not(SS:POW(TT) & not(SS:POW(TT))) &
+   ((POW1(SS)) = (POW(SS)-{{}})) &
+   card(POW1(SS)) = card(POW(SS)) - 1 &
+   card(POW(SS)-{{}}) = card(POW(SS)) - 1 &
+   ((FIN1(SS)) = (FIN(SS)-{{}})) &
+   {} : POW(SS) & 
+   {} : FIN(SS) &  /* this was false due to a bug in the Parser, which returned FIN1 for FIN */
+   {} /: POW1(SS) & {} /: FIN1(SS) &
+
+   (UNION(ss).(ss<:SS | ss) = SS) &
+   (card(SS) /= 1  <=> UNION(ss).(ss<<:SS | ss) = SS) &
+   (INTER(ss).(ss<:SS | ss) = {}) &
+
+   (SS : POW(TT) <=> SS <: TT) &
+   (SS=TT <=> POW(SS) = POW(TT)) &
+   (POW(SS-TT) = { xx | xx<:SS & xx /\ TT = {} })
+
+   & /* new, July 2008 */
+    SS /\ setX = SS &
+    SS \/ setX = setX &
+    SS \/ (setX \ SS) = setX &
+    SS /\ (setX \ SS) = {} &
+    (setX \ (setX \ SS) = SS)
+   &
+   (SS /\ TT = {}  <=> not(#x.(x:SS & x:TT)) )   &
+   (SS /\ TT /\ VV = {}  <=> not(#x.(x:SS & x:TT & x:VV)) ) & 
+   (SS <: TT  <=>  not(#y.(y:SS & y/: TT))) 
+
+   &
+   (SS/={} <=> #ee.(ee:SS) )
+   &
+   (SS /\ TT /= {}  <=>   #ee.(ee:SS & ee:TT) )
+   &
+   ( SS /<: TT  <=>  #ee.(ee:SS & ee/:TT))
+   &
+   ( SS<<:TT <=>  (SS<:TT & #ee.(ee:TT & ee/:SS)))
+   &
+   (id(SS)=SS*SS <=> card(SS)<2) &
+   /* (SS*VV = TT*VV  <=>  (((SS={} or VV={}) & (TT={} or VV={})) or (SS=TT & VV=VV))) & ERROR in TLC */
+   (id(SS)=id(TT) <=> SS=TT) &
+   (id(SS) <: id(TT) <=> SS <: TT) &
+   
+   /* laws on page 124 of B-Book */
+   (inter({SS}) = {x| !y.(y:{SS} => x:y)}) & 
+   (inter({SS,TT}) = {x| !y.(y:{SS,TT} => x:y)}) & 
+   (inter({SS,TT,VV}) = {x| !y.(y:{SS,TT,VV} => x:y)}) & 
+   (union({}) = {x| x<:TT & #y.(y:{} & x:y)}) & 
+   (union({SS}) = {x| #y.(y:{SS} & x:y)}) & 
+   (union({SS,TT}) = {x| #y.(y:{SS,TT} & x:y)}) & 
+   (union({SS,TT,VV}) = {x| #y.(y:{SS,TT,VV} & x:y)})  &
+
+  /* laws from page 127 of B-Book */
+   (inter({SS}) = SS) &
+   (union({SS}) = SS) &
+   (inter({SS,TT}) = SS /\ TT) &
+   (union({SS,TT}) = SS \/ TT) 
+ASSERTIONS
+   /* (UNION(ss).(ss<:SS | ss) = SS); 
+   (POW1(SS) = POW(SS) - {{}}); */
+   VV - SS = VV - SS
+INITIALISATION
+
+   SS,TT,VV := {},{},{}
+
+OPERATIONS
+/* cc <-- powss1 = BEGIN cc := POW(SS-TT) END;
+cc <-- powss2 = BEGIN cc := { xx | xx<:SS & xx /\ TT = {} } END; */
+ add_SS(el) = PRE el: setX & el /: SS THEN  SS := SS \/ {el} END;
+ add_TT(el) = PRE el: setX & el /: TT THEN  TT := TT \/ {el} END;
+ add_VV(el) = PRE el: setX & el /: VV THEN  VV := VV \/ {el} END ;
+
+ set_SS_setX = BEGIN SS := setX END;
+ set_TT_setX = BEGIN TT := setX END;
+ set_VV_setX = BEGIN VV := setX END/* ;
+
+ laws_ok = PRE law1 & law2 & law3 & law4 & law5 &
+              law6 & law7 & law8 & law9 & law10 & law11 THEN skip END */
+
+END
+