diff --git a/src/main/java/de/tlc4b/TLC4B.java b/src/main/java/de/tlc4b/TLC4B.java
index 24504794bddb8a9481bfacaee8f61e9123735305..89610f7bf341b3f93738699f49726790f0233c53 100644
--- a/src/main/java/de/tlc4b/TLC4B.java
+++ b/src/main/java/de/tlc4b/TLC4B.java
@@ -288,18 +288,19 @@ public class TLC4B {
 		handleMainFileName();
 		if (TLC4BGlobals.isTranslate()) {
 			StopWatch.start("Parsing");
+			System.out.println("Parsing...");
 			translator = new Translator(machineFileNameWithoutFileExtension,
 					mainfile, this.ltlFormula, this.constantsSetup);
 			StopWatch.stop("Parsing");
-			System.out.println("Parsing Completed.");
+			
 			StopWatch.start("Translation");
+			System.out.println("Translating...");
 			translator.translate();
 			this.tlaModule = translator.getModuleString();
 			this.config = translator.getConfigString();
 			this.tlcOutputInfo = translator.getTLCOutputInfo();
 			createFiles();
 			StopWatch.stop("Translation");
-			System.out.println("Translation Completed.");
 		}
 
 	}
diff --git a/src/main/java/de/tlc4b/Translator.java b/src/main/java/de/tlc4b/Translator.java
index 27b5ff2ce9752c6af62520340786fcd2fc2a9fe6..87bb1cca6fb9b18f8e47d290aff659da5fb187b5 100644
--- a/src/main/java/de/tlc4b/Translator.java
+++ b/src/main/java/de/tlc4b/Translator.java
@@ -3,6 +3,7 @@ package de.tlc4b;
 import java.io.File;
 import java.io.IOException;
 import java.util.HashSet;
+import java.util.Map;
 
 import de.be4.classicalb.core.parser.BParser;
 import de.be4.classicalb.core.parser.analysis.prolog.RecursiveMachineLoader;
@@ -22,9 +23,12 @@ import de.tlc4b.analysis.Typechecker;
 import de.tlc4b.analysis.UsedStandardModules;
 import de.tlc4b.analysis.UsedStandardModules.STANDARD_MODULES;
 import de.tlc4b.analysis.transformation.DefinitionsEliminator;
+import de.tlc4b.analysis.transformation.SeesEliminator;
+import de.tlc4b.analysis.transformation.SetComprehensionOptimizer;
 import de.tlc4b.analysis.typerestriction.TypeRestrictor;
 import de.tlc4b.analysis.unchangedvariables.InvariantPreservationAnalysis;
 import de.tlc4b.analysis.unchangedvariables.UnchangedVariablesFinder;
+import de.tlc4b.exceptions.TLC4BIOException;
 import de.tlc4b.prettyprint.TLAPrinter;
 import de.tlc4b.tla.Generator;
 import de.tlc4b.tlc.TLCOutputInfo;
@@ -34,6 +38,7 @@ public class Translator {
 
 	private String machineString;
 	private Start start;
+	private Map<String, Start> parsedMachines;
 	private String moduleString;
 	private String configString;
 	private String machineName;
@@ -64,12 +69,16 @@ public class Translator {
 	}
 
 	public Translator(String machineName, File machineFile, String ltlFormula,
-			String constantSetup) throws IOException, BException {
+			String constantSetup) throws BException, IOException {
 		this.machineName = machineName;
 		this.ltlFormula = ltlFormula;
 
 		BParser parser = new BParser(machineName);
-		start = parser.parseFile(machineFile, false);
+		try {
+			start = parser.parseFile(machineFile, false);
+		} catch (NoClassDefFoundError e) {
+			throw new TLC4BIOException("Definitions file cannot be found.");
+		}
 
 		// Definitions of definitions files are injected in the ast of the main
 		// machine
@@ -77,6 +86,8 @@ public class Translator {
 				machineFile.getParent(), parser.getContentProvider());
 		rml.loadAllMachines(machineFile, start, null, parser.getDefinitions(),
 				parser.getPragmas());
+		
+		parsedMachines = rml.getParsedMachines();
 
 		if (constantSetup != null) {
 			BParser con = new BParser();
@@ -104,15 +115,18 @@ public class Translator {
 	}
 
 	public void translate() {
-		new NotSupportedConstructs(start);
+		// ast transformation
+		SeesEliminator.eliminateSeesClauses(start, parsedMachines);
 
-		new DefinitionsEliminator(start);
+		new NotSupportedConstructs(start);
+		DefinitionsEliminator.eliminateDefinitions(start);
 
+		SetComprehensionOptimizer.optimizeSetComprehensions(start);
+		
 		MachineContext machineContext = new MachineContext(machineName, start,
 				ltlFormula, constantsSetup);
 		this.machineName = machineContext.getMachineName();
-		if(machineContext
-				.machineContainsOperations()){
+		if (machineContext.machineContainsOperations()) {
 			TLC4BGlobals.setPrintCoverage(true);
 		}
 
@@ -149,7 +163,8 @@ public class Translator {
 		UsedStandardModules usedModules = new UsedStandardModules(start,
 				typechecker, typeRestrictor, generator.getTlaModule());
 
-		standardModulesToBeCreated = usedModules.getStandardModulesToBeCreated();
+		standardModulesToBeCreated = usedModules
+				.getStandardModulesToBeCreated();
 
 		PrimedNodesMarker primedNodesMarker = new PrimedNodesMarker(generator
 				.getTlaModule().getOperations(), machineContext);
diff --git a/src/main/java/de/tlc4b/analysis/MachineContext.java b/src/main/java/de/tlc4b/analysis/MachineContext.java
index fa0ad62db198d93fd159d30c3dbd8faf7c429153..c621ee8da44f8811e8bcfe556f2e1bd252727585 100644
--- a/src/main/java/de/tlc4b/analysis/MachineContext.java
+++ b/src/main/java/de/tlc4b/analysis/MachineContext.java
@@ -1,10 +1,7 @@
 package de.tlc4b.analysis;
 
-import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.LinkedHashMap;
@@ -29,6 +26,7 @@ import de.be4.classicalb.core.parser.node.ADefinitionPredicate;
 import de.be4.classicalb.core.parser.node.ADefinitionSubstitution;
 import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause;
 import de.be4.classicalb.core.parser.node.AEnumeratedSetSet;
+import de.be4.classicalb.core.parser.node.AEventBComprehensionSetExpression;
 import de.be4.classicalb.core.parser.node.AExistsPredicate;
 import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition;
 import de.be4.classicalb.core.parser.node.AForallPredicate;
@@ -54,7 +52,6 @@ import de.be4.classicalb.core.parser.node.ARecEntry;
 import de.be4.classicalb.core.parser.node.ARecordFieldExpression;
 import de.be4.classicalb.core.parser.node.ASeesMachineClause;
 import de.be4.classicalb.core.parser.node.ASetsContextClause;
-import de.be4.classicalb.core.parser.node.ASetsMachineClause;
 import de.be4.classicalb.core.parser.node.ASubstitutionDefinitionDefinition;
 import de.be4.classicalb.core.parser.node.AVariablesMachineClause;
 import de.be4.classicalb.core.parser.node.Node;
@@ -68,6 +65,8 @@ import de.be4.classicalb.core.parser.node.PSet;
 import de.be4.classicalb.core.parser.node.Start;
 import de.be4.classicalb.core.parser.node.TIdentifierLiteral;
 import de.tlc4b.TLC4BGlobals;
+import de.tlc4b.analysis.transformation.DefinitionsSorter;
+import de.tlc4b.analysis.transformation.MachineClauseSorter;
 import de.tlc4b.exceptions.ScopeException;
 import de.tlc4b.ltl.LTLBPredicate;
 import de.tlc4b.ltl.LTLFormulaVisitor;
@@ -83,8 +82,8 @@ public class MachineContext extends DepthFirstAdapter {
 
 	private boolean constantSetupInTraceFile = false;
 	// machine identifier
-	private final LinkedHashMap<String, Node> setParameter;
-	private final LinkedHashMap<String, Node> scalarParameter;
+	private final LinkedHashMap<String, Node> machineSetParameter;
+	private final LinkedHashMap<String, Node> machineScalarParameter;
 
 	private final LinkedHashMap<String, Node> deferredSets;
 	private final LinkedHashMap<String, Node> enumeratedSets;
@@ -129,8 +128,8 @@ public class MachineContext extends DepthFirstAdapter {
 			this.ltlVisitors.add(ltlVisitor);
 		}
 
-		this.setParameter = new LinkedHashMap<String, Node>();
-		this.scalarParameter = new LinkedHashMap<String, Node>();
+		this.machineSetParameter = new LinkedHashMap<String, Node>();
+		this.machineScalarParameter = new LinkedHashMap<String, Node>();
 
 		this.deferredSets = new LinkedHashMap<String, Node>();
 		this.enumeratedSets = new LinkedHashMap<String, Node>();
@@ -210,17 +209,17 @@ public class MachineContext extends DepthFirstAdapter {
 
 	private void exist(LinkedList<TIdentifierLiteral> list) {
 		String name = Utils.getIdentifierAsString(list);
-		existString(name);
+		identifierAlreadyExists(name);
 	}
 
-	private void existString(String name) {
+	private void identifierAlreadyExists(String name) {
 		if (constants.containsKey(name) || variables.containsKey(name)
 				|| operations.containsKey(name)
 				|| deferredSets.containsKey(name)
 				|| enumeratedSets.containsKey(name)
 				|| enumValues.containsKey(name)
-				|| setParameter.containsKey(name)
-				|| scalarParameter.containsKey(name)
+				|| machineSetParameter.containsKey(name)
+				|| machineScalarParameter.containsKey(name)
 				|| seenMachines.containsKey(name)
 				|| definitions.containsKey(name)) {
 			throw new ScopeException("Duplicate identifier: '" + name + "'");
@@ -236,13 +235,14 @@ public class MachineContext extends DepthFirstAdapter {
 		if (node.getHeader() != null) {
 			node.getHeader().apply(this);
 		}
-		List<PMachineClause> copy = new ArrayList<PMachineClause>(
-				node.getMachineClauses());
-		PMachineClauseComparator comperator = new PMachineClauseComparator();
+		
+		
+		List<PMachineClause> machineClauses = node.getMachineClauses();
 		// Sort the machine clauses: declarations clauses first, then
 		// properties clauses
-		Collections.sort(copy, comperator);
-		for (PMachineClause e : copy) {
+		MachineClauseSorter.sortMachineClauses(start);
+		
+		for (PMachineClause e : machineClauses) {
 			e.apply(this);
 		}
 	}
@@ -263,9 +263,9 @@ public class MachineContext extends DepthFirstAdapter {
 			String name = Utils.getIdentifierAsString(p.getIdentifier());
 			exist(p.getIdentifier());
 			if (Character.isUpperCase(name.charAt(0))) {
-				this.setParameter.put(name, p);
+				this.machineSetParameter.put(name, p);
 			} else {
-				this.scalarParameter.put(name, p);
+				this.machineScalarParameter.put(name, p);
 			}
 		}
 	}
@@ -283,6 +283,8 @@ public class MachineContext extends DepthFirstAdapter {
 	@Override
 	public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) {
 		definitionMachineClause = node;
+		DefinitionsSorter.sortDefinitions(node);
+		
 		List<PDefinition> copy = node.getDefinitions();
 
 		/*
@@ -341,7 +343,7 @@ public class MachineContext extends DepthFirstAdapter {
 	}
 
 	private void evalDefinitionName(String name, Node node) {
-		existString(name);
+		identifierAlreadyExists(name);
 		definitions.put(name, node);
 	}
 
@@ -586,8 +588,8 @@ public class MachineContext extends DepthFirstAdapter {
 		this.constraintMachineClause = node;
 
 		this.contextTable = new ArrayList<LinkedHashMap<String, Node>>();
-		this.contextTable.add(this.scalarParameter);
-		this.contextTable.add(this.setParameter);
+		this.contextTable.add(this.machineScalarParameter);
+		this.contextTable.add(this.machineSetParameter);
 		if (node.getPredicates() != null) {
 			node.getPredicates().apply(this);
 		}
@@ -890,6 +892,22 @@ public class MachineContext extends DepthFirstAdapter {
 		node.getPredicates().apply(this);
 		contextTable.remove(contextTable.size() - 1);
 	}
+	
+	@Override
+	public void caseAEventBComprehensionSetExpression(AEventBComprehensionSetExpression node){
+		contextTable.add(new LinkedHashMap<String, Node>());
+		{
+			List<PExpression> copy = new ArrayList<PExpression>(
+					node.getIdentifiers());
+			for (PExpression e : copy) {
+				putLocalVariableIntoCurrentScope((AIdentifierExpression) e);
+			}
+		}
+		node.getPredicates().apply(this);
+		
+		node.getExpression().apply(this);
+		contextTable.remove(contextTable.size() - 1);
+	}
 
 	@Override
 	public void caseAQuantifiedUnionExpression(AQuantifiedUnionExpression node) {
@@ -991,11 +1009,11 @@ public class MachineContext extends DepthFirstAdapter {
 	}
 
 	public LinkedHashMap<String, Node> getSetParamter() {
-		return setParameter;
+		return machineSetParameter;
 	}
 
 	public LinkedHashMap<String, Node> getScalarParameter() {
-		return scalarParameter;
+		return machineScalarParameter;
 	}
 
 	public ArrayList<Node> getConstantArrayList() {
@@ -1126,42 +1144,3 @@ public class MachineContext extends DepthFirstAdapter {
 
 }
 
-class PMachineClauseComparator implements Comparator<PMachineClause>,
-		Serializable {
-
-	private static final long serialVersionUID = 2606332412649258695L;
-	private static Hashtable<Object, Integer> priority = new Hashtable<Object, Integer>();
-	static {
-		// declarations clauses
-
-		priority.put(ASeesMachineClause.class, 12);
-		priority.put(ASetsMachineClause.class, 11);
-		priority.put(AAbstractConstantsMachineClause.class, 10);
-		priority.put(AConstantsMachineClause.class, 9);
-		priority.put(AVariablesMachineClause.class, 8);
-		priority.put(AConcreteVariablesMachineClause.class, 7);
-		priority.put(ADefinitionsMachineClause.class, 6);
-
-		// properties clauses
-		priority.put(AConstraintsMachineClause.class, 5);
-		priority.put(APropertiesMachineClause.class, 4);
-		priority.put(AInvariantMachineClause.class, 3);
-		priority.put(AAssertionsMachineClause.class, 2);
-		priority.put(AOperationsMachineClause.class, 1);
-		priority.put(AInitialisationMachineClause.class, 0);
-	}
-
-	public int compare(PMachineClause arg0, PMachineClause arg1) {
-		if (priority.get(arg0.getClass()).intValue() < priority.get(
-				arg1.getClass()).intValue()) {
-			return 1;
-		}
-		if (priority.get(arg0.getClass()).intValue() > priority.get(
-				arg1.getClass()).intValue()) {
-			return -1;
-		}
-
-		return 0;
-	}
-
-}
diff --git a/src/main/java/de/tlc4b/analysis/StandardMadules.java b/src/main/java/de/tlc4b/analysis/StandardMadules.java
index bcd4aaf60c7d3c823c9c67b354a866b48ca29cd4..8ff4abbe734a2f12e40c98ff195b220e5d24447e 100644
--- a/src/main/java/de/tlc4b/analysis/StandardMadules.java
+++ b/src/main/java/de/tlc4b/analysis/StandardMadules.java
@@ -230,39 +230,53 @@ public final class StandardMadules {
 	public static final boolean containsNameFromModuleRelations(String name) {
 		return Relations.contains(name);
 	}
-	
+
 	/**
 	 * External Functions
 	 * 
-	 * All external functions must be defined in the standard module ExternalFunctions.tla
-	 * (src/main/resources/standardModules/).
-	 * The B machine must contain a definition declaring the external function.
-	 * The typing definition (e.g. EXTERNAL_FUNCTION_STRING_SPLIT == ((STRING*STRING) --> (INTEGER<->STRING));)
-	 * is not mandatory.
+	 * All external functions must be defined in the standard module
+	 * ExternalFunctions.tla (src/main/resources/standardModules/). The B
+	 * machine must contain a definition declaring the external function. The
+	 * typing definition (e.g. EXTERNAL_FUNCTION_STRING_SPLIT ==
+	 * ((STRING*STRING) --> (INTEGER<->STRING));) is not mandatory.
 	 * 
 	 * The B definitions will be ignored in the {@link TLAPrinter}.
 	 * 
 	 * 
 	 */
-	
+
 	public static final String EXTERNAL_printf = "printf";
 	public static final String INT_TO_STRING = "INT_TO_STRING";
 	public static final String STRING_SPLIT = "STRING_SPLIT";
 	public static final String SORT_SET = "SORT_SET";
 	public static final String STRING_APPEND = "STRING_APPEND";
+	public static final String STRING_TO_INT = "STRING_TO_INT";
+	public static final String DECIMAL_TO_INT = "DECIMAL_TO_INT";
 
 	private static final ArrayList<String> ExternalFunctions = new ArrayList<String>();
 	static {
 		ExternalFunctions.add(EXTERNAL_printf);
 		ExternalFunctions.add(INT_TO_STRING);
 		ExternalFunctions.add(STRING_SPLIT);
-		ExternalFunctions.add(SORT_SET);
 		ExternalFunctions.add(STRING_APPEND);
+		ExternalFunctions.add(STRING_TO_INT);
+
+		ExternalFunctions.add(SORT_SET);
+		ExternalFunctions.add(DECIMAL_TO_INT);
 	}
 
-	public static boolean isKeywordInModuleExternalFunctions(String name){
+	public static boolean isAbstractConstant(String name) {
+		if (name.equals(SORT_SET) 
+				|| name.equals(DECIMAL_TO_INT)) {
+			return true;
+		} else {
+			return false;
+		}
+
+	}
+
+	public static boolean isKeywordInModuleExternalFunctions(String name) {
 		return ExternalFunctions.contains(name);
 	}
-	
-	
+
 }
diff --git a/src/main/java/de/tlc4b/analysis/Typechecker.java b/src/main/java/de/tlc4b/analysis/Typechecker.java
index f811ebd328eb5607c16449ecf1031cee3ee97454..cb927d6fdc779ae337b5f8c3e630f146dc3ad94a 100644
--- a/src/main/java/de/tlc4b/analysis/Typechecker.java
+++ b/src/main/java/de/tlc4b/analysis/Typechecker.java
@@ -2,7 +2,6 @@ package de.tlc4b.analysis;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.LinkedList;
@@ -58,7 +57,7 @@ public class Typechecker extends DepthFirstAdapter implements ITypechecker {
 
 		checkLTLFormulas();
 		checkConstantsSetup();
-		
+
 	}
 
 	private void checkLTLFormulas() {
@@ -133,9 +132,6 @@ public class Typechecker extends DepthFirstAdapter implements ITypechecker {
 		{
 			List<PMachineClause> copy = new ArrayList<PMachineClause>(
 					node.getMachineClauses());
-			PMachineClauseComparator comperator = new PMachineClauseComparator();
-			// Sort the machine clauses
-			Collections.sort(copy, comperator);
 			for (PMachineClause e : copy) {
 				e.apply(this);
 			}
@@ -286,15 +282,10 @@ public class Typechecker extends DepthFirstAdapter implements ITypechecker {
 		node.getRhs().apply(this);
 	}
 
-	
-	
 	@Override
 	public void caseADefinitionExpression(ADefinitionExpression node) {
 		BType expected = getType(node);
-		String name = node.getDefLiteral().getText().toString();
-		if(StandardMadules.isKeywordInModuleExternalFunctions(name)){
-			
-		}
+		// String name = node.getDefLiteral().getText().toString();
 		Node originalDef = referenceTable.get(node);
 		BType found = getType(originalDef);
 
@@ -309,7 +300,8 @@ public class Typechecker extends DepthFirstAdapter implements ITypechecker {
 		List<PExpression> copy = new ArrayList<PExpression>(
 				node.getParameters());
 		for (int i = 0; i < params.size(); i++) {
-			setType(copy.get(i), getType(params.get(i)));
+			BType type = getType(params.get(i));
+			setType(copy.get(i), type);
 			copy.get(i).apply(this);
 		}
 	}
@@ -440,12 +432,15 @@ public class Typechecker extends DepthFirstAdapter implements ITypechecker {
 	public void caseAIdentifierExpression(AIdentifierExpression node) {
 		Node originalIdentifier = referenceTable.get(node);
 		BType expected = getType(node);
+
 		if (expected == null) {
 			System.out.println("Not implemented in Typechecker:"
 					+ node.parent().getClass());
 			throw new RuntimeException(node + " Pos: " + node.getStartPos());
 		}
 		BType found = getType(originalIdentifier);
+
+		String name = Utils.getIdentifierAsString(node.getIdentifier());
 		try {
 			expected.unify(found, this);
 		} catch (UnificationException e) {
@@ -453,7 +448,6 @@ public class Typechecker extends DepthFirstAdapter implements ITypechecker {
 					+ "' , found '" + found + "' at identifier " + node + "\n"
 					+ node.getStartPos());
 		}
-
 	}
 
 	@Override
@@ -1281,6 +1275,61 @@ public class Typechecker extends DepthFirstAdapter implements ITypechecker {
 
 		setType(node.getPredicates(), BoolType.getInstance());
 		node.getPredicates().apply(this);
+
+	}
+
+	@Override
+	public void caseAEventBComprehensionSetExpression(
+			AEventBComprehensionSetExpression node) {
+		List<PExpression> copy = new ArrayList<PExpression>(
+				node.getIdentifiers());
+		for (PExpression e : copy) {
+			AIdentifierExpression v = (AIdentifierExpression) e;
+			setType(v, new UntypedType());
+		}
+
+		setType(node.getPredicates(), BoolType.getInstance());
+		node.getPredicates().apply(this);
+
+		setType(node.getExpression(), new UntypedType());
+		node.getExpression().apply(this);
+
+
+		BType found = new SetType(getType(node.getExpression()));
+
+		BType expected = getType(node);
+		try {
+			found.unify(expected, this);
+		} catch (UnificationException e) {
+			throw new TypeErrorException("Excepted '" + expected + "' , found "
+					+ found + "'");
+		}
+		
+		
+//		List<PExpression> copy = new ArrayList<PExpression>(
+//				node.getIdentifiers());
+//		for (PExpression e : copy) {
+//			AIdentifierExpression v = (AIdentifierExpression) e;
+//			UntypedType u = new UntypedType();
+//			setType(v, u);
+//		}
+//		
+//		setType(node.getPredicates(), BoolType.getInstance());
+//		node.getPredicates().apply(this);
+//		
+//		setType(node.getExpression(), new UntypedType());
+//		node.getExpression().apply(this);
+//		
+//		BType expr = getType(node.getExpression());
+//		System.out.println(getType(node.getExpression()));
+//
+//		BType expected = getType(node);
+//		SetType set = new SetType(getType(node.getExpression()));
+//		unify(expected, set, node);
+//		BType type = getType(node);
+//		System.out.println(getType(node));
+
+
 	}
 
 	public static BType makePair(ArrayList<BType> list) {
@@ -1373,11 +1422,11 @@ public class Typechecker extends DepthFirstAdapter implements ITypechecker {
 			throw new TypeErrorException("Excepted '" + expected + "' , found "
 					+ found + "'");
 		}
-		
+
 		setType(node.getExpression(), new UntypedType());
 		node.getExpression().apply(this);
 		BType type = getType(node.getExpression());
-		if (! (type instanceof FunctionType)){
+		if (!(type instanceof FunctionType)) {
 			new SetType(new UntypedType()).unify(type, this);
 		}
 	}
@@ -1813,6 +1862,9 @@ public class Typechecker extends DepthFirstAdapter implements ITypechecker {
 		for (PExpression e : copy) {
 			setType(e, new UntypedType());
 			e.apply(this);
+		}
+		
+		for (PExpression e : copy) {
 			list.add(getType(e));
 		}
 
@@ -2377,7 +2429,7 @@ public class Typechecker extends DepthFirstAdapter implements ITypechecker {
 		}
 		BType expected = getType(node);
 		try {
-			found.unify(expected, this);
+			unify(expected, found, node);
 		} catch (UnificationException e) {
 			throw new TypeErrorException("Excepted '" + expected + "' , found "
 					+ found + "'");
@@ -2391,17 +2443,19 @@ public class Typechecker extends DepthFirstAdapter implements ITypechecker {
 		String fieldName = Utils.getIdentifierAsString(i.getIdentifier());
 		s.add(fieldName, new UntypedType());
 		setType(node.getRecord(), s);
+
 		node.getRecord().apply(this);
 
 		BType found = ((StructType) getType(node.getRecord()))
 				.getType(fieldName);
 		BType expected = getType(node);
 		try {
-			found.unify(expected, this);
+			unify(expected, found, node);
 		} catch (UnificationException e) {
 			throw new TypeErrorException("Excepted '" + expected + "' , found "
 					+ found + "'");
 		}
+
 	}
 
 	@Override
diff --git a/src/main/java/de/tlc4b/analysis/transformation/DefinitionsEliminator.java b/src/main/java/de/tlc4b/analysis/transformation/DefinitionsEliminator.java
index 1068dedef3fa339587e16ab32d064e5ba8c099ae..38fb4969b12ec1767b1a9f59770cddde2821aefb 100644
--- a/src/main/java/de/tlc4b/analysis/transformation/DefinitionsEliminator.java
+++ b/src/main/java/de/tlc4b/analysis/transformation/DefinitionsEliminator.java
@@ -37,7 +37,11 @@ public class DefinitionsEliminator extends DepthFirstAdapter {
 	private Hashtable<String, PDefinition> definitionsTable;
 	private ArrayList<Hashtable<String, PExpression>> contextStack;
 
-	public DefinitionsEliminator(Start node) {
+	public static void eliminateDefinitions(Start start){
+		new DefinitionsEliminator(start);
+	}
+	
+	private DefinitionsEliminator(Start node) {
 		DefinitionCollector collector = new DefinitionCollector(node);
 		definitionsTable = collector.getDefinitions();
 		contextStack = new ArrayList<Hashtable<String, PExpression>>();
@@ -61,9 +65,19 @@ public class DefinitionsEliminator extends DepthFirstAdapter {
 
 	@Override
 	public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) {
-		List<PDefinition> copy = new ArrayList<PDefinition>(
+		/**
+		 * Definitions from other definitions files were injected into the
+		 * DefinitionsCLause. However, their parent was not correctly set to the
+		 * DefinitionsClause. Hence e.replaceBy(null) would not eliminate them.
+		 * Therefore, we have to create a new list and have to the use the
+		 * setDefinitions method form {link ADefinitionsMachineClause}.
+		 **/
+
+		List<PDefinition> newDefinitionsList = new ArrayList<PDefinition>();
+		List<PDefinition> oldDefinitionsList = new ArrayList<PDefinition>(
 				node.getDefinitions());
-		for (PDefinition e : copy) {
+		for (PDefinition e : oldDefinitionsList) {
+			// replace all definitions calls inside the definitions bodies
 			if (e instanceof AExpressionDefinitionDefinition) {
 				String name = ((AExpressionDefinitionDefinition) e).getName()
 						.getText().toString();
@@ -74,26 +88,39 @@ public class DefinitionsEliminator extends DepthFirstAdapter {
 			}
 			e.apply(this);
 		}
-		for (PDefinition e : copy) {
+
+		// add certain definitions to the new definitions list in order to
+		// obtain them for the translation
+		for (PDefinition e : oldDefinitionsList) {
+
 			if (e instanceof AExpressionDefinitionDefinition) {
+
 				String name = ((AExpressionDefinitionDefinition) e).getName()
 						.getText().toString();
 				if (name.startsWith("ASSERT_LTL")
 						|| name.startsWith("scope_")
 						|| name.startsWith("SET_PREF_")
 						|| StandardMadules
-								.isKeywordInModuleExternalFunctions(name))
-					continue;
+								.isKeywordInModuleExternalFunctions(name)) {
+
+					newDefinitionsList.add(e);
+				}
 			} else if (e instanceof APredicateDefinitionDefinition) {
 				String name = ((APredicateDefinitionDefinition) e).getName()
 						.getText().toString();
 				if (name.equals("GOAL")
 						|| StandardMadules
-								.isKeywordInModuleExternalFunctions(name))
-					continue;
+								.isKeywordInModuleExternalFunctions(name)) {
+					newDefinitionsList.add(e);
+				}
 			}
-			e.replaceBy(null);
 		}
+		for (PDefinition def : newDefinitionsList) {
+			// we have delete all parents of the definitions in order to set
+			// them in the next step (seems to be a bug in SabbleCC)
+			def.replaceBy(null);
+		}
+		node.setDefinitions(newDefinitionsList);
 	}
 
 	@Override
@@ -123,7 +150,6 @@ public class DefinitionsEliminator extends DepthFirstAdapter {
 
 	@Override
 	public void caseADefinitionExpression(ADefinitionExpression node) {
-
 		String name = node.getDefLiteral().getText();
 		ArrayList<PExpression> arguments = new ArrayList<PExpression>(
 				node.getParameters());
diff --git a/src/main/java/de/tlc4b/analysis/transformation/DefinitionsSorter.java b/src/main/java/de/tlc4b/analysis/transformation/DefinitionsSorter.java
new file mode 100644
index 0000000000000000000000000000000000000000..8061e7c03b8f8e5dbe773241407d025c297007af
--- /dev/null
+++ b/src/main/java/de/tlc4b/analysis/transformation/DefinitionsSorter.java
@@ -0,0 +1,136 @@
+package de.tlc4b.analysis.transformation;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+
+import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter;
+import de.be4.classicalb.core.parser.node.ADefinitionExpression;
+import de.be4.classicalb.core.parser.node.ADefinitionPredicate;
+import de.be4.classicalb.core.parser.node.ADefinitionSubstitution;
+import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause;
+import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition;
+import de.be4.classicalb.core.parser.node.APredicateDefinitionDefinition;
+import de.be4.classicalb.core.parser.node.ASubstitutionDefinitionDefinition;
+import de.be4.classicalb.core.parser.node.PDefinition;
+
+public class DefinitionsSorter extends DepthFirstAdapter {
+	final LinkedHashMap<String, HashSet<String>> dependencies;
+	final LinkedHashMap<String, HashSet<String>> allDependencies;
+	final LinkedHashMap<String, PDefinition> definitionsTable;
+	final ArrayList<PDefinition> res;
+	String current = null;
+
+	public DefinitionsSorter(ADefinitionsMachineClause clause) {
+		dependencies = new LinkedHashMap<String, HashSet<String>>();
+		allDependencies = new LinkedHashMap<String, HashSet<String>>();
+		definitionsTable = new LinkedHashMap<String, PDefinition>();
+		res = new ArrayList<PDefinition>();
+
+		clause.apply(this);
+
+		for (String defName : dependencies.keySet()) {
+			resolveDependencies(defName);
+		}
+
+		ArrayList<String> defs = new ArrayList<String>(allDependencies.keySet());
+		
+		
+		while (!res.containsAll(definitionsTable.values())) {
+			Iterator<String> iterator = new ArrayList<String>(defs).iterator();
+			while (iterator.hasNext()) {
+				String next = iterator.next();
+				
+				HashSet<String> deps = allDependencies.get(next);
+				
+				deps.retainAll(defs);
+				
+				if (deps.size() == 0) {
+					PDefinition pDefinition = definitionsTable.get(next);
+					pDefinition.replaceBy(null);
+					res.add(pDefinition);
+					defs.remove(next);
+				}
+			}
+		}
+		clause.setDefinitions(res);
+
+	}
+
+	private void resolveDependencies(String defName) {
+		if (allDependencies.containsKey(defName)) {
+			return;
+		}
+		HashSet<String> allDeps = new HashSet<String>();
+		HashSet<String> deps = dependencies.get(defName);
+		for (String def : deps) {
+			resolveDependencies(def);
+			allDeps.add(def);
+			allDeps.addAll(allDependencies.get(def));
+		}
+		allDependencies.put(defName, allDeps);
+
+	}
+
+	public static void sortDefinitions(ADefinitionsMachineClause clause) {
+		new DefinitionsSorter(clause);
+
+	}
+
+	@Override
+	public void inAPredicateDefinitionDefinition(
+			APredicateDefinitionDefinition node) {
+		String name = node.getName().getText().toString();
+		addDefinition(name);
+		definitionsTable.put(name, node);
+		current = name;
+	}
+
+	@Override
+	public void inASubstitutionDefinitionDefinition(
+			ASubstitutionDefinitionDefinition node) {
+		String name = node.getName().getText().toString();
+		addDefinition(name);
+		definitionsTable.put(name, node);
+		current = name;
+	}
+
+	@Override
+	public void inAExpressionDefinitionDefinition(
+			AExpressionDefinitionDefinition node) {
+		String name = node.getName().getText().toString();
+		addDefinition(name);
+		definitionsTable.put(name, node);
+		current = name;
+	}
+
+	@Override
+	public void inADefinitionExpression(ADefinitionExpression node) {
+		String name = node.getDefLiteral().getText().toString();
+		addDefinitionCall(name);
+	}
+
+	@Override
+	public void inADefinitionPredicate(ADefinitionPredicate node) {
+		String name = node.getDefLiteral().getText().toString();
+		addDefinitionCall(name);
+	}
+
+	@Override
+	public void inADefinitionSubstitution(ADefinitionSubstitution node) {
+		String name = node.getDefLiteral().getText().toString();
+		addDefinitionCall(name);
+	}
+
+	private void addDefinition(String name) {
+		if (!dependencies.keySet().contains(name)) {
+			dependencies.put(name, new HashSet<String>());
+		}
+	}
+
+	private void addDefinitionCall(String name) {
+		dependencies.get(current).add(name);
+	}
+
+}
diff --git a/src/main/java/de/tlc4b/analysis/transformation/MachineClauseSorter.java b/src/main/java/de/tlc4b/analysis/transformation/MachineClauseSorter.java
new file mode 100644
index 0000000000000000000000000000000000000000..98ea212bce3f8a25d12afc481a80b228c403667b
--- /dev/null
+++ b/src/main/java/de/tlc4b/analysis/transformation/MachineClauseSorter.java
@@ -0,0 +1,87 @@
+package de.tlc4b.analysis.transformation;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Hashtable;
+import java.util.LinkedList;
+
+import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter;
+import de.be4.classicalb.core.parser.node.AAbstractConstantsMachineClause;
+import de.be4.classicalb.core.parser.node.AAbstractMachineParseUnit;
+import de.be4.classicalb.core.parser.node.AAssertionsMachineClause;
+import de.be4.classicalb.core.parser.node.AConcreteVariablesMachineClause;
+import de.be4.classicalb.core.parser.node.AConstantsMachineClause;
+import de.be4.classicalb.core.parser.node.AConstraintsMachineClause;
+import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause;
+import de.be4.classicalb.core.parser.node.AInitialisationMachineClause;
+import de.be4.classicalb.core.parser.node.AInvariantMachineClause;
+import de.be4.classicalb.core.parser.node.AOperationsMachineClause;
+import de.be4.classicalb.core.parser.node.APropertiesMachineClause;
+import de.be4.classicalb.core.parser.node.ASeesMachineClause;
+import de.be4.classicalb.core.parser.node.ASetsMachineClause;
+import de.be4.classicalb.core.parser.node.AVariablesMachineClause;
+import de.be4.classicalb.core.parser.node.PMachineClause;
+import de.be4.classicalb.core.parser.node.Start;
+
+public class MachineClauseSorter extends DepthFirstAdapter {
+
+	public static void sortMachineClauses(Start start) {
+		MachineClauseSorter sorter = new MachineClauseSorter();
+		start.apply(sorter);
+	}
+
+	@Override
+	public void caseAAbstractMachineParseUnit(AAbstractMachineParseUnit node) {
+
+		LinkedList<PMachineClause> machineClauses = node.getMachineClauses();
+
+		PMachineClauseComparator comperator = new PMachineClauseComparator();
+		// Sort the machine clauses:
+		// 1. import clauses
+		// 2. declaration clauses
+		// 3. properties clauses
+		// 4. operation clauses
+		Collections.sort(machineClauses, comperator);
+	}
+}
+
+class PMachineClauseComparator implements Comparator<PMachineClause>,
+		Serializable {
+
+	private static final long serialVersionUID = 2606332412649258695L;
+	private static Hashtable<Object, Integer> priority = new Hashtable<Object, Integer>();
+	static {
+		// declarations clauses
+
+		priority.put(ASeesMachineClause.class, 12);
+		priority.put(ASetsMachineClause.class, 11);
+		priority.put(AAbstractConstantsMachineClause.class, 10);
+		priority.put(AConstantsMachineClause.class, 9);
+		priority.put(AVariablesMachineClause.class, 8);
+		priority.put(AConcreteVariablesMachineClause.class, 7);
+		priority.put(ADefinitionsMachineClause.class, 6);
+
+		// properties clauses
+		priority.put(AConstraintsMachineClause.class, 5);
+		priority.put(APropertiesMachineClause.class, 4);
+		priority.put(AInvariantMachineClause.class, 3);
+		priority.put(AAssertionsMachineClause.class, 2);
+		priority.put(AOperationsMachineClause.class, 1);
+		priority.put(AInitialisationMachineClause.class, 0);
+	}
+
+	public int compare(PMachineClause arg0, PMachineClause arg1) {
+		if (priority.get(arg0.getClass()).intValue() < priority.get(
+				arg1.getClass()).intValue()) {
+			return 1;
+		}
+		if (priority.get(arg0.getClass()).intValue() > priority.get(
+				arg1.getClass()).intValue()) {
+			return -1;
+		}
+
+		return 0;
+	}
+
+}
\ No newline at end of file
diff --git a/src/main/java/de/tlc4b/analysis/transformation/SeesEliminator.java b/src/main/java/de/tlc4b/analysis/transformation/SeesEliminator.java
new file mode 100644
index 0000000000000000000000000000000000000000..e7283719de7900fbd94a9a14f40cb3e530cbcb6d
--- /dev/null
+++ b/src/main/java/de/tlc4b/analysis/transformation/SeesEliminator.java
@@ -0,0 +1,199 @@
+package de.tlc4b.analysis.transformation;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import de.be4.classicalb.core.parser.Utils;
+import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter;
+import de.be4.classicalb.core.parser.node.AAbstractConstantsMachineClause;
+import de.be4.classicalb.core.parser.node.AAbstractMachineParseUnit;
+import de.be4.classicalb.core.parser.node.AConjunctPredicate;
+import de.be4.classicalb.core.parser.node.AConstantsMachineClause;
+import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause;
+import de.be4.classicalb.core.parser.node.AIdentifierExpression;
+import de.be4.classicalb.core.parser.node.APropertiesMachineClause;
+import de.be4.classicalb.core.parser.node.ASeesMachineClause;
+import de.be4.classicalb.core.parser.node.PDefinition;
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.be4.classicalb.core.parser.node.PMachineClause;
+import de.be4.classicalb.core.parser.node.PParseUnit;
+import de.be4.classicalb.core.parser.node.Start;
+
+public class SeesEliminator extends DepthFirstAdapter {
+
+	private final Start main;
+	private final Map<String, Start> parsedMachines;
+
+	public static void eliminateSeesClauses(Start start,
+			Map<String, Start> parsedMachines) {
+		new SeesEliminator(start, parsedMachines);
+	}
+
+	private SeesEliminator(Start start, Map<String, Start> parsedMachines) {
+		this.main = start;
+		this.parsedMachines = parsedMachines;
+		MachineClauseSorter.sortMachineClauses(start);
+		start.apply(this);
+	}
+
+	public void inASeesMachineClause(ASeesMachineClause node) {
+		LinkedList<PExpression> machineNames = node.getMachineNames();
+		for (PExpression pExpression : machineNames) {
+			AIdentifierExpression id = (AIdentifierExpression) pExpression;
+			String identifierAsString = Utils.getIdentifierAsString(id
+					.getIdentifier());
+			Start start = parsedMachines.get(identifierAsString);
+			DefinitionsEliminator.eliminateDefinitions(start);
+			eliminateSeesClauses(start, parsedMachines);
+			new MachineClauseAdder(main, start);
+			if(node.parent() != null){
+				node.replaceBy(null);
+			}
+		}
+	}
+
+	class MachineClauseAdder extends DepthFirstAdapter {
+		private final ArrayList<PMachineClause> machineClausesList;
+		private final HashMap<Class<? extends PMachineClause>, PMachineClause> machineClauseHashMap;
+		private final LinkedList<PMachineClause> additionalMachineClauseList;
+
+		public MachineClauseAdder(Start main, Start start) {
+			this.machineClausesList = new ArrayList<PMachineClause>();
+			this.machineClauseHashMap = new LinkedHashMap<Class<? extends PMachineClause>, PMachineClause>();
+			this.additionalMachineClauseList = new LinkedList<PMachineClause>();
+
+			PParseUnit pParseUnit = main.getPParseUnit();
+			AAbstractMachineParseUnit machineParseUnit = (AAbstractMachineParseUnit) pParseUnit;
+
+			for (PMachineClause machineClause : machineParseUnit
+					.getMachineClauses()) {
+				machineClausesList.add(machineClause);
+				machineClauseHashMap.put(machineClause.getClass(),
+						machineClause);
+			}
+
+			start.apply(this);
+			
+			
+			LinkedList<PMachineClause> newMachineClauseList = new LinkedList<PMachineClause>();
+			for (PMachineClause pMachineClause : machineClausesList) {
+				pMachineClause.replaceBy(null); // delete parent of clause
+				newMachineClauseList.add(pMachineClause);
+			}
+			newMachineClauseList.addAll(additionalMachineClauseList);
+			machineParseUnit.setMachineClauses(newMachineClauseList);
+		}
+
+		@Override
+		public void caseAConstantsMachineClause(AConstantsMachineClause node) {
+			AConstantsMachineClause main = (AConstantsMachineClause) machineClauseHashMap
+					.get(node.getClass());
+
+			if (main != null) {
+				ArrayList<PExpression> oldConstantsList = new ArrayList<PExpression>(
+						main.getIdentifiers());
+				ArrayList<PExpression> newConstantsList = new ArrayList<PExpression>();
+				for (PExpression pExpression : oldConstantsList) {
+					pExpression.replaceBy(null); // delete parent
+					newConstantsList.add(pExpression);
+				}
+				ArrayList<PExpression> otherConstants = new ArrayList<PExpression>(
+						node.getIdentifiers());
+
+				for (PExpression pExpression : otherConstants) {
+					pExpression.replaceBy(null); // delete parent
+					newConstantsList.add(pExpression);
+
+				}
+				main.setIdentifiers(newConstantsList);
+			} else {
+				additionalMachineClauseList.add(node);
+			}
+		}
+
+		public void caseAAbstractConstantsMachineClause(
+				AAbstractConstantsMachineClause node) {
+			AAbstractConstantsMachineClause main = (AAbstractConstantsMachineClause) machineClauseHashMap
+					.get(node.getClass());
+
+			if (main != null) {
+				ArrayList<PExpression> oldConstantsList = new ArrayList<PExpression>(
+						main.getIdentifiers());
+				ArrayList<PExpression> newConstantsList = new ArrayList<PExpression>();
+				for (PExpression pExpression : oldConstantsList) {
+					pExpression.replaceBy(null); // delete parent
+					newConstantsList.add(pExpression);
+				}
+				ArrayList<PExpression> otherConstants = new ArrayList<PExpression>(
+						node.getIdentifiers());
+
+				for (PExpression pExpression : otherConstants) {
+					pExpression.replaceBy(null); // delete parent
+					newConstantsList.add(pExpression);
+
+				}
+				main.setIdentifiers(newConstantsList);
+			} else {
+				additionalMachineClauseList.add(node);
+			}
+
+		}
+
+		@Override
+		public void caseAPropertiesMachineClause(APropertiesMachineClause node) {
+			APropertiesMachineClause main = null;
+			for (PMachineClause clause : machineClausesList) {
+				if (clause instanceof APropertiesMachineClause) {
+					main = (APropertiesMachineClause) clause;
+				}
+			}
+
+			if (main != null) {
+				AConjunctPredicate con = new AConjunctPredicate();
+				con.setLeft(main.getPredicates());
+				con.setRight(node.getPredicates());
+				main.setPredicates(con);
+			} else {
+				additionalMachineClauseList.add(node);
+			}
+
+		}
+
+		@Override
+		public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) {
+			ADefinitionsMachineClause main = null;
+			for (PMachineClause clause : machineClausesList) {
+				if (clause instanceof ADefinitionsMachineClause) {
+					main = (ADefinitionsMachineClause) clause;
+				}
+			}
+
+			if (main != null) {
+				ArrayList<PDefinition> oldDefinitions = new ArrayList<PDefinition>(
+						main.getDefinitions());
+				ArrayList<PDefinition> newDefinitionsList = new ArrayList<PDefinition>();
+				for (PDefinition pExpression : oldDefinitions) {
+					pExpression.replaceBy(null); // delete parent
+					newDefinitionsList.add(pExpression);
+				}
+				ArrayList<PDefinition> otherConstants = new ArrayList<PDefinition>(
+						node.getDefinitions());
+
+				for (PDefinition definition : otherConstants) {
+					if (definition.parent() != null) {
+						definition.replaceBy(null); // delete parent
+					}
+					newDefinitionsList.add(definition);
+
+				}
+				main.setDefinitions(newDefinitionsList);
+			} else {
+				additionalMachineClauseList.add(node);
+			}
+		}
+
+	}
+}
diff --git a/src/main/java/de/tlc4b/analysis/transformation/SetComprehensionOptimizer.java b/src/main/java/de/tlc4b/analysis/transformation/SetComprehensionOptimizer.java
new file mode 100644
index 0000000000000000000000000000000000000000..1207e8b7afc1262e68606c1a8f7c6066ba1df5bb
--- /dev/null
+++ b/src/main/java/de/tlc4b/analysis/transformation/SetComprehensionOptimizer.java
@@ -0,0 +1,265 @@
+package de.tlc4b.analysis.transformation;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.LinkedList;
+
+import de.be4.classicalb.core.parser.Utils;
+import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter;
+import de.be4.classicalb.core.parser.node.AComprehensionSetExpression;
+import de.be4.classicalb.core.parser.node.AConjunctPredicate;
+import de.be4.classicalb.core.parser.node.ACoupleExpression;
+import de.be4.classicalb.core.parser.node.ADomainExpression;
+import de.be4.classicalb.core.parser.node.AEqualPredicate;
+import de.be4.classicalb.core.parser.node.AEventBComprehensionSetExpression;
+import de.be4.classicalb.core.parser.node.AIdentifierExpression;
+import de.be4.classicalb.core.parser.node.AMemberPredicate;
+import de.be4.classicalb.core.parser.node.PExpression;
+import de.be4.classicalb.core.parser.node.PPredicate;
+import de.be4.classicalb.core.parser.node.Start;
+
+public class SetComprehensionOptimizer extends DepthFirstAdapter {
+
+	public static void optimizeSetComprehensions(Start start) {
+		SetComprehensionOptimizer optimizer = new SetComprehensionOptimizer();
+		start.apply(optimizer);
+	}
+
+	@Override
+	public void caseAComprehensionSetExpression(AComprehensionSetExpression node) {
+		if (node.parent() instanceof ADomainExpression) {
+			LinkedList<PExpression> identifiers = node.getIdentifiers();
+
+			final ArrayList<String> list = new ArrayList<String>();
+			final AIdentifierExpression last = (AIdentifierExpression) identifiers
+					.getLast();
+			for (int i = 0; i < identifiers.size() - 1; i++) {
+				AIdentifierExpression id = (AIdentifierExpression) identifiers
+						.get(i);
+				String name = Utils.getIdentifierAsString(id.getIdentifier());
+				list.add(name);
+			}
+
+			Hashtable<String, PExpression> values = new Hashtable<String, PExpression>();
+			ArrayList<AEqualPredicate> equalList = new ArrayList<AEqualPredicate>();
+			analysePredicate(node.getPredicates(), list, values, equalList);
+
+			if (values.keySet().containsAll(list)) {
+				// delete nodes
+				new NodesRemover(node.getPredicates(), equalList, values);
+
+				AEventBComprehensionSetExpression eventBcomprehension = new AEventBComprehensionSetExpression();
+				ArrayList<PExpression> ids = new ArrayList<PExpression>();
+				ids.add(last);
+				eventBcomprehension.setIdentifiers(ids);
+
+				ACoupleExpression couple = new ACoupleExpression();
+
+				ArrayList<PExpression> exprs = new ArrayList<PExpression>();
+				for (int i = 0; i < list.size(); i++) {
+					exprs.add(values.get(list.get(i)));
+				}
+				couple.setList(exprs);
+				eventBcomprehension.setExpression(couple);
+
+				AMemberPredicate member = new AMemberPredicate();
+				member.setLeft((AIdentifierExpression) last.clone());
+				AComprehensionSetExpression compre = new AComprehensionSetExpression();
+				ArrayList<PExpression> ids2 = new ArrayList<PExpression>();
+				ids2.add((AIdentifierExpression) last.clone());
+				compre.setIdentifiers(ids2);
+				compre.setPredicates(node.getPredicates());
+				member.setRight(compre);
+				eventBcomprehension.setPredicates(member);
+
+				node.parent().replaceBy(eventBcomprehension);
+
+				eventBcomprehension.apply(this);
+			}
+		}
+
+		if (node.parent() != null)
+			testGeneric(node);
+
+	}
+
+	private void testGeneric(AComprehensionSetExpression node) {
+		final LinkedList<PExpression> identifiers = node.getIdentifiers();
+		final ArrayList<String> list = new ArrayList<String>();
+		final Hashtable<String, AIdentifierExpression> identifierTable = new Hashtable<String, AIdentifierExpression>();
+		for (int i = 0; i < identifiers.size(); i++) {
+			AIdentifierExpression id = (AIdentifierExpression) identifiers
+					.get(i);
+			String name = Utils.getIdentifierAsString(id.getIdentifier());
+			list.add(name);
+			identifierTable.put(name, id);
+		}
+
+		Hashtable<String, PExpression> values = new Hashtable<String, PExpression>();
+		ArrayList<AEqualPredicate> equalList = new ArrayList<AEqualPredicate>();
+		analysePredicate(node.getPredicates(), list, values, equalList);
+		if (values.size() > 0 && list.size()-values.size() > 0) {
+			// delete nodes
+			new NodesRemover(node.getPredicates(), equalList, values);
+
+			AEventBComprehensionSetExpression eventBcomprehension = new AEventBComprehensionSetExpression();
+			ArrayList<PExpression> ids = new ArrayList<PExpression>();
+			ArrayList<PExpression> ids2 = new ArrayList<PExpression>();
+			ArrayList<PExpression> ids3 = new ArrayList<PExpression>();
+			for (String p : list) {
+				if (!values.containsKey(p)) {
+					PExpression clone = (PExpression) identifierTable.get(p)
+							.clone();
+					ids.add(clone);
+					PExpression clone2 = (PExpression) identifierTable.get(p)
+							.clone();
+					ids2.add(clone2);
+					PExpression clone3 = (PExpression) identifierTable.get(p)
+							.clone();
+					ids3.add(clone3);
+				}
+			}
+			eventBcomprehension.setIdentifiers(ids);
+
+			ACoupleExpression couple = new ACoupleExpression();
+			ArrayList<PExpression> exprs = new ArrayList<PExpression>();
+			for (int i = 0; i < list.size(); i++) {
+				String name = list.get(i);
+				if (values.containsKey(name)) {
+					exprs.add(values.get(name));
+				} else {
+					PExpression clone = (PExpression) identifierTable.get(name)
+							.clone();
+					exprs.add(clone);
+				}
+
+			}
+			couple.setList(exprs);
+			eventBcomprehension.setExpression(couple);
+
+			AMemberPredicate member = new AMemberPredicate();
+			if (ids2.size() > 1) {
+				ACoupleExpression couple2 = new ACoupleExpression();
+				couple2.setList(ids2);
+				member.setLeft(couple2);
+			} else {
+				member.setLeft(ids2.get(0));
+			}
+
+			AComprehensionSetExpression compre = new AComprehensionSetExpression();
+			compre.setIdentifiers(ids3);
+			compre.setPredicates(node.getPredicates());
+			member.setRight(compre);
+			eventBcomprehension.setPredicates(member);
+
+			node.replaceBy(eventBcomprehension);
+
+			eventBcomprehension.apply(this);
+		}
+
+	}
+
+	private void analysePredicate(PPredicate predicate, ArrayList<String> list,
+			Hashtable<String, PExpression> values,
+			ArrayList<AEqualPredicate> equalList) {
+		if (predicate instanceof AConjunctPredicate) {
+			AConjunctPredicate con = (AConjunctPredicate) predicate;
+			analysePredicate(con.getLeft(), list, values, equalList);
+			analysePredicate(con.getRight(), list, values, equalList);
+		} else if (predicate instanceof AEqualPredicate) {
+			AEqualPredicate equal = (AEqualPredicate) predicate;
+			if (equal.getLeft() instanceof AIdentifierExpression) {
+				AIdentifierExpression id = (AIdentifierExpression) equal
+						.getLeft();
+				String name = Utils.getIdentifierAsString(id.getIdentifier());
+				if (list.contains(name) && !values.containsKey(name)) {
+					if (equal.getRight() instanceof AIdentifierExpression) {
+						AIdentifierExpression id2 = (AIdentifierExpression) equal
+								.getRight();
+						String name2 = Utils.getIdentifierAsString(id2
+								.getIdentifier());
+						if (values.containsKey(name2)){
+							return;
+						}
+					}
+					equalList.add(equal);
+					values.put(name, equal.getRight());
+				}
+			} else if (!equalList.contains(equal)
+					&& equal.getRight() instanceof AIdentifierExpression) {
+				AIdentifierExpression id = (AIdentifierExpression) equal
+						.getRight();
+				String name = Utils.getIdentifierAsString(id.getIdentifier());
+				if (list.contains(name) && !values.containsKey(name)) {
+					if (equal.getLeft() instanceof AIdentifierExpression) {
+						AIdentifierExpression id2 = (AIdentifierExpression) equal
+								.getLeft();
+						String name2 = Utils.getIdentifierAsString(id2
+								.getIdentifier());
+						if (values.contains(name2))
+							return;
+					}
+					equalList.add(equal);
+					values.put(name, equal.getLeft());
+				}
+			}
+
+		}
+	}
+
+	class NodesRemover extends DepthFirstAdapter {
+		final ArrayList<AEqualPredicate> removeList;
+		final Hashtable<String, PExpression> values;
+
+		public NodesRemover(PPredicate predicate,
+				ArrayList<AEqualPredicate> equalList,
+				Hashtable<String, PExpression> values) {
+			this.removeList = equalList;
+			this.values = values;
+
+			for (AEqualPredicate pred : removeList) {
+				pred.replaceBy(null);
+			}
+
+			predicate.apply(this);
+
+		}
+
+		@Override
+		public void caseAConjunctPredicate(AConjunctPredicate node) {
+			if (node.getLeft() != null) {
+				node.getLeft().apply(this);
+			}
+			if (node.getRight() != null) {
+				node.getRight().apply(this);
+			}
+			outAConjunctPredicate(node);
+		}
+
+		@Override
+		public void outAConjunctPredicate(AConjunctPredicate node) {
+			if (node.parent() != null) {
+				if (node.getLeft() == null && node.getRight() == null) {
+					node.replaceBy(null);
+				} else if (node.getLeft() == null) {
+					PPredicate right = node.getRight();
+					node.replaceBy(right);
+				} else if (node.getRight() == null) {
+					node.replaceBy(node.getLeft());
+				}
+			}
+		}
+
+		@Override
+		public void caseAIdentifierExpression(AIdentifierExpression node) {
+			String name = Utils.getIdentifierAsString(node.getIdentifier());
+
+			PExpression value = values.get(name);
+			if (value != null) {
+				node.replaceBy((PExpression) value.clone());
+			}
+
+		}
+	}
+
+}
diff --git a/src/main/java/de/tlc4b/btypes/PairType.java b/src/main/java/de/tlc4b/btypes/PairType.java
index 6e3afd0f305a7f879f01a5057608f0257e1469f0..4d7d141622b9d22ac3f80317e20afd7a731a065c 100644
--- a/src/main/java/de/tlc4b/btypes/PairType.java
+++ b/src/main/java/de/tlc4b/btypes/PairType.java
@@ -64,16 +64,24 @@ public class PairType extends AbstractHasFollowers {
 	@Override
 	public String toString() {
 		String res = "";
-		if (first instanceof PairType) {
-			res += "(" + first + ")";
-		} else
-			res += first;
-		res += "*";
-		if (second instanceof PairType) {
-			res += "(" + second + ")";
-		} else
-			res += second;
-		return res;
+		if(this.equals(first)|| this.equals(second)){
+			res += "(Recursive Type)";
+			return res;
+		}else{
+			if (first instanceof PairType) {
+				res += "(" + first + ")";
+			} else
+				res += first;
+			res += "*";
+			if (second instanceof PairType) {
+				res += "(" + second + ")";
+			} else
+				res += second;
+			return res;
+		}
+		
+		
+
 	}
 
 	public boolean isUntyped() {
@@ -95,6 +103,9 @@ public class PairType extends AbstractHasFollowers {
 
 	@Override
 	public boolean contains(BType other) {
+		if (this.equals(this.first) || this.equals(this.second)) {
+			return true;
+		}
 		if (this.first.equals(other) || this.second.equals(other)) {
 			return true;
 		}
diff --git a/src/main/java/de/tlc4b/btypes/SetType.java b/src/main/java/de/tlc4b/btypes/SetType.java
index 2661434a1ecc1ecad02c24958d94fef2884a5831..cc3d3613a0ce8f4867c1d5a4cb974d2e57ce5028 100644
--- a/src/main/java/de/tlc4b/btypes/SetType.java
+++ b/src/main/java/de/tlc4b/btypes/SetType.java
@@ -56,7 +56,12 @@ public class SetType extends AbstractHasFollowers {
 
 	@Override
 	public String toString() {
-		return "POW(" + subtype + ")";
+		if(this.equals(subtype)){
+			return "POW(recursive call)";
+		}else{
+			return "POW(" + subtype + ")";
+		}
+		
 	}
 
 	public boolean isUntyped() {
@@ -81,6 +86,9 @@ public class SetType extends AbstractHasFollowers {
 
 	@Override
 	public boolean contains(BType other) {
+		if(this.equals(subtype)){
+			return true;
+		}
 		if (this.subtype.equals(other)) {
 			return true;
 		}
diff --git a/src/main/java/de/tlc4b/btypes/StructType.java b/src/main/java/de/tlc4b/btypes/StructType.java
index 100ce21cdf92031aa8408b7aafe6537c733cead7..1466385fdc3afd6446c54d989b42bdd33d86c15b 100644
--- a/src/main/java/de/tlc4b/btypes/StructType.java
+++ b/src/main/java/de/tlc4b/btypes/StructType.java
@@ -97,13 +97,19 @@ public class StructType extends AbstractHasFollowers {
 					BType res = this.types.get(fieldName).unify(sType,
 							typechecker);
 					this.types.put(fieldName, res);
+					if(res instanceof AbstractHasFollowers){
+						((AbstractHasFollowers) res).addFollower(this);
+					}
 				} else {
+					this.types.put(fieldName, sType);
 					if (sType instanceof AbstractHasFollowers) {
-						((AbstractHasFollowers) sType).addFollower(this);
+						AbstractHasFollowers f = (AbstractHasFollowers) sType;
+						f.deleteFollower(other);
+						f.addFollower(this);
 					}
-					this.types.put(fieldName, sType);
 				}
 			}
+			((StructType) other).setFollowersTo(this, typechecker);
 			complete = this.complete || s.complete;
 			return this;
 
diff --git a/src/main/java/de/tlc4b/prettyprint/TLAPrinter.java b/src/main/java/de/tlc4b/prettyprint/TLAPrinter.java
index 8276701550722999f06042be7a4ed60ef37cdc7b..0f2190c500b259351f805a4008d9036925b43ae9 100644
--- a/src/main/java/de/tlc4b/prettyprint/TLAPrinter.java
+++ b/src/main/java/de/tlc4b/prettyprint/TLAPrinter.java
@@ -310,8 +310,8 @@ public class TLAPrinter extends DepthFirstAdapter {
 				if (i > 0) {
 					moduleStringAppend(", ");
 				}
-				moduleStringAppend(usedStandardModules.getExtendedModules().get(i)
-						.toString());
+				moduleStringAppend(usedStandardModules.getExtendedModules()
+						.get(i).toString());
 			}
 			moduleStringAppend("\n");
 		}
@@ -325,7 +325,7 @@ public class TLAPrinter extends DepthFirstAdapter {
 				def.getDefName().apply(this);
 				continue;
 			}
-			
+
 			def.getDefName().apply(this);
 			moduleStringAppend(" == ");
 			Node e = def.getDefinition();
@@ -1115,7 +1115,8 @@ public class TLAPrinter extends DepthFirstAdapter {
 		if (name == null) {
 			name = Utils.getIdentifierAsString(node.getIdentifier());
 		}
-		if(name.equals(SORT_SET)){
+		if (StandardMadules.isAbstractConstant(name)) {
+			// in order to pass the member check
 			moduleStringAppend("{}");
 			return;
 		}
@@ -1325,7 +1326,7 @@ public class TLAPrinter extends DepthFirstAdapter {
 	public void caseAExpressionDefinitionDefinition(
 			AExpressionDefinitionDefinition node) {
 		String oldName = node.getName().getText().trim();
-		if(StandardMadules.isKeywordInModuleExternalFunctions(oldName)){
+		if (StandardMadules.isKeywordInModuleExternalFunctions(oldName)) {
 			return;
 		}
 		String name = renamer.getName(node);
@@ -1368,7 +1369,7 @@ public class TLAPrinter extends DepthFirstAdapter {
 
 	private void printBDefinition(String name, List<PExpression> args,
 			Node rightSide) {
-		if(StandardMadules.isKeywordInModuleExternalFunctions(name)){
+		if (StandardMadules.isKeywordInModuleExternalFunctions(name)) {
 			return;
 		}
 		moduleStringAppend(name);
@@ -1777,26 +1778,26 @@ public class TLAPrinter extends DepthFirstAdapter {
 	// Function call
 	public void caseAFunctionExpression(AFunctionExpression node) {
 		inAFunctionExpression(node);
-		
-		
-		if(node.getIdentifier() instanceof AIdentifierExpression){
-			AIdentifierExpression id = (AIdentifierExpression) node.getIdentifier();
+
+		if (node.getIdentifier() instanceof AIdentifierExpression) {
+			AIdentifierExpression id = (AIdentifierExpression) node
+					.getIdentifier();
 			String name = Utils.getIdentifierAsString(id.getIdentifier());
-			if(name.equals(SORT_SET)){
-				moduleStringAppend(SORT_SET);
-				//node.getIdentifier().apply(this);
+			if (StandardMadules.isAbstractConstant(name)) {
+
+				moduleStringAppend(name);
+				// node.getIdentifier().apply(this);
 				moduleStringAppend("(");
 				List<PExpression> copy = new ArrayList<PExpression>(
 						node.getParameters());
 				copy.get(0).apply(this);
 				moduleStringAppend(")");
 				return;
-				
+
 			}
 
 		}
-		
-		
+
 		BType type = this.typechecker.getType(node.getIdentifier());
 		if (type instanceof FunctionType) {
 			node.getIdentifier().apply(this);
@@ -2132,6 +2133,20 @@ public class TLAPrinter extends DepthFirstAdapter {
 		outAComprehensionSetExpression(node);
 	}
 
+	@Override
+	public void caseAEventBComprehensionSetExpression(
+			AEventBComprehensionSetExpression node) {
+		inAEventBComprehensionSetExpression(node);
+
+		moduleStringAppend("{");
+		node.getExpression().apply(this);
+		moduleStringAppend(": ");
+		node.getPredicates().apply(this);
+		moduleStringAppend("}");
+
+		outAEventBComprehensionSetExpression(node);
+	}
+
 	private void printAuxiliaryVariables(int size) {
 		for (int i = 0; i < size - 1; i++) {
 			moduleStringAppend("<<");
@@ -2704,7 +2719,8 @@ public class TLAPrinter extends DepthFirstAdapter {
 	public void caseAIseqExpression(AIseqExpression node) {
 		SetType set = (SetType) typechecker.getType(node);
 		if (set.getSubtype() instanceof SetType) {
-			if (node.parent() instanceof AMemberPredicate
+			
+			if (isElementOfRecursive(node.parent())
 					&& !typeRestrictor.isARemovedNode(node.parent())) {
 				moduleStringAppend(REL_INJECTIVE_SEQUENCE_ELEMENT_OF);
 			} else {
diff --git a/src/main/java/de/tlc4b/tlc/TLCResults.java b/src/main/java/de/tlc4b/tlc/TLCResults.java
index d95c8f6b91c1eb32b1d6b3b6bf61f2912f580dc4..d055a7e270cbce5abeba1fe33c77f0bdd89c81a6 100644
--- a/src/main/java/de/tlc4b/tlc/TLCResults.java
+++ b/src/main/java/de/tlc4b/tlc/TLCResults.java
@@ -343,7 +343,9 @@ public class TLCResults implements ToolGlobals {
 	private TLCResult evaluatingParameter(String[] params) {
 		for (int i = 0; i < params.length; i++) {
 			String s = params[i];
-			if (s.contains("not enumerable")) {
+			if (s == null) {
+				break;
+			} else if (s.contains("not enumerable")) {
 				return EnumerationError;
 			} else if (s.contains("The invariant of Assertion")) {
 				return AssertionError;
diff --git a/src/main/resources/standardModules/ExternalFunctions.tla b/src/main/resources/standardModules/ExternalFunctions.tla
index ca46e6a219bd64b9fb22874740fe037d81e4e384..81f00fbcdad3d4ae9ee59c1baafb9d35d2f193f8 100644
--- a/src/main/resources/standardModules/ExternalFunctions.tla
+++ b/src/main/resources/standardModules/ExternalFunctions.tla
@@ -5,22 +5,22 @@ EXTENDS Sequences, Integers, TLC, FiniteSets
                                 (* Strings *)
 RECURSIVE SPLIT1(_,_,_,_)
 LOCAL SPLIT1(s,c,start,i) ==
-    CASE i = Len(s)+1 -> IF i /= start 
-                         THEN <<SubSeq(s,start,i-1)>> 
+    CASE i = Len(s)+1 -> IF i /= start
+                         THEN <<SubSeq(s,start,i-1)>>
                          ELSE <<>>
     [] i+Len(c)-1 > Len(s) -> <<SubSeq(s,start,Len(s))>>
-    [] SubSeq(s,i,i+Len(c)-1) = c -> IF i /= start 
-                                   THEN <<SubSeq(s,start,i-1)>> \o SPLIT1(s,c,i+Len(c),i+Len(c)) 
-                                   ELSE <<>> \o SPLIT1(s,c,i+Len(c),i+Len(c)) 
+    [] SubSeq(s,i,i+Len(c)-1) = c -> IF i /= start
+                                   THEN <<SubSeq(s,start,i-1)>> \o SPLIT1(s,c,i+Len(c),i+Len(c))
+                                   ELSE <<>> \o SPLIT1(s,c,i+Len(c),i+Len(c))
     [] OTHER -> SPLIT1(s,c,start,i+1)
 
 STRING_SPLIT(s, c) == SPLIT1(s,c,1,1)
 
 
-LOCAL DIGIT_TO_STRING(x) == 
+LOCAL DIGIT_TO_STRING(x) ==
     CASE x = 0 -> "0"
     [] x = 1 -> "1"
-    [] x= 2 -> "2" 
+    [] x= 2 -> "2"
     [] x = 3 -> "3"
     [] x = 4 -> "4"
     [] x= 5 -> "5"
@@ -30,26 +30,63 @@ LOCAL DIGIT_TO_STRING(x) ==
     [] x=9 -> "9"
 
 RECURSIVE INT_TO_STRING1(_)
-LOCAL INT_TO_STRING1(i) == 
-    IF i < 10
-    THEN DIGIT_TO_STRING(i)
-    ELSE INT_TO_STRING1(i\div10) \o DIGIT_TO_STRING(i%10)
+LOCAL INT_TO_STRING1(i) ==
+  IF i < 10
+  THEN DIGIT_TO_STRING(i)
+  ELSE INT_TO_STRING1(i\div10) \o DIGIT_TO_STRING(i%10)
 
-INT_TO_STRING(i) == 
-    IF i < 0 
-    THEN "-" \o INT_TO_STRING1(-i)
-    ELSE INT_TO_STRING1(i)
+INT_TO_STRING(i) ==
+  IF i < 0
+  THEN "-" \o INT_TO_STRING1(-i)
+  ELSE INT_TO_STRING1(i)
 
-LOCAL Max(S) == CHOOSE x \in S : \A p \in S : x >= p    
+LOCAL Max(S) == CHOOSE x \in S : \A p \in S : x >= p
 RECURSIVE SORT_SET(_)
 SORT_SET(s) ==
-    IF s = {}
-    THEN {}
-    ELSE LET max == Max(s)
-         IN SORT_SET(s\{max}) \cup {<<Cardinality(s), max>>}
-         
-STRING_APPEND(a,b) == a \o b         
+  IF s = {}
+  THEN {}
+  ELSE LET max == Max(s)
+       IN SORT_SET(s\{max}) \cup {<<Cardinality(s), max>>}
+
+STRING_APPEND(a,b) == a \o b
+
+STRING_TO_INT(str) ==
+  LET
+    STRINGDIGIT_TO_INT(x) ==
+      CASE x = "0" -> 0
+        [] x= "1" -> 1
+        [] x= "2" -> 2
+        [] x= "3" -> 3
+        [] x= "4" -> 4
+        [] x= "5" -> 5
+        [] x= "6" -> 6
+        [] x= "7" -> 7
+        [] x= "8" -> 8
+        [] x= "9" -> 9
+
+    item(s,i) == SubSeq(s,i,i)
+
+    RECURSIVE pow(_,_)
+    pow(a,b) == IF b = 0 THEN 1 ELSE a * pow(a,b-1)
+
+    RECURSIVE STRING_TO_INT1(_,_)
+    STRING_TO_INT1(s, i) ==
+      IF i = Len(s)
+      THEN STRINGDIGIT_TO_INT(item(s,i))
+      ELSE STRINGDIGIT_TO_INT(item(s,i)) * pow(10,Len(s)-i) + STRING_TO_INT1(s,i+1)
+  IN
+    IF item(str, 1) = "-"
+    THEN -1 * STRING_TO_INT1(SubSeq(str,2,Len(str)),1)
+    ELSE STRING_TO_INT1(str,1)
+
+DECIMAL_TO_INT(s) ==
+    STRING_TO_INT(
+      STRING_APPEND(
+        (STRING_SPLIT(s,"."))[1]
+        ,(STRING_SPLIT(s,"."))[2]
+      )
+    )
 -----------------------------------------------------------------------------
 printf(s,v) == PrintT(s) /\ PrintT(v)
-    
-=============================================================================
\ No newline at end of file
+
+=============================================================================
diff --git a/src/test/java/de/tlc4b/analysis/DeferredSetSize.java b/src/test/java/de/tlc4b/analysis/DeferredSetSizeTest.java
similarity index 75%
rename from src/test/java/de/tlc4b/analysis/DeferredSetSize.java
rename to src/test/java/de/tlc4b/analysis/DeferredSetSizeTest.java
index a97c0aabdd53397cad209c8974ceca5ffd633098..b83222309c31d06bd25722644eabea0e9d09a166 100644
--- a/src/test/java/de/tlc4b/analysis/DeferredSetSize.java
+++ b/src/test/java/de/tlc4b/analysis/DeferredSetSizeTest.java
@@ -1,10 +1,10 @@
 package de.tlc4b.analysis;
 
-import static de.tlc4b.util.TestUtil.compareConfig;
+import static de.tlc4b.util.TestUtil.compareModuleAndConfig;
 
 import org.junit.Test;
 
-public class DeferredSetSize {
+public class DeferredSetSizeTest {
 	@Test
 	public void testDeferredSetStandard() throws Exception {
 		String machine = "MACHINE test\n"
@@ -14,7 +14,7 @@ public class DeferredSetSize {
 				+ "CONSTANTS S\n"
 				+ "======";
 		String expectedConfig = "CONSTANTS S = {S1, S2, S3} "; 
-		compareConfig(expectedModule, expectedConfig, machine);
+		compareModuleAndConfig(expectedModule, expectedConfig, machine);
 	}
 	
 	@Test
@@ -29,7 +29,7 @@ public class DeferredSetSize {
 				+ "ASSUME Cardinality(S) = 4 \n"
 				+ "======";
 		String expectedConfig = "CONSTANTS S = {S1, S2, S3, S4} "; 
-		compareConfig(expectedModule, expectedConfig, machine);
+		compareModuleAndConfig(expectedModule, expectedConfig, machine);
 	}
 	
 	@Test
@@ -44,6 +44,6 @@ public class DeferredSetSize {
 				+ "ASSUME 4 = Cardinality(S) \n"
 				+ "======";
 		String expectedConfig = "CONSTANTS S = {S1, S2, S3, S4} "; 
-		compareConfig(expectedModule, expectedConfig, machine);
+		compareModuleAndConfig(expectedModule, expectedConfig, machine);
 	}
 }
diff --git a/src/test/java/de/tlc4b/analysis/NotSupportedTest.java b/src/test/java/de/tlc4b/analysis/NotSupportedTest.java
deleted file mode 100644
index e7e67a600cce7e176736fe7918ae797162e8f690..0000000000000000000000000000000000000000
--- a/src/test/java/de/tlc4b/analysis/NotSupportedTest.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package de.tlc4b.analysis;
-
-import static de.tlc4b.util.TestUtil.checkMachine;
-
-import org.junit.Test;
-
-import de.tlc4b.exceptions.NotSupportedException;
-
-public class NotSupportedTest {
-
-	@Test(expected = NotSupportedException.class)
-	public void testDuplicateSeenMachine() throws Exception {
-		String machine = "MACHINE test \n" + "SEES M1 \n" + "END";
-		checkMachine(machine);
-	}
-}
diff --git a/src/test/java/de/tlc4b/analysis/SetComprehensionOptimizerTest.java b/src/test/java/de/tlc4b/analysis/SetComprehensionOptimizerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d433d16336656001e289cb83c27c71ccefbce8f5
--- /dev/null
+++ b/src/test/java/de/tlc4b/analysis/SetComprehensionOptimizerTest.java
@@ -0,0 +1,32 @@
+package de.tlc4b.analysis;
+
+import static de.tlc4b.util.TestUtil.compare;
+
+import org.junit.Test;
+
+public class SetComprehensionOptimizerTest {
+
+	@Test
+	public void testSetComprehension1() throws Exception {
+		String machine = "MACHINE test\n"
+				+ "CONSTANTS k \n"
+				+ "PROPERTIES k = {x,y | x : 1..10 & y = x + 1} \n" + "END";
+		String expected = "---- MODULE test----\n" 
+				+ "EXTENDS Naturals\n"
+				+ "k == {<<x, x + 1>>: x \\in {x \\in ((1 .. 10)): TRUE}} \n"
+				+ "======";
+		compare(expected, machine);
+	}
+	
+	@Test
+	public void testSetComprehension2() throws Exception {
+		String machine = "MACHINE test\n"
+				+ "CONSTANTS k \n"
+				+ "PROPERTIES k = {x,y|  x : 1..10 & x = y & y = x} \n" + "END";
+		String expected = "---- MODULE test----\n" 
+				+ "EXTENDS Naturals\n"
+				+ "k == {<<x, x + 1>>: x \\in {x \\in ((1 .. 10)): TRUE}} \n"
+				+ "======";
+		compare(expected, machine);
+	}
+}
diff --git a/src/test/java/de/tlc4b/coverage/IntegrationCoverageTest.java b/src/test/java/de/tlc4b/coverage/CoverageTest.java
similarity index 89%
rename from src/test/java/de/tlc4b/coverage/IntegrationCoverageTest.java
rename to src/test/java/de/tlc4b/coverage/CoverageTest.java
index 9614e6fccdac24e6def4855a1146ebb928214694..a106b1f20a8fee813f5516f57ea6df335af43583 100644
--- a/src/test/java/de/tlc4b/coverage/IntegrationCoverageTest.java
+++ b/src/test/java/de/tlc4b/coverage/CoverageTest.java
@@ -14,11 +14,11 @@ import de.tlc4b.util.PolySuite.Config;
 import de.tlc4b.util.PolySuite.Configuration;
 
 @RunWith(PolySuite.class)
-public class IntegrationCoverageTest extends AbstractParseMachineTest {
+public class CoverageTest extends AbstractParseMachineTest {
 
 	private final File machine;
 
-	public IntegrationCoverageTest(File machine, TLCResult result) {
+	public CoverageTest(File machine, TLCResult result) {
 		this.machine = machine;
 	}
 
diff --git a/src/test/java/de/tlc4b/exceptions/ScopeExceptionTest.java b/src/test/java/de/tlc4b/exceptions/ScopeExceptionTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..cb422859ca52816e2fb1c44d4efea31234006c2a
--- /dev/null
+++ b/src/test/java/de/tlc4b/exceptions/ScopeExceptionTest.java
@@ -0,0 +1,48 @@
+package de.tlc4b.exceptions;
+
+import static de.tlc4b.util.TestUtil.checkMachine;
+
+import org.junit.Test;
+
+public class ScopeExceptionTest {
+
+	@Test (expected = ScopeException.class)
+	public void testDuplicateIdentifierEnumeratedSet() throws Exception {
+		String machine = "MACHINE test\n" 
+				+ "SETS S; S ={A,B} \n" 
+				+ "END";
+		checkMachine(machine);
+	}
+	
+	@Test (expected = ScopeException.class)
+	public void testDuplicateIdentifierDeferredSet() throws Exception {
+		String machine = "MACHINE test\n" 
+				+ "SETS S; S \n" 
+				+ "END";
+		checkMachine(machine);
+	}
+	
+	@Test (expected = ScopeException.class)
+	public void testDuplicateIdentifierEnumValue() throws Exception {
+		String machine = "MACHINE test\n" 
+				+ "SETS S= {a,a} \n" 
+				+ "END";
+		checkMachine(machine);
+	}
+	
+	@Test (expected = ScopeException.class)
+	public void testDuplicateIdentifierMachineSetParameterDeferredSet() throws Exception {
+		String machine = "MACHINE test(AB, AB)\n" 
+				+ "END";
+		checkMachine(machine);
+	}
+	
+	@Test (expected = ScopeException.class)
+	public void testDuplicateIdentifierMachineScalarParameter() throws Exception {
+		String machine = "MACHINE test(a, a)\n" 
+				+ "CONSTRAINTS a : BOOL \n"
+				+ "END";
+		checkMachine(machine);
+	}
+	
+}
diff --git a/src/test/java/de/tlc4b/prettyprint/EnumeratedSetsTest.java b/src/test/java/de/tlc4b/prettyprint/EnumeratedSetsTest.java
index f57b8edd2a473bd9d6618b10d9145f12b2b1ad57..4a3e57327ccd597a123e7b05e5155272042c3daa 100644
--- a/src/test/java/de/tlc4b/prettyprint/EnumeratedSetsTest.java
+++ b/src/test/java/de/tlc4b/prettyprint/EnumeratedSetsTest.java
@@ -7,11 +7,15 @@ import org.junit.Test;
 public class EnumeratedSetsTest {
 	@Test
 	public void testTwoEnumeratedSets() throws Exception {
-		String machine = "MACHINE test\n" + "SETS set = {a,b,c}; set2 = {d}\n"
+		String machine = "MACHINE test\n" 
+				+ "SETS set = {a,b,c}; set2 = {d}\n"
 				+ "END";
 
-		String expected = "---- MODULE test ----\n" + "CONSTANTS a, b, c, d\n"
-				+ "set == {a, b, c}\n" + "set2 == {d}\n" + "====";
+		String expected = "---- MODULE test ----\n"
+				+ "CONSTANTS a, b, c, d\n"
+				+ "set == {a, b, c}\n" 
+				+ "set2 == {d}\n" 
+				+ "====";
 		final String config = "CONSTANTS\na = a\nb = b\nc = c\nd = d\n";
 		compareEqualsConfig(expected, config, machine);
 	}
diff --git a/src/test/java/de/tlc4b/prettyprint/MachineParameterTest.java b/src/test/java/de/tlc4b/prettyprint/MachineParameterTest.java
index 9c5dcc8d3c803d90eb6f7ae187f9e753bc0ce0a4..c26f8ceadf80386dd5db1b028bf9d5b225d8d70c 100644
--- a/src/test/java/de/tlc4b/prettyprint/MachineParameterTest.java
+++ b/src/test/java/de/tlc4b/prettyprint/MachineParameterTest.java
@@ -30,7 +30,7 @@ public class MachineParameterTest {
 				+ "Next == 1 = 2 /\\ UNCHANGED <<a>>\n"
 				+ "======";
 		String expectedConfig = "INIT Init\nNEXT Next";
-		compareConfig(expectedModule, expectedConfig, machine);
+		compareModuleAndConfig(expectedModule, expectedConfig, machine);
 	}
 	
 	@Test
@@ -55,7 +55,7 @@ public class MachineParameterTest {
 				+ "CONSTANTS AA\n"
 				+ "======";
 		String expectedConfig = "CONSTANTS AA = {AA1, AA2, AA3}";
-		compareConfig(expectedModule, expectedConfig, machine);
+		compareModuleAndConfig(expectedModule, expectedConfig, machine);
 	}
 	
 	@Test
@@ -70,7 +70,7 @@ public class MachineParameterTest {
 				+ "ASSUME Cardinality(B) = 2\n"
 				+ "====";
 		String expectedConfig = "CONSTANTS B = {B1, B2, B3}";
-		compareConfig(expectedModule, expectedConfig, machine);
+		compareModuleAndConfig(expectedModule, expectedConfig, machine);
 	}
 	
 }
diff --git a/src/test/java/de/tlc4b/prettyprint/SetsClauseTest.java b/src/test/java/de/tlc4b/prettyprint/SetsClauseTest.java
index 5a7795c686c3cbb0c9ffcbf2fbd4120ca95f3ec6..b5faf7e61d667ba89e97d2b1a16b19236cbc27e1 100644
--- a/src/test/java/de/tlc4b/prettyprint/SetsClauseTest.java
+++ b/src/test/java/de/tlc4b/prettyprint/SetsClauseTest.java
@@ -6,7 +6,7 @@ import org.junit.Test;
 
 public class SetsClauseTest {
 	@Test
-	public void testDefferedSet() throws Exception {
+	public void testDeferredSet() throws Exception {
 		String machine = "MACHINE test\n"
 				+ "SETS d \n"
 				+ "END";
@@ -16,7 +16,23 @@ public class SetsClauseTest {
 		String expectedConfig = "CONSTANTS\n" +
 				"d = {d1, d2, d3}\n";
 
-		compareConfig(expectedModule, expectedConfig, machine);
+		compareModuleAndConfig(expectedModule, expectedConfig, machine);
+	}
+	
+	@Test
+	public void testDeferredSet2() throws Exception {
+		String machine = "MACHINE test\n"
+				+ "SETS d \n"
+				+ "CONSTANTS k \n"
+				+ "PROPERTIES k : d \n"
+				+ "END";
+		String expectedModule = "---- MODULE test----\n"
+				+ "CONSTANTS d2asisdfapsdjfa\n"
+				+ "======";
+		String expectedConfig = "CONSTANTS\n" +
+				"d = {d1, d2, d3}\n";
+
+		compareModuleAndConfig(expectedModule, expectedConfig, machine);
 	}
 	
 	@Test
@@ -29,6 +45,6 @@ public class SetsClauseTest {
 				+ "S == {a, b, c}"
 				+ "======";
 		String expectedConfig = "CONSTANTS a = a\n b = b \n c = c"; 
-		compareConfig(expectedModule, expectedConfig, machine);
+		compareModuleAndConfig(expectedModule, expectedConfig, machine);
 	}
 }
diff --git a/src/test/java/de/tlc4b/tlc/integration/BasicTest.java b/src/test/java/de/tlc4b/tlc/integration/BasicTest.java
index a3531aea3b72eed388ca5a01c286a434bfb1e1b9..743559e754f9877a34aac5247472c71c8729261b 100644
--- a/src/test/java/de/tlc4b/tlc/integration/BasicTest.java
+++ b/src/test/java/de/tlc4b/tlc/integration/BasicTest.java
@@ -37,6 +37,7 @@ public class BasicTest extends AbstractParseMachineTest {
 	@Config
 	public static Configuration getConfig() {
 		final ArrayList<TestPair> list = new ArrayList<TestPair>();
+		list.add(new TestPair(NoError, "./src/test/resources/composition/sees"));
 		list.add(new TestPair(NoError, "./src/test/resources/basics"));
 		list.add(new TestPair(NoError, "./src/test/resources/laws"));
 		return getConfiguration(list);
diff --git a/src/test/java/de/tlc4b/typechecking/SetsClauseTest.java b/src/test/java/de/tlc4b/typechecking/SetsClauseTest.java
index 95a7be21d89fb91f09820d4e2b34646c652f6107..90fdd909635144ddf6739aaa3c44c3ff599fce13 100644
--- a/src/test/java/de/tlc4b/typechecking/SetsClauseTest.java
+++ b/src/test/java/de/tlc4b/typechecking/SetsClauseTest.java
@@ -2,6 +2,7 @@ package de.tlc4b.typechecking;
 
 import static org.junit.Assert.assertEquals;
 
+import org.junit.Ignore;
 import org.junit.Test;
 
 import de.be4.classicalb.core.parser.exceptions.BException;
@@ -20,4 +21,15 @@ public class SetsClauseTest {
 		assertEquals("DEF", t.constants.get("k").toString());
 	}
 	
+	@Ignore
+	@Test
+	public void testDeferredSet2() throws BException {
+		String machine = "MACHINE test(DEF)\n" 
+				+ "CONSTANTS k \n"
+				+ "PROPERTIES k : DEF \n" 
+				+ "END";
+		TestTypechecker t = new TestTypechecker(machine);
+		assertEquals("DEF", t.constants.get("k").toString());
+	}
+	
 }
diff --git a/src/test/java/de/tlc4b/typechecking/SetsTest.java b/src/test/java/de/tlc4b/typechecking/SetsTest.java
index 1afcd259ae8c37a966dd552507c048c9a3f6997b..2d5303a58ed412970681eea6bd37ae022b207f47 100644
--- a/src/test/java/de/tlc4b/typechecking/SetsTest.java
+++ b/src/test/java/de/tlc4b/typechecking/SetsTest.java
@@ -72,6 +72,30 @@ public class SetsTest {
 		assertEquals("POW(INTEGER*BOOL)", t.constants.get("k").toString());
 	}
 	
+	@Test
+	public void testEventBSetComprehension() throws BException {
+		String machine = "MACHINE test\n" 
+				+ "CONSTANTS k,k2,k3 \n"
+				+ "PROPERTIES k = {x,y| x = k2(k3) & y : {TRUE}} & k2(2)=1\n" 
+				+ "END";
+		TestTypechecker t = new TestTypechecker(machine);
+		assertEquals("POW(INTEGER*BOOL)", t.constants.get("k").toString());
+		assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k2").toString());
+		assertEquals("INTEGER", t.constants.get("k3").toString());
+	}
+	
+	@Test
+	public void testEventBSetComprehension2() throws BException {
+		String machine = "MACHINE test\n" 
+				+ "CONSTANTS k,k2 \n"
+				+ "PROPERTIES k = {a,b| a : k2 & b = a'foo} & k2={rec(foo:\"123\",bar:TRUE)}\n" 
+				+ "END";
+		TestTypechecker t = new TestTypechecker(machine);
+		assertEquals("POW(struct(foo:STRING,bar:BOOL)*STRING)", t.constants.get("k").toString());
+		assertEquals("POW(struct(foo:STRING,bar:BOOL))", t.constants.get("k2").toString());
+	}
+	
+	
 	@Test (expected = TypeErrorException.class)
 	public void testSetComprehensionException() throws BException {
 		String machine = "MACHINE test\n"
diff --git a/src/test/java/de/tlc4b/util/TestUtil.java b/src/test/java/de/tlc4b/util/TestUtil.java
index 12a628e428b0c53acad6cbc02cd6b36fc91f4beb..24349b05707627582c0b4fa163cbfe28f6f0fbef 100644
--- a/src/test/java/de/tlc4b/util/TestUtil.java
+++ b/src/test/java/de/tlc4b/util/TestUtil.java
@@ -12,6 +12,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import util.ToolIO;
 import de.be4.classicalb.core.parser.exceptions.BException;
 import de.be4.classicalb.core.parser.node.Start;
 import de.tla2b.exceptions.TLA2BException;
@@ -25,6 +26,7 @@ public class TestUtil {
 	public static void compare(String expectedModule, String machine)
 			throws Exception {
 		TLC4BGlobals.setForceTLCToEvalConstants(false);
+		ToolIO.setMode(ToolIO.TOOL);
 
 		Translator b2tlaTranslator = new Translator(machine);
 		b2tlaTranslator.translate();
@@ -112,7 +114,7 @@ public class TestUtil {
 		assertEquals(expectedConfig, b2tlaTranslator.getConfigString());
 	}
 
-	public static void compareConfig(String expectedModule,
+	public static void compareModuleAndConfig(String expectedModule,
 			String expectedConfig, String machine) throws Exception {
 		Translator b2tlaTranslator = new Translator(machine);
 		b2tlaTranslator.translate();
@@ -120,6 +122,12 @@ public class TestUtil {
 		System.out.println(b2tlaTranslator.getModuleString());
 		System.out.println(b2tlaTranslator.getConfigString());
 
+		
+		//TODO include config file in back translation from TLA+ to B
+		
+		
+		
+		
 		// String name = b2tlaTranslator.getMachineName();
 		// StringBuilder sb1 = de.tla2b.translation.Tla2BTranslator
 		// .translateString(name, b2tlaTranslator.getModuleString(),
diff --git a/src/test/resources/basics/ExternalFunctionsTest.mch b/src/test/resources/basics/ExternalFunctionsTest.mch
index c4f4af14bebd37ad2e1343446632bb74098ba28f..4a2116bede8cde19749eda599ba5772d3fe8855f 100644
--- a/src/test/resources/basics/ExternalFunctionsTest.mch
+++ b/src/test/resources/basics/ExternalFunctionsTest.mch
@@ -7,13 +7,15 @@ DEFINITIONS
   STRING_SPLIT(x,y) == ["foo"];
   EXTERNAL_FUNCTION_STRING_SPLIT == ((STRING*STRING) --> (INTEGER<->STRING));
   EXTERNAL_FUNCTION_REC(A,B) == (STRING * A)-->B;
+  STRING_TO_INT(S) == 0;
+  EXTERNAL_FUNCTION_STRING_TO_INT == (STRING --> INTEGER);
+  STRING_APPEND(x,y) == "str";
+  EXTERNAL_FUNCTION_STRING_APPEND == (STRING*STRING) --> STRING;
+
   REC(F,A) == {};
   EXTERNAL_FUNCTION_REC_LET(A) == (STRING * A)-->A;
   REC_LET(F,A) == {};
 
-  STRING_APPEND(x,y) == "str";
-  EXTERNAL_FUNCTION_STRING_APPEND == (STRING*STRING) --> STRING;
-
 ABSTRACT_CONSTANTS SORT_SET
 PROPERTIES
   SORT_SET: POW(INTEGER) <-> POW(INTEGER*INTEGER) &
@@ -31,6 +33,9 @@ ASSERTIONS
   STRING_APPEND("a","bc") = "abc";
   STRING_APPEND("abc","") = "abc";
   STRING_APPEND("","abc") = "abc";
-  STRING_APPEND("","") = ""
+  STRING_APPEND("","") = "";
+  STRING_TO_INT("123") = 123;
+  STRING_TO_INT("000123") = 123;
+  STRING_TO_INT("-123") = -123
 
 END
diff --git a/src/test/resources/composition/sees/M1.mch b/src/test/resources/composition/sees/M1.mch
new file mode 100644
index 0000000000000000000000000000000000000000..1170faa2e0c3a1c8b8b183aa5aee02415ac560f1
--- /dev/null
+++ b/src/test/resources/composition/sees/M1.mch
@@ -0,0 +1,8 @@
+MACHINE M1
+SEES M2
+VARIABLES x
+INVARIANT x : 1..10
+INITIALISATION x := k2
+OPERATIONS
+ Skip = skip
+END
diff --git a/src/test/resources/composition/sees/M2.mch b/src/test/resources/composition/sees/M2.mch
new file mode 100644
index 0000000000000000000000000000000000000000..8d955de80bb2e06b138d295e0a8a1d0dac8dab85
--- /dev/null
+++ b/src/test/resources/composition/sees/M2.mch
@@ -0,0 +1,7 @@
+MACHINE M2
+SEES M3
+CONSTANTS
+  k2
+PROPERTIES
+  k2 = k3 + 1
+END
diff --git a/src/test/resources/composition/sees/M3.mch b/src/test/resources/composition/sees/M3.mch
new file mode 100644
index 0000000000000000000000000000000000000000..fb4b2fbae3167d866d3f724ff0708c7cc5ee5bdf
--- /dev/null
+++ b/src/test/resources/composition/sees/M3.mch
@@ -0,0 +1,6 @@
+MACHINE M3
+CONSTANTS
+  k3
+PROPERTIES
+  k3 = 3
+END