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 1190)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/EventTaskComparisonRule.java	(revision 1294)
@@ -15,6 +15,10 @@
 package de.ugoe.cs.autoquest.tasktrees.taskequality;
 
+import java.util.Collection;
+
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
 
 /**
@@ -29,5 +33,5 @@
     
     /* (non-Javadoc)
-     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     * @see TaskComparisonRule#isApplicable(ITask, ITask)
      */
     @Override
@@ -37,17 +41,31 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask)
      */
     @Override
     public boolean areLexicallyEqual(ITask task1, ITask task2) {
-        IEventTask eventTask1 = (IEventTask) task1;
-        IEventTask eventTask2 = (IEventTask) task2;
+        Collection<ITaskInstance> taskInstances1 = task1.getInstances();
+        Collection<ITaskInstance> taskInstances2 = task2.getInstances();
         
-        return (eventTask1.getEventType().equals(eventTask2.getEventType()) &&
-                eventTask1.getEventTarget().equals(eventTask2.getEventTarget()));
+        for (ITaskInstance instance1 : taskInstances1) {
+            boolean found = false;
+            
+            for (ITaskInstance instance2 : taskInstances2) {
+                if (areLexicallyEqual(instance1, instance2)) {
+                    found = true;
+                    break;
+                }
+            }
+            
+            if (!found) {
+                return false;
+            }
+        }
+        
+        return true;
     }
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask)
      */
     @Override
@@ -57,5 +75,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask)
      */
     @Override
@@ -64,4 +82,7 @@
     }
 
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#compare(ITask, ITask)
+     */
     @Override
     public TaskEquality compare(ITask task1, ITask task2) {
@@ -74,3 +95,54 @@
     }
 
+    
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) {
+        return
+            (instance1 instanceof IEventTaskInstance) && (instance2 instanceof IEventTaskInstance);
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        IEventTaskInstance eventTask1 = (IEventTaskInstance) instance1;
+        IEventTaskInstance eventTask2 = (IEventTaskInstance) instance2;
+        
+        return (eventTask1.getEvent().getType().equals(eventTask2.getEvent().getType()) &&
+                eventTask1.getEvent().getTarget().equals(eventTask2.getEvent().getTarget()));
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        return areLexicallyEqual(instance1, instance2);
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        return areLexicallyEqual(instance1, instance2);
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) {
+        if (areLexicallyEqual(instance1, instance2)) {
+            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 1190)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/GUIEventTaskComparisonRule.java	(revision 1294)
@@ -14,4 +14,6 @@
 
 package de.ugoe.cs.autoquest.tasktrees.taskequality;
+
+import java.util.Collection;
 
 import de.ugoe.cs.autoquest.eventcore.IEventTarget;
@@ -41,6 +43,7 @@
 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.IEventTaskInstance;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
 
 /**
@@ -61,16 +64,29 @@
     
     /* (non-Javadoc)
-     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     * @see TaskComparisonRule#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)
+        for (ITaskInstance instance : task1.getInstances()) {
+            if ((!(instance instanceof IEventTaskInstance)) ||
+                (!(((IEventTaskInstance) instance).getEvent().getType() instanceof IInteraction)))
+            {
+                return false;
+            }
+        }
+        
+        for (ITaskInstance instance : task2.getInstances()) {
+            if ((!(instance instanceof IEventTaskInstance)) ||
+                (!(((IEventTaskInstance) instance).getEvent().getType() instanceof IInteraction)))
+            {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask)
      */
     @Override
@@ -81,5 +97,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask)
      */
     @Override
@@ -90,5 +106,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask)
      */
     @Override
@@ -99,5 +115,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#compare(ITask, ITask)
+     * @see TaskComparisonRule#compare(ITask, ITask)
      */
     @Override
@@ -106,20 +122,115 @@
     }
 
-    /**
-     * 
-     */
-    private TaskEquality getEquality(ITask task1, ITask task2, TaskEquality requiredEqualityLevel) {
-        IEventTask eventTask1 = (IEventTask) task1;
-        IEventTask eventTask2 = (IEventTask) task2;
-        
-        if (!eventTask1.getEventTarget().equals(eventTask2.getEventTarget())) {
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#isApplicable(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance)
+     */
+    @Override
+    public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) {
+        return
+            (instance1 instanceof IEventTaskInstance) &&
+            (instance2 instanceof IEventTaskInstance) &&
+            (((IEventTaskInstance) instance1).getEvent().getType() instanceof IInteraction) &&
+            (((IEventTaskInstance) instance1).getEvent().getType() instanceof IInteraction);
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#areLexicallyEqual(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#areSyntacticallyEqual(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#areSemanticallyEqual(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see de.ugoe.cs.autoquest.tasktrees.taskequality.TaskComparisonRule#compare(de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance, de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance)
+     */
+    @Override
+    public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) {
+        return getEquality(instance1, instance2, null);
+    }
+
+    /**
+     * 
+     */
+    private TaskEquality getEquality(ITask         task1,
+                                     ITask         task2,
+                                     TaskEquality  requiredEqualityLevel)
+    {
+        Collection<ITaskInstance> taskInstances1 = task1.getInstances();
+        Collection<ITaskInstance> taskInstances2 = task2.getInstances();
+        
+        TaskEquality checkedEquality =
+            requiredEqualityLevel != null ? requiredEqualityLevel : TaskEquality.SEMANTICALLY_EQUAL;
+        
+        TaskEquality commonDenominator = TaskEquality.LEXICALLY_EQUAL;
+        
+        for (ITaskInstance instance1 : taskInstances1) {
+            TaskEquality mostConcreteEquality = null;
+            
+            for (ITaskInstance instance2 : taskInstances2) {
+                TaskEquality equality = getEquality(instance1, instance2, requiredEqualityLevel);
+                
+                if ((equality != null) && ((mostConcreteEquality == null) ||
+                                           (equality.isAtLeast(mostConcreteEquality))))
+                {
+                    mostConcreteEquality = equality;
+                    
+                    if (((requiredEqualityLevel != null) &&
+                         (mostConcreteEquality.isAtLeast(requiredEqualityLevel))) ||
+                        (mostConcreteEquality.isAtLeast(TaskEquality.LEXICALLY_EQUAL)))
+                    {
+                        break;
+                    }
+                }
+            }
+            
+            commonDenominator = commonDenominator.getCommonDenominator(mostConcreteEquality);
+            
+            if (!commonDenominator.isAtLeast(checkedEquality)) {
+                return TaskEquality.UNEQUAL;
+            }
+        }
+        
+        return commonDenominator;
+    }
+
+    /**
+     * 
+     */
+    private TaskEquality getEquality(ITaskInstance instance1,
+                                     ITaskInstance instance2,
+                                     TaskEquality  requiredEqualityLevel)
+    {
+        IEventTaskInstance eventTask1 = (IEventTaskInstance) instance1;
+        IEventTaskInstance eventTask2 = (IEventTaskInstance) instance2;
+        
+        if (!eventTask1.getEvent().getTarget().equals(eventTask2.getEvent().getTarget())) {
             return TaskEquality.UNEQUAL;
         }
         
-        IInteraction interaction1 = (IInteraction) eventTask1.getEventType();
-        IInteraction interaction2 = (IInteraction) eventTask2.getEventType();
+        IInteraction interaction1 = (IInteraction) eventTask1.getEvent().getType();
+        IInteraction interaction2 = (IInteraction) eventTask2.getEvent().getType();
         
         return compareInteractions
-            (interaction1, interaction2, eventTask1.getEventTarget(), requiredEqualityLevel);
+            (interaction1, interaction2, eventTask1.getEvent().getTarget(), requiredEqualityLevel);
     }
 
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 1190)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/IterationComparisonRule.java	(revision 1294)
@@ -15,9 +15,9 @@
 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.IIterationInstance;
 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;
 
 /**
@@ -82,5 +82,5 @@
     
     /* (non-Javadoc)
-     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     * @see TaskComparisonRule#isApplicable(ITask, ITask)
      */
     @Override
@@ -90,45 +90,8 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#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();
@@ -146,5 +109,5 @@
                 // ignore the type of the children but check them for equality.
                 
-                return getNodeEquality(child1, child2).isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL);
+                return getNodeEquality(child1, child2).isAtLeast(TaskEquality.LEXICALLY_EQUAL);
             }
         }
@@ -157,5 +120,13 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITask task1, ITask task2) {
+        return areLexicallyEqual(task1, task2);
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask)
      */
     @Override
@@ -165,5 +136,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#compare(ITask, ITask)
+     * @see TaskComparisonRule#compare(ITask, ITask)
      */
     @Override
@@ -203,4 +174,73 @@
         // all other combinations (i.e. sequence with single child and sequence with selection)
         // can not match
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) {
+        return isApplicable(instance1.getTask(), instance2.getTask());
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        IIterationInstance iteration1 = (IIterationInstance) instance1;
+        IIterationInstance iteration2 = (IIterationInstance) instance2;
+
+        // if both sequences do not have children, they are equal although this doesn't make sense
+        if ((iteration1.size() == 0) && (iteration2.size() == 0)) {
+            return true;
+        }
+
+        if (iteration1.size() != iteration2.size()) {
+            return false;
+        }
+
+        for (int i = 0; i < iteration1.size(); i++) {
+            ITaskInstance child1 = iteration1.get(i);
+            ITaskInstance child2 = iteration2.get(i);
+
+            TaskEquality taskEquality =
+                callRuleManager(child1, child2, TaskEquality.LEXICALLY_EQUAL);
+
+            if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        return areLexicallyEqual(instance1, instance2);
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        return areLexicallyEqual(instance1, instance2);
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) {
+        if (areLexicallyEqual(instance1, instance2)) {
+            return TaskEquality.LEXICALLY_EQUAL;
+        }
+        else {
+            return TaskEquality.UNEQUAL;
+        }
     }
 
@@ -272,6 +312,5 @@
                   callRuleManager(task, child, commonDenominatorForAllComparisons);
 
-            if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL))
-            {
+            if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL)) {
                 return TaskEquality.UNEQUAL;
             }
@@ -314,3 +353,34 @@
         }
     }
+    
+    /**
+     * <p>
+     * used to to call the task equality rule manager for the comparison of the two provided
+     * children. If no required equality level is provided, than the most concrete equality is
+     * returned. Otherwise, the required equality is returned as long as the children are equal
+     * on that level.
+     * </p> 
+     * 
+     * @param taskInstance1         the first task instance to be compared
+     * @param taskInstance2         the second task instance to be compared
+     * @param requiredEqualityLevel the equality level to be checked for
+     * 
+     * @return the determined equality
+     */
+    private TaskEquality callRuleManager(ITaskInstance taskInstance1,
+                                         ITaskInstance taskInstance2,
+                                         TaskEquality  requiredEqualityLevel)
+    {
+        if (requiredEqualityLevel == null) {
+            return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2);
+        }
+        else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual
+                     (taskInstance1, taskInstance2, 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 1190)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/SelectionComparisonRule.java	(revision 1294)
@@ -18,5 +18,7 @@
 
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
 
 /**
@@ -39,5 +41,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     * @see TaskComparisonRule#isApplicable(ITask, ITask)
      */
     @Override
@@ -47,5 +49,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask)
      */
     @Override
@@ -56,5 +58,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask)
      */
     @Override
@@ -65,5 +67,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask)
      */
     @Override
@@ -74,9 +76,52 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#compare(ITask, ITask)
+     * @see TaskComparisonRule#compare(ITask, ITask)
      */
     @Override
     public TaskEquality compare(ITask task1, ITask task2) {
         return getEquality(task1, task2, null);
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) {
+        return isApplicable(instance1.getTask(), instance2.getTask());
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) {
+        return getEquality(instance1, instance2, null);
     }
 
@@ -107,23 +152,12 @@
         }
 
-        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;
-            }
+            return getMostConcreteEqualityLevel(children1, children2);
         }
         else {
             // we are searching for a specific equality
-            if (checkEqualityLevel(children1, children2, requiredEqualityLevel) &&
-                checkEqualityLevel(children2, children1, requiredEqualityLevel))
-            {
+            if (checkEqualityLevel(children1, children2, requiredEqualityLevel)) {
                 return requiredEqualityLevel;
             }
@@ -136,7 +170,7 @@
     /**
      * <p>
-     * determines the common equality level for all tasks in the first list compared to all
-     * tasks in the second list. If for one task in the first list, there is no equal task in the
-     * second list, the method return unequality. 
+     * determines the most concrete equality level for all tasks in the first list compared to all
+     * tasks in the second list. It is sufficient, if there is one task in one list for which there
+     * exist an equal task in the other list.
      * </p>
      *
@@ -144,10 +178,9 @@
      * @param children2 the second list to be compared
      * 
-     * @return the common task equality identified for all tasks in the first list with respect to
-     *         the second list
-     */
-    private TaskEquality getCommonEqualityLevel(List<ITask> children1, List<ITask> children2) {
-        TaskEquality listEquality = TaskEquality.LEXICALLY_EQUAL;
-        
+     * @return the most concrete task equality identified for all tasks in the first list with
+     *         respect to the second list
+     */
+    private TaskEquality getMostConcreteEqualityLevel(List<ITask> children1, List<ITask> children2)
+    {
         TaskEquality childEquality;
         TaskEquality currentEquality;
@@ -164,28 +197,20 @@
                     }
                     
-                    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.isAtLeast(TaskEquality.LEXICALLY_EQUAL)) {
+                        // as we calculate the most concrete equality, we can break up here
+                        return TaskEquality.LEXICALLY_EQUAL;
                     }
                 }
             }
-            
-            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>
-     * ensures for the two given lists, that for each task in the first list there is a task
+        }
+
+        // as the comparison should be commutative, we do not need to check, if in list 2 there is
+        // a child equal to one in list 1
+        return TaskEquality.UNEQUAL;
+    }
+
+    /**
+     * <p>
+     * ensures for the two given lists, that for at least one task in the first list there is a task
      * in the second list being on the given level equal to the task in the first list.
      * </p> 
@@ -195,6 +220,6 @@
      * @param requiredEqualityLevel the equality level to be checked for
      * 
-     * @return true if each task in the first list has an equal task in the second list when
-     *         considering the given equality level, false else.
+     * @return true if there is a task in the first list that has an equal task in the second list
+     *         when considering the given equality level, false else.
      */
     private boolean checkEqualityLevel(List<ITask>  children1,
@@ -202,8 +227,6 @@
                                        TaskEquality requiredEqualityLevel)
     {
-        TaskEquality childEquality;
         TaskEquality currentEquality;
         for (ITask child1 : children1) {
-            childEquality = null;
             for (ITask child2 : children2) {
                 currentEquality = callRuleManager(child1, child2, requiredEqualityLevel);
@@ -212,18 +235,10 @@
                     // 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;
+                    return true;
                 }
             }
-            
-            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;
+        }
+
+        return false;
     }
 
@@ -259,3 +274,74 @@
     }
 
+    /**
+     * <p>
+     * compares two selection instances with each other checking for the provided required level of
+     * equality. If this level is ensured, the method immediately returns. The more concrete
+     * the required equality level, the more checks this method performs.
+     * </p>
+     * 
+     * @param taskInstance1         the first task instance to be compared
+     * @param taskInstance2         the second task instance to be compared
+     * @param requiredEqualityLevel the equality level to be checked for
+     * 
+     * @return the determined equality.
+     */
+    private TaskEquality getEquality(ITaskInstance taskInstance1,
+                                     ITaskInstance taskInstance2,
+                                     TaskEquality  requiredEqualityLevel)
+    {
+        ITaskInstance child1 = ((ISelectionInstance) taskInstance1).getChild();
+        ITaskInstance child2 = ((ISelectionInstance) taskInstance2).getChild();
+
+        // if both selections do not have children, they are lexically equal. If only one of them
+        // has children, they are unequal.
+        if ((child1 == null) && (child2 == null)) {
+            return TaskEquality.LEXICALLY_EQUAL;
+        }
+        else if ((child1 == null) || (child2 == null)) {
+            return TaskEquality.UNEQUAL;
+        }
+
+        TaskEquality equality = callRuleManager(child1, child2, requiredEqualityLevel);
+        
+        if (equality == TaskEquality.IDENTICAL) {
+            // two different selection instances can be at most lexically equal even if their
+            // children are identical
+            return TaskEquality.LEXICALLY_EQUAL;
+        }
+        else {
+            return equality;
+        }
+    }
+
+    /**
+     * <p>
+     * used to to call the task equality rule manager for the comparison of the two provided
+     * children. If no required equality level is provided, than the most concrete equality is
+     * returned. Otherwise, the required equality is returned as long as the children are equal
+     * on that level.
+     * </p> 
+     * 
+     * @param taskInstance1         the first task instance to be compared
+     * @param taskInstance2         the second task instance to be compared
+     * @param requiredEqualityLevel the equality level to be checked for
+     * 
+     * @return the determined equality
+     */
+    private TaskEquality callRuleManager(ITaskInstance taskInstance1,
+                                         ITaskInstance taskInstance2,
+                                         TaskEquality  requiredEqualityLevel)
+    {
+        if (requiredEqualityLevel == null) {
+            return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2);
+        }
+        else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual
+                     (taskInstance1, taskInstance2, 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 1190)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/SequenceComparisonRule.java	(revision 1294)
@@ -18,5 +18,7 @@
 
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
 
 /**
@@ -34,5 +36,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     * @see TaskComparisonRule#isApplicable(ITask, ITask)
      */
     @Override
@@ -42,5 +44,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask)
      */
     @Override
@@ -51,5 +53,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask)
      */
     @Override
@@ -60,5 +62,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask)
      */
     @Override
@@ -69,9 +71,52 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#compare(ITask, ITask)
+     * @see TaskComparisonRule#compare(ITask, ITask)
      */
     @Override
     public TaskEquality compare(ITask task1, ITask task2) {
         return getEquality(task1, task2, null);
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) {
+        return isApplicable(instance1.getTask(), instance2.getTask());
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) {
+        return getEquality(instance1, instance2, null);
     }
 
@@ -149,3 +194,80 @@
         }
     }
+
+    /**
+     * <p>
+     * compares two sequence instances with each other checking for the provided required level of
+     * equality. If this level is ensured, the method immediately returns. The more concrete
+     * the required equality level, the more checks this method performs.
+     * </p>
+     * 
+     * @param taskInstance1         the first task instance to be compared
+     * @param taskInstance2         the second task instance to be compared
+     * @param requiredEqualityLevel the equality level to be checked for
+     * 
+     * @return the determined equality.
+     */
+    private TaskEquality getEquality(ITaskInstance taskInstance1,
+                                     ITaskInstance taskInstance2,
+                                     TaskEquality  requiredEqualityLevel)
+    {
+        ISequenceInstance sequence1 = (ISequenceInstance) taskInstance1;
+        ISequenceInstance sequence2 = (ISequenceInstance) taskInstance2;
+
+        // if both sequences do not have children, they are equal although this doesn't make sense
+        if ((sequence1.size() == 0) && (sequence2.size() == 0)) {
+            return TaskEquality.LEXICALLY_EQUAL;
+        }
+
+        if (sequence1.size() != sequence2.size()) {
+            return TaskEquality.UNEQUAL;
+        }
+
+        TaskEquality resultingEquality = TaskEquality.LEXICALLY_EQUAL;
+        for (int i = 0; i < sequence1.size(); i++) {
+            ITaskInstance child1 = sequence1.get(i);
+            ITaskInstance child2 = sequence2.get(i);
+
+            TaskEquality taskEquality = callRuleManager(child1, child2, requiredEqualityLevel);
+
+            if ((taskEquality == null) || (taskEquality == TaskEquality.UNEQUAL)) {
+                return TaskEquality.UNEQUAL;
+            }
+            
+            resultingEquality = resultingEquality.getCommonDenominator(taskEquality);
+        }
+
+        return resultingEquality;
+    }
+    
+    /**
+     * <p>
+     * used to to call the task equality rule manager for the comparison of the two provided
+     * children. If no required equality level is provided, than the most concrete equality is
+     * returned. Otherwise, the required equality is returned as long as the children are equal
+     * on that level.
+     * </p> 
+     * 
+     * @param taskInstance1         the first task instance to be compared
+     * @param taskInstance2         the second task instance to be compared
+     * @param requiredEqualityLevel the equality level to be checked for
+     * 
+     * @return the determined equality
+     */
+    private TaskEquality callRuleManager(ITaskInstance taskInstance1,
+                                         ITaskInstance taskInstance2,
+                                         TaskEquality  requiredEqualityLevel)
+    {
+        if (requiredEqualityLevel == null) {
+            return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2);
+        }
+        else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual
+                     (taskInstance1, taskInstance2, 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 1190)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskAndIterationComparisonRule.java	(revision 1294)
@@ -16,5 +16,7 @@
 
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
 
 /**
@@ -33,5 +35,5 @@
     
     /* (non-Javadoc)
-     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     * @see TaskComparisonRule#isApplicable(ITask, ITask)
      */
     @Override
@@ -42,5 +44,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask)
      */
     @Override
@@ -51,5 +53,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask)
      */
     @Override
@@ -60,5 +62,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask)
      */
     @Override
@@ -69,9 +71,52 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#compare(ITask, ITask)
+     * @see TaskComparisonRule#compare(ITask, ITask)
      */
     @Override
     public TaskEquality compare(ITask task1, ITask task2) {
         return getEquality(task1, task2, null);
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) {
+        return isApplicable(instance1.getTask(), instance2.getTask());
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) {
+        return getEquality(instance1, instance2, null);
     }
 
@@ -167,3 +212,120 @@
         }
     }
+
+    /**
+     * <p>
+     * compares two task instances with each other checking for the provided required level of
+     * equality. One of the task instances must be a iteration, the other one not. If this is not
+     * the case, the method returns null. The returned equality level is at most lexical equality
+     * as the iteration can not be identical to something not being a iteration.
+     * </p>
+     * 
+     * @param taskInstance1         the first task instance to be compared
+     * @param taskInstance2         the second task instance to be compared
+     * @param requiredEqualityLevel the equality level to be checked for
+     * 
+     * @return the determined equality.
+     */
+    private TaskEquality getEquality(ITaskInstance taskInstance1,
+                                     ITaskInstance taskInstance2,
+                                     TaskEquality  requiredEqualityLevel)
+    {
+        IIterationInstance iteration = null;
+        ITaskInstance task = null;
+        
+        if (taskInstance1 instanceof IIterationInstance) {
+            if (taskInstance2 instanceof IIterationInstance) {
+                // the rule is not responsible for two iterations
+                return null;
+            }
+            
+            iteration = (IIterationInstance) taskInstance1;
+            task = taskInstance2;
+        }
+        else if (taskInstance2 instanceof IIterationInstance) {
+            if (taskInstance1 instanceof IIterationInstance) {
+                // the rule is not responsible for two iterations
+                return null;
+            }
+            
+            iteration = (IIterationInstance) taskInstance2;
+            task = taskInstance1;
+        }
+        else {
+            return null;
+        }
+
+        // now, that we found the iteration and the task, lets compare the children of the iteration
+        // with the task.
+        
+        if (iteration.size() < 1) {
+            return null;
+        }
+
+        TaskEquality mostConcreteNodeEquality = null;
+        
+        for (ITaskInstance child : iteration) {
+            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>
+     * used to to call the task equality rule manager for the comparison of the two provided
+     * children. If no required equality level is provided, than the most concrete equality is
+     * returned. Otherwise, the required equality is returned as long as the children are equal
+     * on that level.
+     * </p> 
+     * 
+     * @param taskInstance1         the first task instance to be compared
+     * @param taskInstance2         the second task instance to be compared
+     * @param requiredEqualityLevel the equality level to be checked for
+     * 
+     * @return the determined equality
+     */
+    private TaskEquality callRuleManager(ITaskInstance taskInstance1,
+                                         ITaskInstance taskInstance2,
+                                         TaskEquality  requiredEqualityLevel)
+    {
+        if (requiredEqualityLevel == null) {
+            return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2);
+        }
+        else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual
+                     (taskInstance1, taskInstance2, 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 1190)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskAndSelectionComparisonRule.java	(revision 1294)
@@ -18,5 +18,7 @@
 
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
 
 /**
@@ -34,5 +36,5 @@
     
     /* (non-Javadoc)
-     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     * @see TaskComparisonRule#isApplicable(ITask, ITask)
      */
     @Override
@@ -43,5 +45,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask)
      */
     @Override
@@ -52,5 +54,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask)
      */
     @Override
@@ -61,5 +63,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask)
      */
     @Override
@@ -70,5 +72,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#compare(ITask, ITask)
+     * @see TaskComparisonRule#compare(ITask, ITask)
      */
     @Override
@@ -77,4 +79,47 @@
     }
     
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) {
+        return isApplicable(instance1.getTask(), instance2.getTask());
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.LEXICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.LEXICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SYNTACTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SYNTACTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        TaskEquality equality = getEquality(instance1, instance2, TaskEquality.SEMANTICALLY_EQUAL);
+        return (equality != null) && (equality.isAtLeast(TaskEquality.SEMANTICALLY_EQUAL));
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) {
+        return getEquality(instance1, instance2, null);
+    }
+
     /**
      * <p>
@@ -191,3 +236,98 @@
         }
     }
+
+    /**
+     * <p>
+     * compares two task instances with each other checking for the provided required level of
+     * equality. One of the task instances must be a selection, the other one not. If this is not
+     * the case, the method returns null. The returned equality level is at most lexical equality
+     * as the selection can not be identical to something not being a selection.
+     * </p>
+     * 
+     * @param taskInstance1         the first task instance to be compared
+     * @param taskInstance2         the second task instance to be compared
+     * @param requiredEqualityLevel the equality level to be checked for
+     * 
+     * @return the determined equality.
+     */
+    private TaskEquality getEquality(ITaskInstance taskInstance1,
+                                     ITaskInstance taskInstance2,
+                                     TaskEquality  requiredEqualityLevel)
+    {
+        ISelectionInstance selection = null;
+        ITaskInstance task = null;
+        
+        if (taskInstance1 instanceof ISelectionInstance) {
+            if (taskInstance2 instanceof ISelectionInstance) {
+                // the rule is not responsible for two selections
+                return null;
+            }
+            
+            selection = (ISelectionInstance) taskInstance1;
+            task = taskInstance2;
+        }
+        else if (taskInstance2 instanceof ISelectionInstance) {
+            if (taskInstance1 instanceof ISelectionInstance) {
+                // the rule is not responsible for two selections
+                return null;
+            }
+            
+            selection = (ISelectionInstance) taskInstance2;
+            task = taskInstance1;
+        }
+        else {
+            return null;
+        }
+
+        // now, that we found the selection and the task, lets compare the child of the selection
+        // with the task.
+        ITaskInstance child = selection.getChild();
+        
+        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 selection is not identical to the task, but at most lexically equal
+        if (taskEquality == TaskEquality.IDENTICAL) {
+            return TaskEquality.LEXICALLY_EQUAL;
+        }
+        else {
+            return taskEquality;
+        }
+
+    }
+    
+    /**
+     * <p>
+     * used to to call the task equality rule manager for the comparison of the two provided
+     * children. If no required equality level is provided, than the most concrete equality is
+     * returned. Otherwise, the required equality is returned as long as the children are equal
+     * on that level.
+     * </p> 
+     * 
+     * @param taskInstance1         the first task instance to be compared
+     * @param taskInstance2         the second task instance to be compared
+     * @param requiredEqualityLevel the equality level to be checked for
+     * 
+     * @return the determined equality
+     */
+    private TaskEquality callRuleManager(ITaskInstance taskInstance1,
+                                         ITaskInstance taskInstance2,
+                                         TaskEquality  requiredEqualityLevel)
+    {
+        if (requiredEqualityLevel == null) {
+            return TaskEqualityRuleManager.getInstance().compare(taskInstance1, taskInstance2);
+        }
+        else if (TaskEqualityRuleManager.getInstance().areAtLeastEqual
+                     (taskInstance1, taskInstance2, requiredEqualityLevel))
+        {
+            return requiredEqualityLevel;
+        }
+        else {
+            return TaskEquality.UNEQUAL;
+        }
+    }
 }
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 1190)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskComparisonRule.java	(revision 1294)
@@ -16,9 +16,10 @@
 
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
 
 /**
  * <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.
+ * A task comparison rule is used by the {@link TaskEqualityRuleManager} to compare tasks and
+ * task instances with each other. It provides several methods to be called for a comparison.
  * </p>
  * 
@@ -90,3 +91,65 @@
     public TaskEquality compare(ITask task1, ITask task2);
 
+    /**
+     * <p>
+     * checks if the rule is applicable for comparing the two provided task instances
+     * </p>
+     * 
+     * @param instance1 the first task instance to compare
+     * @param instance2 the second task instance to compare
+     * 
+     * @return true, if the rule is applicable, false else
+     */
+    public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2);
+
+    /**
+     * <p>
+     * checks, if the provided task instances are lexically equal
+     * </p>
+     * 
+     * @param instance1 the first task instance to compare
+     * @param instance2 the second task instance to compare
+     * 
+     * @return true, if the tasks are equal, false else
+     */
+    public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2);
+
+    /**
+     * <p>
+     * checks, if the provided task instances are syntactically equal
+     * </p>
+     * 
+     * @param instance1 the first task instance to compare
+     * @param instance2 the second task instance to compare
+     * 
+     * @return true, if the tasks are equal, false else
+     */
+    public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2);
+
+    /**
+     * <p>
+     * checks, if the provided task instances are semantically equal
+     * </p>
+     * 
+     * @param instance1 the first task instance to compare
+     * @param instance2 the second task instance to compare
+     * 
+     * @return true, if the tasks are equal, false else
+     */
+    public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2);
+
+    /**
+     * <p>
+     * compares two task instances with each other. The result of the method is either a task
+     * instance equality or null. If it is null, it means, that the rule is not able to correctly
+     * compare the two given task instances
+     * </p>
+     * 
+     * @param instance1 the first task instance to compare
+     * @param instance2 the second task instance to compare
+     * 
+     * @return as described
+     */
+    public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2);
+
 }
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 1190)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskEqualityRuleManager.java	(revision 1294)
@@ -19,15 +19,15 @@
 
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
 
 /**
  * <p>
- * The task equality rule manager is capable of comparing tasks based on its internal list
- * of comparison rules. These rules are asked for comparing the two provided tasks. If a rule
- * returns a task equality other than null, this equality is returned. Otherwise the next rule
- * is asked.
+ * The task equality rule manager is capable of comparing tasks and task instances based on its
+ * internal list of comparison rules. These rules are asked for comparing the two provided tasks or
+ * task instance. 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$
+ * @author Patrick Harms
  */
 public class TaskEqualityRuleManager {
@@ -269,3 +269,207 @@
     }
 
+    /**
+     * <p>
+     * this method performs a comparison of the two provided task instances. It iterates its
+     * internal comparison rules. If the first rule returns a task instance equality other than
+     * null, this equality is returned. Otherwise the next rule is tried. If no rule returns an
+     * equality <code>TaskEquality.UNEQUAL</code> is returned.
+     * </p>
+     * 
+     * @param instance1 the first task instance to be compared
+     * @param instance2 the second task instance 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(ITaskInstance instance1, ITaskInstance instance2)
+        throws IllegalStateException
+    {
+        if (mRuleIndex == null) {
+            throw new IllegalStateException("not initialized");
+        }
+        
+        // LOG.info("checking for equality of " + instance1 + " and " + instance2);
+        TaskEquality instanceEquality = null;
+
+        for (TaskComparisonRule rule : mRuleIndex) {
+            if (rule.isApplicable(instance1, instance2)) {
+                instanceEquality = rule.compare(instance1, instance2);
+                if (instanceEquality != null) {
+                    // LOG.warning("used rule " + rule + " for equality check");
+                    return instanceEquality;
+                }
+            }
+        }
+
+        // LOG.warning("no rule could be applied --> handling tasks as unequal");
+
+        return TaskEquality.UNEQUAL;
+    }
+
+    /**
+     * <p>
+     * this method compares two task instances with respect to the given equality level and returns
+     * true, if this level is given.
+     * </p>
+     * 
+     * @param instance1     the first task instance to be compared
+     * @param instance2     the second task instance to be compared
+     * @param equalityLevel the level of equality to be checked for
+     * 
+     * @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 boolean areAtLeastEqual(ITaskInstance        instance1,
+                                   ITaskInstance        instance2,
+                                   TaskEquality equalityLevel)
+    {
+        if (equalityLevel == null) {
+            throw new IllegalArgumentException("required equality level must not be null");
+        }
+        
+        switch (equalityLevel) {
+            case IDENTICAL:
+                return areIdentical(instance1, instance2);
+            case LEXICALLY_EQUAL:
+                return areLexicallyEqual(instance1, instance2);
+            case SYNTACTICALLY_EQUAL:
+                return areSyntacticallyEqual(instance1, instance2);
+            case SEMANTICALLY_EQUAL:
+                return areSemanticallyEqual(instance1, instance2);
+            case UNEQUAL:
+                return !areSemanticallyEqual(instance1, instance2);
+            default:
+                throw new IllegalArgumentException("unknown required equality: " + equalityLevel);
+        }
+    }
+
+    /**
+     * <p>
+     * this method checks if the two given task instances are identical. For this, it iterates its
+     * internal comparison rules. If the first rule returns true, than this method returns true
+     * as well. If no rule returns true, this method returns false.
+     * </p>
+     * 
+     * @param instance1 the first task instance to be compared
+     * @param instance2 the second task instance 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 boolean areIdentical(ITaskInstance instance1, ITaskInstance instance2) {
+        if (mRuleIndex == null) {
+            throw new IllegalStateException("not initialized");
+        }
+        
+        for (TaskComparisonRule rule : mRuleIndex) {
+            if (rule.isApplicable(instance1, instance2) &&
+                rule.areLexicallyEqual(instance1, instance2))
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * <p>
+     * this method checks if the two given task instances are lexically equal. For this, it
+     * iterates its internal comparison rules. If the first rule returns true, than this method
+     * returns true, as well. If no rule returns true, this method returns false.
+     * </p>
+     * 
+     * @param instance1 the first task instance to be compared
+     * @param instance2 the second task instance 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 boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        if (mRuleIndex == null) {
+            throw new IllegalStateException("not initialized");
+        }
+        
+        for (TaskComparisonRule rule : mRuleIndex) {
+            if (rule.isApplicable(instance1, instance2) &&
+                rule.areLexicallyEqual(instance1, instance2))
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * <p>
+     * this method checks if the two given task instances are syntactically equal. For this, it
+     * iterates its internal comparison rules. If the first rule returns true, than this method
+     * returns true, as well. If no rule returns true, this method returns false.
+     * </p>
+     * 
+     * @param instance1 the first task instance to be compared
+     * @param instance2 the second task instance 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 boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        if (mRuleIndex == null) {
+            throw new IllegalStateException("not initialized");
+        }
+        
+        for (TaskComparisonRule rule : mRuleIndex) {
+            if (rule.isApplicable(instance1, instance2) &&
+                rule.areSyntacticallyEqual(instance1, instance2))
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * <p>
+     * this method checks if the two given task instances are semantically equal. For this, it
+     * iterates its internal comparison rules. If the first rule returns true, than this method
+     * returns true, as well. If no rule returns true, this method returns false.
+     * </p>
+     * 
+     * @param instance1 the first task instance to be compared
+     * @param instance2 the second task instance 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 boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        if (mRuleIndex == null) {
+            throw new IllegalStateException("not initialized");
+        }
+        
+        for (TaskComparisonRule rule : mRuleIndex) {
+            if (rule.isApplicable(instance1, instance2) &&
+                rule.areSemanticallyEqual(instance1, instance2))
+            {
+                 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 1190)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/taskequality/TaskIdentityRule.java	(revision 1294)
@@ -16,10 +16,11 @@
 
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
 
 /**
  * <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.
+ * tasks using the <code>==</code> operator returns true. Else it returns null to denote, that
+ * it can not compare the tasks.
  * </p>
  * 
@@ -30,5 +31,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#isApplicable(ITask, ITask)
+     * @see TaskComparisonRule#isApplicable(ITask, ITask)
      */
     @Override
@@ -38,5 +39,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areLexicallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areLexicallyEqual(ITask, ITask)
      */
     @Override
@@ -46,5 +47,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSyntacticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITask, ITask)
      */
     @Override
@@ -54,5 +55,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#areSemanticallyEqual(ITask, ITask)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITask, ITask)
      */
     @Override
@@ -62,5 +63,5 @@
 
     /* (non-Javadoc)
-     * @see NodeComparisonRule#compare(ITask, ITask)
+     * @see TaskComparisonRule#compare(ITask, ITask)
      */
     @Override
@@ -74,3 +75,48 @@
     }
 
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#isApplicable(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean isApplicable(ITaskInstance instance1, ITaskInstance instance2) {
+        return (instance1.getTask() == instance2.getTask());
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areLexicallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        return (instance1.getTask() == instance2.getTask());
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSyntacticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        return (instance1.getTask() == instance2.getTask());
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#areSemanticallyEqual(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITaskInstance instance1, ITaskInstance instance2) {
+        return (instance1.getTask() == instance2.getTask());
+    }
+
+    /* (non-Javadoc)
+     * @see TaskComparisonRule#compare(ITaskInstance, ITaskInstance)
+     */
+    @Override
+    public TaskEquality compare(ITaskInstance instance1, ITaskInstance instance2) {
+        if (isApplicable(instance1, instance2)) {
+            return TaskEquality.IDENTICAL;
+        }
+        else {
+            return null;
+        }
+    }
+
 }
