Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/manager/ComponentManager.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/manager/ComponentManager.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/manager/ComponentManager.java	(revision 1146)
@@ -15,10 +15,10 @@
 package de.ugoe.cs.autoquest.tasktrees.manager;
 
-import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager;
+import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEqualityRuleManager;
 import de.ugoe.cs.autoquest.tasktrees.temporalrelation.TemporalRelationshipRuleManager;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
-import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskTreeNodeFactory;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory;
+import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskBuilder;
+import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskFactory;
 
 /**
@@ -37,11 +37,11 @@
 
     /** */
-    private NodeEqualityRuleManager nodeEqualityRuleManager;
+    private TaskEqualityRuleManager taskEqualityRuleManager;
 
     /** */
-    private ITaskTreeBuilder taskTreeBuilder;
+    private ITaskBuilder taskBuilder;
 
     /** */
-    private ITaskTreeNodeFactory taskTreeNodeFactory;
+    private ITaskFactory taskFactory;
 
     /**
@@ -55,6 +55,6 @@
      *
      */
-    public static NodeEqualityRuleManager getNodeEqualityRuleManager() {
-        return getInstance().nodeEqualityRuleManager;
+    public static TaskEqualityRuleManager getTaskEqualityRuleManager() {
+        return getInstance().taskEqualityRuleManager;
     }
 
@@ -62,6 +62,6 @@
      *
      */
-    public static ITaskTreeBuilder getDefaultTaskTreeBuilder() {
-        return getInstance().taskTreeBuilder;
+    public static ITaskBuilder getDefaultTaskBuilder() {
+        return getInstance().taskBuilder;
     }
 
@@ -69,6 +69,6 @@
      *
      */
-    public static ITaskTreeNodeFactory getDefaultTaskTreeNodeFactory() {
-        return getInstance().taskTreeNodeFactory;
+    public static ITaskFactory getDefaultTaskFactory() {
+        return getInstance().taskFactory;
     }
 
@@ -95,12 +95,12 @@
      */
     private void init() {
-        nodeEqualityRuleManager = new NodeEqualityRuleManager();
-        nodeEqualityRuleManager.init();
+        taskEqualityRuleManager = new TaskEqualityRuleManager();
+        taskEqualityRuleManager.init();
 
-        taskTreeBuilder = new TaskTreeBuilder();
-        taskTreeNodeFactory = new TaskTreeNodeFactory();
+        taskBuilder = new TaskBuilder();
+        taskFactory = new TaskFactory();
 
         temporalRelationshipRuleManager = new TemporalRelationshipRuleManager
-            (nodeEqualityRuleManager, taskTreeNodeFactory, taskTreeBuilder);
+            (taskEqualityRuleManager, taskFactory, taskBuilder);
         temporalRelationshipRuleManager.init();
     }
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/manager/TaskTreeManager.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/manager/TaskTreeManager.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/manager/TaskTreeManager.java	(revision 1146)
@@ -21,9 +21,9 @@
 
 import de.ugoe.cs.autoquest.eventcore.Event;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
 import de.ugoe.cs.util.console.Console;
 
@@ -37,15 +37,14 @@
     
     /** */
-    private ITaskTreeBuilder taskTreeBuilder = ComponentManager.getDefaultTaskTreeBuilder();
+    private ITaskBuilder taskBuilder = ComponentManager.getDefaultTaskBuilder();
 
     /** */
-    private ITaskTreeNodeFactory taskTreeNodeFactory =
-        ComponentManager.getDefaultTaskTreeNodeFactory();
+    private ITaskFactory taskFactory = ComponentManager.getDefaultTaskFactory();
 
     /** */
-    private List<List<IEventTask>> sessions = null;
+    private List<IUserSession> sessions = null;
 
     /** */
-    private List<IEventTask> currentSession = null;
+    private IUserSession currentSession = null;
 
     /**
@@ -53,5 +52,5 @@
      */
     public TaskTreeManager() {
-        sessions = new LinkedList<List<IEventTask>>();
+        sessions = new LinkedList<IUserSession>();
     }
 
@@ -59,5 +58,5 @@
      *
      */
-    public synchronized ITaskTree createTaskTree(Collection<List<Event>> newSessions) {
+    public synchronized ITaskModel createTaskModel(Collection<List<Event>> newSessions) {
         if ((currentSession != null) || (sessions.size() > 0)) {
             throw new IllegalStateException("do not mix calls to this method with calls to the " +
@@ -75,5 +74,5 @@
         }
         
-        return getTaskTree();
+        return getTaskModel();
     }
 
@@ -83,6 +82,6 @@
     public void handleNewEvent(Event event) {
         assertSessionSequence();
-        currentSession.add
-            (taskTreeNodeFactory.createNewEventTask(event.getType(), event.getTarget()));
+        ITask eventTask = taskFactory.createNewEventTask(event.getType(), event.getTarget());
+        taskBuilder.addExecutedTask(currentSession, taskFactory.createNewTaskInstance(eventTask));
     }
 
@@ -91,5 +90,5 @@
      */
     public void finishSession() {
-        if ((currentSession != null) && (currentSession.size() > 0)) {
+        if ((currentSession != null) && (currentSession.getExecutedTasks().size() > 0)) {
             sessions.add(currentSession);
             currentSession = null;
@@ -100,27 +99,12 @@
      *
      */
-    public synchronized ITaskTree getTaskTree() {
+    public synchronized ITaskModel getTaskModel() {
         finishSession();
         
         Console.traceln(Level.INFO, "applying temporal relationship generation rules");
         
-        ISequence rootSequence = taskTreeNodeFactory.createNewSequence();
-        taskTreeBuilder.setDescription(rootSequence, "root");
-        
-        for (List<IEventTask> session : sessions) {
-            ISequence sequence = taskTreeNodeFactory.createNewSequence();
-            taskTreeBuilder.setDescription(sequence, "session");
-            
-            for (IEventTask eventTask : session) {
-                taskTreeBuilder.addChild(sequence, eventTask);
-            }
-            
-            taskTreeBuilder.addChild(rootSequence, sequence);
-        }
-        
-        
-        ComponentManager.getTemporalRelationshipRuleManager().applyRules(rootSequence);
+        ComponentManager.getTemporalRelationshipRuleManager().applyRules(sessions);
 
-        return taskTreeNodeFactory.createTaskTree(rootSequence);
+        return taskFactory.createTaskModel(sessions);
     }
 
@@ -130,5 +114,5 @@
     private void assertSessionSequence() {
         if (currentSession == null) {
-            currentSession = new LinkedList<IEventTask>();
+            currentSession = taskFactory.createUserSession();
         }
     }
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/EventTaskComparisonRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/EventTaskComparisonRule.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/EventTaskComparisonRule.java	(revision 1146)
@@ -0,0 +1,76 @@
+//   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.taskequality;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+
+/**
+ * <p>
+ * This rule identifies two tasks as lexically equal, if they are both event tasks and
+ * if their respective event types and targets equal. 
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public class EventTaskComparisonRule implements TaskComparisonRule {
+    
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     */
+    @Override
+    public boolean isApplicable(ITask task1, ITask task2) {
+        return (task1 instanceof IEventTask) && (task2 instanceof IEventTask);
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITask task1, ITask task2) {
+        IEventTask eventTask1 = (IEventTask) task1;
+        IEventTask eventTask2 = (IEventTask) task2;
+        
+        return (eventTask1.getEventType().equals(eventTask2.getEventType()) &&
+                eventTask1.getEventTarget().equals(eventTask2.getEventTarget()));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITask task1, ITask task2) {
+        return areLexicallyEqual(task1, task2);
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITask task1, ITask task2) {
+        return areLexicallyEqual(task1, task2);
+    }
+
+    @Override
+    public TaskEquality compare(ITask task1, ITask task2) {
+        if (areLexicallyEqual(task1, task2)) {
+            return TaskEquality.LEXICALLY_EQUAL;
+        }
+        else {
+            return TaskEquality.UNEQUAL;
+        }
+    }
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/GUIEventTaskComparisonRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/GUIEventTaskComparisonRule.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/GUIEventTaskComparisonRule.java	(revision 1146)
@@ -0,0 +1,460 @@
+//   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.taskequality;
+
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+import de.ugoe.cs.autoquest.eventcore.gui.IInteraction;
+import de.ugoe.cs.autoquest.eventcore.gui.KeyInteraction;
+import de.ugoe.cs.autoquest.eventcore.gui.KeyPressed;
+import de.ugoe.cs.autoquest.eventcore.gui.KeyReleased;
+import de.ugoe.cs.autoquest.eventcore.gui.KeyTyped;
+import de.ugoe.cs.autoquest.eventcore.gui.MouseButtonDown;
+import de.ugoe.cs.autoquest.eventcore.gui.MouseButtonInteraction;
+import de.ugoe.cs.autoquest.eventcore.gui.MouseButtonUp;
+import de.ugoe.cs.autoquest.eventcore.gui.MouseClick;
+import de.ugoe.cs.autoquest.eventcore.gui.MouseDoubleClick;
+import de.ugoe.cs.autoquest.eventcore.gui.MouseDragAndDrop;
+import de.ugoe.cs.autoquest.eventcore.gui.Scroll;
+import de.ugoe.cs.autoquest.eventcore.gui.TextInput;
+import de.ugoe.cs.autoquest.eventcore.gui.ValueSelection;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IButton;
+import de.ugoe.cs.autoquest.eventcore.guimodel.ICheckBox;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IComboBox;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IImage;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IListBox;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IMenu;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IMenuButton;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IRadioButton;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IShape;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IText;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IToolTip;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+
+/**
+ * <p>
+ * This rule compares GUI event tasks (i.e. it is more concrete, than the
+ * {@link EventTaskComparisonRule}). Two GUI event tasks are only equal if their event type and
+ * target are equal. The returned equality is even more fine-grained for events whose type is
+ * {@link TextInput} and {@link ValueSelection}. For text inputs, lexical equality is returned if
+ * the same text is entered using the same key interactions. Syntactical equality is returned if
+ * the same text is entered using different key interactions. Semantical equality is returned if
+ * different text is entered, but into the same event target. Value selections are syntactically
+ * equal, if the same value is selected. Otherwise they are semantically equal.
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public class GUIEventTaskComparisonRule implements TaskComparisonRule {
+    
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     */
+    @Override
+    public boolean isApplicable(ITask task1, ITask task2) {
+        return
+            ((task1 instanceof IEventTask) && (task2 instanceof IEventTask) &&
+            (((IEventTask) task1).getEventType() instanceof IInteraction) &&
+            (((IEventTask) task2).getEventType() instanceof IInteraction));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#compare(ITask, ITask)
+     */
+    @Override
+    public TaskEquality compare(ITask task1, ITask task2) {
+        return getEquality(task1, task2, null);
+    }
+
+    /**
+     * 
+     */
+    private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) {
+        IEventTask eventTask1 = (IEventTask) task1;
+        IEventTask eventTask2 = (IEventTask) task2;
+        
+        if (!eventTask1.getEventTarget().equals(eventTask2.getEventTarget())) {
+            return TaskEquality.UNEQUAL;
+        }
+        
+        IInteraction interaction1 = (IInteraction) eventTask1.getEventType();
+        IInteraction interaction2 = (IInteraction) eventTask2.getEventType();
+        
+        return compareInteractions
+            (interaction1, interaction2, eventTask1.getEventTarget(), requiredEqualityLevel);
+    }
+
+    /**
+     * <p>
+     * compares two interactions. The method delegates to other, more specific compare method, e.g.,
+     * {@link #compareTextInputs(TextInput, TextInput)} and
+     * {@link #compareValueSelections(ValueSelection, ValueSelection)}, if any exist for the
+     * concrete interaction types. Otherwise it uses the equals method of the interactions for
+     * comparison. In this case, if the interactions equals method returns true, this method
+     * returns lexical equality.
+     * </p>
+     *
+     * @param interaction1 the first interaction to compare
+     * @param interaction2 the second interaction to compare
+     * @param eventTarget  the event target on which the interactions happened (used within
+     *                     special comparisons like mouse clicks on buttons, where the coordinates
+     *                     can be ignored)
+     * 
+     * @return as described
+     */
+    private TaskEquality compareInteractions(IInteraction interaction1,
+                                             IInteraction interaction2,
+                                             IEventTarget eventTarget,
+                                             TaskEquality equalityLevel)
+    {
+        TaskEquality level = equalityLevel;
+        
+        if (level == null) {
+            level = TaskEquality.LEXICALLY_EQUAL;
+        }
+        
+        if (interaction1 == interaction2) {
+            return TaskEquality.LEXICALLY_EQUAL;
+        }
+        else if ((interaction1 instanceof KeyInteraction) &&
+                 (interaction2 instanceof KeyInteraction))
+        {
+            return compareKeyInteractions
+                ((KeyInteraction) interaction1, (KeyInteraction) interaction2, level);
+        }
+        else if ((interaction1 instanceof MouseButtonInteraction) &&
+                 (interaction2 instanceof MouseButtonInteraction))
+        {
+            return compareMouseButtonInteractions
+                ((MouseButtonInteraction) interaction1, (MouseButtonInteraction) interaction2,
+                 eventTarget, level);
+        }
+        else if ((interaction1 instanceof Scroll) && (interaction2 instanceof Scroll)) {
+            return compareScrolls((Scroll) interaction1, (Scroll) interaction2, level);
+        }
+        else if ((interaction1 instanceof TextInput) && (interaction2 instanceof TextInput)) {
+            return compareTextInputs
+                ((TextInput) interaction1, (TextInput) interaction2, level);
+        }
+        else if ((interaction1 instanceof ValueSelection) &&
+                 (interaction2 instanceof ValueSelection))
+        {
+            return compareValueSelections
+                ((ValueSelection<?>) interaction1, (ValueSelection<?>) interaction2, level);
+        }
+        else if (interaction1.equals(interaction2)) {
+            return TaskEquality.LEXICALLY_EQUAL;
+        }
+        else {
+            return TaskEquality.UNEQUAL;
+        }
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param interaction1
+     * @param interaction2
+     * @param eventTarget
+     * @param level
+     * @return
+     */
+    private TaskEquality compareKeyInteractions(KeyInteraction interaction1,
+                                                KeyInteraction interaction2,
+                                                TaskEquality   equalityLevel)
+    {
+        if (((interaction1 instanceof KeyPressed) && (interaction2 instanceof KeyPressed)) ||
+            ((interaction1 instanceof KeyReleased) && (interaction2 instanceof KeyReleased)) ||
+            ((interaction1 instanceof KeyTyped) && (interaction2 instanceof KeyTyped)))
+        {
+            if ((equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) &&
+                (interaction1.getKey() == interaction2.getKey()))
+            {
+                return TaskEquality.LEXICALLY_EQUAL;
+            }
+            else {
+                return TaskEquality.SEMANTICALLY_EQUAL;
+            }
+        }
+        
+        return TaskEquality.UNEQUAL;
+    }
+    
+    /**
+     * <p>
+     * compares two mouse drag and drops. If both drag and drops have the same start and end
+     * coordinates, they are lexically equal. Otherwise, they are semantically equal.
+     * </p>
+     *
+     * @param interaction1 the first mouse drag and drop to compare
+     * @param interaction2 the second mouse drag and drop to compare
+     * 
+     * @return as described
+     */
+    private TaskEquality compareMouseDragAndDrops(MouseDragAndDrop interaction1,
+                                                  MouseDragAndDrop interaction2,
+                                                  TaskEquality     equalityLevel)
+    {
+        if (interaction1.getButton() != interaction2.getButton()) {
+            return TaskEquality.UNEQUAL;
+        }
+        
+        if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) {
+            int x1 = interaction1.getX();
+            int x1Start = interaction1.getXStart();
+            int x2 = interaction2.getX();
+            int x2Start = interaction2.getXStart();
+            int y1 = interaction1.getY();
+            int y1Start = interaction1.getYStart();
+            int y2 = interaction2.getY();
+            int y2Start = interaction2.getYStart();
+        
+            if ((x1Start == x2Start) && (x1 == x2) && (y1Start == y2Start) && (y1 == y2)) {
+                return TaskEquality.LEXICALLY_EQUAL;
+            }
+        }
+        
+        return TaskEquality.SEMANTICALLY_EQUAL;
+    }
+
+    /**
+     * <p>
+     * compares two mouse button interactions such as clicks, mouse button down, or double clicks.
+     * If both interactions have the same coordinates, they are lexically equal. Otherwise, they
+     * are semantically equal. Mouse clicks for which the coordinates make no lexical difference
+     * (see {@link #clickCoordinatesMakeLexicalDifference(IEventTarget)}) are treated as
+     * lexically equal.
+     * </p>
+     *
+     * @param interaction1 the first mouse button interaction to compare
+     * @param interaction2 the second mouse button interaction to compare
+     * @param eventTarget  the event target on which the interactions happened (used within
+     *                     special comparisons like mouse clicks on buttons, where the coordinates
+     *                     can be ignored)
+     * 
+     * @return as described
+     */
+    private TaskEquality compareMouseButtonInteractions(MouseButtonInteraction interaction1,
+                                                        MouseButtonInteraction interaction2,
+                                                        IEventTarget           eventTarget,
+                                                        TaskEquality           equalityLevel)
+    {
+        boolean coordinatesMatch = true;
+        
+        if ((interaction1 instanceof MouseDragAndDrop) &&
+            (interaction2 instanceof MouseDragAndDrop))
+        {
+            return compareMouseDragAndDrops
+                ((MouseDragAndDrop) interaction1, (MouseDragAndDrop) interaction2, equalityLevel);
+        }
+        else if (interaction1.getButton() != interaction2.getButton()) {
+            return TaskEquality.UNEQUAL;
+        }
+        else if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL) &&
+                 clickCoordinatesMakeLexicalDifference(eventTarget))
+        {
+            int x1 = interaction1.getX();
+            int x2 = interaction2.getX();
+            int y1 = interaction1.getY();
+            int y2 = interaction2.getY();
+
+            if ((x1 != x2) || (y1 != y2)) {
+                coordinatesMatch = false;
+            }
+        }
+        
+        // up to now, they can be equal. Now check the types. Do it as last action as these
+        // checks take the most time and should, therefore, only be done latest
+        if (((interaction1 instanceof MouseClick) && (interaction2 instanceof MouseClick)) ||
+            ((interaction1 instanceof MouseDoubleClick) &&
+             (interaction2 instanceof MouseDoubleClick)) ||
+            ((interaction1 instanceof MouseButtonDown) &&
+             (interaction2 instanceof MouseButtonDown)) ||
+            ((interaction1 instanceof MouseButtonUp) &&
+             (interaction2 instanceof MouseButtonUp)))
+        {
+            if (coordinatesMatch) {
+                return TaskEquality.LEXICALLY_EQUAL;
+            }
+            else {
+                return TaskEquality.SEMANTICALLY_EQUAL;
+            }
+        }
+        
+        return TaskEquality.UNEQUAL;
+    }
+
+    /**
+     * <p>
+     * compares two mouse button interactions such as clicks, mouse button down, or double clicks.
+     * If both interactions have the same coordinates, they are lexically equal. Otherwise, they
+     * are semantically equal. Mouse clicks for which the coordinates make no lexical difference
+     * (see {@link #clickCoordinatesMakeLexicalDifference(IEventTarget)}) are treated as
+     * lexically equal.
+     * </p>
+     *
+     * @param interaction1 the first mouse button interaction to compare
+     * @param interaction2 the second mouse button interaction to compare
+     * @param eventTarget  the event target on which the interactions happened (used within
+     *                     special comparisons like mouse clicks on buttons, where the coordinates
+     *                     can be ignored)
+     * 
+     * @return as described
+     */
+    private TaskEquality compareScrolls(Scroll       interaction1,
+                                        Scroll       interaction2,
+                                        TaskEquality equalityLevel)
+    {
+        if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) {
+            int x1 = interaction1.getXPosition();
+            int x2 = interaction2.getXPosition();
+            int y1 = interaction1.getYPosition();
+            int y2 = interaction2.getYPosition();
+        
+            if ((x1 == x2) && (y1 == y2)) {
+                return TaskEquality.LEXICALLY_EQUAL;
+            }
+        }
+        
+        return TaskEquality.SEMANTICALLY_EQUAL;
+    }
+
+    /**
+     * <p>
+     * compares two text inputs. If both text inputs have the same entered text and text input
+     * events, they are lexically equal. If they only have the same entered text, they are
+     * syntactically equal. If they are only both text inputs, they are semantically equal.
+     * (the equality of the event targets is checked beforehand).
+     * </p>
+     *
+     * @param interaction1 the first text input to compare
+     * @param interaction2 the second text input to compare
+     * 
+     * @return as described
+     */
+    private TaskEquality compareTextInputs(TextInput    interaction1,
+                                           TextInput    interaction2,
+                                           TaskEquality equalityLevel)
+    {
+        switch (equalityLevel) {
+            case LEXICALLY_EQUAL:
+                if (interaction1.getTextInputEvents().equals(interaction2.getTextInputEvents())) {
+                    return TaskEquality.LEXICALLY_EQUAL;
+                }
+                // fall through
+            case SYNTACTICALLY_EQUAL:
+                if (interaction1.getEnteredText().equals(interaction2.getEnteredText())) {
+                    return TaskEquality.SYNTACTICALLY_EQUAL;
+                }
+                // fall through
+            case SEMANTICALLY_EQUAL:
+                return TaskEquality.SEMANTICALLY_EQUAL;
+            default:
+                return TaskEquality.UNEQUAL;
+        }
+    }
+
+    /**
+     * <p>
+     * compares two value selections. If both value selections have the same selected value, they
+     * are syntactically equal, otherwise they are semantically equal.
+     * (the equality of the event targets is checked beforehand).
+     * </p>
+     *
+     * @param interaction1 the first value selection to compare
+     * @param interaction2 the second value selection to compare
+     * 
+     * @return as described
+     */
+    private TaskEquality compareValueSelections(ValueSelection<?> interaction1,
+                                                ValueSelection<?> interaction2,
+                                                TaskEquality      equalityLevel)
+    {
+        if (equalityLevel.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL)) {
+            Object value1 = interaction1.getSelectedValue();
+            Object value2 = interaction2.getSelectedValue();
+        
+            if ((value1 == value2) || ((value1 != null) && (value1.equals(value2)))) {
+                return TaskEquality.LEXICALLY_EQUAL;
+            }
+        }
+        
+        return TaskEquality.SEMANTICALLY_EQUAL;
+    }
+
+    /**
+     * <p>
+     * Checks, if the coordinates of a click or double click on the provided event target makes
+     * a lexical difference. Mouse clicks and double clicks on buttons, check boxes,
+     * combo boxes, images, list boxes, menu buttons, radio buttons, shapes, uneditable text,
+     * and tool tips have no lexical difference as long as they happen on the same event target.
+     * The concrete coordinates are not relevant.
+     * </p>
+     *
+     * @param eventTarget the event target on which the interaction occurred
+     * 
+     * @return if the coordinates are important to be considered for clicks and double clicks,
+     *         false else
+     */
+    private boolean clickCoordinatesMakeLexicalDifference(IEventTarget eventTarget) {
+        if ((eventTarget instanceof IButton) ||
+            (eventTarget instanceof ICheckBox) ||
+            (eventTarget instanceof IComboBox) ||
+            (eventTarget instanceof IImage) ||
+            (eventTarget instanceof IListBox) ||
+            (eventTarget instanceof IMenu) ||
+            (eventTarget instanceof IMenuButton) ||
+            (eventTarget instanceof IRadioButton) ||
+            (eventTarget instanceof IShape) ||
+            (eventTarget instanceof IText) ||
+            (eventTarget instanceof IToolTip))
+        {
+            return false;
+        }
+        else {
+            return true;
+        }
+    }
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/IterationComparisonRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/IterationComparisonRule.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/IterationComparisonRule.java	(revision 1146)
@@ -0,0 +1,316 @@
+//   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.taskequality;
+
+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.ITask;
+
+/**
+ * <p>
+ * This class is capable of comparing Iterations. Iterations equal at distinct levels
+ * in distinct situations. The following table shows the results of the comparison for the
+ * specific situations (the parameters are commutative). In any other situation, the comparison
+ * returns <code>NodeEquality.UNEQUAL</code>:
+ * </p>
+ * 
+ * <table border="1">
+ *   <tr>
+ *     <th>iteration 1</th>
+ *     <th>iteration 2</th>
+ *     <th>comparison result</th>
+ *   </tr>
+ *   <tr>
+ *     <td>any iteration</td>
+ *     <td>any iteration with a child that is lexically equal to the child of iteration 1</td>
+ *     <td><code>NodeEquality.LEXICALLY_EQUAL</code></td>
+ *   </tr>
+ *   <tr>
+ *     <td>any iteration</td>
+ *     <td>any iteration with a child that is syntactically equal to the child of iteration 1</td>
+ *     <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td>
+ *   </tr>
+ *   <tr>
+ *     <td>any iteration</td>
+ *     <td>any iteration with a child that is semantically equal to the child of iteration 1</td>
+ *     <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td>
+ *   </tr>
+ *   <tr>
+ *     <td>an iteration with a selection of syntactically equal children</td>
+ *     <td>an iteration with a child that is syntactically equal to the children of the child
+ *     selection of iteration 1</td>
+ *     <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td>
+ *   </tr>
+ *   <tr>
+ *     <td>an iteration with a selection of syntactically equal children</td>
+ *     <td>an iteration with a selection of syntactically equal children that are all syntactically
+ *     equal to the selection of children of iteration 1</td>
+ *     <td><code>NodeEquality.SYNTACTICALLY_EQUAL</code></td>
+ *   </tr>
+ *   <tr>
+ *     <td>an iteration with a selection of semantically equal children</td>
+ *     <td>an iteration with a child that is semantically equal to the children of the child
+ *     selection of iteration 1</td>
+ *     <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td>
+ *   </tr>
+ *   <tr>
+ *     <td>an iteration with a selection of semantically equal children</td>
+ *     <td>an iteration with a selection of semantically equal children that are all semantically
+ *     equal to the selection of children of iteration 1</td>
+ *     <td><code>NodeEquality.SEMANTICALLY_EQUAL</code></td>
+ *   </tr>
+ * </table>
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class IterationComparisonRule implements TaskComparisonRule {
+    
+    /** the rule manager for internally comparing tasks */
+    private TaskEqualityRuleManager mRuleManager;
+
+    /**
+     * <p>
+     * simple constructor to provide the rule with the task equality rule manager to be able
+     * to perform comparisons of the children of provided tasks
+     * </p>
+     * 
+     * @param ruleManager the rule manager for comparing tasks
+     */
+    IterationComparisonRule(TaskEqualityRuleManager ruleManager) {
+        super();
+        mRuleManager = ruleManager;
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     */
+    @Override
+    public boolean isApplicable(ITask task1, ITask task2) {
+        return (task1 instanceof IIteration) && (task2 instanceof IIteration);
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITask task1, ITask task2) {
+        ITask child1 = ((IIteration) task1).getMarkedTask();
+        ITask child2 = ((IIteration) task2).getMarkedTask();
+        
+        if (child1 != null) {
+            if (child2 == null) {
+                return false;
+            }
+            else {
+                // iterations may have 3 different structures.
+                // 1. they have one child, which is the iterated one
+                // 2. they have a sequence of children, which is iterated
+                // 3. they have a selection of different iterated variants (usually the variants
+                //    are semantically equal)
+                // check if the type of children match. If not, return false. If they match,
+                // use the equality manager to perform further comparisons
+                
+                if (((child1 instanceof ISelection) && (child2 instanceof ISelection)) ||
+                    ((child1 instanceof ISequence) && (child2 instanceof ISequence)) ||
+                    ((child1 instanceof IEventTask) && (child2 instanceof IEventTask)))
+                {
+                    return getNodeEquality
+                        (child1, child2).isAtLeast(TaskEquality.LEXICALLY_EQUAL);
+                }
+            }
+        }
+        else if (child2 == null) {
+            return true;
+        }
+        
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITask task1, ITask task2) {
+        ITask child1 = ((IIteration) task1).getMarkedTask();
+        ITask child2 = ((IIteration) task2).getMarkedTask();
+        
+        if (child1 != null) {
+            if (child2 == null) {
+                return false;
+            }
+            else {
+                // iterations may have 3 different structures.
+                // 1. they have one child, which is the iterated one
+                // 2. they have a sequence of children, which is iterated
+                // 3. they have a selection of different iterated variants (usually the variants
+                //    are semantically equal)
+                // ignore the type of the children but check them for equality.
+                
+                return getNodeEquality(child1, child2).isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL);
+            }
+        }
+        else if (child2 == null) {
+            return true;
+        }
+        
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITask task1, ITask task2) {
+        return compare(task1, task2).isAtLeast(TaskEquality.SEMANTICALLY_EQUAL);
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#compare(ITask, ITask)
+     */
+    @Override
+    public TaskEquality compare(ITask task1, ITask task2) {
+        ITask child1 = ((IIteration) task1).getMarkedTask();
+        ITask child2 = ((IIteration) task2).getMarkedTask();
+
+        // if both iterations do not have children, they are equal although this doesn't make sense
+        if ((child1 == null) && (child2 == null)) {
+            return TaskEquality.LEXICALLY_EQUAL;
+        }
+        else if ((child1 == null) || (child2 == null)) {
+            return TaskEquality.UNEQUAL;
+        }
+
+        // iterations may have 3 different structures.
+        // 1. they have one child, which is the iterated one
+        // 2. they have a sequence of children, which is iterated
+        // 3. they have a selection of different iterated variants (usually the variants are
+        // semantically equal)
+        //
+        // the permutations of the three variants in combination must be checked
+
+        // check if both tasks are the same variants of iterations and if their children are equal.
+        // This condition matches, if both iterations are the same variants of iteration. I.e. three
+        // combinations of the permutation are handled herewith.
+        TaskEquality taskEquality = getNodeEquality(child1, child2);
+        
+        if (taskEquality != null) {
+            return taskEquality;
+        }
+
+        // compare one iteration with a single task as a child and another one with a selection of
+        // semantically equal tasks
+        return selectionChildrenSemanticallyEqualNode(child1, child2);
+        
+        // all other combinations (i.e. sequence with single child and sequence with selection)
+        // can not match
+    }
+
+    /**
+     * TODO update comment
+     */
+    private TaskEquality getNodeEquality(ITask child1, ITask child2) {
+        TaskEquality taskEquality = callRuleManager(child1, child2, null);
+
+        if (taskEquality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL)) {
+            // prevent, that identical is returned, because the iterations itself are not identical
+            // although the iterated tasks are
+            if (taskEquality == TaskEquality.IDENTICAL) {
+                return TaskEquality.LEXICALLY_EQUAL;
+            }
+            else {
+                return taskEquality;
+            }
+        }
+        
+        return TaskEquality.UNEQUAL;
+    }
+
+    /**
+     * <p>
+     * compares two tasks. One of them must be a selection, the other one can be any task
+     * tree task. The method returns a task equality that is not <code>NodeEquality.UNEQUAL</code>
+     * if the other task is at least semantically equal to the children of the selection. It
+     * returns more concrete equalities, if the equality between the other task and the children
+     * of the selection is more concrete.
+     * </p> 
+     * 
+     * @param taskTreeNode  the first task to compare
+     * @param taskTreeNode2 the second task to compare
+     * 
+     * @return as described
+     */
+    private TaskEquality selectionChildrenSemanticallyEqualNode(ITask task1, ITask task2) {
+        ISelection selection = null;
+        ITask task = null;
+        if (task1 instanceof ISelection) {
+            selection = (ISelection) task1;
+            task = task2;
+        }
+        else if (task2 instanceof ISelection) {
+            selection = (ISelection) task2;
+            task = task1;
+        }
+        else {
+            return TaskEquality.UNEQUAL;
+        }
+
+        // Iterations, where one has a selection and the other one not can at most be syntactically
+        // equal but not identical
+        TaskEquality commonDenominatorForAllComparisons = TaskEquality.SYNTACTICALLY_EQUAL;
+
+        for (ITask child : selection.getChildren()) {
+            TaskEquality taskEquality =
+                  callRuleManager(task, child, commonDenominatorForAllComparisons);
+
+            if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL))
+            {
+                return TaskEquality.UNEQUAL;
+            }
+            
+            commonDenominatorForAllComparisons =
+                commonDenominatorForAllComparisons.getCommonDenominator(taskEquality);
+        }
+
+        return commonDenominatorForAllComparisons;
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param child1
+     * @param child2
+     * @param requiredEqualityLevel
+     * @return
+     */
+    private TaskEquality callRuleManager(ITask        child1,
+                                         ITask        child2,
+                                         TaskEquality requiredEqualityLevel)
+    {
+        if (requiredEqualityLevel == null) {
+            return mRuleManager.compare(child1, child2);
+        }
+        else if (mRuleManager.areAtLeastEqual(child1, child2, requiredEqualityLevel)) {
+            return requiredEqualityLevel;
+        }
+        else {
+            return TaskEquality.UNEQUAL;
+        }
+    }
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/SelectionComparisonRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/SelectionComparisonRule.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/SelectionComparisonRule.java	(revision 1146)
@@ -0,0 +1,252 @@
+//   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.taskequality;
+
+import java.util.List;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+
+/**
+ * <p>
+ * this task comparison rule is capable of comparing selections. If both selections do not have
+ * children, they are treated as lexically equal. If they have children, each child of both
+ * selections is compared to each child of the respective other selection. The resulting equality
+ * is the most concrete one of all these comparisons. I.e. if all children are at least lexically
+ * equal, then the selections are lexically equal. If all children are at least syntactically
+ * equal, then the selections are syntactically equal. If all children are at least semantically
+ * equal, then the selections are semantically equal. If only one of the selections has children,
+ * then the selections are unequal.
+ * </p>
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class SelectionComparisonRule implements TaskComparisonRule {
+
+    /** the rule manager for internally comparing tasks */
+    private TaskEqualityRuleManager mRuleManager;
+
+    /**
+     * <p>
+     * simple constructor to provide the rule with the task equality rule manager to be able
+     * to perform comparisons of the children of provided tasks
+     * </p>
+     * 
+     * @param ruleManager the rule manager for comparing tasks
+     */
+    SelectionComparisonRule(TaskEqualityRuleManager ruleManager) {
+        super();
+        mRuleManager = ruleManager;
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     */
+    @Override
+    public boolean isApplicable(ITask task1, ITask task2) {
+        return (task1 instanceof ISelection) && (task2 instanceof ISelection);
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#compare(ITask, ITask)
+     */
+    @Override
+    public TaskEquality compare(ITask task1, ITask task2) {
+        return getEquality(task1, task2, null);
+    }
+
+    /**
+     * 
+     */
+    private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) {
+        List<ITask> children1 = ((ISelection) task1).getChildren();
+        List<ITask> children2 = ((ISelection) task2).getChildren();
+
+        // if both selections do not have children, they are lexically equal. If only one of them
+        // has children, they are unequal.
+        if ((children1.size() == 0) && (children2.size() == 0)) {
+            return TaskEquality.LEXICALLY_EQUAL;
+        }
+        else if ((children1.size() == 0) || (children2.size() == 0)) {
+            return TaskEquality.UNEQUAL;
+        }
+
+        TaskEquality selectionEquality;
+
+        if (requiredEqualityLevel == null) {
+            // calculate the common equality level for all children of both selections.
+            // do it in both directions to ensure commutative comparison
+            selectionEquality = getCommonEqualityLevel(children1, children2);
+            if (selectionEquality != TaskEquality.UNEQUAL) {
+                return selectionEquality.getCommonDenominator
+                    (getCommonEqualityLevel(children2, children1));
+            }
+            else {
+                return TaskEquality.UNEQUAL;
+            }
+        }
+        else {
+            // we are searching for a specific equality
+            if (checkEqualityLevel(children1, children2, requiredEqualityLevel) &&
+                checkEqualityLevel(children2, children1, requiredEqualityLevel))
+            {
+                return requiredEqualityLevel;
+            }
+            else {
+                return TaskEquality.UNEQUAL;
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param children1
+     * @param children2
+     * @param requiredEqualityLevel
+     */
+    private TaskEquality getCommonEqualityLevel(List<ITask> children1, List<ITask> children2) {
+        TaskEquality listEquality = TaskEquality.LEXICALLY_EQUAL;
+        
+        TaskEquality childEquality;
+        TaskEquality currentEquality;
+        for (ITask child1 : children1) {
+            childEquality = null;
+            for (ITask child2 : children2) {
+                currentEquality = callRuleManager(child1, child2, null);
+                if ((currentEquality != null) && (currentEquality != TaskEquality.UNEQUAL)) {
+                    if (childEquality == null) {
+                        childEquality = currentEquality;
+                    }
+                    else {
+                        childEquality = childEquality.getCommonDenominator(currentEquality);
+                    }
+                    
+                    if (childEquality == TaskEquality.SEMANTICALLY_EQUAL) {
+                        // as we calculate only the common denominator, we can break up here for
+                        // the current child. We will not improve the denominator anymore
+                        break;
+                    }
+                }
+            }
+            
+            if (childEquality == null) {
+                // we did not find any child in the second list, that is equal to the searched
+                // child
+                return TaskEquality.UNEQUAL;
+            }
+            else {
+                listEquality = listEquality.getCommonDenominator(childEquality);
+            }
+        }
+
+        return listEquality;
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param children1
+     * @param children2
+     * @param requiredEqualityLevel
+     */
+    private boolean checkEqualityLevel(List<ITask>  children1,
+                                       List<ITask>  children2,
+                                       TaskEquality requiredEqualityLevel)
+    {
+        TaskEquality childEquality;
+        TaskEquality currentEquality;
+        for (ITask child1 : children1) {
+            childEquality = null;
+            for (ITask child2 : children2) {
+                currentEquality = callRuleManager(child1, child2, requiredEqualityLevel);
+                if ((currentEquality != null) && (currentEquality.isAtLeast(requiredEqualityLevel)))
+                {
+                    // we found at least one equal child with sufficient equality in the
+                    // second list. So be can break up for this child.
+                    childEquality = currentEquality;
+                    break;
+                }
+            }
+            
+            if (childEquality == null) {
+                // we did not find any child in the second list, that is equal to the searched
+                // child
+                return false;
+            }
+        }
+
+        // for all children, we found an equality 
+        return true;
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param child1
+     * @param child2
+     * @param requiredEqualityLevel
+     * @return
+     */
+    private TaskEquality callRuleManager(ITask        child1,
+                                         ITask        child2,
+                                         TaskEquality requiredEqualityLevel)
+    {
+        if (requiredEqualityLevel == null) {
+            return mRuleManager.compare(child1, child2);
+        }
+        else if (mRuleManager.areAtLeastEqual(child1, child2, requiredEqualityLevel)) {
+            return requiredEqualityLevel;
+        }
+        else {
+            return TaskEquality.UNEQUAL;
+        }
+    }
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/SequenceComparisonRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/SequenceComparisonRule.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/SequenceComparisonRule.java	(revision 1146)
@@ -0,0 +1,151 @@
+//   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.taskequality;
+
+import java.util.List;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+
+/**
+ * <p>
+ * This rule is capable of comparing sequences. If both sequences do not have children, they are
+ * treated as lexically equal. Sequences are lexically equal, if they have the same number and
+ * order of lexically equal children. The rule can not decide, if two sequences are syntactically
+ * or semantically equal.
+ * </p>
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class SequenceComparisonRule implements TaskComparisonRule {
+
+    /** the rule manager for internally comparing tasks */
+    private TaskEqualityRuleManager mRuleManager;
+
+    /**
+     * <p>
+     * simple constructor to provide the rule with the task equality rule manager to be able
+     * to perform comparisons of the children of provided tasks
+     * </p>
+     * 
+     * @param ruleManager the rule manager for comparing tasks
+     */
+    SequenceComparisonRule(TaskEqualityRuleManager ruleManager) {
+        super();
+        mRuleManager = ruleManager;
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     */
+    @Override
+    public boolean isApplicable(ITask task1, ITask task2) {
+        return (task1 instanceof ISequence) && (task2 instanceof ISequence);
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#compare(ITask, ITask)
+     */
+    @Override
+    public TaskEquality compare(ITask task1, ITask task2) {
+        return getEquality(task1, task2, null);
+    }
+
+    /**
+     * 
+     */
+    private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) {
+        List<ITask> children1 = ((ISequence) task1).getChildren();
+        List<ITask> children2 = ((ISequence) task2).getChildren();
+
+        // if both sequences do not have children, they are equal although this doesn't make sense
+        if ((children1.size() == 0) && (children2.size() == 0)) {
+            return TaskEquality.LEXICALLY_EQUAL;
+        }
+
+        if (children1.size() != children2.size()) {
+            return TaskEquality.UNEQUAL;
+        }
+
+        TaskEquality resultingEquality = TaskEquality.LEXICALLY_EQUAL;
+        for (int i = 0; i < children1.size(); i++) {
+            ITask child1 = children1.get(i);
+            ITask child2 = children2.get(i);
+
+            TaskEquality taskEquality = callRuleManager(child1, child2, requiredEqualityLevel);
+
+            if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL)) {
+                return TaskEquality.UNEQUAL;
+            }
+            
+            resultingEquality = resultingEquality.getCommonDenominator(taskEquality);
+        }
+
+        return resultingEquality;
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param child1
+     * @param child2
+     * @param requiredEqualityLevel
+     * @return
+     */
+    private TaskEquality callRuleManager(ITask        child1,
+                                         ITask        child2,
+                                         TaskEquality requiredEqualityLevel)
+    {
+        if (requiredEqualityLevel == null) {
+            return mRuleManager.compare(child1, child2);
+        }
+        else if (mRuleManager.areAtLeastEqual(child1, child2, requiredEqualityLevel)) {
+            return requiredEqualityLevel;
+        }
+        else {
+            return TaskEquality.UNEQUAL;
+        }
+    }
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskAndIterationComparisonRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskAndIterationComparisonRule.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskAndIterationComparisonRule.java	(revision 1146)
@@ -0,0 +1,168 @@
+//   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.taskequality;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+
+/**
+ * <p>
+ * This class is capable of comparing any task which is not an iteration with an
+ * iteration. This is needed, because iterations may iterate exactly that task. In this
+ * case, the iteration would be equal to that task if it was executed exactly once. The rule
+ * returns lexically equal, it the child of the iteration is lexically equal to the task
+ * or if the child of the iteration is a selection and this selections contains a lexically equal
+ * task. The same applies for syntactical and semantical equality.
+ * </p>
+
+ * @author Patrick Harms
+ */
+public class TaskAndIterationComparisonRule implements TaskComparisonRule {
+    
+    /** the rule manager for internally comparing tasks */
+    private TaskEqualityRuleManager mRuleManager;
+
+    /**
+     * <p>
+     * simple constructor to provide the rule with the task equality rule manager to be able
+     * to perform comparisons of the children of provided tasks
+     * </p>
+     * 
+     * @param ruleManager the rule manager for comparing tasks
+     */
+    TaskAndIterationComparisonRule(TaskEqualityRuleManager ruleManager) {
+        super();
+        mRuleManager = ruleManager;
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     */
+    @Override
+    public boolean isApplicable(ITask task1, ITask task2) {
+        return ((task1 instanceof IIteration) && (!(task2 instanceof IIteration))) ||
+               ((task2 instanceof IIteration) && (!(task1 instanceof IIteration)));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#compare(ITask, ITask)
+     */
+    @Override
+    public TaskEquality compare(ITask task1, ITask task2) {
+        return getEquality(task1, task2, null);
+    }
+
+    /**
+     * 
+     */
+    private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) {
+        IIteration iteration = null;
+        ITask task = null;
+        
+        if (task1 instanceof IIteration) {
+            if (task2 instanceof IIteration) {
+                // the rule is not responsible for two iterations
+                return null;
+            }
+            
+            iteration = (IIteration) task1;
+            task = task2;
+        }
+        else if (task2 instanceof IIteration) {
+            if (task1 instanceof IIteration) {
+                // the rule is not responsible for two iterations
+                return null;
+            }
+            
+            iteration = (IIteration) task2;
+            task = task1;
+        }
+        else {
+            return null;
+        }
+
+        ITask child = iteration.getMarkedTask();
+        
+        // now, that we found the iteration and the task, lets compare the child of the iteration
+        // with the task.
+        if (child == null) {
+            return null;
+        }
+
+        TaskEquality taskEquality = callRuleManager(child, task, requiredEqualityLevel);
+
+        // although the subtask may be identical to the task, we can not return identical, as
+        // the iteration is not identical to the task, but at most lexically equal
+        if (taskEquality == TaskEquality.IDENTICAL) {
+            return TaskEquality.LEXICALLY_EQUAL;
+        }
+        else {
+            return taskEquality;
+        }
+
+    }
+    
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param child1
+     * @param child2
+     * @param requiredEqualityLevel
+     * @return
+     */
+    private TaskEquality callRuleManager(ITask        child1,
+                                         ITask        child2,
+                                         TaskEquality requiredEqualityLevel)
+    {
+        if (requiredEqualityLevel == null) {
+            return mRuleManager.compare(child1, child2);
+        }
+        else if (mRuleManager.areAtLeastEqual(child1, child2, requiredEqualityLevel)) {
+            return requiredEqualityLevel;
+        }
+        else {
+            return TaskEquality.UNEQUAL;
+        }
+    }
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskAndSelectionComparisonRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskAndSelectionComparisonRule.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskAndSelectionComparisonRule.java	(revision 1146)
@@ -0,0 +1,192 @@
+//   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.taskequality;
+
+import java.util.List;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+
+/**
+ * <p>
+ * This class is capable of comparing any task which is not a selection with a
+ * selection. This is needed, because selections may contain exactly that task. Therefore, if
+ * this task is selected out of a selection the selection is equal to the task itself. 
+ * The rule returns lexically equal, if the selection contains a lexically equal task. The same
+ * applies for syntactical and semantical equality.
+ * </p>
+
+ * @author Patrick Harms
+ */
+public class TaskAndSelectionComparisonRule implements TaskComparisonRule {
+    
+    /** the rule manager for internally comparing tasks */
+    private TaskEqualityRuleManager mRuleManager;
+    
+    /**
+     * <p>
+     * simple constructor to provide the rule with the task equality rule manager to be able
+     * to perform comparisons of the children of provided tasks
+     * </p>
+     * 
+     * @param ruleManager the rule manager for comparing tasks
+     */
+    TaskAndSelectionComparisonRule(TaskEqualityRuleManager ruleManager) {
+        super();
+        mRuleManager = ruleManager;
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     */
+    @Override
+    public boolean isApplicable(ITask task1, ITask task2) {
+        return ((task1 instanceof ISelection) && (!(task2 instanceof ISelection))) ||
+               ((task2 instanceof ISelection) && (!(task1 instanceof ISelection)));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.LEXICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.SYNTACTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITask task1, ITask task2) {
+        TaskEquality equality = getEquality(task1, task2, TaskEquality.SEMANTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#compare(ITask, ITask)
+     */
+    @Override
+    public TaskEquality compare(ITask task1, ITask task2) {
+        return getEquality(task1, task2, null);
+    }
+    
+    /**
+     * 
+     */
+    private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) {
+        ISelection selection = null;
+        ITask task = null;
+        
+        if (task1 instanceof ISelection) {
+            if (task2 instanceof ISelection) {
+                // the rule is not responsible for two selections
+                return null;
+            }
+            
+            selection = (ISelection) task1;
+            task = task2;
+        }
+        else if (task2 instanceof ISelection) {
+            if (task1 instanceof ISelection) {
+                // the rule is not responsible for two selections
+                return null;
+            }
+            
+            selection = (ISelection) task2;
+            task = task1;
+        }
+        else {
+            return null;
+        }
+
+        // now, that we found the selection and the task, lets compare the children of the selection
+        // with the task.
+        List<ITask> children = selection.getChildren();
+        
+        if (children.size() < 1) {
+            return null;
+        }
+
+        TaskEquality mostConcreteNodeEquality = null;
+        
+        for (ITask child : children) {
+            TaskEquality taskEquality = callRuleManager(child, task, requiredEqualityLevel);
+            
+            if (taskEquality != TaskEquality.UNEQUAL) {
+                if (mostConcreteNodeEquality == null) {
+                    mostConcreteNodeEquality = taskEquality;
+                }
+                else if (mostConcreteNodeEquality.isAtLeast(taskEquality)) {
+                    mostConcreteNodeEquality = taskEquality;
+                    
+                }
+                
+                if ((requiredEqualityLevel != null) &&
+                    (mostConcreteNodeEquality.isAtLeast(requiredEqualityLevel)))
+                {
+                    // if we found one child of the selection that is as equal as required, then
+                    // we can consider the selection to be sufficiently equal to the other task.
+                    // So we break up checking further children.
+                    break;
+                }
+            }
+        }
+        
+        // although the subtask may be identical to the task, we can not return identical, as
+        // the selection is not identical to the task, but at most lexically equal
+        if (mostConcreteNodeEquality == TaskEquality.IDENTICAL) {
+            return TaskEquality.LEXICALLY_EQUAL;
+        }
+        else {
+            return mostConcreteNodeEquality;
+        }
+
+    }
+    
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param child1
+     * @param child2
+     * @param requiredEqualityLevel
+     * @return
+     */
+    private TaskEquality callRuleManager(ITask        child1,
+                                         ITask        child2,
+                                         TaskEquality requiredEqualityLevel)
+    {
+        if (requiredEqualityLevel == null) {
+            return mRuleManager.compare(child1, child2);
+        }
+        else if (mRuleManager.areAtLeastEqual(child1, child2, requiredEqualityLevel)) {
+            return requiredEqualityLevel;
+        }
+        else {
+            return TaskEquality.UNEQUAL;
+        }
+    }
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskComparator.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskComparator.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskComparator.java	(revision 1146)
@@ -0,0 +1,247 @@
+//   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.taskequality;
+
+import java.util.HashMap;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.usageprofiles.SymbolComparator;
+import de.ugoe.cs.util.StopWatch;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public class TaskComparator implements SymbolComparator<ITaskInstance> {
+    
+    /**
+     * <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;
+
+    /** */
+    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;
+
+    /**
+     *
+     */
+    public TaskComparator(TaskEqualityRuleManager taskEqualityRuleManager,
+                                  TaskEquality            minimalNodeEquality)
+    {
+        super();
+        this.taskEqualityRuleManager = taskEqualityRuleManager;
+        this.minimalNodeEquality = minimalNodeEquality;
+        
+        if (minimalNodeEquality == TaskEquality.LEXICALLY_EQUAL) {
+            comparer = new LexicalComparer();
+        }
+        else if (minimalNodeEquality == TaskEquality.SYNTACTICALLY_EQUAL) {
+            comparer = new SyntacticalComparer();
+        }
+        else if (minimalNodeEquality == TaskEquality.SEMANTICALLY_EQUAL) {
+            comparer = new SemanticalComparer();
+        }
+        else {
+            comparer = new DefaultComparer();
+        }
+        
+        if (minimalNodeEquality == TaskEquality.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(ITaskInstance taskInstance1, ITaskInstance taskInstance2) {
+        return equals(taskInstance1.getTask(), taskInstance2.getTask());
+    }        
+
+    /**
+     * 
+     */
+    public boolean equals(ITask task1, ITask task2) {
+        //String id = "compare " + taskInstance1.getClass().getSimpleName() + " " +
+        //    taskInstance2.getClass().getSimpleName();
+        //String id = "compare";
+        //stopWatch.start(id);
+        
+        Boolean result;
+        
+        if (task1 != task2) {
+            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 = true;
+        }
+        //stopWatch.stop(id);
+        
+        /*boolean result2 = taskEqualityRuleManager.areAtLeastEqual(symbol1, symbol2, minimalNodeEquality);
+        if (result != result2) {
+            throw new IllegalStateException("implementation error");
+        }*/
+        
+        return result;
+    }
+
+    /**
+     *
+     */
+    public boolean haveLexicallyEqualTasks(ITaskInstance taskInstance1,
+                                           ITaskInstance taskInstance2)
+    {
+        return areLexicallyEqual(taskInstance1.getTask(), taskInstance2.getTask());
+    }
+        
+
+    /**
+     *
+     */
+    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;
+    }
+
+    /**
+     *
+     */
+    StopWatch getStopWatch() {
+        return stopWatch;
+    }
+
+    /**
+     *
+     */
+    TaskEquality getConsideredNodeEquality() {
+        return minimalNodeEquality;
+    }
+
+    /**
+     * 
+     */
+    private interface Comparer {
+        /**
+         * 
+         */
+        boolean compare(ITask task1, ITask task2);
+    }
+
+    /**
+     * 
+     */
+    private class LexicalComparer implements Comparer {
+        
+        /**
+         * 
+         */
+        public boolean compare(ITask task1, ITask task2) {
+            return taskEqualityRuleManager.areLexicallyEqual(task1, task2);
+        }
+    }
+
+    /**
+     * 
+     */
+    private class SyntacticalComparer implements Comparer {
+        
+        /**
+         * 
+         */
+        public boolean compare(ITask task1, ITask task2) {
+            return taskEqualityRuleManager.areSyntacticallyEqual(task1, task2);
+        }
+    }
+
+    /**
+     * 
+     */
+    private class SemanticalComparer implements Comparer {
+        
+        /**
+         * 
+         */
+        public boolean compare(ITask task1, ITask task2) {
+            return taskEqualityRuleManager.areSemanticallyEqual(task1, task2);
+        }
+    }
+
+    /**
+     * 
+     */
+    private class DefaultComparer implements Comparer {
+        
+        /**
+         * 
+         */
+        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/taskequality/TaskComparisonRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskComparisonRule.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskComparisonRule.java	(revision 1146)
@@ -0,0 +1,92 @@
+//   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.taskequality;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+
+/**
+ * <p>
+ * A task comparison rule is used by the {@link TaskEqualityRuleManager} to compare tasks with
+ * each other. It provides several methods to be called for a comparison.
+ * </p>
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public interface TaskComparisonRule {
+
+    /**
+     * <p>
+     * checks if the rule is applicable for comparing the two provided tasks
+     * </p>
+     * 
+     * @param task1 the first task to compare
+     * @param task2 the second task to compare
+     * 
+     * @return true, if the rule is applicable, false else
+     */
+    public boolean isApplicable(ITask task1, ITask task2);
+
+    /**
+     * <p>
+     * checks, if the provided tasks are lexically equal
+     * </p>
+     * 
+     * @param task1 the first task to compare
+     * @param task2 the second task to compare
+     * 
+     * @return true, if the tasks are equal, false else
+     */
+    public boolean areLexicallyEqual(ITask task1, ITask task2);
+
+    /**
+     * <p>
+     * checks, if the provided tasks are syntactically equal
+     * </p>
+     * 
+     * @param task1 the first task to compare
+     * @param task2 the second task to compare
+     * 
+     * @return true, if the tasks are equal, false else
+     */
+    public boolean areSyntacticallyEqual(ITask task1, ITask task2);
+
+    /**
+     * <p>
+     * checks, if the provided tasks are semantically equal
+     * </p>
+     * 
+     * @param task1 the first task to compare
+     * @param task2 the second task to compare
+     * 
+     * @return true, if the tasks are equal, false else
+     */
+    public boolean areSemanticallyEqual(ITask task1, ITask task2);
+
+    /**
+     * <p>
+     * compares two tasks with each other. The result of the method is either a task equality or
+     * null. If it is null, it means, that the rule is not able to correctly compare the two given
+     * tasks
+     * </p>
+     * 
+     * @param task1 the first task to compare
+     * @param task2 the second task to compare
+     * 
+     * @return as described
+     */
+    public TaskEquality compare(ITask task1, ITask task2);
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskEquality.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskEquality.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskEquality.java	(revision 1146)
@@ -0,0 +1,128 @@
+//   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.taskequality;
+
+/**
+ * <p>
+ * A task equality denotes, how equal two tasks are. There are different equality levels
+ * which are similar to the usual design levels of GUI design. These levels are
+ * <ul>
+ *   <li>conceptual design: defines the concepts to be edited using a GUI</li>
+ *   <li>semantical design: defines the possible functions for editing the concepts</li>
+ *   <li>syntactical design: defines, which steps are needed to execute the functions</li>
+ *   <li>lexical design: defines on the key stroke level, how the steps for executing a function
+ *       can be performed</li>
+ * </ul>
+ * It is not possible to compare two tasks conceptually. But the other design levels can be
+ * identified and compared.
+ * </p>
+ * <p>
+ * Tasks can be identical. This is the case if in the java virtual machine, their comparison
+ * using the <code>==</code> operator or the equals method return true.
+ * </p>
+ * <p>
+ * Tasks are lexically equal, if they represent the same events on a key stroke level to be
+ * carried out to execute the task. Identical tasks are also syntactically equal.
+ * </p>
+ * <p>
+ * Nodes are syntactically equal, if they differ in their events on key stroke level, but the
+ * syntactical result is the same. For example, entering the text "hello" into a text field can
+ * be done by entering the letters in their correct order, but also by copying the text into the
+ * text field. The syntactical result is the same: The text "hello" was entered. But the tasks
+ * lexically differ because the events on key stroke level are different. On the other hand,
+ * lexically equal tasks are also syntactically equal.  
+ * </p>
+ * <p>
+ * Tasks are semantically equal, if they execute the same function for editing the concepts. An
+ * example are a click on a button and a short cut, both executing the same function. These tasks
+ * are syntactically and, therefore, also lexically different, but semantically equal.
+ * Syntactically equal tasks are always also semantically equal.
+ * </p>
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public enum TaskEquality {
+    IDENTICAL,
+    LEXICALLY_EQUAL,
+    SYNTACTICALLY_EQUAL,
+    SEMANTICALLY_EQUAL,
+    UNEQUAL;
+
+    /**
+     * <p>
+     * Checks for the current task equality, if it is at least identical to the
+     * provided one or even more concrete. As an example, the task equality identical also
+     * indicates, that the tasks are e.g. lexically, syntactically and semantically equal.
+     * Therefore, the method called on <code>IDENTICAL</code> with <code>SEMANTICALLY_EQUAL</code>
+     * as parameter will return true. If this method is called on <code>SYNTACTICALLY_EQUAL</code>
+     * with the parameter <code>IDENTICAL</code> instead, it returns false;
+     * </p>
+     *
+     * @param taskEquality the task equality to compare with.
+     * 
+     * @return as described
+     */
+    public boolean isAtLeast(TaskEquality taskEquality)
+    {
+        switch (taskEquality) {
+            case IDENTICAL:
+                return
+                    (this == IDENTICAL);
+            case LEXICALLY_EQUAL:
+                return
+                    (this == IDENTICAL) ||
+                    (this == LEXICALLY_EQUAL);
+            case SYNTACTICALLY_EQUAL:
+                return
+                    (this == IDENTICAL) ||
+                    (this == LEXICALLY_EQUAL) ||
+                    (this == SYNTACTICALLY_EQUAL);
+            case SEMANTICALLY_EQUAL:
+                return
+                    (this == IDENTICAL) ||
+                    (this == LEXICALLY_EQUAL) ||
+                    (this == SYNTACTICALLY_EQUAL) ||
+                    (this == SEMANTICALLY_EQUAL);
+            case UNEQUAL:
+                return
+                    (this == UNEQUAL);
+            default :
+                return false;
+        }
+    }
+
+    /**
+     * <p>
+     * returns the common denominator of this task equality and the provided one. I.e. if one
+     * equality is e.g. syntactical and the other one only semantical, then semantical is returned.
+     * </p>
+     *
+     * @param equality the equality, to compare this with
+     * 
+     * @return as described
+     */
+    public TaskEquality getCommonDenominator(TaskEquality otherEquality) {
+        if (this.isAtLeast(otherEquality)) {
+            return otherEquality;
+        }
+        else if (otherEquality.isAtLeast(this)) {
+            return this;
+        }
+        else {
+            return TaskEquality.UNEQUAL;
+        }
+    }
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskEqualityRuleManager.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskEqualityRuleManager.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskEqualityRuleManager.java	(revision 1146)
@@ -0,0 +1,222 @@
+//   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.taskequality;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+
+/**
+ * <p>
+ * The task equality rule manager is capable of comparing tasks based on its internal list
+ * of comparison rules. The current list of rules contains the {@link TaskIdentityRule}, the
+ * {@link IterationComparisonRule}, the {@link SequenceComparisonRule}, and
+ * {@link SelectionComparisonRule}. These rules are asked for comparing the two provided tasks
+ * in the mentioned order. If a rule returns a task equality other than null, this equality is
+ * returned. Otherwise the next rule is asked.
+ * </p>
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class TaskEqualityRuleManager {
+
+    /** */
+    private List<TaskComparisonRule> mRuleIndex = null;
+
+    /**
+     * <p>
+     * initializes the task equality rule manager by filling the internal list of comparison rules.
+     * This method must be called before any other method is called on the rule manager.
+     * </p>
+     */
+    public void init() {
+        mRuleIndex = new ArrayList<TaskComparisonRule>();
+        mRuleIndex.add(new TaskIdentityRule());
+        mRuleIndex.add(new GUIEventTaskComparisonRule());
+        mRuleIndex.add(new EventTaskComparisonRule());
+        mRuleIndex.add(new IterationComparisonRule(this));
+        mRuleIndex.add(new SequenceComparisonRule(this));
+        mRuleIndex.add(new SelectionComparisonRule(this));
+        mRuleIndex.add(new TaskAndIterationComparisonRule(this));
+        mRuleIndex.add(new TaskAndSelectionComparisonRule(this));
+    }
+
+    /**
+     * <p>
+     * this method performs a comparison of the two provided tasks. It iterates its internal
+     * comparison rules. If the first rule returns a task equality other than null,
+     * this equality is returned. Otherwise the next rule is tried. If no rule returns an equality
+     * <code>NodeEquality.UNEQUAL</code> is returned.
+     * </p>
+     * 
+     * @param task1 the first task to be compared
+     * @param task2 the second task to be compared
+     * 
+     * @return as described
+     * 
+     * @throws IllegalStateException in the case, the {@link #init()} method was not called on the
+     *                               manager before a call to this method.
+     */
+    public TaskEquality compare(ITask task1, ITask task2)
+        throws IllegalStateException
+    {
+        if (mRuleIndex == null) {
+            throw new IllegalStateException("not initialized");
+        }
+        
+        // LOG.info("checking for equality of " + task1 + " and " + task2);
+        TaskEquality taskEquality = null;
+
+        for (TaskComparisonRule rule : mRuleIndex) {
+            if (rule.isApplicable(task1, task2)) {
+                taskEquality = rule.compare(task1, task2);
+                if (taskEquality != null) {
+                    // LOG.warning("used rule " + rule + " for equality check");
+                    return taskEquality;
+                }
+            }
+        }
+
+        // LOG.warning("no rule could be applied --> handling tasks as unequal");
+
+        return TaskEquality.UNEQUAL;
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param child1
+     * @param child2
+     * @param equalityLevel
+     * @return
+     */
+    public boolean areAtLeastEqual(ITask task1, ITask task2, TaskEquality equalityLevel) {
+        if (equalityLevel == null) {
+            throw new IllegalArgumentException("required equality level must not be null");
+        }
+        
+        switch (equalityLevel) {
+            case IDENTICAL:
+                return areIdentical(task1, task2);
+            case LEXICALLY_EQUAL:
+                return areLexicallyEqual(task1, task2);
+            case SYNTACTICALLY_EQUAL:
+                return areSyntacticallyEqual(task1, task2);
+            case SEMANTICALLY_EQUAL:
+                return areSemanticallyEqual(task1, task2);
+            case UNEQUAL:
+                return !areSemanticallyEqual(task1, task2);
+            default:
+                throw new IllegalArgumentException("unknown required equality: " + equalityLevel);
+        }
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param child1
+     * @param child2
+     * @return
+     */
+    public boolean areIdentical(ITask task1, ITask task2) {
+        if (mRuleIndex == null) {
+            throw new IllegalStateException("not initialized");
+        }
+        
+        for (TaskComparisonRule rule : mRuleIndex) {
+            if (rule.isApplicable(task1, task2) && rule.areLexicallyEqual(task1, task2)) {
+                 return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param child1
+     * @param child2
+     * @return
+     */
+    public boolean areLexicallyEqual(ITask task1, ITask task2) {
+        if (mRuleIndex == null) {
+            throw new IllegalStateException("not initialized");
+        }
+        
+        for (TaskComparisonRule rule : mRuleIndex) {
+            if (rule.isApplicable(task1, task2) && rule.areLexicallyEqual(task1, task2)) {
+                 return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param child1
+     * @param child2
+     * @return
+     */
+    public boolean areSyntacticallyEqual(ITask task1, ITask task2) {
+        if (mRuleIndex == null) {
+            throw new IllegalStateException("not initialized");
+        }
+        
+        for (TaskComparisonRule rule : mRuleIndex) {
+            if (rule.isApplicable(task1, task2) && rule.areSyntacticallyEqual(task1, task2)) {
+                 return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param child1
+     * @param child2
+     * @return
+     */
+    public boolean areSemanticallyEqual(ITask task1, ITask task2) {
+        if (mRuleIndex == null) {
+            throw new IllegalStateException("not initialized");
+        }
+        
+        for (TaskComparisonRule rule : mRuleIndex) {
+            if (rule.isApplicable(task1, task2) && rule.areSemanticallyEqual(task1, task2)) {
+                 return true;
+            }
+        }
+
+        return false;
+    }
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskIdentityRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskIdentityRule.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskIdentityRule.java	(revision 1146)
@@ -0,0 +1,76 @@
+//   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.taskequality;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+
+/**
+ * <p>
+ * This comparison rule returns <code>TaskEquality.IDENTICAL</code> if the comparison of the two
+ * tasks using the <code>==</code> operator or the <code>equals</code> method return true.
+ * Else it returns null to denote, that it can not compare the tasks.
+ * </p>
+ * 
+ * @version $Revision: $ $Date: 19.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class TaskIdentityRule implements TaskComparisonRule {
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     */
+    @Override
+    public boolean isApplicable(ITask task1, ITask task2) {
+        return (task1 == task2);
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITask task1, ITask task2) {
+        return (task1 == task2);
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITask task1, ITask task2) {
+        return (task1 == task2);
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITask task1, ITask task2) {
+        return (task1 == task2);
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#compare(ITask, ITask)
+     */
+    @Override
+    public TaskEquality compare(ITask task1, ITask task2) {
+        if (isApplicable(task1, task2)) {
+            return TaskEquality.IDENTICAL;
+        }
+        else {
+            return null;
+        }
+    }
+
+}
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);
-        }
-    }
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IEventTask.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IEventTask.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IEventTask.java	(revision 1146)
@@ -24,5 +24,5 @@
  * @author 2011, last modified by $Author: $
  */
-public interface IEventTask extends ITaskTreeNode {
+public interface IEventTask extends ITask {
     
     /**
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IIteration.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IIteration.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IIteration.java	(revision 1146)
@@ -21,5 +21,5 @@
  * @author 2012, last modified by $Author: patrick$
  */
-public interface IIteration extends ITemporalRelationship {
+public interface IIteration extends IMarkingTemporalRelationship {
 
     /**
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IMarkingTemporalRelationship.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IMarkingTemporalRelationship.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IMarkingTemporalRelationship.java	(revision 1146)
@@ -0,0 +1,36 @@
+//   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.treeifc;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public interface IMarkingTemporalRelationship extends ITemporalRelationship {
+
+    /**
+     *
+     */
+    public ITask getMarkedTask();
+
+    /**
+     *
+     */
+    public IMarkingTemporalRelationship clone();
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IOptional.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IOptional.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IOptional.java	(revision 1146)
@@ -21,5 +21,5 @@
  * @author 2012, last modified by $Author: patrick$
  */
-public interface IOptional extends ITemporalRelationship {
+public interface IOptional extends IMarkingTemporalRelationship {
 
     /**
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ISelection.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ISelection.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ISelection.java	(revision 1146)
@@ -21,5 +21,5 @@
  * @author 2012, last modified by $Author: patrick$
  */
-public interface ISelection extends ITemporalRelationship {
+public interface ISelection extends IStructuringTemporalRelationship {
 
     /**
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ISequence.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ISequence.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ISequence.java	(revision 1146)
@@ -21,5 +21,5 @@
  * @author 2012, last modified by $Author: patrick$
  */
-public interface ISequence extends ITemporalRelationship {
+public interface ISequence extends IStructuringTemporalRelationship {
 
     /**
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IStructuringTemporalRelationship.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IStructuringTemporalRelationship.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IStructuringTemporalRelationship.java	(revision 1146)
@@ -0,0 +1,38 @@
+//   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.treeifc;
+
+import java.util.List;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public interface IStructuringTemporalRelationship extends ITemporalRelationship {
+
+    /**
+     *
+     */
+    public List<ITask> getChildren();
+
+    /**
+     *
+     */
+    public IStructuringTemporalRelationship clone();
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITask.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITask.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITask.java	(revision 1146)
@@ -0,0 +1,52 @@
+//   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.treeifc;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public interface ITask extends Cloneable, Serializable {
+
+    /**
+     *
+     */
+    public int getId();
+
+    /**
+     *
+     */
+    public String getDescription();
+
+    /**
+     *
+     */
+    public boolean equals(ITask task);
+
+    /**
+     *
+     */
+    public int hashCode();
+
+    /**
+     *
+     */
+    public ITask clone();
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskBuilder.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskBuilder.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskBuilder.java	(revision 1146)
@@ -0,0 +1,144 @@
+//   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.treeifc;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public interface ITaskBuilder {
+
+    /**
+     * @param taskInstance
+     * @param child
+     */
+    void addChild(ITaskInstance taskInstance, ITaskInstance child) throws IllegalArgumentException;
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param session
+     * @param taskInstance
+     */
+    void addExecutedTask(IUserSession session, ITaskInstance taskInstance);
+
+    /**
+     * 
+     * @param parent
+     * @param i
+     */
+    void addTaskInstance(ITaskInstanceList taskInstanceList, ITaskInstance taskInstance);
+
+    /**
+     * 
+     * @param parent
+     * @param i
+     */
+    void addTaskInstance(ITaskInstanceList taskInstanceList, int index, ITaskInstance taskInstance);
+
+    /**
+     * 
+     * @param parent
+     * @param i
+     */
+    void setTaskInstance(ITaskInstanceList taskInstanceList, int index, ITaskInstance taskInstance);
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param instance2
+     * @param task
+     */
+    void setTask(ITaskInstance taskInstance, ITask task);
+
+    /**
+     *
+     */
+    void addChild(ISequence parent, ITask child);
+
+    /**
+     *
+     */
+    void addChild(ISequence parent, int index, ITask child);
+
+    /**
+     * 
+     * @param parent
+     * @param i
+     */
+    void setChild(ISequence parent, int index, ITask child);
+
+    /**
+     * @param sequence
+     * @param task
+     */
+    void addChild(ISelection parent, ITask child);
+
+    /**
+     * 
+     * @param iteration
+     * @param newChild
+     */
+    void setMarkedTask(IIteration iteration, ITask newChild);
+
+    /**
+     * 
+     * @param optional
+     * @param newChild
+     */
+    void setMarkedTask(IOptional optional, ITask newChild);
+
+    /**
+     * 
+     * @param parent
+     * @param i
+     */
+    void removeChild(ISequence parent, int index);
+
+    /**
+     *
+     * @param parent
+     * @param i
+     */
+    void removeChild(ISelection parent, ITask child);
+
+    /**
+     * 
+     * @param parent
+     * @param i
+     */
+    void removeTaskInstance(ITaskInstanceList taskInstanceList, int index);
+
+    /**
+     *
+     * @param parent
+     * @param i
+     */
+    void replaceChild(ISelection parent, ITask oldChild, ITask newChild);
+
+    /**
+     * 
+     * @param parent
+     * @param i
+     */
+    void setDescription(ITask task, String description);
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskFactory.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskFactory.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskFactory.java	(revision 1146)
@@ -0,0 +1,87 @@
+//   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.treeifc;
+
+import java.util.List;
+
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+import de.ugoe.cs.autoquest.eventcore.IEventType;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public interface ITaskFactory {
+
+    /**
+     * 
+     * @param eventType
+     * @param eventTarget
+     * @return
+     */
+    IEventTask createNewEventTask(IEventType eventType, IEventTarget eventTarget);
+
+    /**
+     * 
+     * @return
+     */
+    ISequence createNewSequence();
+
+    /**
+     * 
+     * @return
+     */
+    IIteration createNewIteration();
+
+    /**
+     * 
+     * @return
+     */
+    IOptional createNewOptional();
+
+    /**
+     * 
+     * @return
+     */
+    ISelection createNewSelection();
+
+    /**
+     * 
+     * @return
+     */
+    ITaskInstance createNewTaskInstance(ITask task);
+
+    /**
+     *
+     * @return
+     */
+    ITaskInstanceList createNewTaskInstanceList();
+
+    /**
+     * 
+     * @return
+     */
+    IUserSession createUserSession();
+
+    /**
+     * 
+     * @param rootSequence
+     * @return
+     */
+    ITaskModel createTaskModel(List<IUserSession> userSessions);
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInfo.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInfo.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInfo.java	(revision 1146)
@@ -0,0 +1,32 @@
+//   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.treeifc;
+
+import java.io.Serializable;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public interface ITaskInfo extends Serializable {
+
+    /**
+     * 
+     */
+    public ITask getTask();
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInstance.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInstance.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInstance.java	(revision 1146)
@@ -0,0 +1,52 @@
+//   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.treeifc;
+
+import java.util.List;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: $
+ * @author 2011, last modified by $Author: $
+ */
+public interface ITaskInstance extends ITaskInstanceList {
+
+    /**
+     *
+     */
+    public List<ITaskInstance> getChildren();
+
+    /**
+     *
+     */
+    public ITask getTask();
+
+    /**
+     *
+     */
+    public boolean equals(ITaskInstance taskInstance);
+
+    /**
+     *
+     */
+    public int hashCode();
+
+    /**
+     *
+     */
+    public ITaskInstance clone();
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInstanceList.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInstanceList.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskInstanceList.java	(revision 1146)
@@ -0,0 +1,43 @@
+//   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.treeifc;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public interface ITaskInstanceList extends Serializable, Cloneable, Iterable<ITaskInstance> {
+
+    /**
+     *
+     */
+    public ITaskInstance get(int index);
+
+    /**
+     *
+     */
+    public int size();
+
+    /**
+     *
+     */
+    public ITaskInstanceList clone();
+  
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskModel.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskModel.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskModel.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.treeifc;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public interface ITaskModel extends Cloneable, Serializable {
+
+    /**
+     *
+     */
+    public List<IUserSession> getUserSessions();
+
+    /**
+     *
+     */
+    public Collection<ITask> getTasks();
+
+    /**
+     *
+     */
+    public ITaskInfo getTaskInfo(ITask task);
+
+    /**
+     *
+     */
+    public ITaskModel clone();
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskTree.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskTree.java	(revision 1133)
+++ 	(revision )
@@ -1,41 +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.treeifc;
-
-import java.util.Map;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: 21.02.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-public interface ITaskTree extends Cloneable {
-
-    /**
-     *
-     */
-    public ITaskTreeNode getRoot();
-
-    /**
-     *
-     */
-    public Map<ITaskTreeNode, ITaskTreeNodeInfo> getTaskMap();
-
-    /**
-     *
-     */
-    public ITaskTree clone();
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskTreeBuilder.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskTreeBuilder.java	(revision 1133)
+++ 	(revision )
@@ -1,90 +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.treeifc;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: 21.02.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-public interface ITaskTreeBuilder {
-
-    /**
-     *
-     */
-    void addChild(ISequence parent, ITaskTreeNode child);
-
-    /**
-     *
-     */
-    void addChild(ISequence parent, int index, ITaskTreeNode child);
-
-    /**
-     * 
-     * @param parent
-     * @param i
-     */
-    void setChild(ISequence parent, int index, ITaskTreeNode child);
-
-    /**
-     * @param sequence
-     * @param task
-     */
-    void addChild(ISelection parent, ITaskTreeNode child);
-
-    /**
-     * 
-     * @param iteration
-     * @param newChild
-     */
-    void setChild(IIteration iteration, ITaskTreeNode newChild);
-
-    /**
-     * 
-     * @param optional
-     * @param newChild
-     */
-    void setChild(IOptional optional, ITaskTreeNode newChild);
-
-    /**
-     * 
-     * @param parent
-     * @param i
-     */
-    void removeChild(ISequence parent, int index);
-
-    /**
-     *
-     * @param parent
-     * @param i
-     */
-    void removeChild(ISelection parent, ITaskTreeNode child);
-
-    /**
-     *
-     * @param parent
-     * @param i
-     */
-    void replaceChild(ISelection parent, ITaskTreeNode oldChild, ITaskTreeNode newChild);
-
-    /**
-     * 
-     * @param parent
-     * @param i
-     */
-    void setDescription(ITaskTreeNode node, String description);
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskTreeNode.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskTreeNode.java	(revision 1133)
+++ 	(revision )
@@ -1,57 +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.treeifc;
-
-import java.util.List;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: $
- * @author 2011, last modified by $Author: $
- */
-public interface ITaskTreeNode extends Cloneable {
-
-    /**
-     *
-     */
-    public String getName();
-
-    /**
-     *
-     */
-    public String getDescription();
-
-    /**
-     *
-     */
-    public List<ITaskTreeNode> getChildren();
-
-    /**
-     *
-     */
-    public boolean equals(ITaskTreeNode taskTreeNode);
-
-    /**
-     *
-     */
-    public int hashCode();
-
-    /**
-     *
-     */
-    public ITaskTreeNode clone();
-    
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskTreeNodeFactory.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskTreeNodeFactory.java	(revision 1133)
+++ 	(revision )
@@ -1,68 +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.treeifc;
-
-import de.ugoe.cs.autoquest.eventcore.IEventTarget;
-import de.ugoe.cs.autoquest.eventcore.IEventType;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: 21.02.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-public interface ITaskTreeNodeFactory
-{
-
-  /**
-   *
-   * @param eventType
-   * @param eventTarget
-   * @return
-   */
-  IEventTask createNewEventTask(IEventType eventType, IEventTarget eventTarget);
-
-  /**
-   *
-   * @return
-   */
-  ISequence createNewSequence();
-
-  /**
-   *
-   * @return
-   */
-  IIteration createNewIteration();
-
-  /**
-   *
-   * @return
-   */
-  IOptional createNewOptional();
-
-  /**
-   *
-   * @return
-   */
-  ISelection createNewSelection();
-
-  /**
-   *
-   * @param rootSequence
-   * @return
-   */
-  ITaskTree createTaskTree(ITaskTreeNode root);
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskTreeNodeInfo.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITaskTreeNodeInfo.java	(revision 1133)
+++ 	(revision )
@@ -1,40 +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.treeifc;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: 21.02.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-public interface ITaskTreeNodeInfo {
-
-    /**
-     * 
-     */
-    public ITaskTreeNode getTask();
-
-    /**
-     * 
-     */
-    public int getNoOfOccurencesInTree();
-
-    /**
-     *
-     */
-    public long getLastUpdate();
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITemporalRelationship.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITemporalRelationship.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/ITemporalRelationship.java	(revision 1146)
@@ -21,5 +21,5 @@
  * @author 2012, last modified by $Author: patrick$
  */
-public interface ITemporalRelationship extends ITaskTreeNode {
+public interface ITemporalRelationship extends ITask {
 
     /**
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IUserSession.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IUserSession.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeifc/IUserSession.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.treeifc;
+
+import java.util.List;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public interface IUserSession extends ITaskInstanceList {
+
+    /**
+     *
+     */
+    public List<ITaskInstance> getExecutedTasks();
+    
+    /**
+     *
+     */
+    public boolean equals(IUserSession userSession);
+
+    /**
+     *
+     */
+    public int hashCode();
+
+    /**
+     *
+     */
+    public IUserSession clone();
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/EventTask.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/EventTask.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/EventTask.java	(revision 1146)
@@ -18,5 +18,4 @@
 import de.ugoe.cs.autoquest.eventcore.IEventType;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
 
 /**
@@ -26,6 +25,9 @@
  * @author 2011, last modified by $Author: $
  */
-public class EventTask extends TaskTreeNode implements IEventTask {
+class EventTask extends Task implements IEventTask {
     
+    /**  */
+    private static final long serialVersionUID = 1L;
+
     /** */
     private IEventType eventType;
@@ -39,6 +41,5 @@
      */
     EventTask(IEventType eventType, IEventTarget eventTarget) {
-        super(eventType.toString());
-        super.setDescription("executed on " + eventTarget);
+        super.setDescription(eventType.toString() + " executed on " + eventTarget);
         this.eventType = eventType;
         this.eventTarget = eventTarget;
@@ -62,29 +63,4 @@
      * (non-Javadoc)
      * 
-     * @see de.harms.ctte.Task#equals(de.harms.ctte.Task)
-     */
-    @Override
-    public boolean equals(ITaskTreeNode task) {
-        if (!(task instanceof IEventTask)) {
-            return false;
-        }
-
-        IEventType otherType = ((IEventTask) task).getEventType();
-        IEventTarget otherTarget = ((IEventTask) task).getEventTarget();
-
-        if (((eventType == otherType) ||
-             ((eventType != null) && (eventType.equals(otherType)))) &&
-            ((eventTarget == otherTarget) ||
-             ((eventTarget != null) && (eventTarget.equals(otherTarget)))))
-        {
-            return true;
-        }
-
-        return false;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
      * @see de.harms.tasktrees.TreeNode#clone()
      */
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Iteration.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Iteration.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Iteration.java	(revision 1146)
@@ -16,5 +16,6 @@
 
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
 
 /**
@@ -24,5 +25,8 @@
  * @author 2012, last modified by $Author: patrick$
  */
-public class Iteration extends TaskTreeNode implements IIteration {
+class Iteration extends MarkingTemporalRelationship implements IIteration {
+
+    /**  */
+    private static final long serialVersionUID = 1L;
 
     /**
@@ -30,30 +34,22 @@
      */
     Iteration() {
-        super("Iteration");
+        super("iteration");
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNode#addChild(TaskTreeNode)
+    /* (non-Javadoc)
+     * @see MarkingTemporalRelationship#setMarkedTask(ITask)
      */
     @Override
-    public void addChild(ITaskTreeNode child) {
-        // adding more children is not allowed
-        throw new UnsupportedOperationException
-            ("iterations may not have a list of children. Use setChild() instead.");
-    }
-
-    /**
-     * TODO: comment
-     * 
-     * @param selection
-     * @return
-     */
-    public void setChild(ITaskTreeNode child) {
-        if (super.getChildren().size() > 0) {
-            super.removeChild(0);
+    protected void setMarkedTask(ITask markedTask) {
+        if (markedTask instanceof IIteration) {
+            throw new IllegalArgumentException
+                ("the marked task of an iteration must not be an iteration");
         }
-        super.addChild(child);
+        else if (markedTask instanceof IOptional) {
+            throw new IllegalArgumentException
+                ("the marked task of an iteration must not be an optional");
+        }
+        
+        super.setMarkedTask(markedTask);
     }
 
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/MarkingTemporalRelationship.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/MarkingTemporalRelationship.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/MarkingTemporalRelationship.java	(revision 1146)
@@ -0,0 +1,93 @@
+//   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.treeimpl;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+abstract class MarkingTemporalRelationship extends Task
+    implements IMarkingTemporalRelationship
+{
+
+    /**  */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    private ITask markedTask;
+    
+    /**
+     * 
+     */
+    private String relationshipType;
+    
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param description
+     */
+    MarkingTemporalRelationship(String relationshipType) {
+        if ((relationshipType == null) || ("".equals(relationshipType))) {
+            throw new IllegalArgumentException
+                ("the relationship type must be something meaningful");
+        }
+        
+        this.relationshipType = relationshipType;
+        super.setDescription(this.relationshipType);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship#getMarkedTask()
+     */
+    @Override
+    public ITask getMarkedTask() {
+        return markedTask;
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.Task#clone()
+     */
+    @Override
+    public synchronized MarkingTemporalRelationship clone() {
+        MarkingTemporalRelationship clone = null;
+        clone = (MarkingTemporalRelationship) super.clone();
+            
+        if (markedTask != null) {
+            clone.markedTask = markedTask.clone();
+        }
+
+        return clone;
+    }
+
+    /**
+     * @param markedTask the markedTask to set
+     */
+    protected void setMarkedTask(ITask markedTask) {
+        this.markedTask = markedTask;
+        
+        super.setDescription(relationshipType + " of " + markedTask);
+    }
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/NodeInfo.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/NodeInfo.java	(revision 1133)
+++ 	(revision )
@@ -1,104 +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.treeimpl;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeInfo;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: $
- * @author 2011, last modified by $Author: $
- */
-public class NodeInfo implements ITaskTreeNodeInfo {
-    
-    /** */
-    private ITaskTreeNode task;
-
-    /** */
-    private long lastUpdate;
-
-    /** */
-    private List<ITaskTreeNode> parentNodes = new ArrayList<ITaskTreeNode>();
-
-    /**
-     * @param node
-     */
-    NodeInfo(ITaskTreeNode task) {
-        this.task = task;
-        lastUpdate = System.currentTimeMillis();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.NodeInfo#getTask()
-     */
-    @Override
-    public ITaskTreeNode getTask() {
-        return task;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeimpl.NodeInfo#getNoOfOccurencesInTree()
-     */
-    @Override
-    public int getNoOfOccurencesInTree() {
-        return parentNodes.size();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeimpl.NodeInfo#getLastUpdate()
-     */
-    @Override
-    public long getLastUpdate() {
-        return lastUpdate;
-    }
-
-    /**
-     * TODO: comment
-     * 
-     */
-    void addParent(ITaskTreeNode parent) {
-        parentNodes.add(parent);
-    }
-
-    /**
-     * TODO: comment
-     * 
-     */
-    void removeParent(ITaskTreeNode parent) {
-        parentNodes.remove(parent);
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public synchronized String toString() {
-        return "NodeInfo(" + task + ", " + parentNodes.size() + " parents)";
-    }
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Optional.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Optional.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Optional.java	(revision 1146)
@@ -16,5 +16,5 @@
 
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
 
 /**
@@ -24,5 +24,8 @@
  * @author 2012, last modified by $Author: patrick$
  */
-public class Optional extends TaskTreeNode implements IOptional {
+class Optional extends MarkingTemporalRelationship implements IOptional {
+
+    /**  */
+    private static final long serialVersionUID = 1L;
 
     /**
@@ -30,30 +33,18 @@
      */
     Optional() {
-        super("Optional");
+        super("optionality");
     }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNode#addChild(TaskTreeNode)
+    
+    /* (non-Javadoc)
+     * @see MarkingTemporalRelationship#setMarkedTask(ITask)
      */
     @Override
-    public void addChild(ITaskTreeNode child) {
-        // adding more children is not allowed
-        throw new UnsupportedOperationException
-            ("optionalities may not have a list of children. Use setChild() instead.");
-    }
-
-    /**
-     * TODO: comment
-     * 
-     * @param selection
-     * @return
-     */
-    public void setChild(ITaskTreeNode child) {
-        if (super.getChildren().size() > 0) {
-            super.removeChild(0);
+    protected void setMarkedTask(ITask markedTask) {
+        if (markedTask instanceof IOptional) {
+            throw new IllegalArgumentException
+                ("the marked task of an optional must not be an optional");
         }
-        super.addChild(child);
+        
+        super.setMarkedTask(markedTask);
     }
 
@@ -67,4 +58,3 @@
         return (Optional) super.clone();
     }
-
 }
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Selection.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Selection.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Selection.java	(revision 1146)
@@ -16,4 +16,5 @@
 
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
 
 /**
@@ -23,5 +24,8 @@
  * @author 2012, last modified by $Author: patrick$
  */
-public class Selection extends TaskTreeNode implements ISelection {
+class Selection extends StructuringTemporalRelationship implements ISelection {
+
+    /**  */
+    private static final long serialVersionUID = 1L;
 
     /**
@@ -31,5 +35,5 @@
      */
     Selection() {
-        super("Selection");
+        super("selection");
     }
 
@@ -44,3 +48,29 @@
     }
 
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param i
+     * @param newChild
+     */
+    public void addChild(ITask newChild) {
+        super.addChild(newChild);
+        super.setDescription("selection of " + newChild);
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param i
+     * @param newChild
+     */
+    public void addChild(int index, ITask newChild) {
+        super.addChild(index, newChild);
+        super.setDescription("selection of " + newChild);
+    }
+
 }
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Sequence.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Sequence.java	(revision 1133)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Sequence.java	(revision 1146)
@@ -23,6 +23,9 @@
  * @author 2012, last modified by $Author: patrick$
  */
-public class Sequence extends TaskTreeNode implements ISequence {
+class Sequence extends StructuringTemporalRelationship implements ISequence {
     
+    /**  */
+    private static final long serialVersionUID = 1L;
+
     /**
      * TODO: comment
@@ -31,14 +34,5 @@
      */
     Sequence() {
-        super("Sequence");
-    }
-
-    /**
-     * TODO: comment
-     * 
-     * @param name
-     */
-    Sequence(String name) {
-        super(name);
+        super("sequence");
     }
 
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/StructuringTemporalRelationship.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/StructuringTemporalRelationship.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/StructuringTemporalRelationship.java	(revision 1146)
@@ -0,0 +1,117 @@
+//   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.treeimpl;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+abstract class StructuringTemporalRelationship extends Task
+    implements IStructuringTemporalRelationship
+{
+
+    /**  */
+    private static final long serialVersionUID = 1L;
+    
+    /**
+     * 
+     */
+    private List<ITask> children = new LinkedList<ITask>();
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param description
+     */
+    StructuringTemporalRelationship(String relationshipType) {
+        if ((relationshipType == null) || ("".equals(relationshipType))) {
+            throw new IllegalArgumentException
+                ("the relationship type must be something meaningful");
+        }
+        
+        super.setDescription(relationshipType);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship#getChildren()
+     */
+    @Override
+    public List<ITask> getChildren() {
+        return children;
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeimpl.Task#clone()
+     */
+    @Override
+    public synchronized StructuringTemporalRelationship clone() {
+        StructuringTemporalRelationship clone = null;
+        clone = (StructuringTemporalRelationship) super.clone();
+            
+        clone.children = new LinkedList<ITask>();
+        
+        for (ITask child : this.children) {
+            clone.children.add(child.clone());
+        }
+
+        return clone;
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param i
+     * @param newChild
+     */
+    public void addChild(ITask newChild) {
+        children.add(newChild);
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param i
+     * @param newChild
+     */
+    public void addChild(int index, ITask newChild) {
+        children.add(index, newChild);
+    }
+    
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param index
+     */
+    void removeChild(int index) {
+        children.remove(index);
+    }
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Task.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Task.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/Task.java	(revision 1146)
@@ -0,0 +1,147 @@
+//   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.treeimpl;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: $
+ * @author 2011, last modified by $Author: $
+ */
+class Task implements ITask {
+
+    /**  */
+    private static final long serialVersionUID = 1L;
+
+    /** */
+    private static int temporalId = 0;
+
+    /** */
+    private int id;
+
+    /** */
+    private String description;
+
+    /**
+     * 
+     */
+    Task() {
+        id = getNewId();
+    }
+
+    /**
+     * TODO: comment
+     * 
+     * @return
+     */
+    private static synchronized int getNewId() {
+        if (temporalId == Integer.MAX_VALUE) {
+            temporalId = 0;
+        }
+
+        return temporalId++;
+    }
+
+    /**
+     * @return Returns the name.
+     */
+    public int getId() {
+        return id;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNode#getDescription()
+     */
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.TaskTreeNode#equals(TaskTreeNode)
+     */
+    @Override
+    public final boolean equals(ITask task) {
+        // tasks are only equal if they are identical or if they have the same id
+        // (may happen, if they are cloned)
+        return (this == task) || (this.hashCode() == task.hashCode());
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public synchronized int hashCode() {
+        return id;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public synchronized String toString() {
+        StringBuffer result = new StringBuffer();
+        result.append("task ");
+        result.append(id);
+        
+        if (description != null) {
+            result.append(" (");
+            result.append(description);
+            result.append(')');
+        }
+        
+        return result.toString();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#clone()
+     */
+    @Override
+    public synchronized ITask clone() {
+        Task clone = null;
+        try {
+            clone = (Task) super.clone();
+        }
+        catch (CloneNotSupportedException e) {
+            // this should never happen. Therefore simply dump the exception
+            e.printStackTrace();
+        }
+
+        return clone;
+    }
+
+    /**
+     * TODO: comment
+     * 
+     * @param i
+     * @return
+     */
+    void setDescription(String description) {
+        this.description = description;
+    }
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskBuilder.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskBuilder.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskBuilder.java	(revision 1146)
@@ -0,0 +1,411 @@
+//   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.treeimpl;
+
+import java.util.List;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+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.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.IUserSession;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class TaskBuilder implements ITaskBuilder {
+
+    /* (non-Javadoc)
+     * @see ITaskBuilder#addChild(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public void addChild(ITaskInstance parent, ITaskInstance child) throws IllegalArgumentException
+    {
+        if (!(parent instanceof TaskInstance)) {
+            throw new IllegalArgumentException
+                ("illegal type of task instance provided: " + parent.getClass());
+        }
+
+        if (!(child instanceof TaskInstance)) {
+            throw new IllegalArgumentException
+                ("illegal type of task instance provided: " + parent.getClass());
+        }
+        
+        // check, that the correct number of children for the distinct types are added
+        ITask task = parent.getTask();
+        
+        if (task instanceof IEventTask) {
+            throw new IllegalArgumentException
+                ("can not add children to a task instance of an event task");
+        }
+        else if (task instanceof ISelection) {
+            if (parent.getChildren().size() > 0) {
+                throw new IllegalArgumentException
+                    ("the instance of a selection must have at most one child");
+            }
+        }
+        else if (task instanceof IOptional) {
+            if (parent.getChildren().size() > 1) {
+                throw new IllegalArgumentException
+                    ("the instance of an optional must have at most one child");
+            }
+        }
+/*        else if (task instanceof IIteration) {
+            for (ITaskInstance childInstance : parent.getChildren()) {
+                if (!childInstance.getTask().equals(child.getTask())) {
+                    throw new IllegalArgumentException
+                        ("all children of an instance of an iteration must have exactly the " +
+                         "same type");
+                }
+            }
+        }
+        
+        boolean foundChildTask = false;
+        if (parent.getTask() instanceof IStructuringTemporalRelationship) {
+            IStructuringTemporalRelationship parentTask =
+                (IStructuringTemporalRelationship) parent.getTask();
+        
+            for (ITask parentTaskChild : parentTask.getChildren()) {
+                if (parentTaskChild.equals(child.getTask())) {
+                    foundChildTask = true;
+                    break;
+                }
+            }
+        }
+        else if (parent.getTask() instanceof IMarkingTemporalRelationship) {
+            IMarkingTemporalRelationship parentTask =
+                (IMarkingTemporalRelationship) parent.getTask();
+            
+            foundChildTask = parentTask.getMarkedTask() != null ?
+                parentTask.getMarkedTask().equals(child.getTask()) : false;
+        }
+        
+        if (!foundChildTask) {
+            throw new IllegalArgumentException
+                ("the task of the child instance to be added does not belong to the children " +
+                 "of the task of the parent instance");
+        }*/
+
+        // finally, after all checks are positive, add the child
+        ((TaskInstance) parent).addChild(child);
+    }
+
+    /* (non-Javadoc)
+     * @see ITaskBuilder#addExecutedTask(IUserSession, ITaskInstance)
+     */
+    @Override
+    public void addExecutedTask(IUserSession session, ITaskInstance taskInstance) {
+        if (!(session instanceof UserSession)) {
+            throw new IllegalArgumentException
+                ("illegal type of session provided: " + session.getClass());
+        }
+
+        if (!(taskInstance instanceof TaskInstance)) {
+            throw new IllegalArgumentException
+                ("illegal type of task instance provided: " + taskInstance.getClass());
+        }
+        
+        ((UserSession) session).addExecutedTask(taskInstance);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder#addTaskInstance(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance)
+     */
+    @Override
+    public void addTaskInstance(ITaskInstanceList taskInstanceList, ITaskInstance taskInstance) {
+        if (taskInstanceList instanceof TaskInstance) {
+            ((TaskInstance) taskInstanceList).addChild(taskInstance);
+        }
+        else if (taskInstanceList instanceof UserSession) {
+            ((UserSession) taskInstanceList).addExecutedTask(taskInstance);
+        }
+        else {
+            throw new IllegalArgumentException
+                ("illegal type of task instance list provided: " + taskInstanceList.getClass());
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder#addTaskInstance(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList, int, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance)
+     */
+    @Override
+    public void addTaskInstance(ITaskInstanceList taskInstanceList,
+                                int               index,
+                                ITaskInstance     taskInstance)
+    {
+        if (taskInstanceList instanceof TaskInstance) {
+            ((TaskInstance) taskInstanceList).addChild(index, taskInstance);
+        }
+        else if (taskInstanceList instanceof UserSession) {
+            ((UserSession) taskInstanceList).addExecutedTask(index, taskInstance);
+        }
+        else {
+            throw new IllegalArgumentException
+                ("illegal type of task instance list provided: " + taskInstanceList.getClass());
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder#setTaskInstance(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList, int, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance)
+     */
+    @Override
+    public void setTaskInstance(ITaskInstanceList taskInstanceList,
+                                int               index,
+                                ITaskInstance     taskInstance)
+    {
+        if (taskInstanceList instanceof TaskInstance) {
+            ((TaskInstance) taskInstanceList).removeChild(index);
+            ((TaskInstance) taskInstanceList).addChild(index, taskInstance);
+        }
+        else if (taskInstanceList instanceof UserSession) {
+            ((UserSession) taskInstanceList).removeExecutedTask(index);
+            ((UserSession) taskInstanceList).addExecutedTask(index, taskInstance);
+        }
+        else {
+            throw new IllegalArgumentException
+                ("illegal type of task instance list provided: " + taskInstanceList.getClass());
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder#setTask(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITask)
+     */
+    @Override
+    public void setTask(ITaskInstance taskInstance, ITask task) {
+        if (!(taskInstance instanceof TaskInstance)) {
+            throw new IllegalArgumentException
+                ("illegal type of task instance provided: " + taskInstance.getClass());
+        }
+        
+        ((TaskInstance) taskInstance).setTask(task);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#addChild(Sequence, TaskTreeNode)
+     */
+    @Override
+    public void addChild(ISequence parent, ITask child) {
+        if (!(parent instanceof Sequence)) {
+            throw new IllegalArgumentException
+                ("illegal type of sequence provided: " + parent.getClass());
+        }
+
+        addChildInternal((Sequence) parent, -1, child);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#addChild(Sequence, int, TaskTreeNode)
+     */
+    @Override
+    public void addChild(ISequence parent, int index, ITask child) {
+        if (!(parent instanceof Sequence)) {
+            throw new IllegalArgumentException
+                ("illegal type of sequence provided: " + parent.getClass());
+        }
+
+        addChildInternal((Sequence) parent, index, child);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder#setChild(de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence, int, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode)
+     */
+    @Override
+    public void setChild(ISequence parent, int index, ITask child) {
+        if (!(parent instanceof Sequence)) {
+            throw new IllegalArgumentException
+                ("illegal type of sequence provided: " + parent.getClass());
+        }
+
+        ((Sequence) parent).removeChild(index);
+        addChildInternal((Sequence) parent, index, child);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#addChild(Selection, TaskTreeNode)
+     */
+    @Override
+    public void addChild(ISelection parent, ITask child) {
+        if (!(parent instanceof Selection)) {
+            throw new IllegalArgumentException
+                ("illegal type of selection provided: " + parent.getClass());
+        }
+
+        addChildInternal((Selection) parent, -1, child);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#setChild(Iteration, TaskTreeNode)
+     */
+    @Override
+    public void setMarkedTask(IIteration iteration, ITask newChild) {
+        if (!(iteration instanceof Iteration)) {
+            throw new IllegalArgumentException
+                ("illegal type of iteration provided: " + iteration.getClass());
+        }
+
+        if (!(newChild instanceof Task)) {
+            throw new IllegalArgumentException
+                ("illegal type of task provided: " + newChild.getClass());
+        }
+
+        ((Iteration) iteration).setMarkedTask(newChild);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder#setChild(de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode)
+     */
+    @Override
+    public void setMarkedTask(IOptional optional, ITask newChild) {
+        if (!(optional instanceof Optional)) {
+            throw new IllegalArgumentException
+                ("illegal type of optional provided: " + optional.getClass());
+        }
+
+        if (!(newChild instanceof Task)) {
+            throw new IllegalArgumentException
+                ("illegal type of task provided: " + newChild.getClass());
+        }
+
+        ((Optional) optional).setMarkedTask(newChild);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#removeChild(Sequence, int)
+     */
+    @Override
+    public void removeChild(ISequence parent, int index) {
+        if (!(parent instanceof Sequence)) {
+            throw new IllegalArgumentException
+                ("illegal type of sequence provided: " + parent.getClass());
+        }
+
+        ((Sequence) parent).removeChild(index);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#removeChild(Selection, TaskTreeNode)
+     */
+    @Override
+    public void removeChild(ISelection parent, ITask child) {
+        if (!(parent instanceof Selection)) {
+            throw new IllegalArgumentException
+                ("illegal type of selection provided: " + parent.getClass());
+        }
+
+        List<ITask> children = parent.getChildren();
+        
+        for (int i = 0; i < children.size(); i++) {
+            if ((children.get(i) == child) ||
+                ((children.get(i) != null) && (children.get(i).equals(child))))
+            {
+                ((Selection) parent).removeChild(i);
+                break;
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder#removeTaskInstance(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList, int)
+     */
+    @Override
+    public void removeTaskInstance(ITaskInstanceList taskInstanceList, int index) {
+        if (taskInstanceList instanceof TaskInstance) {
+            ((TaskInstance) taskInstanceList).removeChild(index);
+        }
+        else if (taskInstanceList instanceof UserSession) {
+            ((UserSession) taskInstanceList).removeExecutedTask(index);
+        }
+        else {
+            throw new IllegalArgumentException
+                ("illegal type of task instance list provided: " + taskInstanceList.getClass());
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder#replaceChild(de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode)
+     */
+    @Override
+    public void replaceChild(ISelection parent, ITask oldChild, ITask newChild) {
+        if (!(parent instanceof Selection)) {
+            throw new IllegalArgumentException
+                ("illegal type of selection provided: " + parent.getClass());
+        }
+
+        List<ITask> children = parent.getChildren();
+        
+        for (int i = 0; i < children.size(); i++) {
+            if ((children.get(i) == oldChild) ||
+                ((children.get(i) != null) && (children.get(i).equals(oldChild))))
+            {
+                ((Selection) parent).removeChild(i);
+                ((Selection) parent).addChild(i, newChild);
+                break;
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#setDescription(TaskTreeNode, String)
+     */
+    @Override
+    public void setDescription(ITask parent, String description) {
+        if (!(parent instanceof Task)) {
+            throw new IllegalArgumentException
+                ("illegal type of task provided: " + parent.getClass());
+        }
+
+        ((Task) parent).setDescription(description);
+    }
+
+    /**
+     * 
+     */
+    private void addChildInternal(StructuringTemporalRelationship parent, int index, ITask child) {
+        if (!(child instanceof Task)) {
+            throw new IllegalArgumentException
+                ("illegal type of task provided: " + child.getClass());
+        }
+
+        if (index > -1) {
+            parent.addChild(index, child);
+        }
+        else {
+            parent.addChild(child);
+        }
+    }
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskFactory.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskFactory.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskFactory.java	(revision 1146)
@@ -0,0 +1,121 @@
+//   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.treeimpl;
+
+import java.util.List;
+
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+import de.ugoe.cs.autoquest.eventcore.IEventType;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+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.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class TaskFactory implements ITaskFactory {
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see TaskTreeNodeFactory#createNewEventTask(IEventType, IEventTarget)
+     */
+    @Override
+    public IEventTask createNewEventTask(IEventType eventType, IEventTarget eventTarget) {
+        return new EventTask(eventType, eventTarget);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNodeFactory#createNewSequence()
+     */
+    @Override
+    public ISequence createNewSequence() {
+        return new Sequence();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNodeFactory#createNewIteration()
+     */
+    @Override
+    public IIteration createNewIteration() {
+        return new Iteration();
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory#createNewOptional()
+     */
+    @Override
+    public IOptional createNewOptional() {
+        return new Optional();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNodeFactory#createNewSelection()
+     */
+    @Override
+    public ISelection createNewSelection() {
+        return new Selection();
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory#createNewTaskInstance(ITask)
+     */
+    @Override
+    public ITaskInstance createNewTaskInstance(ITask task) {
+        return new TaskInstance(task);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory#createNewTaskInstanceList()
+     */
+    @Override
+    public ITaskInstanceList createNewTaskInstanceList() {
+        return new TaskInstance(new Sequence());
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory#createUserSession()
+     */
+    @Override
+    public IUserSession createUserSession() {
+        return new UserSession();
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory#createTaskModel(IUserSession)
+     */
+    @Override
+    public ITaskModel createTaskModel(List<IUserSession> userSessions) {
+        return new TaskModel(userSessions);
+    }
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskInfo.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskInfo.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskInfo.java	(revision 1146)
@@ -0,0 +1,61 @@
+//   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.treeimpl;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: $
+ * @author 2011, last modified by $Author: $
+ */
+public class TaskInfo implements ITaskInfo {
+    
+    /**  */
+    private static final long serialVersionUID = 1L;
+    
+    /** */
+    private ITask task;
+
+    /**
+     * @param task
+     */
+    TaskInfo(ITask task) {
+        this.task = task;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.treeifc.NodeInfo#getTask()
+     */
+    @Override
+    public ITask getTask() {
+        return task;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public synchronized String toString() {
+        return "NodeInfo(" + task + ")";
+    }
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskInstance.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskInstance.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskInstance.java	(revision 1146)
@@ -0,0 +1,245 @@
+//   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.treeimpl;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: $
+ * @author 2011, last modified by $Author: $
+ */
+class TaskInstance implements ITaskInstance {
+    
+    /**  */
+    private static final long serialVersionUID = 1L;
+
+    /** */
+    private static int temporalId = 0;
+
+    /** */
+    private ITask task;
+    
+    /** */
+    private int id;
+
+    /** children */
+    private List<ITaskInstance> children;
+
+    /**
+     * 
+     */
+    TaskInstance(ITask task) {
+        this.task = task;
+        id = getNewId();
+    }
+
+    /**
+     * TODO: comment
+     * 
+     * @return
+     */
+    private static synchronized int getNewId() {
+        if (temporalId == Integer.MAX_VALUE) {
+            temporalId = 0;
+        }
+
+        return temporalId++;
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance#getTask()
+     */
+    @Override
+    public ITask getTask() {
+        return task;
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance#getChildren()
+     */
+    public synchronized List<ITaskInstance> getChildren() {
+        if (children == null) {
+            children = new LinkedList<ITaskInstance>();
+        }
+
+        return Collections.unmodifiableList(children);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#get(int)
+     */
+    @Override
+    public ITaskInstance get(int index) {
+        if (children == null) {
+            throw new IndexOutOfBoundsException(Integer.toString(index));
+        }
+        else {
+            return children.get(index);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#size()
+     */
+    @Override
+    public int size() {
+        if (children == null) {
+            return 0;
+        }
+        else {
+            return children.size();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Iterable#iterator()
+     */
+    @Override
+    public Iterator<ITaskInstance> iterator() {
+        return getChildren().iterator();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.TaskTreeNode#equals(TaskTreeNode)
+     */
+    @Override
+    public boolean equals(ITaskInstance taskInstance) {
+        // task instances are only equal if they are identical or if they have the same id
+        // (may happen, if they are cloned)
+        return (this == taskInstance) || (this.hashCode() == taskInstance.hashCode());
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public synchronized int hashCode() {
+        return id;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public synchronized String toString() {
+        StringBuffer result = new StringBuffer();
+        result.append("task ");
+        result.append(task.getId());
+        result.append(" (instance ");
+        result.append(id);
+        
+        if (task.getDescription() != null) {
+            result.append(", ");
+            result.append(task.getDescription());
+        }
+        
+        if (children != null) {
+            result.append(", ");
+            result.append(children.size());
+            result.append(" children");
+        }
+        
+        result.append(')');
+        return result.toString();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#clone()
+     */
+    @Override
+    public synchronized ITaskInstance clone() {
+        TaskInstance clone = null;
+        try {
+            clone = (TaskInstance) super.clone();
+
+            if (children != null) {
+                clone.children = new LinkedList<ITaskInstance>();
+
+                for (ITaskInstance child : children) {
+                    clone.children.add(child.clone());
+                }
+            }
+
+        }
+        catch (CloneNotSupportedException e) {
+            // this should never happen. Therefore simply dump the exception
+            e.printStackTrace();
+        }
+
+        return clone;
+    }
+
+    /**
+     * 
+     */
+    synchronized void addChild(ITaskInstance child) {
+        if (children == null) {
+            children = new LinkedList<ITaskInstance>();
+        }
+
+        children.add(child);
+    }
+
+    /**
+     * 
+     */
+    synchronized void addChild(int index, ITaskInstance child) {
+        if (children == null) {
+            children = new LinkedList<ITaskInstance>();
+        }
+
+        children.add(index, child);
+    }
+
+    /**
+     * TODO: comment
+     * 
+     * @param i
+     * @return
+     */
+    synchronized ITaskInstance removeChild(int index) {
+        if (children != null) {
+            return children.remove(index);
+        }
+        else {
+            throw new IllegalArgumentException
+                ("this task instance does not have children that can be removed");
+        }
+    }
+
+    /**
+     * @param task the task to set
+     */
+    void setTask(ITask task) {
+        this.task = task;
+    }
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskModel.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskModel.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskModel.java	(revision 1146)
@@ -0,0 +1,123 @@
+//   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.treeimpl;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 21.02.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+class TaskModel implements ITaskModel {
+    
+    /**  */
+    private static final long serialVersionUID = 1L;
+
+    /** the map of tasks */
+    private List<IUserSession> userSessions;
+
+    /** the map of tasks */
+    private Map<ITask, TaskInfo> taskMap = new HashMap<ITask, TaskInfo>();
+
+    /**
+     *
+     */
+    TaskModel(List<IUserSession> userSessions) {
+        if ((userSessions == null) || (userSessions.size() == 0)) {
+            throw new IllegalArgumentException("user sessions must not be null");
+        }
+        
+        this.userSessions = userSessions;
+        
+        for (IUserSession session : this.userSessions) {
+            for (ITaskInstance taskInstance : session) {
+                addTaskToMap(taskInstance.getTask());
+            }
+        }
+    }
+
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getUserSessions()
+     */
+    @Override
+    public List<IUserSession> getUserSessions() {
+        return Collections.unmodifiableList(userSessions);
+    }
+
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getTasks()
+     */
+    @Override
+    public Collection<ITask> getTasks() {
+        return Collections.unmodifiableCollection(taskMap.keySet());
+    }
+
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getTaskInfo(de.ugoe.cs.autoquest.tasktrees.treeifc.ITask)
+     */
+    @Override
+    public ITaskInfo getTaskInfo(ITask task) {
+        return taskMap.get(task);
+    }
+
+    /**
+     *
+     */
+    private void addTaskToMap(ITask task) {
+        TaskInfo taskInfo = taskMap.get(task);
+
+        if (taskInfo == null) {
+            taskInfo = new TaskInfo(task);
+            taskMap.put(task, taskInfo);
+        }
+
+        if (task instanceof IStructuringTemporalRelationship) {
+            for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) {
+                addTaskToMap(child);
+            }
+        }
+        else if (task instanceof IMarkingTemporalRelationship) {
+            addTaskToMap(((IMarkingTemporalRelationship) task).getMarkedTask());
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#clone()
+     */
+    @Override
+    public TaskModel clone() {
+        return new TaskModel(userSessions);
+    }
+
+}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskTree.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskTree.java	(revision 1133)
+++ 	(revision )
@@ -1,121 +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.treeimpl;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeInfo;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: 21.02.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-public class TaskTree implements ITaskTree {
-    
-    /** the map of nodes */
-    private Map<ITaskTreeNode, ITaskTreeNodeInfo> taskMap;
-
-    /** the root node of the task tree */
-    private ITaskTreeNode rootNode;
-
-    /**
-     * TODO: comment
-     * 
-     */
-    TaskTree(ITaskTreeNode rootNode) {
-        this.rootNode = rootNode;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTree#getRoot()
-     */
-    @Override
-    public ITaskTreeNode getRoot() {
-        return rootNode;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTree#getTaskMap()
-     */
-    @Override
-    public synchronized Map<ITaskTreeNode, ITaskTreeNodeInfo> getTaskMap() {
-        if (taskMap == null) {
-            taskMap = new HashMap<ITaskTreeNode, ITaskTreeNodeInfo>();
-            addNodeToMap(rootNode, null);
-        }
-        return taskMap;
-    }
-
-    /**
-     * TODO: comment
-     * 
-     * @param rootNode
-     */
-    private void addNodeToMap(ITaskTreeNode node, ITaskTreeNode parent) {
-        NodeInfo nodeInfo = (NodeInfo) taskMap.get(node);
-
-        if (nodeInfo == null) {
-            nodeInfo = new NodeInfo(node);
-            taskMap.put(node, nodeInfo);
-        }
-
-        if (parent != null) {
-            // through first removing an existing parent it is assured, that a parent is recorded
-            // only once. This is needed, because parent may be reused in a tree as well, but we
-            // always iterate the whole tree
-            //nodeInfo.removeParent(parent);
-            nodeInfo.addParent(parent);
-        }
-
-        for (ITaskTreeNode child : node.getChildren()) {
-            addNodeToMap(child, node);
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see java.lang.Object#clone()
-     */
-    @Override
-    public TaskTree clone() {
-        TaskTree clone = null;
-        try {
-            clone = (TaskTree) super.clone();
-
-            clone.rootNode = rootNode.clone();
-
-            // the clone will create the task map itself, when it is first retrieved
-            clone.taskMap = null;
-
-        }
-        catch (CloneNotSupportedException e) {
-            // this should never happen. Therefore simply dump the exception
-            e.printStackTrace();
-        }
-
-        return clone;
-    }
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskTreeBuilder.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskTreeBuilder.java	(revision 1133)
+++ 	(revision )
@@ -1,225 +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.treeimpl;
-
-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;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: 21.02.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-public class TaskTreeBuilder implements ITaskTreeBuilder {
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#addChild(Sequence, TaskTreeNode)
-     */
-    @Override
-    public void addChild(ISequence parent, ITaskTreeNode child) {
-        if (!(parent instanceof Sequence)) {
-            throw new IllegalArgumentException
-                ("illegal type of task tree node provided: " + parent.getClass());
-        }
-
-        addChildInternal(parent, -1, child);
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#addChild(Sequence, int, TaskTreeNode)
-     */
-    @Override
-    public void addChild(ISequence parent, int index, ITaskTreeNode child) {
-        if (!(parent instanceof Sequence)) {
-            throw new IllegalArgumentException
-                ("illegal type of task tree node provided: " + parent.getClass());
-        }
-
-        addChildInternal(parent, index, child);
-    }
-
-    /* (non-Javadoc)
-     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder#setChild(de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence, int, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode)
-     */
-    @Override
-    public void setChild(ISequence parent, int index, ITaskTreeNode child) {
-        if (!(parent instanceof Sequence)) {
-            throw new IllegalArgumentException
-                ("illegal type of task tree node provided: " + parent.getClass());
-        }
-
-        ((TaskTreeNode) parent).removeChild(index);
-        addChildInternal(parent, index, child);
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#addChild(Selection, TaskTreeNode)
-     */
-    @Override
-    public void addChild(ISelection parent, ITaskTreeNode child) {
-        if (!(parent instanceof Selection)) {
-            throw new IllegalArgumentException
-                ("illegal type of task tree node provided: " + parent.getClass());
-        }
-
-        addChildInternal(parent, -1, child);
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#setChild(Iteration, TaskTreeNode)
-     */
-    @Override
-    public void setChild(IIteration iteration, ITaskTreeNode newChild) {
-        if (!(iteration instanceof Iteration)) {
-            throw new IllegalArgumentException
-                ("illegal type of iteration provided: " + iteration.getClass());
-        }
-
-        if (!(newChild instanceof TaskTreeNode)) {
-            throw new IllegalArgumentException
-                ("illegal type of task tree node provided: " + newChild.getClass());
-        }
-
-        ((Iteration) iteration).setChild(newChild);
-    }
-
-    /* (non-Javadoc)
-     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder#setChild(de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode)
-     */
-    @Override
-    public void setChild(IOptional optional, ITaskTreeNode newChild) {
-        if (!(optional instanceof Optional)) {
-            throw new IllegalArgumentException
-                ("illegal type of optional provided: " + optional.getClass());
-        }
-
-        if (!(newChild instanceof TaskTreeNode)) {
-            throw new IllegalArgumentException
-                ("illegal type of task tree node provided: " + newChild.getClass());
-        }
-
-        ((Optional) optional).setChild(newChild);
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#removeChild(Sequence, int)
-     */
-    @Override
-    public void removeChild(ISequence parent, int index) {
-        if (!(parent instanceof TaskTreeNode)) {
-            throw new IllegalArgumentException
-                ("illegal type of task tree node provided: " + parent.getClass());
-        }
-
-        ((TaskTreeNode) parent).removeChild(index);
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#removeChild(Selection, TaskTreeNode)
-     */
-    @Override
-    public void removeChild(ISelection parent, ITaskTreeNode child) {
-        if (!(parent instanceof TaskTreeNode)) {
-            throw new IllegalArgumentException
-                ("illegal type of task tree node provided: " + parent.getClass());
-        }
-
-        List<ITaskTreeNode> children = parent.getChildren();
-        
-        for (int i = 0; i < children.size(); i++) {
-            if ((children.get(i) == child) ||
-                ((children.get(i) != null) && (children.get(i).equals(child))))
-            {
-                ((TaskTreeNode) parent).removeChild(i);
-                break;
-            }
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder#replaceChild(de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode)
-     */
-    @Override
-    public void replaceChild(ISelection parent, ITaskTreeNode oldChild, ITaskTreeNode newChild) {
-        if (!(parent instanceof TaskTreeNode)) {
-            throw new IllegalArgumentException
-                ("illegal type of task tree node provided: " + parent.getClass());
-        }
-
-        List<ITaskTreeNode> children = parent.getChildren();
-        
-        for (int i = 0; i < children.size(); i++) {
-            if ((children.get(i) == oldChild) ||
-                ((children.get(i) != null) && (children.get(i).equals(oldChild))))
-            {
-                ((TaskTreeNode) parent).removeChild(i);
-                ((TaskTreeNode) parent).addChild(i, newChild);
-                break;
-            }
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeBuilder#setDescription(TaskTreeNode, String)
-     */
-    @Override
-    public void setDescription(ITaskTreeNode parent, String description) {
-        if (!(parent instanceof TaskTreeNode)) {
-            throw new IllegalArgumentException
-                ("illegal type of task tree node provided: " + parent.getClass());
-        }
-
-        ((TaskTreeNode) parent).setDescription(description);
-    }
-
-    /**
-     * 
-     */
-    private void addChildInternal(ITaskTreeNode parent, int index, ITaskTreeNode child) {
-        if (!(child instanceof TaskTreeNode)) {
-            throw new IllegalArgumentException
-                ("illegal type of task tree node provided: " + child.getClass());
-        }
-
-        if (index > -1) {
-            ((TaskTreeNode) parent).addChild(index, child);
-        }
-        else {
-            ((TaskTreeNode) parent).addChild(child);
-        }
-    }
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskTreeNode.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskTreeNode.java	(revision 1133)
+++ 	(revision )
@@ -1,247 +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.treeimpl;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: $
- * @author 2011, last modified by $Author: $
- */
-public class TaskTreeNode implements ITaskTreeNode {
-    /** */
-    private static int temporalId = 0;
-
-    /** */
-    private String name;
-
-    /** */
-    private String description;
-
-    /** */
-    private int id;
-
-    /** children */
-    private List<ITaskTreeNode> children;
-
-    /**
-     * 
-     */
-    public TaskTreeNode(String name) {
-        this.name = name;
-        id = getNewId();
-    }
-
-    /**
-     * TODO: comment
-     * 
-     * @return
-     */
-    private static synchronized int getNewId() {
-        if (temporalId == Integer.MAX_VALUE) {
-            temporalId = 0;
-        }
-
-        return temporalId++;
-    }
-
-    /**
-     * @return Returns the name.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNode#getDescription()
-     */
-    @Override
-    public String getDescription() {
-        return description;
-    }
-
-    /**
-     * 
-     */
-    public synchronized List<ITaskTreeNode> getChildren() {
-        if ((children == null) || (children.size() == 0)) {
-            return new LinkedList<ITaskTreeNode>();
-        }
-
-        return Collections.unmodifiableList(children);
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.TaskTreeNode#equals(TaskTreeNode)
-     */
-    @Override
-    public boolean equals(ITaskTreeNode taskTreeNode) {
-        if (!this.getClass().isInstance(taskTreeNode)) {
-            return false;
-        }
-
-        if (taskTreeNode.hashCode() != hashCode()) {
-            return false;
-        }
-
-        TaskTreeNode other = (TaskTreeNode) taskTreeNode;
-
-        if (id != other.id) {
-            return false;
-        }
-
-        if (!name.equals(other.name)) {
-            return false;
-        }
-
-        synchronized (other) {
-            if (children == null) {
-                return (other.children == null);
-            }
-            else if (other.children == null) {
-                return (children == null);
-            }
-            else if (other.children.size() != children.size()) {
-                return false;
-            }
-
-            for (int i = 0; i < children.size(); i++) {
-                if (!children.get(i).equals(other.children.get(i))) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see java.lang.Object#hashCode()
-     */
-    @Override
-    public synchronized int hashCode() {
-        return getClass().getSimpleName().hashCode();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public synchronized String toString() {
-        StringBuffer result = new StringBuffer();
-        result.append(name);
-        result.append('(');
-        result.append(id);
-        
-        if (description != null) {
-            result.append(", ");
-            result.append(description);
-        }
-        
-        if (children != null) {
-            result.append(", ");
-            result.append(children.size());
-            result.append(" children");
-        }
-        
-        result.append(')');
-        return result.toString();
-    }
-
-    /**
-     * TODO: comment
-     * 
-     * @param i
-     * @return
-     */
-    void setDescription(String description) {
-        this.description = description;
-    }
-
-    /**
-     * 
-     */
-    synchronized void addChild(ITaskTreeNode child) {
-        if (children == null) {
-            children = new LinkedList<ITaskTreeNode>();
-        }
-
-        children.add(child);
-    }
-
-    /**
-     * 
-     */
-    synchronized void addChild(int index, ITaskTreeNode child) {
-        if (children == null) {
-            children = new LinkedList<ITaskTreeNode>();
-        }
-
-        children.add(index, child);
-    }
-
-    /**
-     * TODO: comment
-     * 
-     * @param i
-     * @return
-     */
-    synchronized ITaskTreeNode removeChild(int index) {
-        return children.remove(index);
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see java.lang.Object#clone()
-     */
-    @Override
-    public synchronized ITaskTreeNode clone() {
-        TaskTreeNode clone = null;
-        try {
-            clone = (TaskTreeNode) super.clone();
-
-            if (children != null) {
-                clone.children = new LinkedList<ITaskTreeNode>();
-
-                for (ITaskTreeNode child : children) {
-                    clone.children.add(child.clone());
-                }
-            }
-
-        }
-        catch (CloneNotSupportedException e) {
-            // this should never happen. Therefore simply dump the exception
-            e.printStackTrace();
-        }
-
-        return clone;
-    }
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskTreeNodeFactory.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskTreeNodeFactory.java	(revision 1133)
+++ 	(revision )
@@ -1,96 +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.treeimpl;
-
-import de.ugoe.cs.autoquest.eventcore.IEventTarget;
-import de.ugoe.cs.autoquest.eventcore.IEventType;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
-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.ITaskTree;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: 21.02.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-public class TaskTreeNodeFactory implements ITaskTreeNodeFactory {
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see TaskTreeNodeFactory#createNewEventTask(IEventType, IEventTarget)
-     */
-    @Override
-    public IEventTask createNewEventTask(IEventType eventType, IEventTarget eventTarget) {
-        return new EventTask(eventType, eventTarget);
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNodeFactory#createNewSequence()
-     */
-    @Override
-    public ISequence createNewSequence() {
-        return new Sequence();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNodeFactory#createNewIteration()
-     */
-    @Override
-    public IIteration createNewIteration() {
-        return new Iteration();
-    }
-
-    /* (non-Javadoc)
-     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory#createNewOptional()
-     */
-    @Override
-    public IOptional createNewOptional() {
-        return new Optional();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.treeifc.TaskTreeNodeFactory#createNewSelection()
-     */
-    @Override
-    public ISelection createNewSelection() {
-        return new Selection();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * de.ugoe.cs.tasktree.treeifc.TaskTreeNodeFactory#createTaskTree(de.ugoe.cs.tasktree.treeifc
-     * .TaskTreeNode)
-     */
-    @Override
-    public ITaskTree createTaskTree(ITaskTreeNode root) {
-        return new TaskTree(root);
-    }
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/UserSession.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/UserSession.java	(revision 1146)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/UserSession.java	(revision 1146)
@@ -0,0 +1,152 @@
+//   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.treeimpl;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+class UserSession implements IUserSession {
+    
+    /**  */
+    private static final long serialVersionUID = 1L;
+    /**
+     * 
+     */
+    private List<ITaskInstance> executedTasks = new LinkedList<ITaskInstance>();
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#get(int)
+     */
+    @Override
+    public ITaskInstance get(int index) {
+        return executedTasks.get(index);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList#size()
+     */
+    @Override
+    public int size() {
+        return executedTasks.size();
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Iterable#iterator()
+     */
+    @Override
+    public Iterator<ITaskInstance> iterator() {
+        return executedTasks.iterator();
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession#getExecutedTasks()
+     */
+    @Override
+    public List<ITaskInstance> getExecutedTasks() {
+        return Collections.unmodifiableList(executedTasks);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.autoquest.tasktrees.treeifc.TaskTreeNode#equals(TaskTreeNode)
+     */
+    @Override
+    public boolean equals(IUserSession userSession) {
+        // task instances are only equal if they are identical or if they have the same id
+        // (may happen, if they are cloned)
+        return (this == userSession) || (this.hashCode() == userSession.hashCode());
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public synchronized int hashCode() {
+        return super.hashCode();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public synchronized String toString() {
+        return "session (" + executedTasks.size() + " task instances)";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#clone()
+     */
+    @Override
+    public synchronized IUserSession clone() {
+        UserSession clone = null;
+        try {
+            clone = (UserSession) super.clone();
+
+            clone.executedTasks = new LinkedList<ITaskInstance>();
+            
+            for (ITaskInstance child : executedTasks) {
+                clone.executedTasks.add(child.clone());
+            }
+
+        }
+        catch (CloneNotSupportedException e) {
+            // this should never happen. Therefore simply dump the exception
+            e.printStackTrace();
+        }
+
+        return clone;
+    }
+
+    /**
+     *
+     */
+    void addExecutedTask(ITaskInstance taskInstance) {
+        executedTasks.add(taskInstance);
+    }
+
+    /**
+     *
+     */
+    void addExecutedTask(int index, ITaskInstance taskInstance) {
+        executedTasks.add(index, taskInstance);
+    }
+
+    /**
+     *
+     */
+    void removeExecutedTask(int index) {
+        executedTasks.remove(index);
+    }
+
+}
