Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/ISessionScopeRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/ISessionScopeRule.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/ISessionScopeRule.java	(revision 1146)
@@ -0,0 +1,48 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
+
+import java.util.List;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
+
+/**
+ * <p>
+ * A session scope rule is able to detected temporal relationships between task instances of the
+ * sessions provided to the {@link #apply(List<IUserSession>)} method. The rule creates temporal
+ * relationships between the tasks of the task instances, i.e. substructures in the task tree, if
+ * it detects a temporal relationship and instantiates the temporal relationships according to
+ * their occurrences.
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+interface ISessionScopeRule extends ITemporalRelationshipRule {
+
+    /**
+     * <p>
+     * Applies the rule to the given sessions. The returned rule application result is null, if the
+     * rule can not be applied, i.e. it does not detect a temporal relationship. It returns a rule
+     * application result with a status {@link RuleApplicationStatus#RULE_APPLICATION_FINISHED} if
+     * the rule was applied. The result contains all newly created tasks and task instances.
+     * </p>
+     * 
+     * @param sessions the session on which the rule shall be applied
+     *                    
+     * @return the rule application result as described.
+     */
+    RuleApplicationResult apply(List<IUserSession> sessions);
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/ITaskInstanceListScopeRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/ITaskInstanceListScopeRule.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/ITaskInstanceListScopeRule.java	(revision 1146)
@@ -0,0 +1,45 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
+
+/**
+ * <p>
+ * a task instance list scope rule is able to detected temporal relationships between a list of task
+ * instances provided to the {@link #apply(ITaskInstanceList)} method. A rule creates temporal
+ * relationships between the task instances, i.e. substructures in the task tree, if
+ * it detects a temporal relationship and instantiates the temporal relationships accordingly.
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+interface ITaskInstanceListScopeRule extends ITemporalRelationshipRule {
+
+  /**
+   * <p>
+   * applies the rule to the given task instance list. The returned rule application result is null,
+   * if the rule can not be applied, i.e. it does not detect a temporal relationship. It returns a
+   * rule application result with a status {@link RuleApplicationStatus#RULE_APPLICATION_FINISHED}
+   * if the rule was applied. The result contains all newly created parent tasks and task instances.
+   * </p>
+   * 
+   * @param taskInstances the list of task instances to apply the rule on
+   *                    
+   * @return the rule application result as described.
+   */
+  RuleApplicationResult apply(ITaskInstanceList taskInstances);
+  
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/ITemporalRelationshipRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/ITemporalRelationshipRule.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/ITemporalRelationshipRule.java	(revision 1146)
@@ -0,0 +1,26 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public interface ITemporalRelationshipRule {
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/IterationOfSubtreesDetectionRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/IterationOfSubtreesDetectionRule.java	(revision 1133)
+++ 	(revision )
@@ -1,525 +1,0 @@
-//   Copyright 2012 Georg-August-Universität Göttingen, Germany
-//
-//   Licensed under the Apache License, Version 2.0 (the "License");
-//   you may not use this file except in compliance with the License.
-//   You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//   Unless required by applicable law or agreed to in writing, software
-//   distributed under the License is distributed on an "AS IS" BASIS,
-//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//   See the License for the specific language governing permissions and
-//   limitations under the License.
-
-package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality;
-import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
-
-/**
- * <p>
- * iterations in a list of nodes are equal subsequences following each other directly. The
- * subsequences can be of any length depending on the type of equality they need to have. If the
- * subsequences have to be lexically equal, then they have to have the same length if they only
- * contain event tasks. As an example entering text can be done through appropriate keystrokes or
- * through pasting the text. As a result, two syntactically different sequences are semantically
- * equal. If both follow each other, then they are an iteration of semantically equal children.
- * But they are not lexically equal.
- * </p>
- * <p>
- * This class determines equal subsequences following each other. It is provided with a minimal node
- * equality the equal nodes should have. Through this, it is possible to find e.g. lexically
- * equal subsequence through a first application of this rule and semantically equal children to 
- * a later application of this rule. This is used by the {@link TemporalRelationshipRuleManager}
- * which instantiates this rule three times, each with a different minimal equality.
- * </p>
- * <p>
- * The equal subsequences are determined through trial and error. This algorithm has a high effort
- * as it tries in the worst case all possible combinations of sub lists in all possible parts of
- * the list of children of a provided parent node. The steps for each trial are.
- * <ul>
- *   <li>for all possible subparts of the children of the provided parent
- *   <ul>
- *     <li>for all possible first sublists in the subpart
- *     <ul>
- *       <li>for all succeeding next sublists in this part</li>
- *       <ul>
- *         <li>check if this sublist is equal to all previously identified sublist in this part</li>
- *       </ul>
- *     </ul>
- *     <li>
- *       if a combination of sublists is found in this subpart which are all equal to each other
- *       at the provided minimal equality level, an iteration in this subpart was found.
- *     </li>
- *       <ul>
- *         <li>merge the identified equal sublists to an iteration</li>
- *       </ul>
- *   </ul>
- * </ul>
- * The algorithm tries to optimize if all children are event tasks and if the sublists shall be
- * lexically equal. In this case, the sublist all have to have the same length. The trial and
- * error reduces to a minimum of possible sublists.
- * </p>
- * 
- * @author Patrick Harms
- */
-class IterationOfSubtreesDetectionRule implements TemporalRelationshipRule {
-
-    /**
-     * <p>
-     * the maximum length for iterated sequences
-     * </p>
-     */
-    private static final int MAX_LENGTH_OF_ITERATED_SEQUENCE = 50;
-    
-    /**
-     * <p>
-     * the task tree node factory to be used for creating substructures for the temporal
-     * relationships identified during rule
-     * </p>
-     */
-    private ITaskTreeNodeFactory taskTreeNodeFactory;
-    /**
-     * <p>
-     * the task tree builder to be used for creating substructures for the temporal relationships
-     * identified during rule application
-     * </p>
-     */
-    private ITaskTreeBuilder taskTreeBuilder;
-
-    /**
-     * <p>
-     * the node comparator used for comparing task tree nodes with each other
-     * </p>
-     */
-    private TaskTreeNodeComparator nodeComparator;
-
-    /**
-     * <p>
-     * instantiates the rule and initializes it with a node equality rule manager and the minimal
-     * node equality identified sublist must have to consider them as iterated.
-     * </p>
-     */
-    IterationOfSubtreesDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager,
-                                     NodeEquality            minimalNodeEquality,
-                                     ITaskTreeNodeFactory    taskTreeNodeFactory,
-                                     ITaskTreeBuilder        taskTreeBuilder)
-    {
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-        
-        this.nodeComparator =
-            new TaskTreeNodeComparator(nodeEqualityRuleManager, minimalNodeEquality);
-    }
-
-    /**
-     * <p>
-     * instantiates the rule and initializes it with a node equality rule manager and the minimal
-     * node equality identified sublist must have to consider them as iterated.
-     * </p>
-     */
-    IterationOfSubtreesDetectionRule(TaskTreeNodeComparator nodeComparator,
-                                     ITaskTreeNodeFactory   taskTreeNodeFactory,
-                                     ITaskTreeBuilder       taskTreeBuilder)
-    {
-        this.nodeComparator = nodeComparator;
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-    }
-
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return "IterationOfSubtreesDetectionRule";
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode,
-     * boolean)
-     */
-    @Override
-    public RuleApplicationResult apply(ITaskTreeNode parent, boolean finalize) {
-        if (!(parent instanceof ISequence)) {
-            return null;
-        }
-
-        if (!finalize) {
-            // the rule is always feasible as iterations may occur at any time
-            RuleApplicationResult result = new RuleApplicationResult();
-            result.setRuleApplicationStatus(RuleApplicationStatus.FEASIBLE);
-            return result;
-        }
-
-        List<ITaskTreeNode> children = parent.getChildren();
-        
-        // parent must already have at least 2 children
-        if ((children == null) || (children.size() < 2)) {
-            return null;
-        }
-        
-        SubSequences subSequences = getEqualSubsequences(children);
-
-        if (subSequences != null) {
-            RuleApplicationResult result = new RuleApplicationResult();
-
-            // merge the identified variants, but preserve the differences in form of selections
-            // by using lexical equality for merge comparisons
-            TaskTreeNodeMerger merger = new TaskTreeNodeMerger
-                (taskTreeNodeFactory, taskTreeBuilder, nodeComparator);
-
-            merger.mergeTaskNodes(subSequences.equalVariants);
-            
-            IIteration newIteration =
-                createIterationBasedOnIdentifiedVariants(subSequences, result);
-
-            determineNewlyCreatedParentTasks(parent, newIteration, result);
-            
-            // remove iterated children
-            for (int j = subSequences.start; j < subSequences.end; j++) {
-                taskTreeBuilder.removeChild((ISequence) parent, subSequences.start);
-            }
-
-            // add the new iteration instead
-            taskTreeBuilder.addChild((ISequence) parent, subSequences.start, newIteration);
-
-            result.setRuleApplicationStatus(RuleApplicationStatus.FINISHED);
-            return result;
-        }
-
-        return null;
-    }
-
-    /**
-     * <p>
-     * this method initiates the trial and error algorithm denoted in the description of this class.
-     * Its main purpose is the selection of a subpart of the provided list of nodes in which
-     * equal sublists shall be searched. It is important, to always find the last iterations in a
-     * part first. The reason for this are iterations of iterations. If we always found the first
-     * iteration in a subpart first, then this may be an iteration of iterations. However, there
-     * may be subsequent iterations to be included in this iteration. But these iterations are not
-     * found yet, as they occur later in the sequence. Therefore, if we always find the last
-     * iteration in a sequence first, iterations of iterations are identified, last.
-     * </p>
-     * 
-     * @param nodes the list of nodes in which iterations shall be found
-     * 
-     * @return the iterated subsequences identified in a specific part (contains the equal
-     *         subsequences as well as the start (inclusive) and end (exclusive) index of the
-     *         subpart in which the sequences were found) 
-     */
-    private SubSequences getEqualSubsequences(List<ITaskTreeNode> nodes) {
-        SubSequences subSequences = null;
-
-        // to find longer iterations first, start with long sequences
-        FIND_ITERATION:
-        for (int end = nodes.size(); end > 0; end--) {
-            for (int start = 0; start < end; start++) {
-                boolean useEqualSublistLengths = equalSublistLengthsCanBeUsed(nodes, start, end);
-
-                subSequences = new SubSequences();
-                subSequences.start = start;
-
-                boolean foundFurtherVariants = findFurtherVariants
-                    (subSequences, nodes, start, end, useEqualSublistLengths);
-
-                if (foundFurtherVariants) {
-                    break FIND_ITERATION;
-                }
-                else {
-                    subSequences = null;
-                }
-            }
-        }
-        
-        return subSequences;
-    }
-
-    /**
-     * <p>
-     * for optimization purposes, we check if the length of the sublists to be identified as
-     * iterations has to be the same for any sublist. This only applies, if the minimum node
-     * equality to be checked for is lexical equality. If the nodes in the provided list are all
-     * event tasks, then sublists can only be lexically equal, if they all have the same length.
-     * Therefore we check, if the minimal node equality is lexical equality. And if so, we also
-     * check if all nodes in the list in which an iteration shall be searched for are event tasks.
-     * </p>
-     *
-     * @param nodes  the list of nodes to search for iterations
-     * @param start  the beginning of the subpart (inclusive) to be considered
-     * @param end    the end of the subpart (exclusive) to be considered
-     * 
-     * @return true, if the sublists must have the same lengths, false else
-     */
-    private boolean equalSublistLengthsCanBeUsed(List<ITaskTreeNode> nodes, int start, int end) {
-        boolean equalLengthsCanBeUsed =
-            nodeComparator.getConsideredNodeEquality().isAtLeast(NodeEquality.LEXICALLY_EQUAL);
-        
-        if (equalLengthsCanBeUsed) {
-            for (int i = start; i < end; i++) {
-                if (!(nodes.get(i) instanceof IEventTask)) {
-                    equalLengthsCanBeUsed = false;
-                    break;
-                }
-            }
-        }
-
-        return equalLengthsCanBeUsed;
-    }
-
-    /**
-     * <p>
-     * this method starts at a specific position in the provided list of nodes and checks, if it
-     * finds a further sublist, that matches the already found sublists. If the sublist lengths
-     * must be equal, it only searches for a sublist of the same length of the already found
-     * sublists. The method calls itself if it identifies a further equal sublist but
-     * if the end of the subpart of the provided list is not yet reached.
-     * </p>
-     * 
-     * @param subSequences           the sublist found so far against which equality of the next
-     *                               sublist must be checked
-     * @param nodes                  the list of nodes to be checked for iterations
-     * @param start                  the starting index from which to start the next sublist to be
-     *                               identified
-     * @param end                    the end index (exclusive) of the current subpart of list of
-     *                               nodes in which iterations are searched for
-     * @param useEqualSublistLengths true if the sublists to be searched for all need to have the
-     *                               same length
-     * 
-     * @return true if a further equal variant was found, false else
-     */
-    private boolean findFurtherVariants(SubSequences        subSequences,
-                                        List<ITaskTreeNode> nodes,
-                                        int                 start,
-                                        int                 end,
-                                        boolean             useEqualSublistLengths)
-    {
-        boolean foundFurtherVariants = (start == end) && (subSequences.equalVariants.size() > 1);
-        
-        int minChildCount = 1;
-        int maxChildCount = Math.min(MAX_LENGTH_OF_ITERATED_SEQUENCE, end - start);
-        
-        if (useEqualSublistLengths && (subSequences.equalVariants.size() > 0)) {
-            minChildCount = subSequences.equalVariants.get(0).getChildren().size();
-            maxChildCount = Math.min(minChildCount, maxChildCount);
-        }
-        
-        for (int childCount = minChildCount; childCount <= maxChildCount; childCount++) {
-            if (useEqualSublistLengths && (((end - start) % childCount) != 0)) {
-                continue;
-            }
-            
-            ISequence furtherVariant = taskTreeNodeFactory.createNewSequence();
-            
-            for (int j = start; j < start + childCount; j++) {
-                taskTreeBuilder.addChild(furtherVariant, nodes.get(j));
-            }
-            
-            boolean allVariantsEqual = true;
-            
-            for (ITaskTreeNode equalVariant : subSequences.equalVariants) {
-                if (!nodeComparator.equals(equalVariant, furtherVariant)) {
-                    allVariantsEqual = false;
-                    break;
-                }
-            }
-            
-            if (allVariantsEqual) {
-                
-                // we found a further variant. Add it to the list of variants and try to find
-                // further variants. Ignore, if none is available
-                int index = subSequences.equalVariants.size();
-                subSequences.equalVariants.add(index, furtherVariant);
-                
-                foundFurtherVariants = findFurtherVariants
-                    (subSequences, nodes, start + childCount, end, useEqualSublistLengths);
-
-                if (foundFurtherVariants) {
-                    subSequences.end = end;
-                    break;
-                }
-                else {
-                    subSequences.equalVariants.remove(index);
-                }
-            }
-        }
-        
-        return foundFurtherVariants;
-    }
-
-    /**
-     * <p>
-     * this is a convenience method to create an iteration based on the identified and already
-     * merged iterated subsequences. This method creates the simplest iteration possible. As an
-     * example, if always the same task tree node is iterated, it becomes the child of the
-     * iteration. If a sequence of tasks is iterated, this sequence becomes the child of the
-     * iteration. It several equal sublists or nodes which are not lexically equal are iterated
-     * they become a selection which in turn become the child of the iteration.
-     * </p>
-     *
-     * @param subsequences the identified and already merged equal subsequences
-     * 
-     * @return the resulting iteration
-     */
-    private IIteration createIterationBasedOnIdentifiedVariants(SubSequences          subsequences,
-                                                                RuleApplicationResult result)
-    {
-        IIteration newIteration = taskTreeNodeFactory.createNewIteration();
-        result.addNewlyCreatedParentNode(newIteration);
-
-        if (subsequences.equalVariants.size() == 1) {
-            // all children are the same. Create an iteration of this child
-            if (subsequences.equalVariants.get(0).getChildren().size() == 1) {
-                // there is only one equal variant and this has only one child. So create an
-                // iteration of this child
-                taskTreeBuilder.setChild
-                    (newIteration, subsequences.equalVariants.get(0).getChildren().get(0));
-            }
-            else {
-                // there was an iteration of one equal sequence
-                taskTreeBuilder.setChild(newIteration, subsequences.equalVariants.get(0));
-                result.addNewlyCreatedParentNode(subsequences.equalVariants.get(0));
-            }
-        }
-        else {
-            // there are distinct variants of equal subsequences or children --> create an
-            // iterated selection
-            ISelection selection = taskTreeNodeFactory.createNewSelection();
-            result.addNewlyCreatedParentNode(selection);
-
-            for (ITaskTreeNode variant : subsequences.equalVariants) {
-                if (variant.getChildren().size() == 1) {
-                    taskTreeBuilder.addChild(selection, variant.getChildren().get(0));
-                }
-                else {
-                    taskTreeBuilder.addChild(selection, variant);
-                    result.addNewlyCreatedParentNode(variant);
-                }
-            }
-
-            taskTreeBuilder.setChild(newIteration, selection);
-        }
-        
-        return newIteration;
-    }
-
-    /**
-     * <p>
-     * as the method has to denote all newly created parent nodes this method identifies them by
-     * comparing the existing subtree with the newly created iteration. Only those parent nodes
-     * in the new iteration, which are not already found in the existing sub tree are denoted as
-     * newly created. We do this in this way, as during the iteration detection algorithm, many
-     * parent nodes are created, which may be discarded later. It is easier to identify the
-     * remaining newly created parent nodes through this way than to integrate it into the
-     * algorithm.
-     * </p>
-     * 
-     * @param existingSubTree the existing subtree
-     * @param newSubTree      the identified iteration
-     * @param result          the rule application result into which the newly created parent nodes
-     *                        shall be stored.
-     */
-    private void determineNewlyCreatedParentTasks(ITaskTreeNode         existingSubTree,
-                                                  ITaskTreeNode         newSubTree,
-                                                  RuleApplicationResult result)
-    {
-        List<ITaskTreeNode> existingParentNodes = getParentNodes(existingSubTree);
-        List<ITaskTreeNode> newParentNodes = getParentNodes(newSubTree);
-        
-        boolean foundNode;
-        for (ITaskTreeNode newParentNode : newParentNodes) {
-            foundNode = false;
-            for (ITaskTreeNode existingParentNode : existingParentNodes) {
-                // It is sufficient to compare the references. The algorithm reuses nodes as they
-                // are. So any node existing in the new structure that is also in the old structure
-                // was unchanged an therefore does not need to be handled as a newly created one.
-                // but every node in the new structure that is not included in the old structure
-                // must be treated as a newly created one.
-                if (newParentNode == existingParentNode) {
-                    foundNode = true;
-                    break;
-                }
-            }
-            
-            if (!foundNode) {
-                result.addNewlyCreatedParentNode(newParentNode);
-            }
-        }
-        
-    }
-
-    /**
-     * <p>
-     * convenience method to determine all parent nodes existing in a subtree
-     * </p>
-     *
-     * @param subtree the subtree to search for parent nodes in
-     * 
-     * @return a list of parent nodes existing in the subtree
-     */
-    private List<ITaskTreeNode> getParentNodes(ITaskTreeNode subtree) {
-        List<ITaskTreeNode> parentNodes = new ArrayList<ITaskTreeNode>();
-        
-        List<ITaskTreeNode> children = subtree.getChildren();
-        
-        if (children.size() > 0) {
-            parentNodes.add(subtree);
-            
-            for (ITaskTreeNode child : children) {
-                parentNodes.addAll(getParentNodes(child));
-            }
-        }
-        
-        return parentNodes;
-    }
-
-    /**
-     * <p>
-     * used to have a container for equal sublists identified in a sub part of the children of
-     * a parent node.
-     * </p>
-     * 
-     * @author Patrick Harms
-     */
-    private static class SubSequences {
-
-        /**
-         * <p>
-         * the beginning of the subpart of the children of the parent node in which the sublists
-         * are found (inclusive)
-         * </p>
-         */
-        public int start;
-        
-        /**
-         * <p>
-         * the end of the subpart of the children of the parent node in which the sublists
-         * are found (exclusive)
-         * </p>
-         */
-        public int end;
-        
-        /**
-         * <p>
-         * the equal sublists found in the subpart of the children of the parent node
-         * </p>
-         */
-        List<ITaskTreeNode> equalVariants = new ArrayList<ITaskTreeNode>();
-        
-    }
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationResult.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationResult.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationResult.java	(revision 1146)
@@ -18,12 +18,13 @@
 import java.util.List;
 
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
 
 /**
  * <p>
- * The rule application result describes the result of applying a {@link TemporalRelationshipRule}
- * on a task tree node. It contains a {@link RuleApplicationStatus} and a list of all parent
- * task tree nodes that were created during a rule application. See the description of
- * {@link TemporalRelationshipRule} for more details.
+ * The rule application result describes the result of applying a {@link ITemporalRelationshipRule}.
+ * It contains a {@link RuleApplicationStatus} and a list of all parent task instances and tasks
+ * that were created during a rule application. See the description of
+ * {@link ITemporalRelationshipRule} for more details.
  * </p>
  * 
@@ -36,5 +37,8 @@
 
     /** */
-    private List<ITaskTreeNode> newParents = new ArrayList<ITaskTreeNode>();
+    private List<ITask> newParentTasks = new ArrayList<ITask>();
+
+    /** */
+    private List<ITaskInstance> newParentInstances = new ArrayList<ITaskInstance>();
 
     /**
@@ -67,18 +71,36 @@
     /**
      * <p>
-     * add a further parent node created during the rule application
+     * add a further parent task created during the rule application
      * </p>
      */
-    void addNewlyCreatedParentNode(ITaskTreeNode newParent) {
-        newParents.add(newParent);
+    void addNewlyCreatedTask(ITask newParent) {
+        newParentTasks.add(newParent);
     }
 
     /**
      * <p>
-     * return all parent nodes created during the rule application
+     * return all parent tasks created during the rule application
      * </p>
      */
-    List<ITaskTreeNode> getNewlyCreatedParentNodes() {
-        return newParents;
+    List<ITask> getNewlyCreatedTasks() {
+        return newParentTasks;
+    }
+
+    /**
+     * <p>
+     * add a further parent task instance created during the rule application
+     * </p>
+     */
+    void addNewlyCreatedTaskInstance(ITaskInstance newParent) {
+        newParentInstances.add(newParent);
+    }
+
+    /**
+     * <p>
+     * return all parent task instances created during the rule application
+     * </p>
+     */
+    List<ITaskInstance> getNewlyCreatedTaskInstances() {
+        return newParentInstances;
     }
 
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationStatus.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationStatus.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationStatus.java	(revision 1146)
@@ -17,6 +17,6 @@
 /**
  * <p>
- * The rule application status describes the result of applying a {@link TemporalRelationshipRule}
- * on a task tree node. See the description of {@link TemporalRelationshipRule} for more details.
+ * The rule application status describes the result of applying a {@link ITemporalRelationshipRule}.
+ * See the description of {@link ITemporalRelationshipRule} for more details.
  * </p>
  * 
@@ -25,4 +25,5 @@
 enum RuleApplicationStatus {
     FINISHED,
+    // TODO drop feasible
     FEASIBLE,
     NOT_APPLIED;
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleUtils.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleUtils.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleUtils.java	(revision 1146)
@@ -15,8 +15,9 @@
 package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
 
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory;
 
 /**
@@ -35,21 +36,18 @@
      * 
      */
-    static ISequence getSubSequenceInRange(ITaskTreeNode         parent,
-                                           int                   startIndex,
-                                           int                   endIndex,
-                                           String                description,
-                                           ITaskTreeNodeFactory  nodeFactory,
-                                           ITaskTreeBuilder      builder)
+    static ITaskInstance getSubSequenceInRange(ITaskInstanceList parent,
+                                               int               startIndex,
+                                               int               endIndex,
+                                               ITask             model,
+                                               ITaskFactory      taskFactory,
+                                               ITaskBuilder      taskBuilder)
     {
-        ISequence sequence = nodeFactory.createNewSequence();
-        if (description != null) {
-            builder.setDescription(sequence, description);
+        ITaskInstance subsequence = taskFactory.createNewTaskInstance(model);
+
+        for (int i = startIndex; i <= endIndex; i++) {
+            taskBuilder.addChild(subsequence, parent.get(i));
         }
 
-        for (int i = startIndex; i <= endIndex; i++) {
-            builder.addChild(sequence, parent.getChildren().get(i));
-        }
-
-        return sequence;
+        return subsequence;
     }
 
@@ -57,24 +55,22 @@
      * 
      */
-    static ISequence createNewSubSequenceInRange(ITaskTreeNode         parent,
-                                                 int                   startIndex,
-                                                 int                   endIndex,
-                                                 String                description,
-                                                 ITaskTreeNodeFactory  nodeFactory,
-                                                 ITaskTreeBuilder      builder)
+    static ITaskInstance createNewSubSequenceInRange(ITaskInstanceList parent,
+                                                     int               startIndex,
+                                                     int               endIndex,
+                                                     ITask             model,
+                                                     ITaskFactory      taskFactory,
+                                                     ITaskBuilder      taskBuilder)
     {
-        ISequence sequence = nodeFactory.createNewSequence();
-        if (description != null) {
-            builder.setDescription(sequence, description);
+        ITaskInstance subsequence = taskFactory.createNewTaskInstance(model);
+
+        for (int i = startIndex; i <= endIndex; i++) {
+            taskBuilder.addChild(subsequence, parent.get(startIndex));
+            taskBuilder.removeTaskInstance(parent, startIndex);
         }
 
-        for (int i = startIndex; i <= endIndex; i++) {
-            builder.addChild(sequence, parent.getChildren().get(startIndex));
-            builder.removeChild((ISequence) parent, startIndex);
-        }
 
-        builder.addChild((ISequence) parent, startIndex, sequence);
+        taskBuilder.addTaskInstance(parent, startIndex, subsequence);
 
-        return sequence;
+        return subsequence;
     }
 
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceDependingOnEventTypeDetectionRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceDependingOnEventTypeDetectionRule.java	(revision 1133)
+++ 	(revision )
@@ -1,207 +1,0 @@
-//   Copyright 2012 Georg-August-Universität Göttingen, Germany
-//
-//   Licensed under the Apache License, Version 2.0 (the "License");
-//   you may not use this file except in compliance with the License.
-//   You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//   Unless required by applicable law or agreed to in writing, software
-//   distributed under the License is distributed on an "AS IS" BASIS,
-//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//   See the License for the specific language governing permissions and
-//   limitations under the License.
-
-package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
-
-import java.util.List;
-import java.util.Stack;
-
-import de.ugoe.cs.autoquest.eventcore.gui.IInteraction;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
-
-/**
- * This rule generates sequences of events depending on the event types, more concrete, the
- * {@link IInteraction}s and the return values of their {@link IInteraction#startsLogicalSequence()}
- * and {@link IInteraction#finishesLogicalSequence()}. If a new logical sequence is started by
- * an interaction, then a real sequence is instantiated. The sequence is finished, if an
- * interaction finishes a logical sequence. Examples include keyboard focus changes.
- * 
- * @version $Revision: $ $Date: 18.03.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-class SequenceDependingOnEventTypeDetectionRule implements TemporalRelationshipRule {
-
-    /**
-     * <p>
-     * the task tree node factory to be used for creating substructures for the temporal
-     * relationships identified during rule
-     * </p>
-     */
-    private ITaskTreeNodeFactory taskTreeNodeFactory;
-    /**
-     * <p>
-     * the task tree builder to be used for creating substructures for the temporal relationships
-     * identified during rule application
-     * </p>
-     */
-    private ITaskTreeBuilder taskTreeBuilder;
-    
-    /**
-     * <p>
-     * instantiates the rule with a task tree node factory and builder to be used during rule
-     * application.
-     * </p>
-     * 
-     * @param taskTreeNodeFactory the task tree node factory to be used for creating substructures
-     *                            for the temporal relationships identified during rule
-     *                            application
-     * @param taskTreeBuilder     the task tree builder to be used for creating substructures for
-     *                            the temporal relationships identified during rule application
-     */
-    SequenceDependingOnEventTypeDetectionRule(ITaskTreeNodeFactory taskTreeNodeFactory,
-                                              ITaskTreeBuilder     taskTreeBuilder)
-    {
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-    }
-    
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return "SequenceDependingOnEventTypeDetectionRule";
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode,
-     * boolean)
-     */
-    @Override
-    public RuleApplicationResult apply(ITaskTreeNode parent, boolean finalize) {
-        if (!(parent instanceof ISequence)) {
-            return null;
-        }
-
-        RuleApplicationResult result = new RuleApplicationResult();
-        Stack<Integer> sequenceStartingIndex = new Stack<Integer>();
-
-        List<ITaskTreeNode> children = parent.getChildren();
-        
-        int index = 0;
-        while (index < children.size()) {
-            ITaskTreeNode child = children.get(index);
-
-            if ((child instanceof IEventTask) &&
-                (((IEventTask) child).getEventType() instanceof IInteraction))
-            {
-                IInteraction eventType = (IInteraction) ((IEventTask) child).getEventType();
-
-                if (eventType.finishesLogicalSequence() && (sequenceStartingIndex.size() > 0)) {
-                    index = handleLogicalSequence(sequenceStartingIndex, index, parent, result);
-                    // the parents child list will have changed, retrieve it again
-                    children = parent.getChildren();
-                }
-
-                if (eventType.startsLogicalSequence()) {
-                    sequenceStartingIndex.push(index);
-                }
-            }
-
-            index++;
-        }
-
-        if (sequenceStartingIndex.size() > 0) {
-            if (!finalize) {
-                result.setRuleApplicationStatus(RuleApplicationStatus.FEASIBLE);
-            }
-            else {
-                ITaskTreeNode lastChild = children.get(children.size() - 1);
-                
-                if (lastChild instanceof IEventTask) {
-                    handleLogicalSequence
-                        (sequenceStartingIndex, children.size() - 1, parent, result);
-                }
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     */
-    private int handleLogicalSequence(Stack<Integer>        sequenceStartingIndex,
-                                      int                   index,
-                                      ITaskTreeNode         parent,
-                                      RuleApplicationResult result)
-    {
-        int newIndex = index;
-        
-        List<ITaskTreeNode> children = parent.getChildren();
-        
-        IInteraction eventType =
-            (IInteraction) ((IEventTask) children.get(index)).getEventType();
-
-        // There are several situations in which this implementation may cause infinite
-        // loops. This is because the rule manager will reapply rules until
-        // no rule is applied anymore. A sequence identified in a first iteration will
-        // be identified as a sequence also in a second iteration. As an example
-        // many sequences start with an interaction starting that sequence and end
-        // with an interaction ending that sequence. This will be reidentified as
-        // further subsequence. It must therefore be assured, that a sequence, that
-        // was once identified is not reidentified in a further application of the rule.
-        // For this, the implementation performs a kind of dry run. It creates a list of
-        // children that would belong to an identified sequence. Only if this list is
-        // not a reidentification then a new sequence is created and added to the
-        // parent. If it is a reidentification can be identified, if the list of
-        // children will contain all children of the parent, or if the list of children
-        // only consists of one sequence. Further, an identified sequence must at least
-        // have one child.
-        
-        boolean allChildrenBelongToSubSequence =
-            (sequenceStartingIndex.peek() == 0) && (index == (children.size() - 1));
-        
-        boolean atLeastOneChildToCondense = index - sequenceStartingIndex.peek() > 0;
-        
-        if (!allChildrenBelongToSubSequence && atLeastOneChildToCondense) {
-            int startIndex = sequenceStartingIndex.pop();
-            ISequence sequence = taskTreeNodeFactory.createNewSequence();
-
-            for (int j = startIndex; j < index; j++) {
-                taskTreeBuilder.addChild(sequence, children.get(startIndex));
-                taskTreeBuilder.removeChild((ISequence) parent, startIndex);
-            }
-
-            if (!eventType.startsLogicalSequence()) {
-                taskTreeBuilder.addChild(sequence, children.get(startIndex));
-                taskTreeBuilder.removeChild((ISequence) parent, startIndex);
-                newIndex = startIndex;
-            }
-            else {
-                newIndex = startIndex + 1;
-            }
-
-            taskTreeBuilder.addChild((ISequence) parent, startIndex, sequence);
-
-            result.addNewlyCreatedParentNode(sequence);
-                
-            taskTreeBuilder.setDescription(sequence, "logical sequence started by the first event");
-                
-            result.setRuleApplicationStatus(RuleApplicationStatus.FINISHED);
-        }
-        
-        return newIndex;
-    }
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRule.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRule.java	(revision 1146)
@@ -15,20 +15,25 @@
 package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
 
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 
-import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality;
-import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager;
+import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEquality;
+import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEqualityRuleManager;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
+import de.ugoe.cs.autoquest.usageprofiles.SymbolComparator;
 import de.ugoe.cs.autoquest.usageprofiles.Trie;
 import de.ugoe.cs.autoquest.usageprofiles.TrieProcessor;
 import de.ugoe.cs.util.StopWatch;
-import de.ugoe.cs.util.console.Console;
 
 /**
@@ -39,44 +44,43 @@
  * @author Patrick Harms
  */
-class SequenceForTaskDetectionRule implements TemporalRelationshipRule {
+class SequenceForTaskDetectionRule implements ISessionScopeRule {
     
     /**
      * <p>
-     * the task tree node factory to be used for creating substructures for the temporal
+     * the task factory to be used for creating substructures for the temporal
      * relationships identified during rule
      * </p>
      */
-    private ITaskTreeNodeFactory taskTreeNodeFactory;
+    private ITaskFactory taskFactory;
     /**
      * <p>
-     * the task tree builder to be used for creating substructures for the temporal relationships
+     * the task builder to be used for creating substructures for the temporal relationships
      * identified during rule application
      * </p>
      */
-    private ITaskTreeBuilder taskTreeBuilder;
+    private ITaskBuilder taskBuilder;
 
     /**
      * <p>
-     * the node comparator to be used for comparing task tree nodes
+     * the task comparator to be used for comparing tasks
      * </p>
      */
-    private TaskTreeNodeComparator nodeComparator;
+    private TaskComparator taskComparator;
 
     /**
      * <p>
-     * instantiates the rule and initializes it with a node equality rule manager and the minimal
-     * node equality identified sublist must have to consider them as iterated.
+     * instantiates the rule and initializes it with a task equality rule manager and the minimal
+     * task equality identified sublist must have to consider them as iterated.
      * </p>
      */
-    SequenceForTaskDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager,
-                                 NodeEquality            minimalNodeEquality,
-                                 ITaskTreeNodeFactory    taskTreeNodeFactory,
-                                 ITaskTreeBuilder        taskTreeBuilder)
+    SequenceForTaskDetectionRule(TaskEqualityRuleManager taskEqualityRuleManager,
+                                 TaskEquality            minimalTaskEquality,
+                                 ITaskFactory            taskFactory,
+                                 ITaskBuilder            taskBuilder)
     {
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-        
-        this.nodeComparator =
-            new TaskTreeNodeComparator(nodeEqualityRuleManager, minimalNodeEquality);
+        this.taskFactory = taskFactory;
+        this.taskBuilder = taskBuilder;
+        
+        this.taskComparator = new TaskComparator(taskEqualityRuleManager, minimalTaskEquality);
     }
 
@@ -89,40 +93,11 @@
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode,
-     * boolean)
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.temporalrelation.ISessionScopeRule#apply(java.util.List)
      */
     @Override
-    public RuleApplicationResult apply(ITaskTreeNode parent, boolean finalize) {
-        if (!(parent instanceof ISequence)) {
-            return null;
-        }
-
-        if (!finalize) {
-            // the rule is always feasible as tasks may occur at any time
-            RuleApplicationResult result = new RuleApplicationResult();
-            result.setRuleApplicationStatus(RuleApplicationStatus.FEASIBLE);
-            return result;
-        }
-
-        List<ITaskTreeNode> children = parent.getChildren();
-        List<ISequence> sessions = new LinkedList<ISequence>();
-        
-        for (ITaskTreeNode child : children) {
-            if (child instanceof ISequence) {
-                sessions.add((ISequence) child);
-            }
-            else {
-                Console.println("provided parent is no parent of sessions");
-                return null;
-            }
-        }
-        
+    public RuleApplicationResult apply(List<IUserSession> sessions) {
         RuleApplicationData appData = new RuleApplicationData(sessions);
 
-        boolean finished = false;
-        
         // this is the real rule application. Loop while something is replaced.
         do {
@@ -137,18 +112,21 @@
             appData.getStopWatch().stop("whole loop");
             
-            //((TaskTreeNodeComparator) nodeComparator).getStopWatch().dumpStatistics(System.out);
-            //((TaskTreeNodeComparator) nodeComparator).getStopWatch().reset();
+            //((TaskTreeNodeComparator) taskComparator).getStopWatch().dumpStatistics(System.out);
+            //((TaskTreeNodeComparator) taskComparator).getStopWatch().reset();
             
             appData.getStopWatch().dumpStatistics(System.out);
             appData.getStopWatch().reset();
             
-            finished = (appData.getReplacementCounter() == 0);
-        }
-        while (!finished);
-        
-        System.out.println("created " + appData.getResult().getNewlyCreatedParentNodes().size() +
-                           " new parent nodes\n");
-        
-        if (appData.getResult().getNewlyCreatedParentNodes().size() > 0) {
+        }
+        while (appData.detectedAndReplacedTasks());
+        
+        System.out.println
+            ("created " + appData.getResult().getNewlyCreatedTasks().size() +
+             " new tasks and " + appData.getResult().getNewlyCreatedTaskInstances().size() +
+             " appropriate instances\n");
+        
+        if ((appData.getResult().getNewlyCreatedTasks().size() > 0) ||
+            (appData.getResult().getNewlyCreatedTaskInstances().size() > 0))
+        {
             appData.getResult().setRuleApplicationStatus(RuleApplicationStatus.FINISHED);
         }
@@ -164,38 +142,133 @@
         appData.getStopWatch().start("detecting iterations");
         
-        List<ISequence> sessions = appData.getSessions();
-        int foundIterations = 0;
-        
-        for (ISequence session : sessions) {
-            foundIterations += detectAndReplaceIterations(session, appData);
-        }
+        List<IUserSession> sessions = appData.getSessions();
+        int iteratedTasks = 0;
+        
+        ITask iteratedTask = null;
+        
+        do {
+            iteratedTask = searchIteratedTask(sessions);
+            
+            if (iteratedTask != null) {
+                replaceIterationsOf(iteratedTask, sessions, appData);
+                iteratedTasks++;
+            }
+        }
+        while (iteratedTask != null);
         
         appData.getStopWatch().stop("detecting iterations");
-        System.out.println(" --> found " + foundIterations);
-    }
-
-    /**
-     * @param appData
-     */
-    private int detectAndReplaceIterations(ISequence           session,
-                                           RuleApplicationData appData)
+        System.out.println(" --> found " + iteratedTasks + " iterated tasks");
+    }
+
+    /**
+     *
+     */
+    private ITask searchIteratedTask(List<IUserSession> sessions) {
+        for (IUserSession session : sessions) {
+            for (int i = 0; i < (session.size() - 1); i++) {
+                if (taskComparator.equals(session.get(i).getTask(), session.get(i + 1).getTask())) {
+                    return session.get(i).getTask();
+                }
+            }
+        }
+        
+        return null;
+    }
+
+    /**
+     *
+     */
+    private void replaceIterationsOf(ITask               iteratedTask,
+                                     List<IUserSession>  sessions,
+                                     RuleApplicationData appData)
     {
-        int count = 0;
-        
-        TemporalRelationshipRule rule = new SimpleIterationDetectionRule
-            (nodeComparator, taskTreeNodeFactory, taskTreeBuilder);
-
-        RuleApplicationResult result = rule.apply(session, true);
-            
-        if ((result != null) && (result.getNewlyCreatedParentNodes() != null)) {
-            for (ITaskTreeNode newParent : result.getNewlyCreatedParentNodes()) {
-                appData.getResult().addNewlyCreatedParentNode(newParent);
-                if (newParent instanceof IIteration) {
-                    count++;
-                }
-            }
-        }
-        
-        return count;
+        IIteration iteration = taskFactory.createNewIteration();
+        ITaskInstance iterationInstance = null;
+        
+        List<ITaskInstance> iterationInstances = new LinkedList<ITaskInstance>();
+        
+        for (IUserSession session : sessions) {
+            int index = 0;
+            while (index < session.size()) {
+                if (taskComparator.equals(iteratedTask, session.get(index).getTask())) {
+                    if (iterationInstance == null) {
+                        iterationInstance = taskFactory.createNewTaskInstance(iteration);
+                        iterationInstances.add(iterationInstance);
+                        taskBuilder.addTaskInstance(session, index, iterationInstance);
+                        index++;
+                    }
+                    
+                    taskBuilder.addChild(iterationInstance, session.get(index));
+                    taskBuilder.removeTaskInstance(session, index);
+                }
+                else {
+                    if (iterationInstance != null) {
+                        iterationInstance = null;
+                    }
+                    index++;
+                }
+            }
+        }
+        
+        harmonizeIterationInstancesModel(iteration, iterationInstances);
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param iteratedTaskVariants
+     */
+    private void harmonizeIterationInstancesModel(IIteration          iteration,
+                                                  List<ITaskInstance> iterationInstances)
+    {
+        List<ITask> iteratedTaskVariants = new LinkedList<ITask>();
+        
+        // merge the lexically different variants of iterated task to a unique list 
+        for (ITaskInstance iterationInstance : iterationInstances) {
+            for (ITaskInstance executionVariant : iterationInstance) {
+                ITask candidate = executionVariant.getTask();
+            
+                boolean found = false;
+                for (ITask taskVariant : iteratedTaskVariants) {
+                    if (taskComparator.areLexicallyEqual(taskVariant, candidate)) {
+                        taskBuilder.setTask(executionVariant, taskVariant);
+                        found = true;
+                        break;
+                    }
+                }
+                
+                if (!found) {
+                    iteratedTaskVariants.add(candidate);
+                }
+            }
+        }
+        
+        // if there are more than one lexically different variant of iterated tasks, adapt the
+        // iteration model to be a selection of different variants. In this case also adapt
+        // the generated iteration instances to correctly contain selection instances. If there
+        // is only one variant of an iterated task, simply set this as the marked task of the
+        // iteration. In this case, the instances can be preserved as is
+        if (iteratedTaskVariants.size() > 1) {
+            ISelection selection = taskFactory.createNewSelection();
+            
+            for (ITask variant : iteratedTaskVariants) {
+                taskBuilder.addChild(selection, variant);
+            }
+            
+            taskBuilder.setMarkedTask(iteration, selection);
+            
+            for (ITaskInstance instance : iterationInstances) {
+                for (int i = 0; i < instance.size(); i++) {
+                    ITaskInstance selectionInstance = taskFactory.createNewTaskInstance(selection);
+                    taskBuilder.addChild(selectionInstance, instance.get(i));
+                    taskBuilder.setTaskInstance(instance, i, selectionInstance);
+                }
+            }
+        }
+        else {
+            taskBuilder.setMarkedTask(iteration, iteratedTaskVariants.get(0));
+        }
     }
 
@@ -226,5 +299,5 @@
         Tasks tasks;
         boolean createNewTrie = (appData.getLastTrie() == null) ||
-            appData.getReplacementCounter() > 0; // tree has changed
+            appData.detectedAndReplacedTasks(); // tree has changed
         
         do {
@@ -240,5 +313,5 @@
             createNewTrie = false;
             
-            for (List<ITaskTreeNode> task : tasks) {
+            for (List<ITaskInstance> task : tasks) {
                 if (task.size() >= appData.getTrainedSequenceLength()) {
                     // Trie must be recreated with a longer sequence length to be sure that
@@ -267,9 +340,9 @@
 
         appData.getStopWatch().start("training trie");
-        appData.setLastTrie(new Trie<ITaskTreeNode>(nodeComparator));
+        appData.setLastTrie(new Trie<ITaskInstance>(taskComparator));
     
-        List<ISequence> sessions = appData.getSessions();
-        
-        for (ISequence session : sessions) {
+        List<IUserSession> sessions = appData.getSessions();
+        
+        for (IUserSession session : sessions) {
             trainTrie(session, appData);
         }
@@ -282,6 +355,6 @@
      * @param parent
      */
-    private void trainTrie(ISequence session, RuleApplicationData appData) {
-        List<ITaskTreeNode> children = session.getChildren();
+    private void trainTrie(IUserSession session, RuleApplicationData appData) {
+        List<ITaskInstance> children = session.getExecutedTasks();
         
         if ((children != null) && (children.size() > 0)) {
@@ -294,35 +367,25 @@
      */
     private void replaceSequencesOccurringMostOften(RuleApplicationData appData) {
-        appData.resetReplacementCounter();
+        appData.detectedAndReplacedTasks(false);
 
         if ((appData.getLastFoundTasks().size() > 0) &&
             (appData.getLastFoundTasks().getOccurrenceCount() > 1))
         {
-            System.out.println("replacing tasks occurrences with merged variants of all versions");
-
-            for (List<ITaskTreeNode> task : appData.getLastFoundTasks()) {
-                String taskId = "task " + RuleUtils.getNewId();
-                System.out.println("replacing " + taskId + ": " + task);
-
-                appData.clearTaskOccurrences();
-                determineVariantsOfTaskOccurrences(task, appData.getSessions(), appData);
-                
-                appData.getStopWatch().start("merging task nodes");
-                ITaskTreeNode taskReplacement = mergeVariantsOfTaskOccurrence(taskId, appData);
-                appData.getStopWatch().stop("merging task nodes");
-
-                appData.resetReplacementCounter();
-                replaceTaskOccurrences(task, taskReplacement, appData.getSessions(), appData);
-
-                if (appData.getReplacementCounter() > 0) {
-                    appData.getResult().addNewlyCreatedParentNode(taskReplacement);
-                }
-
-                if (appData.getReplacementCounter() <
-                    appData.getLastFoundTasks().getOccurrenceCount())
-                {
-                    System.out.println(taskId + ": replaced task only " +
-                                       appData.getReplacementCounter() +
-                                       " times instead of expected " +
+            System.out.println("replacing tasks occurrences");
+
+            for (List<ITaskInstance> task : appData.getLastFoundTasks()) {
+                ISequence sequence = taskFactory.createNewSequence();
+                
+                System.out.println("replacing " + sequence.getId() + ": " + task);
+
+                List<ITaskInstance> sequenceInstances =
+                    replaceTaskOccurrences(task, appData.getSessions(), sequence);
+                
+                harmonizeSequenceInstancesModel(sequence, sequenceInstances,task.size());
+                appData.detectedAndReplacedTasks(sequenceInstances.size() > 0);
+
+                if (sequenceInstances.size() < appData.getLastFoundTasks().getOccurrenceCount()) {
+                    System.out.println(sequence.getId() + ": replaced task only " +
+                                       sequenceInstances.size() + " times instead of expected " +
                                        appData.getLastFoundTasks().getOccurrenceCount());
                 }
@@ -333,118 +396,90 @@
 
     /**
-     * @param tree
-     */
-    private void determineVariantsOfTaskOccurrences(List<ITaskTreeNode> task,
-                                                    List<ISequence>     sessions,
-                                                    RuleApplicationData appData)
+     *
+     */
+    private void harmonizeSequenceInstancesModel(ISequence           sequence,
+                                                 List<ITaskInstance> sequenceInstances,
+                                                 int                 sequenceLength)
     {
-        for (ISequence session : sessions) {
-            int index = -1;
-                
-            List<ITaskTreeNode> children = session.getChildren();
-
-            do {
-                index = getSubListIndex(children, task, ++index);
-
-                if (index > -1) {
-                    ISequence taskOccurrence = RuleUtils.getSubSequenceInRange
-                            (session, index, index + task.size() - 1, null,
-                             taskTreeNodeFactory, taskTreeBuilder);
-
-                    appData.addTaskOccurrence(taskOccurrence);
-
-                    // let the index point to the last element the belongs the identified occurrence
-                    index += task.size() - 1;
-                }
-            }
-            while (index > -1);
-        }
-    }
-
-    /**
-     * @param appData
-     * @return
-     */
-    private ITaskTreeNode mergeVariantsOfTaskOccurrence(String              taskId,
-                                                        RuleApplicationData appData)
-    {
-        return mergeVariantsOfTasks(taskId, appData.getTaskOccurrences());
-    }
-
-    /**
-     * @param appData
-     * @return
-     */
-    private ITaskTreeNode mergeVariantsOfTasks(String description, List<ITaskTreeNode> variants) {
-        // merge but preserve lexically distinct variants
-        TaskTreeNodeMerger merger = new TaskTreeNodeMerger
-            (taskTreeNodeFactory, taskTreeBuilder, nodeComparator);
-        
-        merger.mergeTaskNodes(variants);
-        
-        if (variants.size() == 1) {
-            ITaskTreeNode replacement = variants.get(0);
-            taskTreeBuilder.setDescription(replacement, description);
-            return replacement;
-        }
-        else {
-            ISelection selection = taskTreeNodeFactory.createNewSelection();
-            taskTreeBuilder.setDescription(selection, "variants of task " + description);
-            
-            for (ITaskTreeNode variant : variants) {
-                taskTreeBuilder.addChild(selection, variant);
-            }
-            
-            return selection;
-        }
-    }
-
-    /**
-     * @param task
-     * @param parent
-     * @param treeBuilder
-     * @param nodeFactory
-     * @param result
-     */
-    private void replaceTaskOccurrences(List<ITaskTreeNode> task,
-                                        ITaskTreeNode       replacement,
-                                        List<ISequence>     sessions,
-                                        RuleApplicationData appData)
-    {
-        // now check the children themselves for an occurrence of the task
-        for (int i = 0; i < sessions.size(); i++) {
-            ISequence session = sessions.get(i);
-            
-            int index = -1;
-        
-            List<ITaskTreeNode> children = session.getChildren();
-
-            do {
-                index = getSubListIndex(children, task, ++index);
-
-                if (index > -1) {
-                    if ((!(replacement instanceof ISequence)) ||
-                        (task.size() < children.size()))
-                    {
-                        for (int j = index; j < index + task.size(); j++) {
-                            taskTreeBuilder.removeChild(session, index);
-                        }
-
-                        taskTreeBuilder.addChild(session, index, replacement);
-                        appData.incrementReplacementCounter();
-
-                        children = session.getChildren();
-                    }
-                    else {
-                        // the whole list of children is an occurrence of this task. So ask the
-                        // caller of the method to replace the whole node
-                        sessions.set(i, (ISequence) replacement);
-                        appData.incrementReplacementCounter();
+        
+        // ensure for each subtask that lexically different variants are preserved
+        for (int subTaskIndex = 0; subTaskIndex < sequenceLength; subTaskIndex++) {
+            List<ITask> subTaskVariants = new LinkedList<ITask>();
+            
+            for (ITaskInstance sequenceInstance : sequenceInstances) {
+                ITask candidate = sequenceInstance.get(subTaskIndex).getTask();
+                
+                boolean found = false;
+                
+                for (int i = 0; i < subTaskVariants.size(); i++) {
+                    if (taskComparator.areLexicallyEqual(subTaskVariants.get(i), candidate)) {
+                        taskBuilder.setTask
+                            (sequenceInstance.get(subTaskIndex), subTaskVariants.get(i));
+                        
+                        found = true;
                         break;
                     }
                 }
+                
+                if (!found) {
+                    subTaskVariants.add(candidate);
+                }
+            }
+            
+            // if there are more than one lexically different variant of the sub task at
+            // the considered position, adapt the sequence model at that position to have
+            // a selection of the different variants. In this case also adapt the
+            // generated sequence instances to correctly contain selection instances. If
+            // there is only one variant of sub tasks at the given position, simply set
+            // this variant as the sub task of the selection. In this case, the instances
+            // can be preserved as is
+            if (subTaskVariants.size() > 1) {
+                ISelection selection = taskFactory.createNewSelection();
+                
+                for (ITask variant : subTaskVariants) {
+                    taskBuilder.addChild(selection, variant);
+                }
+                
+                taskBuilder.addChild(sequence, selection);
+                
+                for (ITaskInstance instance : sequenceInstances) {
+                    ITaskInstance selectionInstance =
+                        taskFactory.createNewTaskInstance(selection);
+                    taskBuilder.addChild(selectionInstance, instance.get(subTaskIndex));
+                    taskBuilder.setTaskInstance(instance, subTaskIndex, selectionInstance);
+                }
+            }
+            else if (subTaskVariants.size() == 1) {
+                taskBuilder.addChild(sequence, subTaskVariants.get(0));
+            }
+        }
+    }
+
+    /**
+     * @param tree
+     */
+    private List<ITaskInstance> replaceTaskOccurrences(List<ITaskInstance> task,
+                                                       List<IUserSession>  sessions,
+                                                       ISequence           temporalTaskModel)
+    {
+        List<ITaskInstance> sequenceInstances = new LinkedList<ITaskInstance>();
+        
+        for (IUserSession session : sessions) {
+            int index = -1;
+                
+            do {
+                index = getSubListIndex(session, task, ++index);
+
+                if (index > -1) {
+                    sequenceInstances.add
+                        (RuleUtils.createNewSubSequenceInRange
+                             (session, index, index + task.size() - 1, temporalTaskModel,
+                              taskFactory, taskBuilder));
+                }
             }
             while (index > -1);
         }
+        
+        return sequenceInstances;
     }
 
@@ -454,6 +489,6 @@
      * @return
      */
-    private int getSubListIndex(List<ITaskTreeNode> list,
-                                List<ITaskTreeNode> subList,
+    private int getSubListIndex(ITaskInstanceList   list,
+                                List<ITaskInstance> subList,
                                 int                 startIndex)
     {
@@ -465,5 +500,5 @@
             
             for (int j = 0; j < subList.size(); j++) {
-                if (!nodeComparator.equals(list.get(i + j), subList.get(j))) {
+                if (!taskComparator.equals(list.get(i + j), subList.get(j))) {
                     matchFound = false;
                     break;
@@ -479,9 +514,40 @@
         return result;
     }
+
+    /**
+     * @param trie
+     * @param object
+     * @return
+     */
+    private int getSubListIndex(List<ITaskInstance> list,
+                                List<ITaskInstance> subList,
+                                int                 startIndex)
+    {
+        boolean matchFound;
+        int result = -1;
+        
+        for (int i = startIndex; i <= list.size() - subList.size(); i++) {
+            matchFound = true;
+            
+            for (int j = 0; j < subList.size(); j++) {
+                if (!taskComparator.equals(list.get(i + j), subList.get(j))) {
+                    matchFound = false;
+                    break;
+                }
+            }
+            
+            if (matchFound) {
+                result = i;
+                break;
+            }
+        }
+        
+        return result;
+    }
     
     /**
      * @author Patrick Harms
      */
-    private class MaxCountAndLongestTasksFinder implements TrieProcessor<ITaskTreeNode> {
+    private class MaxCountAndLongestTasksFinder implements TrieProcessor<ITaskInstance> {
         
         /**
@@ -493,5 +559,5 @@
          * 
          */
-        private List<List<ITaskTreeNode>> foundTasks = new LinkedList<List<ITaskTreeNode>>();
+        private List<List<ITaskInstance>> foundTasks = new LinkedList<List<ITaskInstance>>();
 
         /**
@@ -507,7 +573,7 @@
          */
         @Override
-        public TrieProcessor.Result process(List<ITaskTreeNode> task, int count) {
-            if (task.size() < 2) {
-                // ignore single nodes
+        public TrieProcessor.Result process(List<ITaskInstance> foundTask, int count) {
+            if (foundTask.size() < 2) {
+                // ignore single tasks
                 return TrieProcessor.Result.CONTINUE;
             }
@@ -519,5 +585,5 @@
 
             if (this.currentCount > count) {
-                // ignore this children of this node, as they may have only smaller counts than
+                // ignore this children of this task, as they may have only smaller counts than
                 // the already found tasks
                 return TrieProcessor.Result.SKIP_NODE;
@@ -536,7 +602,7 @@
                 boolean added = false;
                 for (int i = 0; i < foundTasks.size(); i++) {
-                    if (foundTasks.get(i).size() < task.size()) {
+                    if (foundTasks.get(i).size() < foundTask.size()) {
                         // defensive copy
-                        foundTasks.add(i, new LinkedList<ITaskTreeNode>(task)); // defensive copy
+                        foundTasks.add(i, new LinkedList<ITaskInstance>(foundTask)); // defensive copy
                         added = true;
                         break;
@@ -545,5 +611,5 @@
                 
                 if (!added) {
-                    foundTasks.add(new LinkedList<ITaskTreeNode>(task)); // defensive copy
+                    foundTasks.add(new LinkedList<ITaskInstance>(foundTask)); // defensive copy
                 }
             }
@@ -571,6 +637,6 @@
                         // found a task that is a potential subtask. Check for this and remove the
                         // subtask if needed
-                        List<ITaskTreeNode> longTask = foundTasks.get(i);
-                        List<ITaskTreeNode> shortTask = foundTasks.get(j);
+                        List<ITaskInstance> longTask = foundTasks.get(i);
+                        List<ITaskInstance> shortTask = foundTasks.get(j);
                         
                         if (getSubListIndex(longTask, shortTask, 0) > -1) {
@@ -598,10 +664,10 @@
          * 
          */
-        private List<ISequence> sessions;
-        
-        /**
-         * 
-         */
-        private Trie<ITaskTreeNode> lastTrie;
+        private List<IUserSession> sessions;
+        
+        /**
+         * 
+         */
+        private Trie<ITaskInstance> lastTrie;
         
         /**
@@ -618,10 +684,5 @@
          * 
          */
-        private List<ITaskTreeNode> taskOccurrences = new LinkedList<ITaskTreeNode>();
-        
-        /**
-         * 
-         */
-        private int replacementCounter;
+        private boolean detectedAndReplacedTasks;
         
         /**
@@ -638,5 +699,5 @@
          * 
          */
-        private RuleApplicationData(List<ISequence> sessions) {
+        private RuleApplicationData(List<IUserSession> sessions) {
             this.sessions = sessions;
         }
@@ -645,5 +706,5 @@
          * @return the tree
          */
-        private List<ISequence> getSessions() {
+        private List<IUserSession> getSessions() {
             return sessions;
         }
@@ -652,5 +713,5 @@
          * @param lastTrie the lastTrie to set
          */
-        private void setLastTrie(Trie<ITaskTreeNode> lastTrie) {
+        private void setLastTrie(Trie<ITaskInstance> lastTrie) {
             this.lastTrie = lastTrie;
         }
@@ -659,5 +720,5 @@
          * @return the lastTrie
          */
-        private Trie<ITaskTreeNode> getLastTrie() {
+        private Trie<ITaskInstance> getLastTrie() {
             return lastTrie;
         }
@@ -692,29 +753,8 @@
 
         /**
-         * @return the taskOccurrences
-         */
-        private void clearTaskOccurrences() {
-            taskOccurrences.clear();
-        }
-
-        /**
-         * @return the taskOccurrences
-         */
-        private void addTaskOccurrence(ITaskTreeNode taskOccurrence) {
-            taskOccurrences.add(taskOccurrence);
-        }
-
-        /**
-         * @return the taskOccurrences
-         */
-        private List<ITaskTreeNode> getTaskOccurrences() {
-            return taskOccurrences;
-        }
-
-        /**
          *
          */
-        private void resetReplacementCounter() {
-            replacementCounter = 0;
+        private void detectedAndReplacedTasks(boolean detectedAndReplacedTasks) {
+            this.detectedAndReplacedTasks = detectedAndReplacedTasks;
         }
 
@@ -722,13 +762,6 @@
          *
          */
-        private void incrementReplacementCounter() {
-            replacementCounter++;
-        }
-
-        /**
-         *
-         */
-        private int getReplacementCounter() {
-            return replacementCounter;
+        private boolean detectedAndReplacedTasks() {
+            return detectedAndReplacedTasks;
         }
         
@@ -753,5 +786,5 @@
      * @author Patrick Harms
      */
-    private static class Tasks implements Iterable<List<ITaskTreeNode>> {
+    private static class Tasks implements Iterable<List<ITaskInstance>> {
         
         /**
@@ -763,5 +796,5 @@
          * 
          */
-        private List<List<ITaskTreeNode>> sequences;
+        private List<List<ITaskInstance>> sequences;
 
         /**
@@ -769,5 +802,5 @@
          * @param sequences
          */
-        private Tasks(int occurrenceCount, List<List<ITaskTreeNode>> sequences) {
+        private Tasks(int occurrenceCount, List<List<ITaskInstance>> sequences) {
             super();
             this.occurrenceCount = occurrenceCount;
@@ -797,5 +830,5 @@
          */
         @Override
-        public Iterator<List<ITaskTreeNode>> iterator() {
+        public Iterator<List<ITaskInstance>> iterator() {
             return this.sequences.iterator();
         }
@@ -803,3 +836,241 @@
     }
 
+    /**
+     *
+     */
+    private class TaskComparator implements SymbolComparator<ITaskInstance> {
+
+        /** */
+        private Comparer comparer;
+
+        /** */
+        private Comparer lexicalComparer;
+
+        /** */
+        private HashMap<Long, Boolean> equalityBuffer = new HashMap<Long, Boolean>();
+
+        /** */
+        private HashMap<Long, Boolean> lexicalEqualityBuffer;
+
+        /**
+         *
+         */
+        public TaskComparator(TaskEqualityRuleManager taskEqualityRuleManager,
+                              TaskEquality            minimalNodeEquality)
+        {
+            super();
+            
+            if (minimalNodeEquality == TaskEquality.LEXICALLY_EQUAL) {
+                comparer = new LexicalComparer(taskEqualityRuleManager);
+            }
+            else if (minimalNodeEquality == TaskEquality.SYNTACTICALLY_EQUAL) {
+                comparer = new SyntacticalComparer(taskEqualityRuleManager);
+            }
+            else if (minimalNodeEquality == TaskEquality.SEMANTICALLY_EQUAL) {
+                comparer = new SemanticalComparer(taskEqualityRuleManager);
+            }
+            else {
+                comparer = new DefaultComparer(taskEqualityRuleManager, minimalNodeEquality);
+            }
+            
+            if (minimalNodeEquality == TaskEquality.LEXICALLY_EQUAL) {
+                lexicalComparer = comparer;
+                lexicalEqualityBuffer = equalityBuffer;
+            }
+            else {
+                lexicalComparer = new LexicalComparer(taskEqualityRuleManager);
+                lexicalEqualityBuffer = new HashMap<Long, Boolean>();
+            }
+        }
+
+        /* (non-Javadoc)
+         * @see de.ugoe.cs.autoquest.tasktrees.temporalrelation.SymbolComparator#equals(java.lang.Object, java.lang.Object)
+         */
+        @Override
+        public boolean equals(ITaskInstance taskInstance1, ITaskInstance taskInstance2) {
+            return equals(taskInstance1.getTask(), taskInstance2.getTask());
+        }        
+
+        /**
+         * 
+         */
+        public boolean equals(ITask task1, ITask task2) {
+            Boolean result;
+            
+            if (task1 != task2) {
+                if ((task1 instanceof IEventTask) && (task2 instanceof IEventTask)) {
+                    long key = ((long) System.identityHashCode(task1)) << 32;
+                    key += System.identityHashCode(task2);
+                
+                    result = equalityBuffer.get(key);
+                
+                    if (result == null) {
+                        result = comparer.compare(task1, task2);
+                        equalityBuffer.put(key, result);
+                    }
+                }
+                else {
+                    result = false;
+                }
+            }
+            else {
+                result = true;
+            }
+            
+            return result;
+        }
+
+        /**
+         *
+         */
+        public boolean areLexicallyEqual(ITask task1, ITask task2) {
+            Boolean result;
+            
+            if (task1 != task2) {
+                long key = ((long) System.identityHashCode(task1)) << 32;
+                key += System.identityHashCode(task2);
+                
+                result = lexicalEqualityBuffer.get(key);
+                
+                if (result == null) {
+                    result = lexicalComparer.compare(task1, task2);
+                    lexicalEqualityBuffer.put(key, result);
+                }
+            }
+            else {
+                result = true;
+            }
+            
+            return result;
+        }
+    }
+
+    /**
+     * 
+     */
+    private interface Comparer {
+        
+        /**
+         * 
+         */
+        boolean compare(ITask task1, ITask task2);
+    }
+
+    /**
+     * 
+     */
+    private class LexicalComparer implements Comparer {
+        
+        /**
+         * <p>
+         * the task equality manager needed for comparing tasks with each other
+         * </p>
+         */
+        private TaskEqualityRuleManager taskEqualityRuleManager;
+        
+        /**
+         *
+         */
+        public LexicalComparer(TaskEqualityRuleManager taskEqualityRuleManager) {
+           this.taskEqualityRuleManager = taskEqualityRuleManager;
+        }
+        
+        /**
+         * 
+         */
+        public boolean compare(ITask task1, ITask task2) {
+            return taskEqualityRuleManager.areLexicallyEqual(task1, task2);
+        }
+    }
+
+    /**
+     * 
+     */
+    private class SyntacticalComparer implements Comparer {
+        
+        /**
+         * <p>
+         * the task equality manager needed for comparing tasks with each other
+         * </p>
+         */
+        private TaskEqualityRuleManager taskEqualityRuleManager;
+        
+        /**
+         *
+         */
+        public SyntacticalComparer(TaskEqualityRuleManager taskEqualityRuleManager) {
+           this.taskEqualityRuleManager = taskEqualityRuleManager;
+        }
+        
+        /**
+         * 
+         */
+        public boolean compare(ITask task1, ITask task2) {
+            return taskEqualityRuleManager.areSyntacticallyEqual(task1, task2);
+        }
+    }
+
+    /**
+     * 
+     */
+    private class SemanticalComparer implements Comparer {
+        
+        /**
+         * <p>
+         * the task equality manager needed for comparing tasks with each other
+         * </p>
+         */
+        private TaskEqualityRuleManager taskEqualityRuleManager;
+        
+        /**
+         *
+         */
+        public SemanticalComparer(TaskEqualityRuleManager taskEqualityRuleManager) {
+           this.taskEqualityRuleManager = taskEqualityRuleManager;
+        }
+        
+        /**
+         * 
+         */
+        public boolean compare(ITask task1, ITask task2) {
+            return taskEqualityRuleManager.areSemanticallyEqual(task1, task2);
+        }
+    }
+
+    /**
+     * 
+     */
+    private class DefaultComparer implements Comparer {
+        
+        /**
+         * <p>
+         * the task equality manager needed for comparing tasks with each other
+         * </p>
+         */
+        private TaskEqualityRuleManager taskEqualityRuleManager;
+
+        /**
+         * <p>
+         * the minimal task equality two identified sublists need to have to consider them as equal
+         * </p>
+         */
+        private TaskEquality minimalNodeEquality;
+        
+        /**
+         *
+         */
+        public DefaultComparer(TaskEqualityRuleManager taskEqualityRuleManager,
+                               TaskEquality            minimalNodeEquality)
+        {
+           this.taskEqualityRuleManager = taskEqualityRuleManager;
+           this.minimalNodeEquality = minimalNodeEquality;
+        }
+        
+        /**
+         * 
+         */
+        public boolean compare(ITask task1, ITask task2) {
+            return taskEqualityRuleManager.areAtLeastEqual(task1, task2, minimalNodeEquality);
+        }
+    }
 }
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceOnGuiElementDetectionRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceOnGuiElementDetectionRule.java	(revision 1133)
+++ 	(revision )
@@ -1,504 +1,0 @@
-//   Copyright 2012 Georg-August-Universität Göttingen, Germany
-//
-//   Licensed under the Apache License, Version 2.0 (the "License");
-//   you may not use this file except in compliance with the License.
-//   You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//   Unless required by applicable law or agreed to in writing, software
-//   distributed under the License is distributed on an "AS IS" BASIS,
-//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//   See the License for the specific language governing permissions and
-//   limitations under the License.
-
-package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
-
-/**
- * This rule structures the task tree based on GUI elements of the GUI model. The rule can
- * be provided with a filter for considered GUI elements. It generates sub sequences for any
- * GUI element in the hierarchy matching the filter so that each sequence represents all
- * interactions in a certain GUI element.
- * 
- * @version $Revision: $ $Date: 18.03.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-class SequenceOnGuiElementDetectionRule implements TemporalRelationshipRule {
-
-    /**
-     * <p>
-     * the task tree node factory to be used for creating substructures for the temporal
-     * relationships identified during rule
-     * </p>
-     */
-    private ITaskTreeNodeFactory taskTreeNodeFactory;
-    /**
-     * <p>
-     * the task tree builder to be used for creating substructures for the temporal relationships
-     * identified during rule application
-     * </p>
-     */
-    private ITaskTreeBuilder taskTreeBuilder;
-    
-    /**
-     * <p>
-     * the GUI element filter to be applied or null if none is specified.
-     * </p>
-     */
-    private List<Class<? extends IGUIElement>> guiElementFilter;
-
-    /**
-     * <p>
-     * instantiates the rule with a task tree node factory and builder to be used during rule
-     * application but without a GUI element filter
-     * </p>
-     * 
-     * @param taskTreeNodeFactory the task tree node factory to be used for creating substructures
-     *                            for the temporal relationships identified during rule
-     *                            application
-     * @param taskTreeBuilder     the task tree builder to be used for creating substructures for
-     *                            the temporal relationships identified during rule application
-     */
-    SequenceOnGuiElementDetectionRule(ITaskTreeNodeFactory taskTreeNodeFactory,
-                                      ITaskTreeBuilder     taskTreeBuilder)
-    {
-        this(null, taskTreeNodeFactory, taskTreeBuilder);
-    }
-    
-    /**
-     * <p>
-     * instantiates the rule with a GUI element filter. Only those types given in the filter will
-     * be considered during the rule application. For all other types, no subsequences will be
-     * created.
-     * </p>
-     *
-     * @param guiElementFilter    the GUI element filter to be applied
-     * @param taskTreeNodeFactory the task tree node factory to be used for creating substructures
-     *                            for the temporal relationships identified during rule
-     *                            application
-     * @param taskTreeBuilder     the task tree builder to be used for creating substructures for
-     *                            the temporal relationships identified during rule application
-     */
-    SequenceOnGuiElementDetectionRule(List<Class<? extends IGUIElement>> guiElementFilter,
-                                           ITaskTreeNodeFactory taskTreeNodeFactory,
-                                           ITaskTreeBuilder     taskTreeBuilder)
-    {
-        this.guiElementFilter = guiElementFilter;
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-    }
-
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return "SequenceOnGuiElementDetectionRule";
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode,
-     * boolean)
-     */
-    @Override
-    public RuleApplicationResult apply(ITaskTreeNode parent, boolean finalize) {
-        if (!(parent instanceof ISequence)) {
-            return null;
-        }
-
-        RuleApplicationResult result = new RuleApplicationResult();
-        List<List<IGUIElement>> hierarchies = new ArrayList<List<IGUIElement>>();
-        
-        // collect information about the GUI hierarchy
-        int maxHierarchyDepth = 0;
-        IGUIElement guiElement;
-        List<IGUIElement> guiElements = new ArrayList<IGUIElement>();
-        List<IGUIElement> hierarchy;
-        
-        for (ITaskTreeNode child : parent.getChildren()) {
-            guiElement = getGuiElement(child);
-            guiElements.add(guiElement);
-            hierarchy = getGuiElementHierarchy(guiElement);
-            hierarchies.add(hierarchy);
-            if (hierarchy != null) {
-                maxHierarchyDepth = Math.max(maxHierarchyDepth, hierarchy.size());
-            }
-        }
-        
-        IGUIElement commonDenominator = getCommonDenominator(guiElements);
-        hierarchy = getGuiElementHierarchy(commonDenominator);
-        int initialHierarchyLevel = hierarchy != null ? hierarchy.size() : 0;
-        
-        // now generate sub sequences for the different GUI elements. Start at the hierarchy
-        // level of the children of the common denominator to ensure, that different children are
-        // found. If this level is already the maximum hierarchy depth, we do not need to condense
-        // anything.
-        
-        RuleApplicationStatus status = null;
-        if (initialHierarchyLevel < maxHierarchyDepth) {
-            status = generateSubSequences
-                (parent, hierarchies, initialHierarchyLevel, finalize, result);
-        }
-        
-        if (status == null) {
-            status = RuleApplicationStatus.NOT_APPLIED;
-        }
-            
-        result.setRuleApplicationStatus(status);
-        
-        return result;
-    }
-
-    /**
-     * <p>
-     * generates subsequences for all groups of children of the provided parent, that operate
-     * in different GUI elements at the provided hierarchy level. It will not generate a sub
-     * sequence for the last elements, if the rule application shall not finalize.
-     * </p>
-     *
-     * @param parent            the parent node of which the children shall be grouped
-     * @param hierarchies       the GUI hierarchies for the children of the parent
-     * @param hierarchyLevel    the current hierarchy level to be considered
-     * @param maxHierarchyDepth the maximum hierarchy depth that may apply in this application
-     * @param finalize          true, if the application shall be finalized, false else
-     * @param result            the result of the rule application to add newly created parent
-     *                          nodes to
-     *                          
-     * @return RULE_APPLICATION_FINISHED, if at least one subsequence was generated,
-     *         RULE_APPLICATION_FEASIBLE, if the application shall not be finalized but some
-     *         children could be condensed if further data was available, and RULE_NOT_APPLIED,
-     *         if no subsequence was created and none is can be created, because no further
-     *         data is expected
-     */
-    private RuleApplicationStatus generateSubSequences(ITaskTreeNode           parent,
-                                                       List<List<IGUIElement>> hierarchies,
-                                                       int                     hierarchyLevel,
-                                                       boolean                 finalize,
-                                                       RuleApplicationResult   result)
-    {
-        IGUIElement currentParent = null;
-        List<IGUIElement> hierarchy;
-        int startingIndex = -1;
-        
-        RuleApplicationStatus status = RuleApplicationStatus.NOT_APPLIED;
-        boolean subsequenceHasStarted = false;
-        boolean exceedingGuiHierarchyDepth = false;
-        boolean nextGuiElementDiffers = false;
-       
-        currentParent = null;
-        startingIndex = -1;
-
-        int index = 0;
-        List<ITaskTreeNode> children = parent.getChildren();
-        
-        while (index < children.size()) {
-            hierarchy = hierarchies.get(index);
-
-            exceedingGuiHierarchyDepth =
-                hierarchy != null ? hierarchyLevel >= hierarchy.size() : true;
-            nextGuiElementDiffers =
-                subsequenceHasStarted &&
-                (exceedingGuiHierarchyDepth || !currentParent.equals(hierarchy.get(hierarchyLevel)));
-
-
-            if (!subsequenceHasStarted && !exceedingGuiHierarchyDepth) {
-                currentParent = hierarchy.get(hierarchyLevel);
-                startingIndex = index;
-                subsequenceHasStarted = true;
-            }
-            else if (nextGuiElementDiffers) {
-                status = condenseSequence
-                    (parent, hierarchies, hierarchyLevel, startingIndex, index - 1, result);
-                
-                // children may have changed, retrieve them again.
-                children = parent.getChildren();
-
-                if (status != null) {
-                    index = startingIndex + 1;
-                }
-                
-                if (!exceedingGuiHierarchyDepth) {
-                    currentParent = hierarchy.get(hierarchyLevel);
-                    startingIndex = index;
-                    subsequenceHasStarted = true;
-                }
-                else {
-                    currentParent = null;
-                    startingIndex = -1;
-                    subsequenceHasStarted = false;
-                }
-            }
-            
-            index++;
-        }
-
-        if (finalize) {
-            if (subsequenceHasStarted) {
-                status = condenseSequence
-                    (parent, hierarchies, hierarchyLevel, startingIndex,
-                     children.size() - 1, result);
-            }
-            else if (status != RuleApplicationStatus.FINISHED) {
-                status = RuleApplicationStatus.NOT_APPLIED;
-            }
-        }
-        else {
-            if ((currentParent != null) && (status != RuleApplicationStatus.FINISHED)) {
-                status = RuleApplicationStatus.FEASIBLE;
-            }
-        }
-
-        return status;
-    }
-
-    /**
-     * <p>
-     * condenses a specified group of children on the provided parent to a subsequences and
-     * calls {@link #generateSubSequences(ITaskTreeNode, List, int, boolean, ITaskTreeBuilder, ITaskTreeNodeFactory, RuleApplicationResult)}
-     * for the newly created subsequence. The method does not condense subgroups consisting of
-     * only one child which is already a sequence.
-     * </p>
-     *
-     * @param parent         the parent task of which children shall be condensed
-     * @param hierarchies    the GUI element hierarchies of the children of the parent
-     * @param hierarchyLevel the currently considered GUI element hierarchy level
-     * @param startIndex     the index of the first child belonging to the subgroup
-     * @param endIndex       the index of the last child belonging to the subgroup
-     * @param result         the result of the rule application to add newly created parent nodes to
-     * 
-     * @return RULE_APPLICATION_FINISHED, if at the subsequence was generated and RULE_NOT_APPLIED,
-     *         if no subsequence was created, because only one child belonged to the group which
-     *         was already a sequence
-     */
-    private RuleApplicationStatus condenseSequence(ITaskTreeNode           parent,
-                                                   List<List<IGUIElement>> hierarchies,
-                                                   int                     hierarchyLevel,
-                                                   int                     startIndex,
-                                                   int                     endIndex,
-                                                   RuleApplicationResult   result)
-    {
-        boolean onlyASingleChildToReduce = (endIndex - startIndex) == 0;
-        
-        List<ITaskTreeNode> children = parent.getChildren();
-        
-        boolean singleChildIsSequence = onlyASingleChildToReduce &&
-            children.get(startIndex) instanceof ISequence;
-
-        if (!onlyASingleChildToReduce || !singleChildIsSequence) {
-            ISequence sequence = taskTreeNodeFactory.createNewSequence();
-            
-            List<List<IGUIElement>> subHierarchies = new ArrayList<List<IGUIElement>>();
-            List<IGUIElement> newHierarchy =
-                hierarchies.get(startIndex).subList(0, hierarchyLevel + 1);
-            taskTreeBuilder.setDescription
-                (sequence, "interactions on " +
-                 newHierarchy.get(newHierarchy.size() - 1).getStringIdentifier());
-
-            for (int i = startIndex; i <= endIndex; i++) {
-                taskTreeBuilder.addChild(sequence, children.get(startIndex));
-                taskTreeBuilder.removeChild((ISequence) parent, startIndex);
-                
-                subHierarchies.add(hierarchies.remove(startIndex));
-            }
-
-            taskTreeBuilder.addChild((ISequence) parent, startIndex, sequence);
-            
-            hierarchies.add(startIndex, newHierarchy);
-            
-            generateSubSequences(sequence, subHierarchies, hierarchyLevel + 1, true, result);
-
-            result.addNewlyCreatedParentNode(sequence);
-
-            return RuleApplicationStatus.FINISHED;
-        }
-        else {
-            return null;
-        }
-
-    }
-
-    /**
-     * <p>
-     * return a common denominator for the provided list of GUI elements, i.e. a GUI element, that
-     * is part of the parent GUI hiearchy of all GUI elements in the list. If there is no common
-     * denominator, the method returns null.
-     * </p>
-     */
-    private IGUIElement getCommonDenominator(List<IGUIElement> guiElements) {
-        IGUIElement commonDenominator = null;
-        
-        if (guiElements.size() > 0) {
-            List<IGUIElement> commonDenominatorPath = new ArrayList<IGUIElement>();
-            
-            // create a reference list using the first GUI element
-            IGUIElement guiElement = guiElements.get(0);
-            while (guiElement != null) {
-                if (guiElementMatchesConsideredTypes(guiElement)) {
-                    commonDenominatorPath.add(0, guiElement);
-                }
-                guiElement = guiElement.getParent();
-            }
-            
-            if (commonDenominatorPath.size() == 0) {
-                return null;
-            }
-            
-            // for each other GUI element, check the reference list for the first element in the
-            // path, that is not common to the current one, and delete it as well as it subsequent
-            // siblings
-            List<IGUIElement> currentPath = new ArrayList<IGUIElement>();
-            for (int i = 1; i < guiElements.size(); i++) {
-                currentPath.clear();
-                guiElement = guiElements.get(i);
-                while (guiElement != null) {
-                    if (guiElementMatchesConsideredTypes(guiElement)) {
-                        currentPath.add(0, guiElement);
-                    }
-                    guiElement = guiElement.getParent();
-                }
-                
-                // determine the index of the first unequal path element
-                int index = 0;
-                while ((index < commonDenominatorPath.size()) && (index < currentPath.size()) &&
-                        commonDenominatorPath.get(index).equals(currentPath.get(index)))
-                {
-                    index++;
-                }
-                
-                // remove all elements from the common denonimator path, that do not match
-                while (index < commonDenominatorPath.size()) {
-                    commonDenominatorPath.remove(index);
-                }
-            }
-            
-            if (commonDenominatorPath.size() > 0) {
-                commonDenominator = commonDenominatorPath.get(commonDenominatorPath.size() - 1);
-            }
-        }
-        
-        return commonDenominator;
-    }
-
-    /**
-     * <p>
-     * returns the GUI element on which all interactions of the provided task takes place. If
-     * the task is a simple event task its target is returned. If the task is a parent task
-     * of several children, the common denominator of the GUI elements of all its children is
-     * returned. The method returns null, if there is no common GUI element for all events
-     * represented by the provided task.
-     * </p>
-     */
-    private IGUIElement getGuiElement(ITaskTreeNode node) {
-        if (node != null) {
-            List<IGUIElement> terminalGuiElements = new ArrayList<IGUIElement>();
-            getTerminalGuiElements(node, terminalGuiElements);
-            return getCommonDenominator(terminalGuiElements);
-        }
-        else {
-            return null;
-        }
-    }
-        
-    /**
-     * <p>
-     * recursive method calling itself to determine all terminal GUI elements of the provided
-     * task. The terminal GUI elements are stored in the provided list.
-     * </p>
-     */
-    private void getTerminalGuiElements(ITaskTreeNode node, List<IGUIElement> terminalGuiElements) {
-        if (node instanceof IEventTask) {
-            if (((IEventTask) node).getEventTarget() instanceof IGUIElement) {
-                IGUIElement terminalGuiElement = (IGUIElement) ((IEventTask) node).getEventTarget();
-                terminalGuiElement =
-                    searchHierarchyForGuiElementWithConsideredType(terminalGuiElement);
-                
-                if (terminalGuiElement != null) {
-                    terminalGuiElements.add(terminalGuiElement);
-                }
-            }
-        }
-        else {
-            for (ITaskTreeNode child : node.getChildren()) {
-                getTerminalGuiElements(child, terminalGuiElements);
-            }
-        }
-    }
-
-    /**
-     * <p>
-     * returns a list of GUI elements that represents the whole GUI element hierarchy of the
-     * provided GUI element. The method considers the GUI element filter applied by this rule.
-     * </p>
-     */
-    private List<IGUIElement> getGuiElementHierarchy(IGUIElement guiElement) {
-        IGUIElement element = guiElement;
-        
-        if (!guiElementMatchesConsideredTypes(element)) {
-            element = searchHierarchyForGuiElementWithConsideredType(element);
-        }
-        
-        List<IGUIElement> hierarchy = new ArrayList<IGUIElement>();
-        
-        while (element != null) {
-            hierarchy.add(0, element);
-            element = searchHierarchyForGuiElementWithConsideredType(element.getParent());
-        }
-        
-        if (hierarchy.size() > 0) {
-            return hierarchy;
-        }
-        else {
-            return null;
-        }
-    }
-
-    /**
-     * <p>
-     * returns for a given GUI element the next GUI element in the upper GUI element hierarchy
-     * that matches the GUI element filter of the rule. If the provided GUI element already
-     * matches the filter, it is returned directly.
-     * </p>
-     */
-    private IGUIElement searchHierarchyForGuiElementWithConsideredType(IGUIElement guiElement) {
-        IGUIElement returnValue = guiElement;
-        
-        while ((returnValue != null) && !guiElementMatchesConsideredTypes(returnValue)) {
-            returnValue = returnValue.getParent();
-        }
-        
-        return returnValue;
-    }
-
-    /**
-     * <p>
-     * checks if the provided GUI element matches the GUI element filter applied by the rule.
-     * </p>
-     */
-    private boolean guiElementMatchesConsideredTypes(IGUIElement guiElement) {
-        if (guiElementFilter == null) {
-            return true;
-        }
-        else {
-            for (Class<? extends IGUIElement> clazz : guiElementFilter) {
-                if (clazz.isInstance(guiElement)) {
-                    return true;
-                }
-            }
-            
-            return false;
-        }
-    }
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceOnSameTargetDetectionRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceOnSameTargetDetectionRule.java	(revision 1133)
+++ 	(revision )
@@ -1,204 +1,0 @@
-//   Copyright 2012 Georg-August-Universität Göttingen, Germany
-//
-//   Licensed under the Apache License, Version 2.0 (the "License");
-//   you may not use this file except in compliance with the License.
-//   You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//   Unless required by applicable law or agreed to in writing, software
-//   distributed under the License is distributed on an "AS IS" BASIS,
-//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//   See the License for the specific language governing permissions and
-//   limitations under the License.
-
-package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
-
-import java.util.List;
-
-import de.ugoe.cs.autoquest.eventcore.IEventTarget;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
-
-/**
- * This rule subdivides long sequences into subsequences of tasks on the same event target.
- * Event targets are compared using the equals method. A more complex GUI model is ignored.
- * 
- * @version $Revision: $ $Date: 18.03.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-class SequenceOnSameTargetDetectionRule implements TemporalRelationshipRule {
-
-    /**
-     * <p>
-     * the task tree node factory to be used for creating substructures for the temporal
-     * relationships identified during rule
-     * </p>
-     */
-    private ITaskTreeNodeFactory taskTreeNodeFactory;
-    /**
-     * <p>
-     * the task tree builder to be used for creating substructures for the temporal relationships
-     * identified during rule application
-     * </p>
-     */
-    private ITaskTreeBuilder taskTreeBuilder;
-    
-    /**
-     * <p>
-     * instantiates the rule with a task tree node factory and builder to be used during rule
-     * application.
-     * </p>
-     * 
-     * @param taskTreeNodeFactory the task tree node factory to be used for creating substructures
-     *                            for the temporal relationships identified during rule
-     *                            application
-     * @param taskTreeBuilder     the task tree builder to be used for creating substructures for
-     *                            the temporal relationships identified during rule application
-     */
-    SequenceOnSameTargetDetectionRule(ITaskTreeNodeFactory taskTreeNodeFactory,
-                                      ITaskTreeBuilder     taskTreeBuilder)
-    {
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-    }
-    
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return "SequenceOnSameTargetDetectionRule";
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode,
-     * boolean)
-     */
-    @Override
-    public RuleApplicationResult apply(ITaskTreeNode parent, boolean finalize) {
-        if (!(parent instanceof ISequence)) {
-            return null;
-        }
-
-        RuleApplicationResult result = new RuleApplicationResult();
-
-        IEventTarget currentEventTarget = null;
-        int startingIndex = -1;
-
-        int index = 0;
-        List<ITaskTreeNode> children = parent.getChildren();
-        
-        while (index < children.size()) {
-            ITaskTreeNode child = children.get(index);
-
-            IEventTarget eventTarget = determineEventTarget(child);
-
-            if (((eventTarget == null) && (currentEventTarget != null)) ||
-                ((eventTarget != null) && (!eventTarget.equals(currentEventTarget))))
-            {
-                if (startingIndex < 0) {
-                    startingIndex = index;
-                    currentEventTarget = eventTarget;
-                }
-                else {
-                    int endIndex = index - 1;
-                    
-                    // only reduce to a sequence, if it is not a sequence with only one child
-                    // or if this child is not a sequence itself
-                    if ((startingIndex != endIndex) ||
-                        (!(children.get(startingIndex) instanceof ISequence)))
-                    {
-                        handleEventTargetSequence
-                            (parent, currentEventTarget, startingIndex, endIndex, result);
-
-                        result.setRuleApplicationStatus(RuleApplicationStatus.FINISHED);
-                        return result;
-                    }
-                    else if (eventTarget != null) {
-                        // here a new sequence on a new target begins
-                        startingIndex = index;
-                        currentEventTarget = eventTarget;
-                    }
-                    else {
-                        startingIndex = -1;
-                        currentEventTarget = null;
-                    }
-                }
-            }
-
-            index++;
-        }
-
-        if (startingIndex > -1) {
-            int endIndex = children.size() - 1;
-            
-            if (finalize) {
-                // only reduce to a sequence, if it is not a sequence with only one child
-                // or if this child is not a sequence itself
-                if ((startingIndex > 0) &&
-                    ((startingIndex != endIndex) ||
-                     (!(children.get(startingIndex) instanceof ISequence))))
-                {
-                    handleEventTargetSequence
-                        (parent, currentEventTarget, startingIndex, endIndex, result);
-                
-                    result.setRuleApplicationStatus(RuleApplicationStatus.FINISHED);
-                }
-            }
-            else {
-                result.setRuleApplicationStatus(RuleApplicationStatus.FEASIBLE);
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     *
-     */
-    private IEventTarget determineEventTarget(ITaskTreeNode node) {
-        if (node instanceof IEventTask) {
-            return ((IEventTask) node).getEventTarget();
-        }
-        else {
-            IEventTarget commonTarget = null;
-            
-            for (ITaskTreeNode child : node.getChildren()) {
-                if (commonTarget == null) {
-                    commonTarget = determineEventTarget(child);
-                }
-                else {
-                    if (!commonTarget.equals(determineEventTarget(child))) {
-                        return null;
-                    }
-                }
-            }
-            
-            return commonTarget;
-        }
-    }
-
-    /**
-     *
-     */
-    private void handleEventTargetSequence(ITaskTreeNode         parent,
-                                           IEventTarget          target,
-                                           int                   startIndex,
-                                           int                   endIndex,
-                                           RuleApplicationResult result)
-    {
-        String description = "interactions on " + target.getStringIdentifier();
-        
-        ISequence sequence = RuleUtils.createNewSubSequenceInRange
-            (parent, startIndex, endIndex, description, taskTreeNodeFactory, taskTreeBuilder);
-
-        result.addNewlyCreatedParentNode(sequence);
-    }
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SimpleIterationDetectionRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SimpleIterationDetectionRule.java	(revision 1133)
+++ 	(revision )
@@ -1,222 +1,0 @@
-//   Copyright 2012 Georg-August-Universität Göttingen, Germany
-//
-//   Licensed under the Apache License, Version 2.0 (the "License");
-//   you may not use this file except in compliance with the License.
-//   You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//   Unless required by applicable law or agreed to in writing, software
-//   distributed under the License is distributed on an "AS IS" BASIS,
-//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//   See the License for the specific language governing permissions and
-//   limitations under the License.
-
-package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
-
-import java.util.LinkedList;
-import java.util.List;
-
-import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality;
-import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
-
-/**
- * <p>
- * TODO comment
- * </p>
- * 
- * @author Patrick Harms
- */
-class SimpleIterationDetectionRule implements TemporalRelationshipRule {
-
-    /**
-     * <p>
-     * the task tree node factory to be used for creating substructures for the temporal
-     * relationships identified during rule
-     * </p>
-     */
-    private ITaskTreeNodeFactory taskTreeNodeFactory;
-    /**
-     * <p>
-     * the task tree builder to be used for creating substructures for the temporal relationships
-     * identified during rule application
-     * </p>
-     */
-    private ITaskTreeBuilder taskTreeBuilder;
-
-    /**
-     * <p>
-     * the node comparator used for comparing task tree nodes with each other
-     * </p>
-     */
-    private TaskTreeNodeComparator nodeComparator;
-
-    /**
-     * <p>
-     * instantiates the rule and initializes it with a node equality rule manager and the minimal
-     * node equality identified sublist must have to consider them as iterated.
-     * </p>
-     */
-    SimpleIterationDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager,
-                                 NodeEquality            minimalNodeEquality,
-                                 ITaskTreeNodeFactory    taskTreeNodeFactory,
-                                 ITaskTreeBuilder        taskTreeBuilder)
-    {
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-        
-        this.nodeComparator =
-            new TaskTreeNodeComparator(nodeEqualityRuleManager, minimalNodeEquality);
-    }
-
-    /**
-     * <p>
-     * instantiates the rule and initializes it with a node equality rule manager and the minimal
-     * node equality identified sublist must have to consider them as iterated.
-     * </p>
-     */
-    SimpleIterationDetectionRule(TaskTreeNodeComparator nodeComparator,
-                                 ITaskTreeNodeFactory   taskTreeNodeFactory,
-                                 ITaskTreeBuilder       taskTreeBuilder)
-    {
-        this.nodeComparator = nodeComparator;
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-    }
-
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return "SimpleIterationDetectionRule";
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode,
-     * boolean)
-     */
-    @Override
-    public RuleApplicationResult apply(ITaskTreeNode parent, boolean finalize) {
-        if (!(parent instanceof ISequence)) {
-            return null;
-        }
-        
-        if (!finalize) {
-            // this rule can only finalize whole trees
-            return null;
-        }
-
-        RuleApplicationResult result = new RuleApplicationResult();
-
-        applyOn(parent, result);
-        
-        if (result.getNewlyCreatedParentNodes().size() > 0) {
-            result.setRuleApplicationStatus(RuleApplicationStatus.FINISHED);
-        }
-
-        return result;
-    }
-
-    /**
-     *
-     */
-    private void applyOn(ITaskTreeNode node, RuleApplicationResult result) {
-        int iterationStartIndex = -1;
-        ITaskTreeNode iteratedChild = null;
-
-        int index = 0;
-        List<ITaskTreeNode> children = node.getChildren();
-        
-        while (index < children.size()) {
-            ITaskTreeNode child = children.get(index);
-
-            if (iteratedChild == null) {
-                // new iteration may start
-                iterationStartIndex = index;
-                iteratedChild = child;
-            }
-            else {
-                if (!nodeComparator.equals(iteratedChild, child)) {
-                    // iteration finished
-                    handleIteration(node, iterationStartIndex, index - 1, result);
-                    
-                    // children may have changed
-                    children = node.getChildren();
-
-                    // new iteration may start
-                    index = iterationStartIndex + 1;
-                    iterationStartIndex = index;
-                    iteratedChild = child;
-                }
-            }
-            index++;
-        }
-        
-        if (iterationStartIndex > -1) {
-            handleIteration(node, iterationStartIndex, children.size() - 1, result);
-        }
-    }
-
-    /**
-     *
-     */
-    private void handleIteration(ITaskTreeNode         parent,
-                                 int                   startIndex,
-                                 int                   endIndex,
-                                 RuleApplicationResult result)
-    {
-        if (startIndex == endIndex) {
-            // only one child
-            return;
-        }
-        
-        IIteration iteration = taskTreeNodeFactory.createNewIteration();
-        result.addNewlyCreatedParentNode(iteration);
-
-        List<ITaskTreeNode> children = parent.getChildren();
-        
-        List<ITaskTreeNode> equalChildren = new LinkedList<ITaskTreeNode>();
-            
-        for (int i = endIndex - startIndex; i >= 0; i--) {
-             equalChildren.add(children.get(startIndex));
-             taskTreeBuilder.removeChild((ISequence) parent, startIndex);
-        }
-            
-        // merge the identified variants, but preserve the differences in form of selections
-        // by using lexical equality for merge comparisons
-        TaskTreeNodeMerger merger = new TaskTreeNodeMerger
-            (taskTreeNodeFactory, taskTreeBuilder, nodeComparator);
-
-        merger.mergeTaskNodes(equalChildren);
-
-        if (equalChildren.size() == 1) {
-            taskTreeBuilder.setChild(iteration, equalChildren.get(0));
-            taskTreeBuilder.setDescription(iteration, "several " + equalChildren.get(0));
-        }
-        else {
-            taskTreeBuilder.setDescription(iteration, "several " + equalChildren.get(0));
-
-            // create a selection of all variants
-            ISelection selection = taskTreeNodeFactory.createNewSelection();
-            result.addNewlyCreatedParentNode(selection);
-            taskTreeBuilder.setChild(iteration, selection);
-            taskTreeBuilder.setDescription(selection, "variants");
-
-            for (ITaskTreeNode variant : equalChildren) {
-                taskTreeBuilder.addChild(selection, variant);
-            }
-        }
-
-        taskTreeBuilder.addChild((ISequence) parent, startIndex, iteration);
-    }
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskTreeNodeComparator.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskTreeNodeComparator.java	(revision 1133)
+++ 	(revision )
@@ -1,246 +1,0 @@
-//   Copyright 2012 Georg-August-Universität Göttingen, Germany
-//
-//   Licensed under the Apache License, Version 2.0 (the "License");
-//   you may not use this file except in compliance with the License.
-//   You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//   Unless required by applicable law or agreed to in writing, software
-//   distributed under the License is distributed on an "AS IS" BASIS,
-//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//   See the License for the specific language governing permissions and
-//   limitations under the License.
-
-package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
-
-import java.util.HashMap;
-
-import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality;
-import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.usageprofiles.SymbolComparator;
-import de.ugoe.cs.util.StopWatch;
-
-/**
- * <p>
- * TODO comment
- * </p>
- * 
- * @author Patrick Harms
- */
-public class TaskTreeNodeComparator implements SymbolComparator<ITaskTreeNode> {
-    
-    /**
-     * <p>
-     * the node equality manager needed for comparing task tree nodes with each other
-     * </p>
-     */
-    private NodeEqualityRuleManager nodeEqualityRuleManager;
-
-    /**
-     * <p>
-     * the minimal node equality two identified sublists need to have to consider them as equal
-     * and to create an iteration for
-     * </p>
-     */
-    private NodeEquality minimalNodeEquality;
-
-    private Comparer comparer;
-
-    private Comparer lexicalComparer;
-
-    private StopWatch stopWatch = new StopWatch();
-    
-    private HashMap<Long, Boolean> equalityBuffer = new HashMap<Long, Boolean>();
-
-    private HashMap<Long, Boolean> lexicalEqualityBuffer;
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param nodeEqualityRuleManager
-     * @param minimalNodeEquality
-     */
-    public TaskTreeNodeComparator(NodeEqualityRuleManager nodeEqualityRuleManager,
-                                  NodeEquality            minimalNodeEquality)
-    {
-        super();
-        this.nodeEqualityRuleManager = nodeEqualityRuleManager;
-        this.minimalNodeEquality = minimalNodeEquality;
-        
-        if (minimalNodeEquality == NodeEquality.LEXICALLY_EQUAL) {
-            comparer = new LexicalComparer();
-        }
-        else if (minimalNodeEquality == NodeEquality.SYNTACTICALLY_EQUAL) {
-            comparer = new SyntacticalComparer();
-        }
-        else if (minimalNodeEquality == NodeEquality.SEMANTICALLY_EQUAL) {
-            comparer = new SemanticalComparer();
-        }
-        else {
-            comparer = new DefaultComparer();
-        }
-        
-        if (minimalNodeEquality == NodeEquality.LEXICALLY_EQUAL) {
-            lexicalComparer = comparer;
-            lexicalEqualityBuffer = equalityBuffer;
-        }
-        else {
-            lexicalComparer = new LexicalComparer();
-            lexicalEqualityBuffer = new HashMap<Long, Boolean>();
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see de.ugoe.cs.autoquest.tasktrees.temporalrelation.SymbolComparator#equals(java.lang.Object, java.lang.Object)
-     */
-    @Override
-    public boolean equals(ITaskTreeNode symbol1, ITaskTreeNode symbol2) {
-        //String id = "compare " + symbol1.getClass().getSimpleName() + " " +
-        //    symbol2.getClass().getSimpleName();
-        //String id = "compare";
-        //stopWatch.start(id);
-        
-        Boolean result;
-        
-        if (symbol1 != symbol2) {
-            long key = ((long) System.identityHashCode(symbol1)) << 32;
-            key += System.identityHashCode(symbol2);
-            
-            result = equalityBuffer.get(key);
-            
-            if (result == null) {
-                result = comparer.compare(symbol1, symbol2);
-                equalityBuffer.put(key, result);
-            }
-        }
-        else {
-            result = true;
-        }
-        //stopWatch.stop(id);
-        
-        /*boolean result2 = nodeEqualityRuleManager.areAtLeastEqual(symbol1, symbol2, minimalNodeEquality);
-        if (result != result2) {
-            throw new IllegalStateException("implementation error");
-        }*/
-        
-        return result;
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @return
-     */
-    StopWatch getStopWatch() {
-        return stopWatch;
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param node1
-     * @param node2
-     * @return
-     */
-    boolean areLexicallyEqual(ITaskTreeNode symbol1, ITaskTreeNode symbol2) {
-        Boolean result;
-        
-        if (symbol1 != symbol2) {
-            long key = ((long) System.identityHashCode(symbol1)) << 32;
-            key += System.identityHashCode(symbol2);
-            
-            result = lexicalEqualityBuffer.get(key);
-            
-            if (result == null) {
-                result = lexicalComparer.compare(symbol1, symbol2);
-                lexicalEqualityBuffer.put(key, result);
-            }
-        }
-        else {
-            result = true;
-        }
-        
-        return result;
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @return
-     */
-    NodeEquality getConsideredNodeEquality() {
-        return minimalNodeEquality;
-    }
-
-    /**
-     * 
-     */
-    private interface Comparer {
-        /**
-         * 
-         */
-        boolean compare(ITaskTreeNode node1, ITaskTreeNode node2);
-    }
-
-    /**
-     * 
-     */
-    private class LexicalComparer implements Comparer {
-        
-        /**
-         * 
-         */
-        public boolean compare(ITaskTreeNode node1, ITaskTreeNode node2) {
-            return nodeEqualityRuleManager.areLexicallyEqual(node1, node2);
-        }
-    }
-
-    /**
-     * 
-     */
-    private class SyntacticalComparer implements Comparer {
-        
-        /**
-         * 
-         */
-        public boolean compare(ITaskTreeNode node1, ITaskTreeNode node2) {
-            return nodeEqualityRuleManager.areSyntacticallyEqual(node1, node2);
-        }
-    }
-
-    /**
-     * 
-     */
-    private class SemanticalComparer implements Comparer {
-        
-        /**
-         * 
-         */
-        public boolean compare(ITaskTreeNode node1, ITaskTreeNode node2) {
-            return nodeEqualityRuleManager.areSemanticallyEqual(node1, node2);
-        }
-    }
-
-    /**
-     * 
-     */
-    private class DefaultComparer implements Comparer {
-        
-        /**
-         * 
-         */
-        public boolean compare(ITaskTreeNode node1, ITaskTreeNode node2) {
-            return nodeEqualityRuleManager.areAtLeastEqual(node1, node2, minimalNodeEquality);
-        }
-    }
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskTreeNodeMerger.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskTreeNodeMerger.java	(revision 1133)
+++ 	(revision )
@@ -1,590 +1,0 @@
-//   Copyright 2012 Georg-August-Universität Göttingen, Germany
-//
-//   Licensed under the Apache License, Version 2.0 (the "License");
-//   you may not use this file except in compliance with the License.
-//   You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//   Unless required by applicable law or agreed to in writing, software
-//   distributed under the License is distributed on an "AS IS" BASIS,
-//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//   See the License for the specific language governing permissions and
-//   limitations under the License.
-
-package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
-
-import java.util.List;
-
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
-import difflib.ChangeDelta;
-import difflib.Chunk;
-import difflib.DeleteDelta;
-import difflib.Delta;
-import difflib.InsertDelta;
-import difflib.Patch;
-import difflib.myers.DiffNode;
-import difflib.myers.MyersDiff;
-import difflib.myers.PathNode;
-import difflib.myers.Snake;
-
-/**
- * <p>
- * TODO comment
- * </p>
- * 
- * @author Patrick Harms
- */
-class TaskTreeNodeMerger {
-    
-    /** */
-    private ITaskTreeNodeFactory taskTreeNodeFactory;
-    
-    /** */
-    private ITaskTreeBuilder taskTreeBuilder;
-    
-    /** */
-    private TaskTreeNodeComparator nodeComparator;
-    
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param taskTreeNodeFactory     the node factory to be used if nodes must be instantiated
-     * @param taskTreeBuilder         the task tree builder to be used if nodes must be merged
-     * @param nodeEqualityRuleManager the node equality rule manager that may be needed for
-     *                                comparing nodes during merge
-     * @param consideredNodeEquality  the node equality considered when comparing nodes to
-     *                                identify them as equal
-     */
-    TaskTreeNodeMerger(ITaskTreeNodeFactory   taskTreeNodeFactory,
-                       ITaskTreeBuilder       taskTreeBuilder,
-                       TaskTreeNodeComparator nodeComparator)
-    {
-        super();
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-        this.nodeComparator = nodeComparator;
-    }
-
-    /**
-     * <p>
-     * this method merges task tree nodes in a list, if they can be merged. For this, it tries
-     * to merge every node with every other node in the provided list using the
-     * {@link #mergeTaskNodes(ITaskTreeNode, ITaskTreeNode)} method. If a merge is possible, it
-     * removes the merged nodes from the list and adds the merge result. 
-     * </p>
-     *
-     * @param nodes the list of nodes to be merged
-     */
-    void mergeTaskNodes(List<ITaskTreeNode> nodes) {
-        int index1 = 0;
-        int index2 = 0;
-        ITaskTreeNode variant1;
-        ITaskTreeNode variant2;
-        
-        while (index1 < nodes.size()) {
-            variant1 = nodes.get(index1);
-            index2 = index1 + 1;
-            
-            while (index2 < nodes.size()) {
-                variant2 = nodes.get(index2);
-                ITaskTreeNode mergedChild = mergeTaskNodes(variant1, variant2);
-                
-                if (mergedChild != null) {
-                    // if we merged something start from the beginning to perform the next merge
-                    nodes.remove(index2);
-                    nodes.remove(index1);
-                    nodes.add(index1, mergedChild);
-                    index1 = -1;
-                    break;
-                }
-                else {
-                    index2++;
-                }
-            }
-            
-            index1++;
-        }
-    }
-
-    /**
-     * <p>
-     * this method merges two tasks with each other if possible. If the tasks are lexically
-     * equal, the first of them is returned as merge result. If both tasks are of the same
-     * temporal relationship type, the appropriate merge method is called to merge them. If one
-     * of the nodes is a selection, the other one is added as a variant of this selection.
-     * (However, if both nodes are selections, they are merged using the appropriate merge method.)
-     * If merging is not possible, then a selection of both provided nodes is created and
-     * returned as merge result.
-     * </p>
-     *
-     * @param node1 the first task to be merged
-     * @param node2 the second task to be merged
-     * 
-     * @return the result of the merge
-     */
-    ITaskTreeNode mergeTaskNodes(ITaskTreeNode node1, ITaskTreeNode node2) {
-        ITaskTreeNode mergeResult = null;
-        
-        // both are of same parent type
-        if ((node1 instanceof ISequence) && (node2 instanceof ISequence)) {
-            mergeResult = mergeSequences((ISequence) node1, (ISequence) node2);
-        }
-        else if ((node1 instanceof ISelection) && (node2 instanceof ISelection)) {
-            mergeResult = mergeSelections((ISelection) node1, (ISelection) node2);
-        }
-        else if ((node1 instanceof IIteration) && (node2 instanceof IIteration)) {
-            mergeResult = mergeIterations((IIteration) node1, (IIteration) node2);
-        }
-        else if ((node1 instanceof IOptional) && (node2 instanceof IOptional)) {
-            mergeResult = mergeOptionals((IOptional) node1, (IOptional) node2);
-        }
-        // one is an iteration
-        else if (node1 instanceof IIteration) {
-            mergeResult = mergeTaskNodes(((IIteration) node1).getChildren().get(0), node2);
-            
-            if (mergeResult != null) {
-                taskTreeBuilder.setChild((IIteration) node1, mergeResult);
-                mergeResult = node1;
-            }
-        }
-        else if (node2 instanceof IIteration) {
-            mergeResult = mergeTaskNodes(((IIteration) node2).getChildren().get(0), node1);
-            
-            if (mergeResult != null) {
-                taskTreeBuilder.setChild((IIteration) node2, mergeResult);
-                mergeResult = node2;
-            }
-        }
-        // one is an optional
-        else if (node1 instanceof IOptional) {
-            mergeResult = mergeTaskNodes(((IOptional) node1).getChildren().get(0), node2);
-            
-            if (mergeResult != null) {
-                taskTreeBuilder.setChild((IOptional) node1, mergeResult);
-                mergeResult = node1;
-            }
-        }
-        else if (node2 instanceof IOptional) {
-            mergeResult = mergeTaskNodes(((IOptional) node2).getChildren().get(0), node1);
-            
-            if (mergeResult != null) {
-                taskTreeBuilder.setChild((IOptional) node2, mergeResult);
-                mergeResult = node2;
-            }
-        }
-        // one is a selection
-        else if (node1 instanceof ISelection) {
-            ISelection selection2 = taskTreeNodeFactory.createNewSelection();
-            taskTreeBuilder.addChild(selection2, node2);
-            mergeResult = mergeSelections((ISelection) node1, selection2);
-        }
-        else if (node2 instanceof ISelection) {
-            ISelection selection1 = taskTreeNodeFactory.createNewSelection();
-            taskTreeBuilder.addChild(selection1, node1);
-            mergeResult = mergeSelections(selection1, (ISelection) node2);
-        }
-        // one is a sequence
-        else if (node1 instanceof ISequence) {
-            ISequence sequence2 = taskTreeNodeFactory.createNewSequence();
-            taskTreeBuilder.addChild(sequence2, node2);
-            mergeResult = mergeSequences((ISequence) node1, sequence2);
-        }
-        else if (node2 instanceof ISequence) {
-            ISequence sequence1 = taskTreeNodeFactory.createNewSequence();
-            taskTreeBuilder.addChild(sequence1, node1);
-            mergeResult = mergeSequences(sequence1, (ISequence) node2);
-        }
-        // both are event tasks
-        else {
-            // only drop nodes which are definitely lexically equal
-            if (nodeComparator.areLexicallyEqual(node1, node2)) {
-                mergeResult = node1;
-            }
-        }
-
-        if (mergeResult == null) {
-            mergeResult = taskTreeNodeFactory.createNewSelection();
-            taskTreeBuilder.setDescription(mergeResult, "variants of " + node1);
-            taskTreeBuilder.addChild((ISelection) mergeResult, node1);
-            taskTreeBuilder.addChild((ISelection) mergeResult, node2);
-        }
-        
-        return mergeResult;
-    }
-
-    /**
-     * <p>
-     * merges equal sequences. This is done through performing a diff between the two sequences.
-     * For each identified difference appropriate substructures are created. For equal parts,
-     * the appropriate equal nodes are merged using
-     * {@link #mergeTaskNodes(ITaskTreeNode, ITaskTreeNode)} and the result is added to the
-     * overall merge result.
-     * </p>
-     *
-     * @param sequence1 the first sequence to be merged
-     * @param sequence2 the second sequence to be merged
-     * 
-     * @return the result of the merge or null if merging was not possible
-     */
-    ITaskTreeNode mergeSequences(ISequence sequence1, ISequence sequence2) {
-        ITaskTreeNode mergeResult = taskTreeNodeFactory.createNewSequence();
-        
-        List<ITaskTreeNode> children1 = sequence1.getChildren();
-        List<ITaskTreeNode> children2 = sequence2.getChildren();
-        
-        Patch patch = new TaskTreeNodeSequenceMyersDiff().getDiff(children1, children2);
-        
-        int index1 = 0;
-        int index2 = 0;
-        
-        while ((index1 < children1.size()) || (index2 < children2.size())) {
-            boolean foundDelta = false;
-            for (Delta delta : patch.getDeltas()) {
-                if ((delta.getOriginal().getPosition() == index1) &&
-                    (delta.getRevised().getPosition() == index2))
-                {
-                    if (delta.getType() == Delta.TYPE.DELETE) {
-                        ITaskTreeNode option = getSubTree(children1, delta.getOriginal());
-                        index1 += delta.getOriginal().size();
-                        
-                        IOptional optional = taskTreeNodeFactory.createNewOptional();
-                        taskTreeBuilder.setChild(optional, option);
-                        taskTreeBuilder.addChild((ISequence) mergeResult, optional);
-                    }
-                    else if (delta.getType() == Delta.TYPE.INSERT) {
-                        ITaskTreeNode option = getSubTree(children2, delta.getRevised());
-                        index2 += delta.getRevised().size();
-                        
-                        IOptional optional = taskTreeNodeFactory.createNewOptional();
-                        taskTreeBuilder.setChild(optional, option);
-                        taskTreeBuilder.addChild((ISequence) mergeResult, optional);
-                    }
-                    else {
-                        ITaskTreeNode variant1 = getSubTree(children1, delta.getOriginal());
-                        index1 += delta.getOriginal().size();
-                        
-                        ITaskTreeNode variant2 = getSubTree(children2, delta.getRevised());
-                        index2 += delta.getRevised().size();
-                        
-                        ISelection selection = taskTreeNodeFactory.createNewSelection();
-                        taskTreeBuilder.addChild(selection, variant1);
-                        taskTreeBuilder.addChild(selection, variant2);
-                        taskTreeBuilder.addChild((ISequence) mergeResult, selection);
-                    }
-                    
-                    foundDelta = true;
-                }
-            }
-                
-            if (!foundDelta) {
-                ITaskTreeNode mergedNode =
-                    mergeTaskNodes(children1.get(index1++), children2.get(index2++));
-                taskTreeBuilder.addChild((ISequence) mergeResult, mergedNode);
-            }
-        }
-        
-        List<ITaskTreeNode> mergeResultChildren = mergeResult.getChildren();
-        if ((mergeResultChildren != null) && (mergeResultChildren.size() == 1) &&
-            (mergeResultChildren.get(0) instanceof ISelection))
-        {
-            mergeResult = mergeResultChildren.get(0);
-        }
-        
-        taskTreeBuilder.setDescription(mergeResult, sequence1.getDescription());
-        
-        return mergeResult;
-    }
-
-    /**
-     * <p>
-     * merges equal selections. This is done by adding those children of the second selection to
-     * the first selection that can not be merged with any of the children of the first selection.
-     * If a merge is possible and this merge is not a simple selection of the merged children,
-     * then the merged child replaces the child of the first selection which was merged.
-     * </p>
-     *
-     * @param selection1 the first selection to be merged
-     * @param selection2 the second selection to be merged
-     * 
-     * @return the result of the merge which is never null
-     */
-    ITaskTreeNode mergeSelections(ISelection selection1, ISelection selection2) {
-        ISelection mergeResult = selection1;
-        
-        ITaskTreeNode childToMerge = null;
-        ITaskTreeNode mergedChild = null;
-        
-        List<ITaskTreeNode> children1 = selection1.getChildren();
-        List<ITaskTreeNode> children2 = selection2.getChildren();
-        
-        // check for each child of selection 2 if it is a duplicate of one of the children
-        // if selection 1. If not, add it as further child to the merge result, else skip it.
-        for (int i = 0; i < children2.size(); i++) {
-            childToMerge = children2.get(i);
-            for (int j = 0; j < children1.size(); j++) {
-                mergedChild = mergeTaskNodes(children1.get(j), childToMerge);
-                
-                // a merge must not be a selection, except it is one of the children. Otherwise
-                // no real merge was done.
-                if ((mergedChild != null) &&
-                    ((!(mergedChild instanceof ISelection)) ||
-                     (children1.get(j) == mergedChild) || (childToMerge == mergedChild)))
-                {
-                    // we found a real merge. So replace the original child in selection 1 with
-                    // the merged child
-                    taskTreeBuilder.removeChild(selection1, children1.get(j));
-                    taskTreeBuilder.addChild(selection1, mergedChild);
-                    mergedChild = null;
-                    childToMerge = null;
-                    break;
-                }
-            }
-            
-            if (childToMerge != null) {
-                taskTreeBuilder.addChild(selection1, childToMerge);
-            }
-        }
-        
-        return mergeResult;
-    }
-
-    /**
-     * <p>
-     * merges equal iterations. This is done through merging the children of both iterations. If
-     * this is possible, a resulting iteration with the merge result of the children as its own
-     * child is returned. Otherwise null is returned to indicate that merging was not possible.
-     * </p>
-     *
-     * @param iteration1 the first iteration to be merged
-     * @param iteration2 the second iteration to be merged
-     * 
-     * @return the result of the merge or null if merging is not possible
-     */
-    ITaskTreeNode mergeIterations(IIteration iteration1, IIteration iteration2) {
-        ITaskTreeNode mergedChild = mergeTaskNodes
-            (iteration1.getChildren().get(0), iteration2.getChildren().get(0));
-        
-        IIteration mergeResult = null;
-        
-        if (mergedChild != null) {
-            mergeResult = iteration1;
-            taskTreeBuilder.setChild(mergeResult, mergedChild);
-        }
-        
-        return mergeResult;
-    }
-
-    /**
-     * <p>
-     * merges equal optionals. This is done through merging the children of both optionals. If
-     * this is possible, a resulting optional with the merge result of the children as its own
-     * child is returned. Otherwise null is returned to indicate that merging was not possible.
-     * </p>
-     *
-     * @param optional1 the first optional to be merged
-     * @param optional2 the second optional to be merged
-     * 
-     * @return the result of the merge or null if merging is not possible
-     */
-    ITaskTreeNode mergeOptionals(IOptional optional1, IOptional optional2) {
-        ITaskTreeNode mergedChild = mergeTaskNodes
-            (optional1.getChildren().get(0), optional2.getChildren().get(0));
-        
-        IOptional mergeResult = null;
-        
-        if (mergedChild != null) {
-            mergeResult = optional1;
-            taskTreeBuilder.setChild(mergeResult, mergedChild);
-        }
-        
-        return mergeResult;
-    }
-
-    /**
-     * <p>
-     * determines a task tree node defined by the provided chunk. This is either a single node if
-     * the chunck denotes a single child, or it is a sequence of the denoted children.
-     * </p>
-     */
-    private ITaskTreeNode getSubTree(List<ITaskTreeNode> children1, Chunk chunk) {
-        ITaskTreeNode part;
-        
-        if (chunk.size() == 1) {
-            part = children1.get(chunk.getPosition());
-        }
-        else {
-            part = taskTreeNodeFactory.createNewSequence();
-        
-            for (int i = 0; i < chunk.size(); i++) {
-                taskTreeBuilder.addChild
-                    ((ISequence) part, children1.get(chunk.getPosition() + i));
-            }
-        }
-        
-        return part;
-    }
-
-    /**
-     * 
-     */
-    private class TaskTreeNodeSequenceMyersDiff extends MyersDiff {
-        
-        /**
-         * 
-         */
-        private Patch getDiff(List<ITaskTreeNode> variant1, List<ITaskTreeNode> variant2) {
-            PathNode path = buildPath(variant1, variant2);
-            return buildRevision(path, variant1, variant2);
-        }
-        
-        /**
-         * overwrites the default implementation just to change the tree node comparison.
-         * This is an extended version of the original implementation respecting the appropriate
-         * copyrights. Please see the copyrights of the implementers of the base class for more
-         * information
-         */
-        private PathNode buildPath(List<ITaskTreeNode> variant1, List<ITaskTreeNode> variant2) {
-            if (variant1 == null) {
-                throw new IllegalArgumentException("variant1 is null");
-            }
-            
-            if (variant2 == null) {
-                throw new IllegalArgumentException("variant2 is null");
-            }
-            
-            // these are local constants
-            final int N = variant1.size();
-            final int M = variant2.size();
-            
-            final int MAX = N + M + 1;
-            final int size = 1 + 2 * MAX;
-            final int middle = size / 2;
-            final PathNode diagonal[] = new PathNode[size];
-            
-            diagonal[middle + 1] = new Snake(0, -1, null);
-            
-            for (int d = 0; d < MAX; d++) {
-                for (int k = -d; k <= d; k += 2) {
-                    final int kmiddle = middle + k;
-                    final int kplus = kmiddle + 1;
-                    final int kminus = kmiddle - 1;
-                    PathNode prev = null;
-                    
-                    int i;
-                    if ((k == -d) || ((k != d) && (diagonal[kminus].i < diagonal[kplus].i))) {
-                        i = diagonal[kplus].i;
-                        prev = diagonal[kplus];
-                    }
-                    else {
-                        i = diagonal[kminus].i + 1;
-                        prev = diagonal[kminus];
-                    }
-                    
-                    diagonal[kminus] = null; // no longer used
-                    
-                    int j = i - k;
-                    
-                    PathNode node = new DiffNode(i, j, prev);
-                    
-                    // orig and rev are zero-based
-                    // but the algorithm is one-based
-                    // that's why there's no +1 when indexing the sequences
-                    while ((i < N) && (j < M) &&
-                           nodeComparator.equals(variant1.get(i), variant2.get(j)))
-                    {
-                        i++;
-                        j++;
-                    }
-                    
-                    if (i > node.i) {
-                        node = new Snake(i, j, node);
-                    }
-                    
-                    diagonal[kmiddle] = node;
-                    
-                    if ((i >= N) && (j >= M)) {
-                        return diagonal[kmiddle];
-                    }
-                }
-                diagonal[middle + d - 1] = null;
-                
-            }
-            
-            // According to Myers, this cannot happen
-            throw new RuntimeException("could not find a diff path");
-        }
-
-        /**
-         * overwrites the default implementation just to change the tree node comparison.
-         * This is an extended version of the original implementation respecting the appropriate
-         * copyrights. Please see the copyrights of the implementers of the base class for more
-         * information
-         */
-        private Patch buildRevision(PathNode            path,
-                                    List<ITaskTreeNode> variant1,
-                                    List<ITaskTreeNode> variant2)
-        {
-            if (path == null) {
-                throw new IllegalArgumentException("path is null");
-            }
-            
-            if (variant1 == null) {
-                throw new IllegalArgumentException("variant1 is null");
-            }
-            
-            if (variant2 == null) {
-                throw new IllegalArgumentException("variant2 is null");
-            }
-            
-            Patch patch = new Patch();
-            if (path.isSnake()) {
-                path = path.prev;
-            }
-            
-            while ((path != null) && (path.prev != null) && (path.prev.j >= 0)) {
-                if (path.isSnake()) {
-                    throw new IllegalStateException
-                        ("bad diffpath: found snake when looking for diff");
-                }
-                
-                int i = path.i;
-                int j = path.j;
-                
-                path = path.prev;
-                int ianchor = path.i;
-                int janchor = path.j;
-                
-                Chunk original = new Chunk(ianchor, variant1.subList(ianchor, i));
-                Chunk revised = new Chunk(janchor, variant2.subList(janchor, j));
-                Delta delta = null;
-                
-                if ((original.size() == 0) && (revised.size() != 0)) {
-                    delta = new InsertDelta(original, revised);
-                }
-                else if ((original.size() > 0) && (revised.size() == 0)) {
-                    delta = new DeleteDelta(original, revised);
-                }
-                else {
-                    delta = new ChangeDelta(original, revised);
-                }
-                
-                patch.addDelta(delta);
-                
-                if (path.isSnake()) {
-                    path = path.prev;
-                }
-            }
-            return patch;
-        }
-        
-    }
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TemporalRelationshipRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TemporalRelationshipRule.java	(revision 1133)
+++ 	(revision )
@@ -1,58 +1,0 @@
-//   Copyright 2012 Georg-August-Universität Göttingen, Germany
-//
-//   Licensed under the Apache License, Version 2.0 (the "License");
-//   you may not use this file except in compliance with the License.
-//   You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//   Unless required by applicable law or agreed to in writing, software
-//   distributed under the License is distributed on an "AS IS" BASIS,
-//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//   See the License for the specific language governing permissions and
-//   limitations under the License.
-
-package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
-
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-
-/**
- * <p>
- * a temporal relationship rule is able to detected temporal relationships between the child nodes
- * of the parent node provided to the {@link #apply(ITaskTreeNode, boolean)} method. A rule
- * creates temporal relationships between the child nodes, i.e. substructures in the task tree, if
- * it detects a temporal relationship and it can be sure that it is complete. Incomplete but
- * detected temporal relationships may occur, if there can be more children expected to be added
- * to the provided parent node. This could be the case during parsing a interaction log file of
- * a GUI.
- * </p>
- * 
- * @author Patrick Harms
- */
-interface TemporalRelationshipRule {
-
-  /**
-   * <p>
-   * applies the rule to the given parent node. The finalize parameter is used to command the rule
-   * to finish rule applications, in the case it is known that no further data will be available. 
-   * </p>
-   * <p>
-   * The returned rule application result is null, if the rule can not be applied, i.e. it does not
-   * detect a temporal relationship. It returns a rule application result with a status
-   * {@link RuleApplicationStatus#RULE_APPLICATION_FINISHED} if the rule was applied. The result
-   * contains all newly created parent nodes. It returns a rule application result with status
-   * {@link RuleApplicationStatus#RULE_APPLICATION_FEASIBLE} if the rule would be applicable if
-   * further children would be available in the parent node. This status MUST not be returned if 
-   * the finalize parameter is true. In this case the rule must be applied or not. 
-   * </p>
-   * 
-   * @param parent   the parent node with the children to apply the rule on
-   * @param finalize true, if the rule shall not expect further children to come and that it
-   *                 should therefore be applied in any case
-   *                    
-   * @return the rule application result as described.
-   */
-  RuleApplicationResult apply(ITaskTreeNode parent,
-                              boolean       finalize);
-  
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java	(revision 1146)
@@ -22,23 +22,27 @@
 import de.ugoe.cs.autoquest.eventcore.guimodel.IFrame;
 import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
-import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality;
-import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
+import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEquality;
+import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEqualityRuleManager;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
 import de.ugoe.cs.util.console.Console;
 
 /**
+ * TODO update comment
+ * 
  * <p>
  * This class is responsible for applying temporal relationship rules on a task tree. Through this,
  * a flat task tree is restructured to have more depth but to include more temporal relationships
- * between task tree nodes which are not only a major sequence. I.e. through the application of
- * rule iterations and selections of task tree nodes are detected. Which kind of temporal relations
- * between task tree nodes are detected depends on the {@link TemporalRelationshipRule}s known to
+ * between tasks which are not only a major sequence. I.e. through the application of the
+ * rules iterations and selections of tasks are detected. Which kind of temporal relations
+ * between tasks are detected depends on the {@link ITaskInstanceListScopeRule}s known to
  * this class.
  * </p>
- * <p>The class holds references to the appropriate {@link TemporalRelationshipRule}s and calls
- * their {@link TemporalRelationshipRule#apply(ITaskTreeNode, ITaskTreeBuilder, ITaskTreeNodeFactory, boolean)}
- * method for each node in the task tree it is needed for. The general behavior of this class is
+ * <p>The class holds references to the appropriate {@link ITaskInstanceListScopeRule}s and calls
+ * their {@link ITaskInstanceListScopeRule#apply(ITask, ITaskBuilder, ITaskFactory, boolean)}
+ * method for each task in the task tree it is needed for. The general behavior of this class is
  * the following:
  * <ol>
@@ -48,10 +52,10 @@
  *   </li>
  *   <li>
- *     then the {@link #applyRules(ITaskTreeNode, ITaskTreeBuilder, ITaskTreeNodeFactory, boolean)}
- *     method is called for a so far unstructured task tree node
+ *     then the {@link #applyRules(ITask, ITaskBuilder, ITaskFactory, boolean)}
+ *     method is called for a so far unstructured task
  *   </li>
  *   <li>
  *     the class iterates its internal list of rules and calls their
- *     {@link TemporalRelationshipRule#apply(ITaskTreeNode, ITaskTreeBuilder, ITaskTreeNodeFactory, boolean)}
+ *     {@link ITaskInstanceListScopeRule#apply(ITask, ITaskBuilder, ITaskFactory, boolean)}
  *     method.
  *   </li>
@@ -69,6 +73,6 @@
  *       <li>
  *         if a rule returns, that it was applied, the same rule is applied again until it returns
- *         null or feasible. For each newly created parent node provided in the rule application
- *         result, the {@link #applyRules(ITaskTreeNode, ITaskTreeBuilder, ITaskTreeNodeFactory, boolean)}
+ *         null or feasible. For each newly created parent task provided in the rule application
+ *         result, the {@link #applyRules(ITask, ITaskBuilder, ITaskFactory, boolean)}
  *         method is called.
  *       </li>
@@ -76,6 +80,6 @@
  *   </li>
  * </ol>
- * Through this, all rules are tried to be applied at least once to the provided parent node and
- * all parent nodes created during the rule application.
+ * Through this, all rules are tried to be applied at least once to the provided parent task and
+ * all parent tasks created during the rule application.
  * </p>
  * 
@@ -86,22 +90,30 @@
     /**
      * <p>
-     * the node equality manager needed by the rules to compare task tree nodes with each other
-     * </p>
-     */
-    private NodeEqualityRuleManager nodeEqualityRuleManager;
-
-    /**
-     * <p>
-     * the task tree node factory to be used during rule application
-     * </p>
-     */
-    private ITaskTreeNodeFactory taskTreeNodeFactory;
-
-    /**
-     * <p>
-     * the task tree builder to be used during rule application
-     * </p>
-     */
-    private ITaskTreeBuilder taskTreeBuilder;
+     * the task equality manager needed by the rules to compare tasks with each other
+     * </p>
+     */
+    private TaskEqualityRuleManager taskEqualityRuleManager;
+
+    /**
+     * <p>
+     * the task factory to be used during rule application
+     * </p>
+     */
+    private ITaskFactory taskFactory;
+
+    /**
+     * <p>
+     * the task builder to be used during rule application
+     * </p>
+     */
+    private ITaskBuilder taskBuilder;
+
+    /**
+     * <p>
+     * the temporal relationship rules known to the manager that are executed on whole sessions.
+     * The rules are applied in the order they occur in this list.
+     * </p>
+     */
+    private ISessionScopeRule[] sessionScopeRules;
 
     /**
@@ -111,13 +123,5 @@
      * </p>
      */
-    private TemporalRelationshipRule[] treeScopeRules;
-
-    /**
-     * <p>
-     * the temporal relationship rules known to the manager that are executed on whole sub trees.
-     * The rules are applied in the order they occur in this list.
-     * </p>
-     */
-    private TemporalRelationshipRule[] nodeScopeRules;
+    private ITaskInstanceListScopeRule[] taskScopeRules;
 
     /**
@@ -126,19 +130,19 @@
      * </p>
      * 
-     * @param nodeEqualityRuleManager the node equality rule manager to be used by the known rules
-     *                                for task tree node comparison during rule application
-     * @param taskTreeNodeFactory     the node factory to be used for instantiating new task tree
-     *                                nodes during rule application
-     * @param taskTreeBuilder         the task tree builder to be used for linking task tree nodes
+     * @param taskEqualityRuleManager the task equality rule manager to be used by the known rules
+     *                                for task comparison during rule application
+     * @param taskFactory             the task factory to be used for instantiating new task tree
+     *                                tasks during rule application
+     * @param taskBuilder             the task builder to be used for linking tasks
      *                                with each other during rule application
      */
-    public TemporalRelationshipRuleManager(NodeEqualityRuleManager nodeEqualityRuleManager,
-                                           ITaskTreeNodeFactory    taskTreeNodeFactory,
-                                           ITaskTreeBuilder        taskTreeBuilder)
+    public TemporalRelationshipRuleManager(TaskEqualityRuleManager taskEqualityRuleManager,
+                                           ITaskFactory            taskFactory,
+                                           ITaskBuilder            taskBuilder)
     {
         super();
-        this.nodeEqualityRuleManager = nodeEqualityRuleManager;
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
+        this.taskEqualityRuleManager = taskEqualityRuleManager;
+        this.taskFactory = taskFactory;
+        this.taskBuilder = taskBuilder;
     }
 
@@ -146,5 +150,5 @@
      * <p>
      * initialized the temporal relationship rule manager by instantiating the known rules and
-     * providing them with a reference to the node equality manager or other information they need.
+     * providing them with a reference to the task equality manager or other information they need.
      * </p>
      */
@@ -156,36 +160,35 @@
         //frameFilter.add(ICanvas.class);
 
-        treeScopeRules = new TemporalRelationshipRule[] {
+        sessionScopeRules = new ISessionScopeRule[] {
             new SequenceForTaskDetectionRule
-                (nodeEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL,
-                 taskTreeNodeFactory, taskTreeBuilder),
+                (taskEqualityRuleManager, TaskEquality.SEMANTICALLY_EQUAL,
+                 taskFactory, taskBuilder),
             /*new DefaultTaskSequenceDetectionRule
-                (nodeEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL,
-                 taskTreeNodeFactory, taskTreeBuilder),
+                (taskEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL,
+                 taskFactory, taskTreeBuilder),
             new DefaultTaskSequenceDetectionRule
-                (nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL,
-                 taskTreeNodeFactory, taskTreeBuilder),*/
+                (taskEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL,
+                 taskFactory, taskTreeBuilder),*/
             /*new TreeScopeWrapperRule
                 (new DefaultIterationDetectionRule
-                    (nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL,
-                     taskTreeNodeFactory, taskTreeBuilder)),
+                    (taskEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL,
+                     taskFactory, taskTreeBuilder)),
             new TreeScopeWrapperRule
                 (new DefaultIterationDetectionRule
-                    (nodeEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL,
-                     taskTreeNodeFactory, taskTreeBuilder)),
+                    (taskEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL,
+                     taskFactory, taskTreeBuilder)),
             new TreeScopeWrapperRule
                 (new DefaultIterationDetectionRule
-                    (nodeEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL,
-                     taskTreeNodeFactory, taskTreeBuilder))*/
+                    (taskEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL,
+                     taskFactory, taskTreeBuilder))*/
         };
         
         //treeScopeRules.add(new DefaultGuiElementSequenceDetectionRule(frameFilter));
 
-        nodeScopeRules = new TemporalRelationshipRule[] {
-            //new SequenceOnGuiElementDetectionRule(taskTreeNodeFactory, taskTreeBuilder),
-            //new EventSequenceOnSameTargetDetectionRule(taskTreeNodeFactory, taskTreeBuilder),
-            new TrackBarSelectionDetectionRule
-                (nodeEqualityRuleManager, taskTreeNodeFactory, taskTreeBuilder),
-            //new DefaultGuiEventSequenceDetectionRule(taskTreeNodeFactory, taskTreeBuilder),
+        taskScopeRules = new ITaskInstanceListScopeRule[] {
+            //new SequenceOnGuiElementDetectionRule(taskFactory, taskTreeBuilder),
+            //new EventSequenceOnSameTargetDetectionRule(taskFactory, taskTreeBuilder),
+            //new TrackBarSelectionDetectionRule(taskEqualityRuleManager, taskFactory, taskBuilder),
+            //new DefaultGuiEventSequenceDetectionRule(taskFactory, taskTreeBuilder),
         };
 
@@ -194,43 +197,26 @@
     /**
      * <p>
-     * applies the known rules to the provided parent node. For the creation of further nodes,
-     * the provided builder and node factory are utilized. The method expectes, that no more data
+     * applies the known rules to the provided sessions. For the creation of further tasks,
+     * the provided builder and task factory are utilized. The method expects, that no more data
      * is available and, therefore, finalizes the rule application.
      * </p>
      * 
-     * @param nodeFactory  the node factory to be used for instantiating new task tree nodes.
-     */
-    public void applyRules(ITaskTreeNode parent) {
-        applyRules(parent, true);
-    }
-
-    /**
-     * <p>
-     * applies the known rules to the provided parent node. For the creation of further nodes,
-     * the provided builder and node factory are utilized. If the finalize parameter is true, the
+     * @param taskFactory  the task factory to be used for instantiating new tasks.
+     */
+    public void applyRules(List<IUserSession> sessions) {
+        applyRules(sessionScopeRules, sessions, "");
+    }
+
+    /**
+     * <p>
+     * applies the known rules to the provided parent task. For the creation of further tasks,
+     * the provided builder and task factory are utilized. If the finalize parameter is true, the
      * rule application is finalized as far as possible without waiting for further data. If it is
      * false, the rule application is broken up at the first rule returning, that its application
-     * would be feasible. 
+     * would be feasible. The method calls itself for each parent task created through the rule
+     * application. In this case, the finalize parameter is always true.
      * </p>
      * 
-     * @param parent       the parent node to apply the rules on
-     * @param finalize     used to indicate, if the rule application shall break up if a rule would
-     *                     be feasible if further data was available, or not.
-     */
-    public void applyRules(ITaskTreeNode parent, boolean finalize) {
-        applyRules(treeScopeRules, parent, finalize, "");
-    }
-
-    /**
-     * <p>
-     * applies the known rules to the provided parent node. For the creation of further nodes,
-     * the provided builder and node factory are utilized. If the finalize parameter is true, the
-     * rule application is finalized as far as possible without waiting for further data. If it is
-     * false, the rule application is broken up at the first rule returning, that its application
-     * would be feasible. The method calls itself for each parent node created through the rule
-     * application. In this case, the finalize parameter is always true.
-     * </p>
-     * 
-     * @param parent       the parent node to apply the rules on
+     * @param parent       the parent task to apply the rules on
      * @param finalize     used to indicate, if the rule application shall break up if a rule would
      *                     be feasible if further data was available, or not.
@@ -238,31 +224,30 @@
      *                     on the recursion depth of calling this method.
      */
-    private int applyRules(TemporalRelationshipRule[] rules,
-                           ITaskTreeNode              parent,
-                           boolean                    finalize,
-                           String                     logIndent)
+    private int applyRules(ISessionScopeRule[] rules,
+                           List<IUserSession>  sessions,
+                           String              logIndent)
     {
-        Console.traceln(Level.FINER, logIndent + "applying rules for " + parent);
+        Console.traceln
+            (Level.FINER, logIndent + "applying rules for " + sessions.size() + " sessions");
 
         int noOfRuleApplications = 0;
 
-        for (TemporalRelationshipRule rule : rules) {
+        for (ISessionScopeRule rule : rules) {
             RuleApplicationResult result;
             do {
-                Console.traceln(Level.FINER, logIndent + "trying rule " + rule + " on " + parent);
-                result = rule.apply(parent, finalize);
+                Console.traceln(Level.FINER, logIndent + "trying rule " + rule);
+                result = rule.apply(sessions);
 
                 if ((result != null) &&
                     (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED))
                 {
-                    Console.traceln
-                        (Level.FINE, logIndent + "applied rule " + rule + " on " + parent);
+                    Console.traceln(Level.FINE, logIndent + "applied rule " + rule);
                     noOfRuleApplications++;
                     
                     //dumpTask(parent, "");
 
-                    for (ITaskTreeNode newParent : result.getNewlyCreatedParentNodes()) {
+                    for (ITaskInstance newParent : result.getNewlyCreatedTaskInstances()) {
                         noOfRuleApplications +=
-                            applyRules(nodeScopeRules, newParent, true, logIndent + "  ");
+                            applyRules(taskScopeRules, newParent, logIndent + "  ");
                     }
                 }
@@ -271,11 +256,4 @@
                    (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED));
 
-            if ((!finalize) &&
-                (result != null) &&
-                (result.getRuleApplicationStatus() == RuleApplicationStatus.FEASIBLE))
-            {
-                // in this case, don't go on applying rules, which should not be applied yet
-                break;
-            }
         }
 
@@ -289,7 +267,66 @@
 
     /**
+     * <p>
+     * applies the known rules to the provided parent task. For the creation of further tasks,
+     * the provided builder and task factory are utilized. If the finalize parameter is true, the
+     * rule application is finalized as far as possible without waiting for further data. If it is
+     * false, the rule application is broken up at the first rule returning, that its application
+     * would be feasible. The method calls itself for each parent task created through the rule
+     * application. In this case, the finalize parameter is always true.
+     * </p>
+     * 
+     * @param parent       the parent task to apply the rules on
+     * @param finalize     used to indicate, if the rule application shall break up if a rule would
+     *                     be feasible if further data was available, or not.
+     * @param logIndent    simply used for logging purposes to indent the log messages depending
+     *                     on the recursion depth of calling this method.
+     */
+    private int applyRules(ITaskInstanceListScopeRule[] rules,
+                           ITaskInstanceList            taskInstances,
+                           String                       logIndent)
+    {
+        Console.traceln(Level.FINER, logIndent + "applying rules for " + taskInstances.size() +
+                        " task instances");
+
+        int noOfRuleApplications = 0;
+
+        for (ITaskInstanceListScopeRule rule : rules) {
+            RuleApplicationResult result;
+            do {
+                Console.traceln
+                    (Level.FINER, logIndent + "trying rule " + rule + " on " + taskInstances);
+                result = rule.apply(taskInstances);
+
+                if ((result != null) &&
+                    (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED))
+                {
+                    Console.traceln
+                        (Level.FINE, logIndent + "applied rule " + rule + " on " + taskInstances);
+                    noOfRuleApplications++;
+                    
+                    //dumpTask(parent, "");
+
+                    for (ITaskInstance newParent : result.getNewlyCreatedTaskInstances()) {
+                        noOfRuleApplications +=
+                            applyRules(taskScopeRules, newParent, logIndent + "  ");
+                    }
+                }
+            }
+            while ((result != null) &&
+                   (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED));
+        }
+
+        if (noOfRuleApplications <= 0) {
+            Console.traceln(Level.FINE, logIndent + "no rules applied --> no temporal " +
+                            "relationship generated");
+        }
+
+        return noOfRuleApplications;
+    }
+
+    /**
      *
      */
-    /*private void dumpTask(ITaskTreeNode task, String indent) {
+    /*private void dumpTask(ITask task, String indent) {
         StringBuffer message = new StringBuffer();
         message.append(indent);
@@ -304,5 +341,5 @@
         
         if ((task.getChildren() != null) && (task.getChildren().size() > 0)) {
-            for (ITaskTreeNode child : task.getChildren()) {
+            for (ITask child : task.getChildren()) {
                 dumpTask(child, indent + "  ");
             }
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TrackBarSelectionDetectionRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TrackBarSelectionDetectionRule.java	(revision 1133)
+++ 	(revision )
@@ -1,195 +1,0 @@
-//   Copyright 2012 Georg-August-Universität Göttingen, Germany
-//
-//   Licensed under the Apache License, Version 2.0 (the "License");
-//   you may not use this file except in compliance with the License.
-//   You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//   Unless required by applicable law or agreed to in writing, software
-//   distributed under the License is distributed on an "AS IS" BASIS,
-//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//   See the License for the specific language governing permissions and
-//   limitations under the License.
-
-package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
-
-import java.util.List;
-
-import de.ugoe.cs.autoquest.eventcore.gui.ValueSelection;
-import de.ugoe.cs.autoquest.eventcore.guimodel.ITrackBar;
-import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: 28.04.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-class TrackBarSelectionDetectionRule implements TemporalRelationshipRule {
-    /**
-     * <p>
-     * the task tree node factory to be used for creating substructures for the temporal
-     * relationships identified during rule
-     * </p>
-     */
-    private ITaskTreeNodeFactory taskTreeNodeFactory;
-    /**
-     * <p>
-     * the task tree builder to be used for creating substructures for the temporal relationships
-     * identified during rule application
-     * </p>
-     */
-    private ITaskTreeBuilder taskTreeBuilder;
-
-    /**
-     * <p>
-     * the node equality manager needed for comparing task tree nodes with each other
-     * </p>
-     */
-    private NodeEqualityRuleManager nodeEqualityRuleManager;
-
-    /**
-     * <p>
-     * instantiates the rule and initializes it with a node equality rule manager and the minimal
-     * node equality identified sublist must have to consider them as iterated.
-     * </p>
-     */
-    TrackBarSelectionDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager,
-                                   ITaskTreeNodeFactory    taskTreeNodeFactory,
-                                   ITaskTreeBuilder        taskTreeBuilder)
-    {
-        this.nodeEqualityRuleManager = nodeEqualityRuleManager;
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-    }
-
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return "TrackBarSelectionDetectionRule";
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode,
-     * boolean)
-     */
-    @Override
-    public RuleApplicationResult apply(ITaskTreeNode parent, boolean finalize) {
-        if (!(parent instanceof ISequence)) {
-            return null;
-        }
-
-        RuleApplicationResult result = new RuleApplicationResult();
-
-        int valueSelectionStartIndex = -1;
-        ITrackBar currentTrackBar = null;
-
-        int index = 0;
-        List<ITaskTreeNode> children = parent.getChildren();
-        
-        while (index < children.size()) {
-            ITaskTreeNode child = children.get(index);
-
-            if ((child instanceof IEventTask) &&
-                (((IEventTask) child).getEventTarget() instanceof ITrackBar) &&
-                (((IEventTask) child).getEventType() instanceof ValueSelection) &&
-                ((currentTrackBar == null) ||
-                 (currentTrackBar.equals((((IEventTask) child).getEventTarget())))))
-            {
-                if (valueSelectionStartIndex < 0) {
-                    // let the show begin
-                    valueSelectionStartIndex = index;
-                    currentTrackBar = (ITrackBar) ((IEventTask) child).getEventTarget();
-                }
-            }
-            else if (valueSelectionStartIndex >= 0) {
-                // current child is no more value selection. But the preceding tasks were.
-                // Therefore,
-                // create an iteration with the different selectable values as selection children
-                handleValueSelections
-                    (parent, currentTrackBar, valueSelectionStartIndex, index - 1, result);
-
-                return result;
-            }
-
-            index++;
-        }
-
-        if (valueSelectionStartIndex >= 0) {
-            if (finalize) {
-                handleValueSelections(parent, currentTrackBar, valueSelectionStartIndex,
-                                      children.size() - 1, result);
-            }
-            else {
-                result.setRuleApplicationStatus(RuleApplicationStatus.FEASIBLE);
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     *
-     */
-    private void handleValueSelections(ITaskTreeNode         parent,
-                                       ITrackBar             trackbar,
-                                       int                   startIndex,
-                                       int                   endIndex,
-                                       RuleApplicationResult result)
-    {
-        IIteration iteration = taskTreeNodeFactory.createNewIteration();
-        taskTreeBuilder.setDescription
-            (iteration, "value selection on " + trackbar.getStringIdentifier());
-        result.addNewlyCreatedParentNode(iteration);
-
-        ISelection selection = taskTreeNodeFactory.createNewSelection();
-        result.addNewlyCreatedParentNode(selection);
-        taskTreeBuilder.setChild(iteration, selection);
-
-        List<ITaskTreeNode> children = parent.getChildren();
-        
-        for (int i = endIndex - startIndex; i >= 0; i--) {
-            addChildIfNecessary(selection, children.get(startIndex), result);
-            taskTreeBuilder.removeChild((ISequence) parent, startIndex);
-        }
-
-        taskTreeBuilder.addChild((ISequence) parent, startIndex, iteration);
-
-        result.setRuleApplicationStatus(RuleApplicationStatus.FINISHED);
-    }
-
-    /**
-     *
-     */
-    private void addChildIfNecessary(ISelection            parentSelection,
-                                     ITaskTreeNode         node,
-                                     RuleApplicationResult result)
-    {
-        List<ITaskTreeNode> children = parentSelection.getChildren();
-        
-        for (int i = 0; i < children.size(); i++) {
-            ITaskTreeNode child = children.get(i);
-
-            // check, if the new node is a variant for the current event task
-            if (nodeEqualityRuleManager.areSyntacticallyEqual(child, node)) {
-                return;
-            }
-        }
-
-        // if we did not return in the previous checks, then the node must be added
-        taskTreeBuilder.addChild(parentSelection, node);
-    }
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TreeScopeWrapperRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TreeScopeWrapperRule.java	(revision 1133)
+++ 	(revision )
@@ -1,114 +1,0 @@
-//   Copyright 2012 Georg-August-Universität Göttingen, Germany
-//
-//   Licensed under the Apache License, Version 2.0 (the "License");
-//   you may not use this file except in compliance with the License.
-//   You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//   Unless required by applicable law or agreed to in writing, software
-//   distributed under the License is distributed on an "AS IS" BASIS,
-//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//   See the License for the specific language governing permissions and
-//   limitations under the License.
-
-package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
-
-import java.util.List;
-
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-
-/**
- * This rule applies a node scope rule (working only in the scope of the provided parent node)
- * as a tree scope rule, i.e. it applies the provided wrapped rule recursively on the subtree
- * provided by the parent node. It traverses the nodes in post order.
- * 
- * @author 2013, last modified by $Author: patrick$
- */
-class TreeScopeWrapperRule implements TemporalRelationshipRule {
-
-    /**
-     * <p>
-     * the node scope rule wrapped by this wrapper
-     * </p>
-     */
-    private TemporalRelationshipRule rule;
-    
-    /**
-     * <p>
-     * instantiates the wrapper with the rule to be wrapped
-     * </p>
-     * 
-     * @param rule the rule to be wrapped and applied recursively
-     */
-    TreeScopeWrapperRule(TemporalRelationshipRule rule) {
-        if (rule == null) {
-            throw new IllegalArgumentException("rule must not be null");
-        }
-        
-        this.rule = rule;
-    }
-    
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return this.rule.toString() + " (tree scope)";
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode,
-     * boolean)
-     */
-    @Override
-    public RuleApplicationResult apply(ITaskTreeNode parent, boolean finalize) {
-        RuleApplicationResult result = null;
-        
-        if (parent != null) {
-            result = new RuleApplicationResult();
-            
-            List<ITaskTreeNode> children = parent.getChildren();
-            if (children != null) {
-                for (ITaskTreeNode child : children) {
-                    merge(result, apply(child, finalize));
-                }
-            }
-            
-            merge(result, rule.apply(parent, finalize));
-        }
-
-        return result;
-    }
-
-    /**
-     * <p>
-     * merges the overall rule application result with an intermediate result
-     * </p>
-     *
-     * @param overallResult the current overall result
-     * @param intermediate  the intermediate result to be merged into the overall result
-     */
-    private void merge(RuleApplicationResult overallResult, RuleApplicationResult intermediate) {
-        if (intermediate == null) {
-            return;
-        }
-        
-        RuleApplicationStatus overallStatus = overallResult.getRuleApplicationStatus();
-        RuleApplicationStatus intermediateStatus = intermediate.getRuleApplicationStatus();
-        
-        if ((intermediateStatus == RuleApplicationStatus.FINISHED) ||
-            ((intermediateStatus == RuleApplicationStatus.FEASIBLE) &&
-             (overallStatus == RuleApplicationStatus.NOT_APPLIED)))
-        {
-            overallResult.setRuleApplicationStatus(intermediateStatus);
-        }
-        
-        for (ITaskTreeNode newlyCreatedNode : intermediate.getNewlyCreatedParentNodes()) {
-            overallResult.addNewlyCreatedParentNode(newlyCreatedNode);
-        }
-    }
-
-}
