Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/nodeequality/IterationComparisonRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/nodeequality/IterationComparisonRule.java	(revision 1113)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/nodeequality/IterationComparisonRule.java	(revision 1125)
@@ -15,6 +15,10 @@
 package de.ugoe.cs.autoquest.tasktrees.nodeequality;
 
+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.ISelection;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
 
@@ -95,29 +99,105 @@
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see de.ugoe.cs.tasktree.nodeequality.NodeEqualityRule#apply(TaskTreeNode, TaskTreeNode)
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#isApplicable(ITaskTreeNode, ITaskTreeNode)
+     */
+    @Override
+    public boolean isApplicable(ITaskTreeNode node1, ITaskTreeNode node2) {
+        return (node1 instanceof IIteration) && (node2 instanceof IIteration);
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areLexicallyEqual(ITaskTreeNode, ITaskTreeNode)
+     */
+    @Override
+    public boolean areLexicallyEqual(ITaskTreeNode node1, ITaskTreeNode node2) {
+        List<ITaskTreeNode> children1 = node1.getChildren();
+        List<ITaskTreeNode> children2 = node2.getChildren();
+        
+        if (children1.size() == children2.size()) {
+            if (children1.size() == 0) {
+                return true;
+            }
+            else {
+                ITaskTreeNode child1 = children1.get(0);
+                ITaskTreeNode child2 = children2.get(0);
+                
+                // 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(NodeEquality.LEXICALLY_EQUAL);
+                }
+            }
+        }
+        
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSyntacticallyEqual(ITaskTreeNode, ITaskTreeNode)
+     */
+    @Override
+    public boolean areSyntacticallyEqual(ITaskTreeNode node1, ITaskTreeNode node2) {
+        List<ITaskTreeNode> children1 = node1.getChildren();
+        List<ITaskTreeNode> children2 = node2.getChildren();
+        
+        if (children1.size() == children2.size()) {
+            if (children1.size() == 0) {
+                return true;
+            }
+            else {
+                ITaskTreeNode child1 = children1.get(0);
+                ITaskTreeNode child2 = children2.get(0);
+                
+                // 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(NodeEquality.SYNTACTICALLY_EQUAL);
+            }
+        }
+        
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#areSemanticallyEqual(ITaskTreeNode, ITaskTreeNode)
+     */
+    @Override
+    public boolean areSemanticallyEqual(ITaskTreeNode node1, ITaskTreeNode node2) {
+        return compare(node1, node2).isAtLeast(NodeEquality.SEMANTICALLY_EQUAL);
+    }
+
+    /* (non-Javadoc)
+     * @see NodeComparisonRule#compare(ITaskTreeNode, ITaskTreeNode)
      */
     @Override
     public NodeEquality compare(ITaskTreeNode node1, ITaskTreeNode node2) {
-        if ((!(node1 instanceof IIteration)) || (!(node2 instanceof IIteration))) {
-            return null;
-        }
-
-        if (node1 == node2) {
-            return NodeEquality.IDENTICAL;
-        }
+        List<ITaskTreeNode> children1 = node1.getChildren();
+        List<ITaskTreeNode> children2 = node2.getChildren();
 
         // if both iterations do not have children, they are equal although this doesn't make sense
-        if ((node1.getChildren().size() == 0) && (node2.getChildren().size() == 0)) {
+        if ((children1.size() == 0) && (children2.size() == 0)) {
             return NodeEquality.LEXICALLY_EQUAL;
         }
-        else if ((node1.getChildren().size() == 0) || (node2.getChildren().size() == 0)) {
+        else if ((children1.size() == 0) || (children2.size() == 0)) {
             return NodeEquality.UNEQUAL;
         }
 
-        ITaskTreeNode child1 = node1.getChildren().get(0);
-        ITaskTreeNode child2 = node2.getChildren().get(0);
+        ITaskTreeNode child1 = children1.get(0);
+        ITaskTreeNode child2 = children2.get(0);
 
         // iterations may have 3 different structures.
@@ -132,5 +212,23 @@
         // This condition matches, if both iterations are the same variants of iteration. I.e. three
         // combinations of the permutation are handled herewith.
-        NodeEquality nodeEquality = mRuleManager.applyRules(child1, child2);
+        NodeEquality nodeEquality = getNodeEquality(child1, child2);
+        
+        if (nodeEquality != null) {
+            return nodeEquality;
+        }
+
+        // compare one iteration with a single node as a child and another one with a selection of
+        // semantically equal nodes
+        return selectionChildrenSemanticallyEqualNode(child1, child2);
+        
+        // all other combinations (i.e. sequence with single child and sequence with selection)
+        // can not match
+    }
+
+    /**
+     * TODO update comment
+     */
+    private NodeEquality getNodeEquality(ITaskTreeNode child1, ITaskTreeNode child2) {
+        NodeEquality nodeEquality = callRuleManager(child1, child2, null);
 
         if (nodeEquality.isAtLeast(NodeEquality.SEMANTICALLY_EQUAL)) {
@@ -144,11 +242,6 @@
             }
         }
-
-        // compare one iteration with a single node as a child and another one with a selection of
-        // semantically equal nodes
-        return selectionChildrenSemanticallyEqualNode(child1, child2);
-        
-        // all other combinations (i.e. sequence with single child and sequence with selection)
-        // can not match
+        
+        return NodeEquality.UNEQUAL;
     }
 
@@ -189,5 +282,6 @@
 
         for (ITaskTreeNode child : selection.getChildren()) {
-            NodeEquality nodeEquality = mRuleManager.applyRules(node, child);
+            NodeEquality nodeEquality =
+                  callRuleManager(node, child, commonDenominatorForAllComparisons);
 
             if ((nodeEquality == null) || (nodeEquality == NodeEquality.UNEQUAL))
@@ -203,3 +297,27 @@
     }
 
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param child1
+     * @param child2
+     * @param requiredEqualityLevel
+     * @return
+     */
+    private NodeEquality callRuleManager(ITaskTreeNode child1,
+                                         ITaskTreeNode child2,
+                                         NodeEquality  requiredEqualityLevel)
+    {
+        if (requiredEqualityLevel == null) {
+            return mRuleManager.compare(child1, child2);
+        }
+        else if (mRuleManager.areAtLeastEqual(child1, child2, requiredEqualityLevel)) {
+            return requiredEqualityLevel;
+        }
+        else {
+            return NodeEquality.UNEQUAL;
+        }
+    }
 }
