Index: branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/Match.java
===================================================================
--- branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/Match.java	(revision 1740)
+++ branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/Match.java	(revision 1741)
@@ -6,4 +6,5 @@
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.LinkedList;
 
@@ -12,5 +13,5 @@
  * The Class Match.
  */
-public class Match implements Serializable {
+public class Match implements Comparable<Match>,Serializable {
 	
 	/** The Constant serialVersionUID. */
@@ -21,5 +22,5 @@
 
 	/** The occurences. */
-	private LinkedList<MatchOccurence> occurences;
+	private LinkedList<MatchOccurrence> occurrences;
 
 	/**
@@ -28,8 +29,8 @@
 	public Match() {
 		matchseqs = new ArrayList<NumberSequence>(2);
-		occurences = new LinkedList<MatchOccurence>();
+		occurrences = new LinkedList<MatchOccurrence>();
 		matchseqs.add(null);
 		matchseqs.add(null);
-	}
+	}		// TODO Auto-generated method stub
 
 	/**
@@ -38,15 +39,15 @@
 	 * @param occurence the occurence
 	 */
-	public void addOccurence(MatchOccurence occurence) {
-		occurences.add(occurence);
+	public void addOccurence(MatchOccurrence occurence) {
+		occurrences.add(occurence);
 	}
 
 	/**
-	 * Adds the occurences of.
+	 * Adds the occurrences of given match to this match .
 	 *
-	 * @param m the m
+	 * @param m the match the occurrences should be merged with this one
 	 */
 	public void addOccurencesOf(Match m) {
-		occurences.addAll(m.getOccurences());
+		occurrences.addAll(m.getOccurences());
 	}
 
@@ -54,6 +55,6 @@
 	 * Equals.
 	 *
-	 * @param m the m
-	 * @return true, if successful
+	 * @param m the Match the equality should be checked against
+	 * @return true, if both Matches are equal
 	 */
 	public boolean equals(Match m) {
@@ -77,10 +78,10 @@
 
 	/**
-	 * Gets the occurences.
+	 * Gets the occurrences.
 	 *
-	 * @return the occurences
+	 * @return the occurrences
 	 */
-	public LinkedList<MatchOccurence> getOccurences() {
-		return occurences;
+	public LinkedList<MatchOccurrence> getOccurences() {
+		return occurrences;
 	}
 
@@ -95,10 +96,10 @@
 
 	/**
-	 * Occurence count.
+	 * Occurrence count.
 	 *
-	 * @return the int
+	 * @return the number of occurrences of this match
 	 */
 	public int occurenceCount() {
-		return occurences.size();
+		return occurrences.size();
 	}
 
@@ -113,10 +114,10 @@
 
 	/**
-	 * Sets the occurences.
+	 * Sets the occurrences.
 	 *
-	 * @param occurences the new occurences
+	 * @param occurences the new occurrences
 	 */
-	public void setOccurences(LinkedList<MatchOccurence> occurences) {
-		this.occurences = occurences;
+	public void setOccurences(LinkedList<MatchOccurrence> occurences) {
+		this.occurrences = occurences;
 	}
 
@@ -130,8 +131,45 @@
 	}
 
+
+	/**
+	 * Ocurrence id sum. Used for comparing and sorting matches
+	 *
+	 * @return th
+	 */
+	public int ocurrenceIDSum() {
+		int sum = 0;
+		for(Iterator<MatchOccurrence> it = occurrences.iterator();it.hasNext();) {
+			MatchOccurrence mo = it.next();
+			sum+=mo.getSequenceId();
+		}
+		return sum;
+	}
+	
+	/**
+	 * Task id sum. Used for comparing and sorting matches
+	 *
+	 * @return 
+	 */
+	public int taskIdSum() {
+		int sum = 0;
+		int[] first = this.getFirstSequence().getSequence();
+		int[] second = this.getSecondSequence().getSequence();
+		for(int i = 0;i < this.getFirstSequence().size();i++) {
+			sum= first[i]+second[i];
+		}
+		return sum;
+	}
+	
+	public Match cloneWithoutOccurences() throws CloneNotSupportedException  {
+		Match result;
+		result = (Match) this.clone();
+		result.occurrences.clear();
+		return result;
+	}
+	
 	/**
 	 * Size.
 	 *
-	 * @return the int
+	 * @return the size (number of aligned tasks)
 	 */
 	public int size() {
@@ -140,3 +178,12 @@
 	}
 
+	/* (non-Javadoc)
+	 * @see java.lang.Comparable#compareTo(java.lang.Object)
+	 */
+	@Override
+	public int compareTo(Match arg0) {
+		
+		return 0;
+	}
+
 }
Index: branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/MatchOccurence.java
===================================================================
--- branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/MatchOccurence.java	(revision 1740)
+++ 	(revision )
@@ -1,92 +1,0 @@
-/*
- * 
- */
-package de.ugoe.cs.autoquest.tasktrees.alignment.algorithms;
-
-import java.io.Serializable;
-
-// TODO: Auto-generated Javadoc
-/**
- * The Class MatchOccurence.
- */
-public class MatchOccurence implements Serializable {
-	
-	/** The Constant serialVersionUID. */
-	private static final long serialVersionUID = 6186633243145293781L;
-	
-	/** The startindex. */
-	private int startindex;
-	
-	/** The endindex. */
-	private int endindex;
-	
-	/** The sequence id. */
-	private int sequenceId;
-
-	/**
-	 * Instantiates a new match occurence.
-	 *
-	 * @param startindex the startindex
-	 * @param endindex the endindex
-	 * @param sequenceId the sequence id
-	 */
-	public MatchOccurence(int startindex, int endindex, int sequenceId) {
-		this.startindex = startindex;
-		this.endindex = endindex;
-		this.sequenceId = sequenceId;
-	}
-
-	/**
-	 * Gets the endindex.
-	 *
-	 * @return the endindex
-	 */
-	public int getEndindex() {
-		return endindex;
-	}
-
-	/**
-	 * Gets the sequence id.
-	 *
-	 * @return the sequence id
-	 */
-	public int getSequenceId() {
-		return sequenceId;
-	}
-
-	/**
-	 * Gets the startindex.
-	 *
-	 * @return the startindex
-	 */
-	public int getStartindex() {
-		return startindex;
-	}
-
-	/**
-	 * Sets the endindex.
-	 *
-	 * @param endindex the new endindex
-	 */
-	public void setEndindex(int endindex) {
-		this.endindex = endindex;
-	}
-
-	/**
-	 * Sets the sequence id.
-	 *
-	 * @param sequenceId the new sequence id
-	 */
-	public void setSequenceId(int sequenceId) {
-		this.sequenceId = sequenceId;
-	}
-
-	/**
-	 * Sets the startindex.
-	 *
-	 * @param startindex the new startindex
-	 */
-	public void setStartindex(int startindex) {
-		this.startindex = startindex;
-	}
-}
Index: branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/MatchOccurrence.java
===================================================================
--- branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/MatchOccurrence.java	(revision 1741)
+++ branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/MatchOccurrence.java	(revision 1741)
@@ -0,0 +1,92 @@
+/*
+ * 
+ */
+package de.ugoe.cs.autoquest.tasktrees.alignment.algorithms;
+
+import java.io.Serializable;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class MatchOccurence.
+ */
+public class MatchOccurrence implements Serializable {
+	
+	/** The Constant serialVersionUID. */
+	private static final long serialVersionUID = 6186633243145293781L;
+	
+	/** The startindex. */
+	private int startindex;
+	
+	/** The endindex. */
+	private int endindex;
+	
+	/** The sequence id. */
+	private int sequenceId;
+
+	/**
+	 * Instantiates a new match occurence.
+	 *
+	 * @param startindex the startindex
+	 * @param endindex the endindex
+	 * @param sequenceId the sequence id
+	 */
+	public MatchOccurrence(int startindex, int endindex, int sequenceId) {
+		this.startindex = startindex;
+		this.endindex = endindex;
+		this.sequenceId = sequenceId;
+	}
+
+	/**
+	 * Gets the endindex.
+	 *
+	 * @return the endindex
+	 */
+	public int getEndindex() {
+		return endindex;
+	}
+
+	/**
+	 * Gets the sequence id.
+	 *
+	 * @return the sequence id
+	 */
+	public int getSequenceId() {
+		return sequenceId;
+	}
+
+	/**
+	 * Gets the startindex.
+	 *
+	 * @return the startindex
+	 */
+	public int getStartindex() {
+		return startindex;
+	}
+
+	/**
+	 * Sets the endindex.
+	 *
+	 * @param endindex the new endindex
+	 */
+	public void setEndindex(int endindex) {
+		this.endindex = endindex;
+	}
+
+	/**
+	 * Sets the sequence id.
+	 *
+	 * @param sequenceId the new sequence id
+	 */
+	public void setSequenceId(int sequenceId) {
+		this.sequenceId = sequenceId;
+	}
+
+	/**
+	 * Sets the startindex.
+	 *
+	 * @param startindex the new startindex
+	 */
+	public void setStartindex(int startindex) {
+		this.startindex = startindex;
+	}
+}
Index: branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/SmithWatermanRepeated.java
===================================================================
--- branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/SmithWatermanRepeated.java	(revision 1740)
+++ branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/SmithWatermanRepeated.java	(revision 1741)
@@ -262,8 +262,4 @@
 				tmpal.setFirstSequence(tmpns1);
 				tmpal.setSecondSequence(tmpns2);
-				// tmpal.addOccurence(new
-				// MatchOccurence(start,alignment.get(0).getId()));
-				// tmpal.addOccurence(new
-				// MatchOccurence(start,alignment.get(1).getId()));
 				result.add(tmpal);
 			}
Index: branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/matrix/ObjectDistanceSubstitionMatrix.java
===================================================================
--- branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/matrix/ObjectDistanceSubstitionMatrix.java	(revision 1740)
+++ branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/matrix/ObjectDistanceSubstitionMatrix.java	(revision 1741)
@@ -220,13 +220,13 @@
 		matrix.initialize(0);
 
-		int count = 0;
-		final int size = uniqueTasks.size();
+		//int count = 0;
+		//final int size = uniqueTasks.size();
 		for (final Iterator<ITask> it = uniqueTasks.iterator(); it.hasNext();) {
 			final ITask task1 = it.next();
-			count++;
-			if (((count % (size / 100)) == 0)) {
-				Console.traceln(Level.INFO,
-						(Math.round(((float) count / size) * 100)) + "%");
-			}
+			//count++;
+			//if (((count % (size / 100)) == 0)) {
+			//	Console.traceln(Level.INFO,
+			//			(Math.round(((float) count / size) * 100)) + "%");
+			//}
 			for (final Iterator<ITask> jt = uniqueTasks.iterator(); jt
 					.hasNext();) {
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 1740)
+++ branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleUtils.java	(revision 1741)
@@ -64,5 +64,6 @@
 		final ISequenceInstance subsequence = taskFactory
 				.createNewTaskInstance(model);
-		@SuppressWarnings("unused")
+		// TODO: Debugging output
+		/*
 		int modelid = model.getId();
 		if(modelid == 5412) {
@@ -77,5 +78,5 @@
 			}
 			
-		}
+		}*/
 		// TODO: This is dirty, return this in addition with the sequence
 		// instance instead
@@ -125,8 +126,8 @@
 					} 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++;
+						taskBuilder.setChild(selection, parent.get(startIndex));
+						taskBuilder.addChild(subsequence, selection);
+						taskBuilder.removeTaskInstance(parent, startIndex);
+						modelindex++;
 						continue;
 						
@@ -226,7 +227,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 {
@@ -234,7 +235,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) + "%");
 
 		}
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 1740)
+++ branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRuleAlignment.java	(revision 1741)
@@ -25,4 +25,6 @@
 import java.util.List;
 import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.Queue;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
@@ -34,5 +36,5 @@
 import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithmFactory;
 import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.Match;
-import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.MatchOccurence;
+import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.MatchOccurrence;
 import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.NumberSequence;
 import de.ugoe.cs.autoquest.tasktrees.alignment.matrix.ObjectDistanceSubstitionMatrix;
@@ -72,229 +74,5 @@
 public class SequenceForTaskDetectionRuleAlignment implements ISessionScopeRule {
 
-	/**
-	 * The Class RuleApplicationData.
-	 */
-	private static class RuleApplicationData implements Serializable {
-
-		/** The Constant serialVersionUID. */
-		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
-		 */
-		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.
-		 */
-		private final HashSet<ITask> uniqueTasks;
-
-		/**
-		 * 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
-		 */
-		private HashMap<Integer, List<MatchOccurence>> replacedOccurences;
-
-		/** The list of all found matches */
-		private LinkedList<Match> matchseqs;
-
-		/**
-		 * The generated NumberSequences. This is the integer representation of
-		 * the user sessions
-		 */
-		private ArrayList<NumberSequence> numberseqs;
-
-		/** The list of newly created tasks (of one iteration). */
-		private final LinkedList<ITask> newTasks;
-
-		/** The user sessions containing all EventTasks/Instances */
-		private final List<IUserSession> sessions;
-
-		/** True if we replaced something in the user sessions in one iteration. */
-		private boolean detectedAndReplacedTasks;
-
-		/** The result we give autoquest back */
-		private final RuleApplicationResult result;
-
-		/** Stop Watch to measure performance */
-		private final StopWatch stopWatch;
-
-		/**
-		 * Instantiates a new rule application data.
-		 *
-		 * @param sessions
-		 *            The user sessions
-		 */
-		private RuleApplicationData(List<IUserSession> sessions) {
-			this.sessions = sessions;
-			numberseqs = new ArrayList<NumberSequence>();
-			uniqueTasks = new HashSet<ITask>();
-			number2task = new HashMap<Integer, ITask>();
-			stopWatch = new StopWatch();
-			result = new RuleApplicationResult();
-			submat = new ObjectDistanceSubstitionMatrix(6, -3, false);
-			newTasks = new LinkedList<ITask>();
-			this.detectedAndReplacedTasks = true;
-		}
-
-		/**
-		 * Detected and replaced tasks.
-		 *
-		 * @return true, if successful
-		 */
-		private boolean detectedAndReplacedTasks() {
-			return detectedAndReplacedTasks;
-		}
-
-		/**
-		 * Gets the matchseqs.
-		 *
-		 * @return the matchseqs
-		 */
-		public LinkedList<Match> getMatchseqs() {
-			return matchseqs;
-		}
-
-		/**
-		 * Gets the new tasks.
-		 *
-		 * @return the new tasks
-		 */
-		public LinkedList<ITask> getNewTasks() {
-			return newTasks;
-		}
-
-		/**
-		 * Gets the number2task.
-		 *
-		 * @return the number2task HashMap
-		 */
-		private HashMap<Integer, ITask> getNumber2Task() {
-			return number2task;
-		}
-
-		/**
-		 * Gets the number sequences.
-		 *
-		 * @return the number sequences
-		 */
-		private ArrayList<NumberSequence> getNumberSequences() {
-			return numberseqs;
-		}
-
-		/**
-		 * Gets the replaced occurrences.
-		 *
-		 * @return the replaced occurences
-		 */
-		public HashMap<Integer, List<MatchOccurence>> getReplacedOccurrences() {
-			return replacedOccurences;
-		}
-
-		/**
-		 * Gets the result.
-		 *
-		 * @return the result
-		 */
-		private RuleApplicationResult getResult() {
-			return result;
-		}
-
-		/**
-		 * Gets the sessions.
-		 *
-		 * @return the UserSessions as List.
-		 */
-		private List<IUserSession> getSessions() {
-			return sessions;
-		}
-
-		/**
-		 * Gets the stop watch.
-		 *
-		 * @return the stopWatch
-		 */
-		private StopWatch getStopWatch() {
-			return stopWatch;
-		}
-
-		/**
-		 * Gets the submat.
-		 *
-		 * @return the submat
-		 */
-		private ObjectDistanceSubstitionMatrix getSubmat() {
-			return submat;
-		}
-
-		/**
-		 * Gets the unique tasks.
-		 *
-		 * @return the unique tasks
-		 */
-		private HashSet<ITask> getUniqueTasks() {
-			return uniqueTasks;
-		}
-
-		/**
-		 * New task created.
-		 *
-		 * @param task
-		 *            the task
-		 */
-		private void newTaskCreated(ITask task) {
-			number2task.put(task.getId(), task);
-			newTasks.add(task);
-		}
-
-		/**
-		 * Reset newly created tasks.
-		 */
-		synchronized private void resetNewlyCreatedTasks() {
-			uniqueTasks.addAll(newTasks);
-			newTasks.clear();
-		}
-
-		/**
-		 * Sets the number sequences.
-		 *
-		 * @param numberseqs
-		 *            the new number sequences
-		 */
-		private void setNumberSequences(ArrayList<NumberSequence> numberseqs) {
-			this.numberseqs = numberseqs;
-		}
-
-		/**
-		 * Sets the replaced occurences.
-		 *
-		 * @param replacedOccurences
-		 *            the replaced occurences
-		 */
-		public void setReplacedOccurences(
-				HashMap<Integer, List<MatchOccurence>> replacedOccurences) {
-			this.replacedOccurences = replacedOccurences;
-		}
-
-		/**
-		 * Update substitution matrix.
-		 */
-		private void updateSubstitutionMatrix() {
-			submat.update(getNewTasks());
-			resetNewlyCreatedTasks();
-		}
-
-	}
-
+	
 	/** The n threads. */
 	public static int nThreads = Runtime.getRuntime().availableProcessors() - 1;
@@ -380,9 +158,10 @@
 			detectAndReplaceIterations(appData);
 			appData.getStopWatch().start("task replacement");
+			//Just does anything if the substitution matrix is created with the option to do so
 			appData.updateSubstitutionMatrix();
 			detectAndReplaceTasks(appData); //
 			appData.getStopWatch().stop("task replacement");
 			appData.getStopWatch().stop("whole loop");
-			appData.getStopWatch().dumpStatistics(System.out);
+			//appData.getStopWatch().dumpStatistics(System.out);
 			appData.getStopWatch().reset();
 
@@ -400,5 +179,5 @@
 					RuleApplicationStatus.FINISHED);
 		}
-		new TaskTreeValidator().validate(appData.getSessions());
+		//new TaskTreeValidator().validate(appData.getSessions());
 		return appData.getResult();
 	}
@@ -488,10 +267,32 @@
 			@Override
 			public int compare(Match m1, Match m2) {
-				return m2.occurenceCount() - m1.occurenceCount();
-
+				int cmp = m2.occurenceCount() - m1.occurenceCount();
+				if(cmp != 0) {
+					return cmp;
+				}
+				else {
+					cmp = m2.size()-m1.size();
+					if(cmp != 0) {
+						return cmp;
+					}
+					else {
+						//This should rarely happen
+						cmp = m2.ocurrenceIDSum()-m1.ocurrenceIDSum();
+						if(cmp !=0) {
+							return cmp;
+						}
+						else {
+							cmp = m2.taskIdSum()-m1.taskIdSum();
+							
+							return cmp;
+						}
+					}
+				}
 			}
 		};
+		
 		Collections.sort(appData.getMatchseqs(), comparator);
 		appData.getStopWatch().stop("detecting tasks");
+	
 
 		// Replace matches in the sessions
@@ -502,49 +303,26 @@
 	}
 
-	/**
-	 * Generate pairwise alignments.
-	 *
-	 * @param appData
-	 *            the app data
-	 */
-	private void generatePairwiseAlignments(RuleApplicationData appData) {
-		final int numberSeqSize = appData.getNumberSequences().size();
-		appData.matchseqs = new LinkedList<Match>();
-		Console.traceln(Level.INFO, "generating pairwise alignments from "
-				+ numberSeqSize + " sessions with " + nThreads + " threads");
-
-		int newThreads = nThreads;
-		if (numberSeqSize < nThreads) {
-			newThreads = numberSeqSize;
-		}
-
-		final ExecutorService executor = Executors
-				.newFixedThreadPool(newThreads);
-		final int interval = numberSeqSize / newThreads;
-		int rest = numberSeqSize % newThreads;
-		Console.traceln(Level.FINE, "Interval: " + interval + " Rest: " + rest);
-		for (int i = 0; i <= (numberSeqSize - interval); i += interval) {
-			int offset = 0;
-			if (rest != 0) {
-				offset = 1;
-				rest--;
-			}
-		
-			final int from = i;
-			final int to = i + interval+offset-1;
-			Console.traceln(Level.FINER, "Aligning: Creating thread for sessions " + from + " till " + to);
-			final ParallelPairwiseAligner aligner = new ParallelPairwiseAligner(
-					appData, from, to);
-			executor.execute(aligner);
-			i+=offset;
-		}
-		executor.shutdown();
-		try {
-			executor.awaitTermination(2, TimeUnit.HOURS);
-		} catch (final InterruptedException e) {
-			e.printStackTrace();
-		}
-	}
-
+	
+	//TODO: DEBUG METHOD
+	@SuppressWarnings("unused")
+	private void printMatches(RuleApplicationData appData) {
+		LinkedList<Match> matchseqs = appData.getMatchseqs();
+		if(iteration>1) {
+		System.out.println("PRINTING MATCHES");
+		for (Iterator<Match> it = matchseqs.iterator(); it.hasNext();) {
+			Match m = it.next();
+			m.getFirstSequence().printSequence();
+			m.getSecondSequence().printSequence();
+			for(Iterator<MatchOccurrence> jt = m.getOccurences().iterator();jt.hasNext();) {
+				MatchOccurrence mo = jt.next();
+				System.out.print(mo.getSequenceId() + " ");
+			}
+			System.out.println();
+			System.out.println();
+ 		}
+		}
+	}
+
+	
 	/**
 	 * <p>
@@ -879,4 +657,27 @@
 	}
 
+	private void prepareReplacements(RuleApplicationData appData) {
+		appData.initializeQueues(appData.getSessions().size());
+		final int matchSeqSize = appData.getMatchseqs().size();
+		int count = 0;
+		for (Iterator<Match> it = appData.getMatchseqs().iterator(); it.hasNext();) {
+			Match m = it.next();
+			for(Iterator<MatchOccurrence> jt=m.getOccurences().iterator();jt.hasNext();) {
+				MatchOccurrence mo = jt.next();
+				
+				Match emptyMatch = null;
+				try {
+					emptyMatch = m.cloneWithoutOccurences();
+				} catch (CloneNotSupportedException e) {
+					e.printStackTrace();
+				}
+				emptyMatch.addOccurence(mo);
+				appData.getPlannedReplacements()[mo.getSequenceId()].add(m);
+			}
+			count++;
+			
+		}
+	}
+	
 	/**
 	 * Replace matches.
@@ -886,22 +687,23 @@
 	 */
 	private void replaceMatches(RuleApplicationData appData) {
-		appData.setReplacedOccurences(new HashMap<Integer, List<MatchOccurence>>());
+		appData.setReplacedOccurences(new HashMap<Integer, List<MatchOccurrence>>());
 
 		final int matchSeqSize = appData.getMatchseqs().size();
-
+		int count = 0;
 		for (int i = 0; i < matchSeqSize; 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
+			RuleUtils.printProgressPercentage("Replacement progress", count, matchSeqSize);
 			if (appData.getMatchseqs().get(i).occurenceCount() > 2) {
 
 				final ISequence task = matchAsSequence(appData, appData
 						.getMatchseqs().get(i));
-				invalidOccurence: for (final Iterator<MatchOccurence> it = appData
+				invalidOccurence: for (final Iterator<MatchOccurrence> it = appData
 						.getMatchseqs().get(i).getOccurences().iterator(); it
 						.hasNext();) {
-					final MatchOccurence oc = it.next();
+					final MatchOccurrence oc = it.next();
 
 					// Check if nothing has been replaced in the sequence we
@@ -911,5 +713,5 @@
 						appData.getReplacedOccurrences().put(
 								oc.getSequenceId(),
-								new LinkedList<MatchOccurence>());
+								new LinkedList<MatchOccurrence>());
 					} else {
 						// check if we have any replaced occurence with
@@ -928,9 +730,9 @@
 						// harmonized.
 
-						for (final Iterator<MatchOccurence> jt = appData
+						for (final Iterator<MatchOccurrence> jt = appData
 								.getReplacedOccurrences()
 								.get(oc.getSequenceId()).iterator(); jt
 								.hasNext();) {
-							final MatchOccurence tmpOC = jt.next();
+							final MatchOccurrence tmpOC = jt.next();
 
 							if ((oc.getStartindex() >= tmpOC.getStartindex())
@@ -1004,4 +806,52 @@
 
 	/**
+	 * Generate pairwise alignments.
+	 *
+	 * @param appData
+	 *            the app data
+	 */
+	private void generatePairwiseAlignments(RuleApplicationData appData) {
+		final int numberSeqSize = appData.getNumberSequences().size();
+		appData.matchseqs = new LinkedList<Match>();
+		Console.traceln(Level.INFO, "generating pairwise alignments from "
+				+ numberSeqSize + " sessions with " + nThreads + " threads");
+
+		int newThreads = nThreads;
+		if (numberSeqSize < nThreads) {
+			newThreads = numberSeqSize;
+		}
+
+		final ExecutorService executor = Executors
+				.newFixedThreadPool(newThreads);
+		final int interval = numberSeqSize / newThreads;
+		int rest = numberSeqSize % newThreads;
+		Console.traceln(Level.FINE, "Interval: " + interval + " Rest: " + rest);
+		for (int i = 0; i <= (numberSeqSize - interval); i += interval) {
+			int offset = 0;
+			if (rest != 0) {
+				offset = 1;
+				rest--;
+			}
+		
+			final int from = i;
+			final int to = i + interval+offset-1;
+			Console.traceln(Level.FINER, "Aligning: Creating thread for sessions " + from + " till " + to);
+			final ParallelPairwiseAligner aligner = new ParallelPairwiseAligner(
+					appData, from, to);
+			executor.execute(aligner);
+			i+=offset;
+		}
+		executor.shutdown();
+		try {
+			executor.awaitTermination(2, TimeUnit.HOURS);
+		} catch (final InterruptedException e) {
+			e.printStackTrace();
+		}
+	}
+
+	
+	
+	
+	/**
 	 * Search matches in all sessions.
 	 *
@@ -1089,5 +939,4 @@
 			this.to = to;
 		}
-
 		/*
 		 * (non-Javadoc)
@@ -1124,5 +973,5 @@
 								.iterator(); jt.hasNext();) {
 							final int start = jt.next();
-							pattern.addOccurence(new MatchOccurence(start,
+							pattern.addOccurence(new MatchOccurrence(start,
 									start + pattern.size(), j));
 						}
@@ -1132,4 +981,6 @@
 		}
 	}
+	
+	
 
 	/**
@@ -1193,4 +1044,251 @@
 		}
 	}
+	
+	/**
+	 * The Class RuleApplicationData.
+	 */
+	private static class RuleApplicationData implements Serializable {
+
+		/** The Constant serialVersionUID. */
+		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
+		 */
+		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.
+		 */
+		private final HashSet<ITask> uniqueTasks;
+
+		/**
+		 * 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
+		 */
+		private HashMap<Integer, List<MatchOccurrence>> replacedOccurences;
+		
+		private Queue<Match>[] plannedReplacements;
+		
+
+		/** The list of all found matches */
+		private LinkedList<Match> matchseqs;
+
+		/**
+		 * The generated NumberSequences. This is the integer representation of
+		 * the user sessions
+		 */
+		private ArrayList<NumberSequence> numberseqs;
+
+		/** The list of newly created tasks (of one iteration). */
+		private final LinkedList<ITask> newTasks;
+
+		/** The user sessions containing all EventTasks/Instances */
+		private final List<IUserSession> sessions;
+
+		/** True if we replaced something in the user sessions in one iteration. */
+		private boolean detectedAndReplacedTasks;
+
+		/** The result we return from this rule */
+		private final RuleApplicationResult result;
+
+		/** Stop Watch to measure performance */
+		private final StopWatch stopWatch;
+		
+		
+
+		/**
+		 * Instantiates a new rule application data.
+		 *
+		 * @param sessions
+		 *            The user sessions
+		 */
+		private RuleApplicationData(List<IUserSession> sessions) {
+			this.sessions = sessions;
+			numberseqs = new ArrayList<NumberSequence>();
+			uniqueTasks = new HashSet<ITask>();
+			number2task = new HashMap<Integer, ITask>();
+			stopWatch = new StopWatch();
+			result = new RuleApplicationResult();
+			submat = new ObjectDistanceSubstitionMatrix(6, -3, false);
+			newTasks = new LinkedList<ITask>();
+			this.detectedAndReplacedTasks = true;
+		}
+		
+		private void initializeQueues(int size) {
+			plannedReplacements = new Queue[size];
+			for(int i=0;i<size;i++) {
+				plannedReplacements[i] = new PriorityQueue<Match>();
+			}
+		}
+
+		public Queue<Match>[] getPlannedReplacements() {
+			return plannedReplacements;
+		}
+
+		public void setPlannedReplacements(Queue<Match>[] plannedReplacements) {
+			this.plannedReplacements = plannedReplacements;
+		}
+
+		/**
+		 * Detected and replaced tasks.
+		 *
+		 * @return true, if successful
+		 */
+		private boolean detectedAndReplacedTasks() {
+			return detectedAndReplacedTasks;
+		}
+
+		/**
+		 * Gets the matchseqs.
+		 *
+		 * @return the matchseqs
+		 */
+		public LinkedList<Match> getMatchseqs() {
+			return matchseqs;
+		}
+
+		/**
+		 * Gets the new tasks.
+		 *
+		 * @return the new tasks
+		 */
+		public LinkedList<ITask> getNewTasks() {
+			return newTasks;
+		}
+
+		/**
+		 * Gets the number2task.
+		 *
+		 * @return the number2task HashMap
+		 */
+		private HashMap<Integer, ITask> getNumber2Task() {
+			return number2task;
+		}
+
+		/**
+		 * Gets the number sequences.
+		 *
+		 * @return the number sequences
+		 */
+		private ArrayList<NumberSequence> getNumberSequences() {
+			return numberseqs;
+		}
+
+		/**
+		 * Gets the replaced occurrences.
+		 *
+		 * @return the replaced occurences
+		 */
+		public HashMap<Integer, List<MatchOccurrence>> getReplacedOccurrences() {
+			return replacedOccurences;
+		}
+
+		/**
+		 * Gets the result.
+		 *
+		 * @return the result
+		 */
+		private RuleApplicationResult getResult() {
+			return result;
+		}
+
+		/**
+		 * Gets the sessions.
+		 *
+		 * @return the UserSessions as List.
+		 */
+		private List<IUserSession> getSessions() {
+			return sessions;
+		}
+
+		/**
+		 * Gets the stop watch.
+		 *
+		 * @return the stopWatch
+		 */
+		private StopWatch getStopWatch() {
+			return stopWatch;
+		}
+
+		/**
+		 * Gets the submat.
+		 *
+		 * @return the submat
+		 */
+		private ObjectDistanceSubstitionMatrix getSubmat() {
+			return submat;
+		}
+
+		/**
+		 * Gets the unique tasks.
+		 *
+		 * @return the unique tasks
+		 */
+		private HashSet<ITask> getUniqueTasks() {
+			return uniqueTasks;
+		}
+
+		/**
+		 * New task created.
+		 *
+		 * @param task
+		 *            can be called when new tasks are created to keep track of all newly created tasks
+		 */
+		private void newTaskCreated(ITask task) {
+			number2task.put(task.getId(), task);
+			newTasks.add(task);
+		}
+
+		/**
+		 * Reset newly created tasks.
+		 */
+		synchronized private void resetNewlyCreatedTasks() {
+			uniqueTasks.addAll(newTasks);
+			newTasks.clear();
+		}
+
+		/**
+		 * Sets the number sequences.
+		 *
+		 * @param numberseqs
+		 *            the new number sequences
+		 */
+		private void setNumberSequences(ArrayList<NumberSequence> numberseqs) {
+			this.numberseqs = numberseqs;
+		}
+
+		/**
+		 * Sets the replaced occurences.
+		 *
+		 * @param replacedOccurences
+		 *            the replaced occurences
+		 */
+		public void setReplacedOccurences(
+				HashMap<Integer, List<MatchOccurrence>> replacedOccurences) {
+			this.replacedOccurences = replacedOccurences;
+		}
+
+		/**
+		 * Update substitution matrix.
+		 */
+		private void updateSubstitutionMatrix() {
+			submat.update(getNewTasks());
+			resetNewlyCreatedTasks();
+		}
+
+	}
+
+	
 
 }
