Index: branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleUtils.java
===================================================================
--- branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleUtils.java	(revision 1736)
+++ branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleUtils.java	(revision 1738)
@@ -28,11 +28,11 @@
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory;
 
-
 /**
  * <p>
  * provides some convenience methods for rule application
- * </p>.
+ * </p>
+ * .
  *
- * @author Patrick Harms
+ * @author Patrick Harms, Ralph Krimmel
  */
 class RuleUtils {
@@ -42,12 +42,19 @@
 	 * replaces a sub sequence for a specified range of elements in the provided
 	 * task instances list by a sub task instance
-	 * </p>.
-	 *
-	 * @param parent            the list of which the range shall be replaced
-	 * @param startIndex            the start index of the range
-	 * @param endIndex            the end index of the range (inclusive)
-	 * @param model            the task model (required for instantiating the sub sequence)
-	 * @param taskFactory            the task factory used for instantiating the sub sequence
-	 * @param taskBuilder            the task builder to perform changes in the task structure
+	 * </p>
+	 * .
+	 *
+	 * @param parent
+	 *            the list of which the range shall be replaced
+	 * @param startIndex
+	 *            the start index of the range
+	 * @param endIndex
+	 *            the end index of the range (inclusive)
+	 * @param model
+	 *            the task model (required for instantiating the sub sequence)
+	 * @param taskFactory
+	 *            the task factory used for instantiating the sub sequence
+	 * @param taskBuilder
+	 *            the task builder to perform changes in the task structure
 	 * @return the replacement for the range
 	 */
@@ -57,7 +64,20 @@
 		final ISequenceInstance subsequence = taskFactory
 				.createNewTaskInstance(model);
-
-		
-		// TODO: This is dirty, return this in addition with the sequence instance instead
+		@SuppressWarnings("unused")
+		int modelid = model.getId();
+		if(modelid == 5412) {
+			System.out.println("Printing session: ");
+			for (int i = 0; i < parent.size();i++) {
+				System.out.println(parent.get(i));
+			}
+			System.out.println("startIndex: " + startIndex + " endIndex: " + endIndex + "\n");
+			System.out.println("Printing model: ");
+			for(int i = 0; i < ((ISequence)model).getChildren().size();i++) {
+				System.out.println((ISequence)model.getChildren().get(i));		
+			}
+			
+		}
+		// TODO: This is dirty, return this in addition with the sequence
+		// instance instead
 		missedOptionals = 0;
 		int modelindex = 0;
@@ -89,31 +109,29 @@
 					continue;
 				}
-			} else if (tempTask.getType() == "selection") {
-				final ISelectionInstance selection = taskFactory
-						.createNewTaskInstance((ISelection) tempTask);
+			} else if (tempTask instanceof ISelection) {
+				final ISelectionInstance selection = taskFactory.createNewTaskInstance((ISelection) tempTask);
 				final ISelection tmpSel = (ISelection) tempTask;
-				if ((tmpSel.getChildren().get(0).getType() == "sequence")
-						&& (tmpSel.getChildren().get(1).getType() == "sequence")) {
+				//Check if the selection has 2 sequences as children
+				if ((tmpSel.getChildren().get(0) instanceof ISequence) && (tmpSel.getChildren().get(1) instanceof ISequence)) {
 					ISequenceInstance selseq = null;
-					// The selection I create can just have 2 children
-					if (parent.get(startIndex).getTask().getId() == ((ISequence) tmpSel
-							.getChildren().get(0)).getChildren().get(0).getId()) {
-						selseq = taskFactory
-								.createNewTaskInstance((ISequence) tmpSel
-										.getChildren().get(0));
-					} else if (parent.get(startIndex).getTask().getId() == ((ISequence) tmpSel
-							.getChildren().get(1)).getChildren().get(0).getId()) {
-						selseq = taskFactory
-								.createNewTaskInstance((ISequence) tmpSel
-										.getChildren().get(1));
-					} else if ((parent.get(startIndex).getTask().getId() == tmpSel
-							.getChildren().get(0).getId())
-							|| (parent.get(startIndex).getTask().getId() == tmpSel
-									.getChildren().get(1).getId())) {
+					// The selection I create can just have 2 children, we need to check here, to which sequence of the model this occurence belongs
+					//This if checks of the occurrence is equal to the first element of the first sequence in the model
+					if (parent.get(startIndex).getTask().equals(((ISequence) tmpSel.getChildren().get(0)).getChildren().get(0))) {
+						selseq = taskFactory.createNewTaskInstance((ISequence) tmpSel.getChildren().get(0));
+					//This if checks of the occurrence is equal to the first element of the second sequence in the model						
+					} else if (parent.get(startIndex).getTask().equals(((ISequence) tmpSel.getChildren().get(1)).getChildren().get(0))) {
+						selseq = taskFactory.createNewTaskInstance((ISequence) tmpSel.getChildren().get(1));
+					//If the occurence is already a sequence we don't need to do anything, the next iteration will detect this as a sequence and add it
+					} else if ((parent.get(startIndex).getTask().equals(tmpSel.getChildren().get(0).getId()))
+							|| (parent.get(startIndex).getTask().equals(tmpSel.getChildren().get(1).getId()))) {
+						//taskBuilder.setChild(selection, parent.get(startIndex));
+						//taskBuilder.addChild(subsequence, selection);
+						//taskBuilder.removeTaskInstance(parent, startIndex);
+						//modelindex++;
 						continue;
+						
 					}
-
-					for (int k = 0; k < selseq.getSequence().getChildren()
-							.size(); k++) {
+					//TODO: Sometimes nullpointer exception here :(
+					for (int k = 0; k < ((ISequence)tmpSel.getChildren().get(0)).getChildren().size(); k++) {
 						taskBuilder.addChild(selseq, parent.get(startIndex));
 						taskBuilder.removeTaskInstance(parent, startIndex);
@@ -124,4 +142,5 @@
 					modelindex++;
 					continue;
+				//It is just a plain selection
 				} else {
 					taskBuilder.setChild(selection, parent.get(startIndex));
@@ -140,4 +159,5 @@
 
 		taskBuilder.addTaskInstance(parent, startIndex, subsequence);
+	
 
 		return subsequence;
@@ -147,5 +167,6 @@
 	 * <p>
 	 * returns the next available id (uses the id counter)
-	 * </p>.
+	 * </p>
+	 * .
 	 *
 	 * @return the next available id
@@ -192,7 +213,10 @@
 	 * Prints the progress percentage.
 	 *
-	 * @param message the message
-	 * @param count the count
-	 * @param size the size
+	 * @param message
+	 *            the message
+	 * @param count
+	 *            the count
+	 * @param size
+	 *            the size
 	 */
 	static void printProgressPercentage(String message, int count, int size) {
@@ -202,7 +226,7 @@
 				// Thread.currentThread().getName() + ": " + Math.round((float)
 				// count/size*100))+ "%");
-				System.out.println(message + " in thread"
-						+ Thread.currentThread().getName() + ": "
-						+ Math.round(((float) count / size) * 100) + "%");
+				// System.out.println(message + " in thread"
+				// + Thread.currentThread().getName() + ": "
+				// + Math.round(((float) count / size) * 100) + "%");
 			}
 		} else {
@@ -210,7 +234,7 @@
 			// Thread.currentThread().getName() + ": " +Math.round((float)
 			// count/size*100))+ "%");
-			System.out.println(message + " in thread"
-					+ Thread.currentThread().getName() + ": "
-					+ Math.round(((float) count / size) * 100) + "%");
+			// System.out.println(message + " in thread"
+			// + Thread.currentThread().getName() + ": "
+			// + Math.round(((float) count / size) * 100) + "%");
 
 		}
@@ -230,5 +254,6 @@
 	 * <p>
 	 * prevent instantiation
-	 * </p>.
+	 * </p>
+	 * .
 	 */
 	private RuleUtils() {
Index: branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRuleAlignment.java
===================================================================
--- branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRuleAlignment.java	(revision 1736)
+++ branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRuleAlignment.java	(revision 1738)
@@ -54,5 +54,4 @@
 import de.ugoe.cs.util.console.Console;
 
-
 /**
  * <p>
@@ -60,9 +59,9 @@
  * of recorded user sessions. For this, it first harmonizes all tasks. This
  * eases later comparison. Then it searches the sessions for iterations and
- * replaces them accordingly. Then it searches for sub sequences using alignment algorithms
- * For each found sub sequence, it replaces
- * the occurrences by creating appropriate {@link ISequence}s. Afterwards, again
- * searches for iterations and then again for sub sequences until no more
- * replacements are done.
+ * replaces them accordingly. Then it searches for sub sequences using alignment
+ * algorithms For each found sub sequence, it replaces the occurrences by
+ * creating appropriate {@link ISequence}s. Afterwards, again searches for
+ * iterations and then again for sub sequences until no more replacements are
+ * done.
  * </p>
  * <p>
@@ -73,5 +72,4 @@
 public class SequenceForTaskDetectionRuleAlignment implements ISessionScopeRule {
 
-	
 	/**
 	 * The Class RuleApplicationData.
@@ -82,20 +80,28 @@
 		private static final long serialVersionUID = -7559657686755522960L;
 
-		/** The number2task HashMap. Since we align the tasks just by their integer id, 
-		 *  we need this to convert them back to Tasks again*/
+		/**
+		 * The number2task HashMap. Since we align the tasks just by their
+		 * integer id, we need this to convert them back to Tasks again
+		 */
 		private final HashMap<Integer, ITask> number2task;
 
-		
-		/** The unique tasks, keeps track about all unique tasks 
-		 * TODO: We Actually just need number2task here, this structure can be
-		 * removed in the future.*/
+		/**
+		 * The unique tasks, keeps track about all unique tasks TODO: We
+		 * Actually just need number2task here, this structure can be removed in
+		 * the future.
+		 */
 		private final HashSet<ITask> uniqueTasks;
 
-		/** The substitution matrix used by the alignment algorithm to be able to compare
-		 *  distances of tasks */
+		/**
+		 * The substitution matrix used by the alignment algorithm to be able to
+		 * compare distances of tasks
+		 */
 		private final ObjectDistanceSubstitionMatrix submat;
 
-		/** HashMap for keeping track in which sequence which replacement has been performed.
-		 *  Neccessary for updating the indices of other occurrences accordingly */
+		/**
+		 * HashMap for keeping track in which sequence which replacement has
+		 * been performed. Neccessary for updating the indices of other
+		 * occurrences accordingly
+		 */
 		private HashMap<Integer, List<MatchOccurence>> replacedOccurences;
 
@@ -103,6 +109,8 @@
 		private LinkedList<Match> matchseqs;
 
-		/** The generated NumberSequences. 
-		 * This is the integer representation of the user sessions */
+		/**
+		 * The generated NumberSequences. This is the integer representation of
+		 * the user sessions
+		 */
 		private ArrayList<NumberSequence> numberseqs;
 
@@ -125,5 +133,6 @@
 		 * Instantiates a new rule application data.
 		 *
-		 * @param sessions The user sessions
+		 * @param sessions
+		 *            The user sessions
 		 */
 		private RuleApplicationData(List<IUserSession> sessions) {
@@ -241,5 +250,6 @@
 		 * New task created.
 		 *
-		 * @param task the task
+		 * @param task
+		 *            the task
 		 */
 		private void newTaskCreated(ITask task) {
@@ -259,5 +269,6 @@
 		 * Sets the number sequences.
 		 *
-		 * @param numberseqs the new number sequences
+		 * @param numberseqs
+		 *            the new number sequences
 		 */
 		private void setNumberSequences(ArrayList<NumberSequence> numberseqs) {
@@ -268,5 +279,6 @@
 		 * Sets the replaced occurences.
 		 *
-		 * @param replacedOccurences the replaced occurences
+		 * @param replacedOccurences
+		 *            the replaced occurences
 		 */
 		public void setReplacedOccurences(
@@ -291,8 +303,20 @@
 	private int iteration = 0;
 
-	/** <p> the task factory to be used for creating substructures for the temporal relationships identified during rul application </p>. */
+	/**
+	 * <p>
+	 * the task factory to be used for creating substructures for the temporal
+	 * relationships identified during rul application
+	 * </p>
+	 * .
+	 */
 	private final ITaskFactory taskFactory;
 
-	/** <p> the task builder to be used for creating substructures for the temporal relationships identified during rule application </p>. */
+	/**
+	 * <p>
+	 * the task builder to be used for creating substructures for the temporal
+	 * relationships identified during rule application
+	 * </p>
+	 * .
+	 */
 	private final ITaskBuilder taskBuilder;
 
@@ -339,7 +363,6 @@
 	public RuleApplicationResult apply(List<IUserSession> sessions) {
 		final RuleApplicationData appData = new RuleApplicationData(sessions);
-		
+
 		harmonizeEventTaskInstancesModel(appData);
-
 
 		Console.traceln(Level.INFO, "generating substitution matrix from "
@@ -362,4 +385,5 @@
 			appData.getStopWatch().stop("whole loop");
 			appData.getStopWatch().dumpStatistics(System.out);
+			new TaskTreeValidator().validate(appData.getSessions());
 			appData.getStopWatch().reset();
 
@@ -384,5 +408,6 @@
 	 * Creates the number sequences.
 	 *
-	 * @param appData the app data
+	 * @param appData
+	 *            the app data
 	 * @return the array list
 	 */
@@ -438,5 +463,6 @@
 	 * Detect and replace tasks.
 	 *
-	 * @param appData            the rule application data combining all data used for applying
+	 * @param appData
+	 *            the rule application data combining all data used for applying
 	 *            this rule
 	 */
@@ -451,4 +477,6 @@
 		// appData.setMatchseqs(generatePairwiseAlignments(appData));
 		generatePairwiseAlignments(appData);
+		Console.traceln(Level.FINE, "Found " + appData.getMatchseqs().size()
+				+ " results");
 
 		// Searching each match in all other sessions, counting its occurences
@@ -475,9 +503,9 @@
 	}
 
-	
 	/**
 	 * Generate pairwise alignments.
 	 *
-	 * @param appData the app data
+	 * @param appData
+	 *            the app data
 	 */
 	private void generatePairwiseAlignments(RuleApplicationData appData) {
@@ -496,6 +524,6 @@
 		final int interval = numberSeqSize / newThreads;
 		int rest = numberSeqSize % newThreads;
-
-		for (int i = 0; i < (numberSeqSize - interval); i += interval) {
+		Console.traceln(Level.FINE, "Interval: " + interval + " Rest: " + rest);
+		for (int i = 0; i <= (numberSeqSize - interval); i += interval) {
 			int offset = 0;
 			if (rest != 0) {
@@ -503,11 +531,12 @@
 				rest--;
 			}
+		
 			final int from = i;
-			final int to = i + interval + offset;
-			System.out.println("Creating thread for sessions " + from
-					+ " till " + to);
+			final int to = i + interval+offset-1;
+			Console.traceln(Level.FINE, "Aligning: Creating thread for sessions " + from + " till " + to);
 			final ParallelPairwiseAligner aligner = new ParallelPairwiseAligner(
 					appData, from, to);
 			executor.execute(aligner);
+			i+=offset;
 		}
 		executor.shutdown();
@@ -578,8 +607,11 @@
 	 * <p>
 	 * TODO clarify why this is done (in fact, ask Patrick Harms)
-	 * </p>.
+	 * </p>
+	 * .
 	 *
-	 * @param iteration the iteration
-	 * @param iterationInstances the iteration instances
+	 * @param iteration
+	 *            the iteration
+	 * @param iterationInstances
+	 *            the iteration instances
 	 */
 	private void harmonizeIterationInstancesModel(IIteration iteration,
@@ -641,11 +673,12 @@
 	}
 
-
 	/**
 	 * Match as sequence.
 	 *
-	 * @param appData		RuleApplicationData needed to keep track of all created tasks 
-	 * @param m				The match to be converted into a Task
-	 * @return 				The task of the match with an ISequence as its root
+	 * @param appData
+	 *            RuleApplicationData needed to keep track of all created tasks
+	 * @param m
+	 *            The match to be converted into a Task
+	 * @return The task of the match with an ISequence as its root
 	 */
 	synchronized public ISequence matchAsSequence(RuleApplicationData appData,
@@ -690,9 +723,12 @@
 			}
 			// Both tasks are not equal, we need to insert a selection here.
-			// Now things get complicated. We first need to check 
-			// if the next position is not a selection. Then we can just create a selection
+			// Now things get complicated. We first need to check
+			// if the next position is not a selection. Then we can just create
+			// a selection
 			// of the both Tasks
-			// In the other case (more than one selection following this selection), we want to 
-			// create a selection of sequences where each sequence gets the corresponding task of 
+			// In the other case (more than one selection following this
+			// selection), we want to
+			// create a selection of sequences where each sequence gets the
+			// corresponding task of
 			// the its sequence in the pattern.
 			//
@@ -728,4 +764,5 @@
 					taskBuilder.addChild(selection, subsequence2);
 					taskBuilder.addChild(sequence, selection);
+					// TODO: We run not till the end!
 					while ((i < (first.length - 1)) && selectionfound) {
 						selectionfound = false;
@@ -743,12 +780,13 @@
 						i++;
 					}
-					if ((i == (first.length - 1)) && selectionfound) {
-						taskBuilder.addChild(subsequence1, appData
-								.getNumber2Task().get(first[i]));
-						taskBuilder.addChild(subsequence2, appData
-								.getNumber2Task().get(second[i]));
-					}
+					 if ((i == (first.length - 1)) && selectionfound) {
+					 taskBuilder.addChild(subsequence1, appData
+					 .getNumber2Task().get(first[i]));
+					 taskBuilder.addChild(subsequence2, appData
+					 .getNumber2Task().get(second[i]));
+					 }
 				}
 			} else {
+				// i = length-1
 				if ((first[i] != second[i])) {
 
@@ -771,9 +809,13 @@
 	 * <p>
 	 * replaces all occurrences of all tasks provided in the set with iterations
-	 * </p>.
+	 * </p>
+	 * .
 	 *
-	 * @param iteratedTasks            the tasks to be replaced with iterations
-	 * @param sessions            the sessions in which the tasks are to be replaced
-	 * @param appData            the rule application data combining all data used for applying
+	 * @param iteratedTasks
+	 *            the tasks to be replaced with iterations
+	 * @param sessions
+	 *            the sessions in which the tasks are to be replaced
+	 * @param appData
+	 *            the rule application data combining all data used for applying
 	 *            this rule
 	 */
@@ -841,5 +883,6 @@
 	 * Replace matches.
 	 *
-	 * @param appData the app data
+	 * @param appData
+	 *            the app data
 	 */
 	private void replaceMatches(RuleApplicationData appData) {
@@ -847,38 +890,90 @@
 
 		final int matchSeqSize = appData.getMatchseqs().size();
-		int newThreads = nThreads;
-		if (matchSeqSize < nThreads) {
-			newThreads = matchSeqSize;
-		}
-		final ExecutorService executor = Executors
-				.newFixedThreadPool(newThreads);
-		final int interval = matchSeqSize / newThreads;
-		int rest = matchSeqSize % newThreads;
-
-		for (int i = 0; i < (matchSeqSize - interval); i += interval) {
-			int offset = 0;
-			if (rest != 0) {
-				offset = 1;
-				rest--;
-			}
-			final int from = i;
-			final int to = i + interval + offset;
-			System.out
-			.println("Replacement: Creating thread with matches from "
-					+ from + " to " + to);
-			// search each match in every other sequence
-			final ParallelMatchReplacer replacer = new ParallelMatchReplacer(
-					appData, from, to);
-			executor.execute(replacer);
-		}
-		executor.shutdown();
-		try {
-			executor.awaitTermination(2, TimeUnit.HOURS);
-		} catch (final InterruptedException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}
-
+
+		for (int i = 0; i < matchSeqSize; i++) {
+
+			// Every pattern consists of 2 sequences, therefore the minimum
+			// occurrences here is 2.
+			// We just need the sequences also occurring in other sequences
+			// as well
+			if (appData.getMatchseqs().get(i).occurenceCount() > 2) {
+
+				final ISequence task = matchAsSequence(appData, appData
+						.getMatchseqs().get(i));
+				invalidOccurence: for (final Iterator<MatchOccurence> it = appData
+						.getMatchseqs().get(i).getOccurences().iterator(); it
+						.hasNext();) {
+					final MatchOccurence oc = it.next();
+
+					// Check if nothing has been replaced in the sequence we
+					// want to replace now
+					if (appData.getReplacedOccurrences()
+							.get(oc.getSequenceId()) == null) {
+						appData.getReplacedOccurrences().put(
+								oc.getSequenceId(),
+								new LinkedList<MatchOccurence>());
+					} else {
+						// check if we have any replaced occurence with
+						// indexes
+						// smaller than ours. If so, we need to adjust
+						// our start
+						// and endpoints
+						// of the replacement.
+						// Also do a check if we have replaced this
+						// specific
+						// MatchOccurence in this sequence already. Jump
+						// to the
+						// next occurence if this is the case.
+						// This is no more neccessary once the matches
+						// are
+						// harmonized.
+
+						for (final Iterator<MatchOccurence> jt = appData
+								.getReplacedOccurrences()
+								.get(oc.getSequenceId()).iterator(); jt
+								.hasNext();) {
+							final MatchOccurence tmpOC = jt.next();
+
+							if ((oc.getStartindex() >= tmpOC.getStartindex())
+									&& (oc.getStartindex() <= tmpOC
+											.getEndindex())) {
+								continue invalidOccurence;
+							}
+							if (oc.getEndindex() >= tmpOC.getStartindex()) {
+								continue invalidOccurence;
+
+							} else if (oc.getStartindex() > tmpOC.getEndindex()) {
+								final int diff = tmpOC.getEndindex()
+										- tmpOC.getStartindex();
+								// Just to be sure.
+								if (diff > 0) {
+									oc.setStartindex((oc.getStartindex() - diff) + 1);
+									oc.setEndindex((oc.getEndindex() - diff) + 1);
+								} else {
+									Console.traceln(Level.WARNING,
+											"End index of a Match before start. This should never happen");
+								}
+							}
+						}
+					}
+					appData.detectedAndReplacedTasks = true;
+					final ISequenceInstance sequenceInstances = RuleUtils
+							.createNewSubSequenceInRange(appData.getSessions()
+									.get(oc.getSequenceId()), oc
+									.getStartindex(), oc.getEndindex(), task,
+									taskFactory, taskBuilder);
+					oc.setEndindex((oc.getStartindex() + sequenceInstances
+							.size()) - RuleUtils.missedOptionals);
+
+					// Adjust the length of the match regarding to the
+					// length of
+					// instance. (OptionalInstances may be shorter)
+
+					appData.getReplacedOccurrences().get(oc.getSequenceId())
+							.add(oc);
+				}
+			}
+		}
+	}
 
 	/**
@@ -888,5 +983,6 @@
 	 * </p>
 	 *
-	 * @param sessions the sessions
+	 * @param sessions
+	 *            the sessions
 	 * @return a set of tasks being iterated somewhere
 	 */
@@ -911,12 +1007,14 @@
 	 * Search matches in all sessions.
 	 *
-	 * @param appData the app data
+	 * @param appData
+	 *            the app data
 	 */
 	private void searchMatchesInAllSessions(RuleApplicationData appData) {
-		Console.traceln(Level.INFO,
-				"searching for patterns occuring most with " + nThreads
-						+ " threads");
+		
 		// Prepare parallel search of matchseqs
 		final int matchSeqSize = appData.getMatchseqs().size();
+		Console.traceln(Level.INFO,
+				"searching for patterns ("+ matchSeqSize+") occuring most with " + nThreads
+						+ " threads");
 		int newThreads = nThreads;
 		if (matchSeqSize < nThreads) {
@@ -926,6 +1024,6 @@
 		int rest = matchSeqSize % newThreads;
 		final ExecutorService executor = Executors.newFixedThreadPool(nThreads);
-
-		for (int i = 0; i < (matchSeqSize - interval); i += interval) {
+		Console.traceln(Level.FINE, "Interval: " + interval + " Rest: " + rest);
+		for (int i = 0; i <= (matchSeqSize-interval); i += interval) {
 			int offset = 0;
 			if (rest != 0) {
@@ -934,12 +1032,12 @@
 			}
 			final int from = i;
-			final int to = i + interval + offset;
-			System.out
-			.println("Match finding: Creating thread with matches from "
-					+ from + " to " + to);
+			final int to = i + interval + offset-1;
+			Console.traceln(Level.FINE, "Match finding: Creating thread with matches from "
+							+ from + " to " + to);
 			// search each match in every other sequence
 			final ParallelMatchOcurrencesFinder finder = new ParallelMatchOcurrencesFinder(
 					appData, from, to);
 			executor.execute(finder);
+			i+=offset;
 		}
 		executor.shutdown();
@@ -947,5 +1045,4 @@
 			executor.awaitTermination(2, TimeUnit.HOURS);
 		} catch (final InterruptedException e) {
-			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
@@ -967,11 +1064,11 @@
 	 */
 	private class ParallelMatchOcurrencesFinder implements Runnable {
-		
+
 		/** The app data. */
 		private final RuleApplicationData appData;
-		
+
 		/** The from. */
 		private final int from;
-		
+
 		/** The to. */
 		private final int to;
@@ -980,7 +1077,10 @@
 		 * Instantiates a new parallel match ocurrences finder.
 		 *
-		 * @param appData the app data
-		 * @param from the from
-		 * @param to the to
+		 * @param appData
+		 *            the app data
+		 * @param from
+		 *            the from
+		 * @param to
+		 *            the to
 		 */
 		ParallelMatchOcurrencesFinder(RuleApplicationData appData, int from,
@@ -991,5 +1091,7 @@
 		}
 
-		/* (non-Javadoc)
+		/*
+		 * (non-Javadoc)
+		 * 
 		 * @see java.lang.Runnable#run()
 		 */
@@ -1033,159 +1135,26 @@
 
 	/**
-	 * The Class ParallelMatchReplacer.
-	 */
-	private class ParallelMatchReplacer implements Runnable {
+	 * The Class ParallelPairwiseAligner.
+	 */
+	private class ParallelPairwiseAligner implements Runnable {
 
 		/** The app data. */
 		private final RuleApplicationData appData;
-		
+
 		/** The from. */
 		private final int from;
-		
+
 		/** The to. */
 		private final int to;
 
 		/**
-		 * Instantiates a new parallel match replacer.
-		 *
-		 * @param appData the app data
-		 * @param from the from
-		 * @param to the to
-		 */
-		ParallelMatchReplacer(RuleApplicationData appData, int from, int to) {
-			this.appData = appData;
-			this.from = from;
-			this.to = to;
-		}
-
-		/* (non-Javadoc)
-		 * @see java.lang.Runnable#run()
-		 */
-		@Override
-		public void run() {
-			// TODO Cleanup
-			// int count = 0;
-			// int size = to - from;
-			for (int i = from; i < to; i++) {
-				// count++;
-				// Every pattern consists of 2 sequences, therefore the minimum
-				// occurrences here is 2.
-				// We just need the sequences also occurring in other sequences
-				// as well
-				if (appData.getMatchseqs().get(i).occurenceCount() > 2) {
-
-					final ISequence task = matchAsSequence(appData, appData
-							.getMatchseqs().get(i));
-					invalidOccurence: for (final Iterator<MatchOccurence> it = appData
-							.getMatchseqs().get(i).getOccurences().iterator(); it
-							.hasNext();) {
-						final MatchOccurence oc = it.next();
-
-						// Check if nothing has been replaced in the sequence we
-						// want to replace now
-
-						synchronized (appData.getReplacedOccurrences()) {
-							if (appData.getReplacedOccurrences().get(
-									oc.getSequenceId()) == null) {
-								appData.getReplacedOccurrences().put(
-										oc.getSequenceId(),
-										new LinkedList<MatchOccurence>());
-							} else {
-								// check if we have any replaced occurence with
-								// indexes
-								// smaller than ours. If so, we need to adjust
-								// our start
-								// and endpoints
-								// of the replacement.
-								// Also do a check if we have replaced this
-								// specific
-								// MatchOccurence in this sequence already. Jump
-								// to the
-								// next occurence if this is the case.
-								// This is no more neccessary once the matches
-								// are
-								// harmonized.
-								for (final Iterator<MatchOccurence> jt = appData
-										.getReplacedOccurrences()
-										.get(oc.getSequenceId()).iterator(); jt
-										.hasNext();) {
-									final MatchOccurence tmpOC = jt.next();
-
-									if ((oc.getStartindex() >= tmpOC
-											.getStartindex())
-											&& (oc.getStartindex() <= tmpOC
-											.getEndindex())) {
-										continue invalidOccurence;
-									}
-									if (oc.getEndindex() >= tmpOC
-											.getStartindex()) {
-										continue invalidOccurence;
-
-									} else if (oc.getStartindex() > tmpOC
-											.getEndindex()) {
-										final int diff = tmpOC.getEndindex()
-												- tmpOC.getStartindex();
-										// Just to be sure.
-										if (diff > 0) {
-											oc.setStartindex((oc
-													.getStartindex() - diff) + 1);
-											oc.setEndindex((oc.getEndindex() - diff) + 1);
-										} else {
-											Console.traceln(Level.WARNING,
-													"End index of a Match before start. This should never happen");
-										}
-									}
-								}
-							}
-							synchronized (appData) {
-								appData.detectedAndReplacedTasks = true;
-							}
-							synchronized (appData.getSessions().get(
-									oc.getSequenceId())) {
-								final ISequenceInstance sequenceInstances = RuleUtils
-										.createNewSubSequenceInRange(
-												appData.getSessions().get(
-														oc.getSequenceId()),
-														oc.getStartindex(),
-														oc.getEndindex(), task,
-														taskFactory, taskBuilder);
-								oc.setEndindex((oc.getStartindex() + sequenceInstances
-										.size()) - RuleUtils.missedOptionals);
-							}
-						}
-						// Adjust the length of the match regarding to the
-						// length of
-						// instance. (OptionalInstances may be shorter)
-						synchronized (appData.getReplacedOccurrences().get(
-								oc.getSequenceId())) {
-							appData.getReplacedOccurrences()
-							.get(oc.getSequenceId()).add(oc);
-						}
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * The Class ParallelPairwiseAligner.
-	 */
-	private class ParallelPairwiseAligner implements Runnable {
-		
-		/** The app data. */
-		private final RuleApplicationData appData;
-		
-		/** The from. */
-		private final int from;
-		
-		/** The to. */
-		private final int to;
-
-		/**
 		 * Instantiates a new parallel pairwise aligner.
 		 *
-		 * @param appData the app data
-		 * @param from the from
-		 * @param to the to
+		 * @param appData
+		 *            the app data
+		 * @param from
+		 *            the from
+		 * @param to
+		 *            the to
 		 */
 		ParallelPairwiseAligner(RuleApplicationData appData, int from, int to) {
@@ -1195,5 +1164,7 @@
 		}
 
-		/* (non-Javadoc)
+		/*
+		 * (non-Javadoc)
+		 * 
 		 * @see java.lang.Runnable#run()
 		 */
@@ -1201,5 +1172,5 @@
 		public void run() {
 			int count = 0;
-			final int size = to - from;
+			final int size = to - from; 
 
 			for (int i = from; i < to; i++) {
@@ -1223,4 +1194,4 @@
 		}
 	}
-	
+
 }
Index: branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskTreeValidator.java
===================================================================
--- branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskTreeValidator.java	(revision 1738)
+++ branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskTreeValidator.java	(revision 1738)
@@ -0,0 +1,290 @@
+package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
+
+
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public class TaskTreeValidator {
+
+    /**
+     * 
+     */
+    public void validate(List<IUserSession> userSessions, boolean checkInstances) {
+        validate(userSessions);
+        
+        if (!checkInstances) {
+            return;
+        }
+        
+        Map<ITask, List<ITaskInstance>> allTasks = new HashMap<ITask, List<ITaskInstance>>();
+        
+        for (IUserSession userSession : userSessions) {
+            getAllTasksAndInstances(userSession, allTasks);
+        }
+        
+        for (Map.Entry<ITask, List<ITaskInstance>> entry : allTasks.entrySet()) {
+            assertEquals("number of task instances of task " + entry.getKey() + " in the " +
+                         "sessions is not equal to those referenced by the model",
+                         entry.getValue().size(), entry.getKey().getInstances().size());
+            
+            for (ITaskInstance candidate : entry.getValue()) {
+                boolean found = false;
+                for (ITaskInstance instance : entry.getKey().getInstances()) {
+                    if (candidate.equals(instance)) {
+                        if (!found) {
+                            found = true;
+                        }
+                        else {
+                            fail("the same instance is referred twice by the task");
+                        }
+                    }
+                }
+                
+                assertTrue("instance " + candidate + " is not referred by task", found);
+            }
+        }
+    }
+
+    /**
+     * 
+     */
+    public void validate(List<IUserSession> userSessions) {
+        for (IUserSession userSession : userSessions) {
+            validate(userSession);
+        }
+    }
+
+    /**
+     * 
+     */
+    public void validate(ITaskInstanceList taskInstances) {
+        for (ITaskInstance taskInstance : taskInstances) {
+            validate(taskInstance);
+        }
+    }
+
+    /**
+     * 
+     */
+    public void validate(ITaskInstance taskInstance) {
+        assertNotNull("task model of task instance must not be null", taskInstance.getTask());
+        
+        if (taskInstance.getTask() instanceof ISequence) {
+            ISequence task = (ISequence) taskInstance.getTask();
+            System.out.println("Task: " + task);
+            String instance="\n";
+            String model="\n";
+            
+            for(int i =0; i<((ISequenceInstance)taskInstance).size(); i++) {
+            	instance = instance + ((ISequenceInstance)taskInstance).get(i).toString() + "\n";
+            	
+            }
+            
+            for(int i=0;i<task.getChildren().size();i++) {
+            	model = model + task.getChildren().get(i) + "\n";
+            	if(task.getChildren().get(i) instanceof ISelection) {
+            		model = model + "\t" + ((ISelection)task.getChildren().get(i)).getChildren() + "\n";
+            	}
+            }
+            
+            if (((ISequenceInstance) taskInstance).size() != task.getChildren().size()) {
+            	System.out.println("INSTANCE (Size " +((ISequenceInstance) taskInstance).size() + "): "+ instance);
+            	System.out.println("MODEL    (Size " + task.getChildren().size()+ "):" + model);
+            }
+            
+       
+            assertEquals("number of children of sequence instance must match sequence model ",
+                         ((ISequenceInstance) taskInstance).size(), task.getChildren().size());
+            
+            for (int i = 0; i < ((ISequenceInstance) taskInstance).size(); i++) {
+                assertNotNull("sequence instance child " + i + " was null",
+                              ((ISequenceInstance) taskInstance).get(i));
+                ITask childTask = ((ISequenceInstance) taskInstance).get(i).getTask();
+                assertSame("task of sequence child " + i + " does not match sequence model",
+                           childTask, task.getChildren().get(i));
+            }
+        }
+        else if (taskInstance.getTask() instanceof ISelection) {
+            ISelection task = (ISelection) taskInstance.getTask();
+            
+            assertNotNull("number of children of selection instance must be 1",
+                          ((ISelectionInstance) taskInstance).getChild());
+            assertTrue
+                ("number of children of selection must be larger 0", task.getChildren().size() > 0);
+            
+            boolean found = false;
+            for (ITask childTask : task.getChildren()) {
+                assertNotNull("child of selection model must not be null", childTask);
+                assertFalse("child of selection model must not be a selection",
+                            childTask instanceof ISelection);
+                /*assertFalse("child of selection model must not be an optional",
+                            childTask instanceof IOptional);*/
+                if (childTask.equals(((ISelectionInstance) taskInstance).getChild().getTask())) {
+                    found = true;
+                    break;
+                }
+            }
+            
+            assertTrue("no child of the selection model matches the model of child of the " +
+                       "selection instance", found);
+        }
+        else if (taskInstance.getTask() instanceof IIteration) {
+            ITask childTask = ((IIteration) taskInstance.getTask()).getMarkedTask();
+            assertNotNull("child task of iteration model must not be null", childTask);
+            assertFalse("child of iteration model must not be an iteration",
+                        childTask instanceof IIteration);
+            assertFalse("child of iteration model must not be an optional",
+                        childTask instanceof IOptional);
+            
+            for (int i = 0; i < ((IIterationInstance) taskInstance).size(); i++) {
+                assertNotNull("iteration instance child " + i + " was null",
+                              ((IIterationInstance) taskInstance).get(i));
+                assertSame("task of iteration child " + i + " does not match iteration model",
+                           childTask, ((IIterationInstance) taskInstance).get(i).getTask());
+            }
+        }
+        else if (taskInstance.getTask() instanceof IOptional) {
+            ITask childTask = ((IOptional) taskInstance.getTask()).getMarkedTask();
+            assertNotNull("child task of optional model must not be null", childTask);
+            assertFalse("child of optional model must not be an optional",
+                        childTask instanceof IOptional);
+            
+            if (((IOptionalInstance) taskInstance).getChild() != null) {
+                assertEquals("task of optional child does not match optional model",
+                             childTask, ((IOptionalInstance) taskInstance).getChild().getTask());
+            }
+        }
+        else if (taskInstance.getTask() instanceof IEventTask) {
+            IEventTask task = (IEventTask) taskInstance.getTask();
+            assertNotNull("event task model must not be null", task);
+            assertNotNull("event of event task instance must not be null",
+                          ((IEventTaskInstance) taskInstance).getEvent());
+        }
+        else {
+            fail("unknown task model: " + taskInstance.getTask());
+        }
+        
+        if (taskInstance instanceof ITaskInstanceList) {
+            for (ITaskInstance child : (ITaskInstanceList) taskInstance) {
+                validate(child);
+            }
+        }
+        else if (taskInstance instanceof ISelectionInstance) {
+            validate(((ISelectionInstance) taskInstance).getChild());
+        }
+        else if (taskInstance instanceof IOptionalInstance) {
+            if (((IOptionalInstance) taskInstance).getChild() != null) {
+                validate(((IOptionalInstance) taskInstance).getChild());
+            }
+        }
+    }
+
+
+    /**
+     * 
+     */
+    private void getAllTasksAndInstances(ITaskInstanceList                     taskInstances,
+                                         final Map<ITask, List<ITaskInstance>> allTasks)
+    {
+        for (ITaskInstance taskInstance : taskInstances) {
+            
+            taskInstance.accept(new DefaultTaskInstanceTraversingVisitor() {
+
+                /* (non-Javadoc)
+                 * @see DefaultTaskInstanceTraversingVisitor#visit(IOptionalInstance)
+                 */
+                @Override
+                public void visit(IOptionalInstance optionalInstance) {
+                    addToInstanceList(optionalInstance);
+                    super.visit(optionalInstance);
+                }
+
+                /* (non-Javadoc)
+                 * @see DefaultTaskInstanceTraversingVisitor#visit(ISelectionInstance)
+                 */
+                @Override
+                public void visit(ISelectionInstance selectionInstance) {
+                    addToInstanceList(selectionInstance);
+                    super.visit(selectionInstance);
+                }
+
+                /* (non-Javadoc)
+                 * @see DefaultTaskInstanceTraversingVisitor#visit(IEventTaskInstance)
+                 */
+                @Override
+                public void visit(IEventTaskInstance eventTaskInstance) {
+                    addToInstanceList(eventTaskInstance);
+                    super.visit(eventTaskInstance);
+                }
+
+                /* (non-Javadoc)
+                 * @see DefaultTaskInstanceTraversingVisitor#visit(IIterationInstance)
+                 */
+                @Override
+                public void visit(IIterationInstance iterationInstance) {
+                    addToInstanceList(iterationInstance);
+                    super.visit(iterationInstance);
+                }
+
+                /* (non-Javadoc)
+                 * @see DefaultTaskInstanceTraversingVisitor#visit(ISequenceInstance)
+                 */
+                @Override
+                public void visit(ISequenceInstance sequenceInstance) {
+                    addToInstanceList(sequenceInstance);
+                    super.visit(sequenceInstance);
+                }
+
+                private void addToInstanceList(ITaskInstance taskInstance) {
+                    List<ITaskInstance> instances = allTasks.get(taskInstance.getTask());
+                    
+                    if (instances == null) {
+                        instances = new LinkedList<ITaskInstance>();
+                        allTasks.put(taskInstance.getTask(), instances);
+                    }
+                    
+                    boolean found = false;
+                    
+                    for (ITaskInstance candidate : instances) {
+                        if (candidate.equals(taskInstance)) {
+                            found = true;
+                            break;
+                        }
+                    }
+                    
+                    assertFalse("instance " + taskInstance + " occurred twice", found);
+                    
+                    instances.add(taskInstance);
+                }
+                
+            });
+        }
+    }
+}
