Index: trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/AbstractTemporalRelationshipTC.java
===================================================================
--- trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/AbstractTemporalRelationshipTC.java	(revision 1126)
+++ trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/AbstractTemporalRelationshipTC.java	(revision 1127)
@@ -184,8 +184,8 @@
             }
             else {
-                status = RuleApplicationStatus.RULE_NOT_APPLIED;
-            }
-            
-            assertTrue(status != RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);
+                status = RuleApplicationStatus.NOT_APPLIED;
+            }
+            
+            assertTrue(status != RuleApplicationStatus.FEASIBLE);
             
             if ((result != null) && (result.getNewlyCreatedParentNodes() != null)) {
@@ -195,11 +195,10 @@
             }
             
-            if (status == RuleApplicationStatus.RULE_NOT_APPLIED) {
+            if (status == RuleApplicationStatus.NOT_APPLIED) {
                 toBeAppliedOn.pop();
             }
             
         }
-        while ((!toBeAppliedOn.isEmpty()) ||
-               (status == RuleApplicationStatus.RULE_APPLICATION_FINISHED));
+        while ((!toBeAppliedOn.isEmpty()) || (status == RuleApplicationStatus.FINISHED));
 
         return taskTreeNodeFactory.createTaskTree(sequence);
Index: trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiElementSequenceDetectionRuleTest.java
===================================================================
--- trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiElementSequenceDetectionRuleTest.java	(revision 1126)
+++ 	(revision )
@@ -1,238 +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 org.junit.Test;
-
-import de.ugoe.cs.autoquest.eventcore.IEventTarget;
-import de.ugoe.cs.autoquest.tasktrees.TaskTreeChecker;
-import de.ugoe.cs.autoquest.test.DummyGUIElement;
-import de.ugoe.cs.autoquest.test.DummyInteraction;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: $
- * @author 2011, last modified by $Author: $
- */
-public class DefaultGuiElementSequenceDetectionRuleTest extends AbstractTemporalRelationshipTC {
-    
-    /**
-     *
-     */
-    @Test
-    public void testOneInteractionOnOneElement() {
-        simulateEvent(new DummyInteraction("bla", 1), new DummyGUIElement("elem1"));
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence {" +
-             "  Event bla {}" +
-             "}", getTaskTree());
-    }
-
-    /**
-     *
-     */
-    @Test
-    public void testManyInteractionsOnOneElement() {
-        IEventTarget eventTarget = new DummyGUIElement("elem1");
-        simulateEvent(new DummyInteraction("bla", 1), eventTarget);
-        simulateEvent(new DummyInteraction("bli", 1), eventTarget);
-        simulateEvent(new DummyInteraction("blo", 1), eventTarget);
-        simulateEvent(new DummyInteraction("blu", 1), eventTarget);
-        simulateEvent(new DummyInteraction("bla", 1), eventTarget);
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence {" +
-             "  Event bla {}" +
-             "  Event bli {}" +
-             "  Event blo {}" +
-             "  Event blu {}" +
-             "  Event bla {}" +
-             "}", getTaskTree(DefaultGuiElementSequenceDetectionRule.class, null));
-    }
-
-    /**
-     *
-     */
-    @Test
-    public void testOneInteractionOnManyElements() {
-        IEventTarget eventTarget1 = new DummyGUIElement("elem1");
-        IEventTarget eventTarget2 = new DummyGUIElement("elem2");
-        IEventTarget eventTarget3 = new DummyGUIElement("elem3");
-        IEventTarget eventTarget4 = new DummyGUIElement("elem4");
-        IEventTarget eventTarget5 = new DummyGUIElement("elem5");
-        IEventTarget eventTarget6 = new DummyGUIElement("elem6");
-        simulateEvent(new DummyInteraction("bla", 1), eventTarget1);
-        simulateEvent(new DummyInteraction("bli", 1), eventTarget2);
-        simulateEvent(new DummyInteraction("bla", 1), eventTarget3);
-        simulateEvent(new DummyInteraction("bli", 1), eventTarget4);
-        simulateEvent(new DummyInteraction("blo", 1), eventTarget5);
-        simulateEvent(new DummyInteraction("bla", 1), eventTarget6);
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence0 {" +
-             "  Sequence sequence1 {" +
-             "    Event bla {}" +
-             "  }" +
-             "  Sequence sequence2 {" +
-             "    Event bli {}" +
-             "  }" +
-             "  Sequence sequence3 {" +
-             "    Event bla {}" +
-             "  }" +
-             "  Sequence sequence4 {" +
-             "    Event bli {}" +
-             "  }" +
-             "  Sequence sequence5 {" +
-             "    Event blo {}" +
-             "  }" +
-             "  Sequence sequence6 {" +
-             "    Event bla {}" +
-             "  }" +
-             "}", getTaskTree(DefaultGuiElementSequenceDetectionRule.class, null));
-    }
-
-    /**
-     *
-     */
-    @Test
-    public void testManyInteractionsOnManyElementsWithoutHierarchy() {
-        IEventTarget eventTarget1 = new DummyGUIElement("elem1");
-        IEventTarget eventTarget2 = new DummyGUIElement("elem2");
-        IEventTarget eventTarget3 = new DummyGUIElement("elem3");
-        IEventTarget eventTarget4 = new DummyGUIElement("elem4");
-        IEventTarget eventTarget5 = new DummyGUIElement("elem5");
-        IEventTarget eventTarget6 = new DummyGUIElement("elem6");
-        simulateEvent(new DummyInteraction("bla", 1), eventTarget1);
-        simulateEvent(new DummyInteraction("bli", 1), eventTarget1);
-        simulateEvent(new DummyInteraction("bla", 1), eventTarget1);
-        simulateEvent(new DummyInteraction("bli", 1), eventTarget2);
-        simulateEvent(new DummyInteraction("blo", 1), eventTarget2);
-        simulateEvent(new DummyInteraction("bla", 1), eventTarget3);
-        simulateEvent(new DummyInteraction("bli", 1), eventTarget4);
-        simulateEvent(new DummyInteraction("bla", 1), eventTarget4);
-        simulateEvent(new DummyInteraction("bli", 1), eventTarget4);
-        simulateEvent(new DummyInteraction("blo", 1), eventTarget4);
-        simulateEvent(new DummyInteraction("bla", 1), eventTarget5);
-        simulateEvent(new DummyInteraction("bli", 1), eventTarget6);
-        simulateEvent(new DummyInteraction("bla", 1), eventTarget6);
-        simulateEvent(new DummyInteraction("bli", 1), eventTarget6);
-        simulateEvent(new DummyInteraction("blo", 1), eventTarget6);
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence0 {" +
-             "  Sequence sequence1 {" +
-             "    Event bla {}" +
-             "    Event bli {}" +
-             "    Event bla {}" +
-             "  }" +
-             "  Sequence sequence2 {" +
-             "    Event bli {}" +
-             "    Event blo {}" +
-             "  }" +
-             "  Sequence sequence3 {" +
-             "    Event bla {}" +
-             "  }" +
-             "  Sequence sequence4 {" +
-             "    Event bli {}" +
-             "    Event bla {}" +
-             "    Event bli {}" +
-             "    Event blo {}" +
-             "  }" +
-             "  Sequence sequence5 {" +
-             "    Event bla {}" +
-             "  }" +
-             "  Sequence sequence6 {" +
-             "    Event bli {}" +
-             "    Event bla {}" +
-             "    Event bli {}" +
-             "    Event blo {}" +
-             "  }" +
-             "}", getTaskTree(DefaultGuiElementSequenceDetectionRule.class, null));
-    }
-
-    /**
-     *
-     */
-    @Test
-    public void testManyInteractionsOnManyElementsWithHierarchy() {
-        DummyGUIElement parentA = new DummyGUIElement("A");
-        DummyGUIElement parentB = new DummyGUIElement("B", parentA);
-        DummyGUIElement parentC = new DummyGUIElement("C", parentB);
-        DummyGUIElement parentF = new DummyGUIElement("F", parentB);
-        DummyGUIElement parentH = new DummyGUIElement("H", parentA);
-        DummyGUIElement parentI = new DummyGUIElement("I", parentH);
-        
-        DummyGUIElement eventTargetD = new DummyGUIElement("D", parentC);
-        DummyGUIElement eventTargetE = new DummyGUIElement("E", parentC);
-        DummyGUIElement eventTargetG = new DummyGUIElement("G", parentF);
-        DummyGUIElement eventTargetJ = new DummyGUIElement("J", parentI);
-        
-        simulateEvent(new DummyInteraction("1", 1), eventTargetD);
-        simulateEvent(new DummyInteraction("2", 1), eventTargetD);
-        simulateEvent(new DummyInteraction("3", 1), eventTargetE);
-        simulateEvent(new DummyInteraction("4", 1), eventTargetD);
-        simulateEvent(new DummyInteraction("5", 1), eventTargetG);
-        simulateEvent(new DummyInteraction("6", 1), eventTargetG);
-        simulateEvent(new DummyInteraction("7", 1), eventTargetD);
-        simulateEvent(new DummyInteraction("8", 1), eventTargetJ);
-        simulateEvent(new DummyInteraction("9", 1), eventTargetG);
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence0 {" +
-             "  Sequence sequence1 {" +
-             "    Sequence sequence2 {" +
-             "      Sequence sequence3 {" +
-             "        Event 1 {}" +
-             "        Event 2 {}" +
-             "      }" +
-             "      Sequence sequence4 {" +
-             "        Event 3 {}" +
-             "      }" +
-             "      Sequence sequence5 {" +
-             "        Event 4 {}" +
-             "      }" +
-             "    }" +
-             "    Sequence sequence6 {" +
-             "      Sequence sequence7 {" +
-             "        Event 5 {}" +
-             "        Event 6 {}" +
-             "      }" +
-             "    }" +
-             "    Sequence sequence8 {" +
-             "      Sequence sequence9 {" +
-             "        Event 7 {}" +
-             "      }" +
-             "    }" +
-             "  }" +
-             "  Sequence sequence10 {" +
-             "    Sequence sequence11 {" +
-             "      Sequence sequence12 {" +
-             "        Event 8 {}" +
-             "      }" +
-             "    }" +
-             "  }" +
-             "  Sequence sequence13 {" +
-             "    Sequence sequence14 {" +
-             "      Sequence sequence15 {" +
-             "        Event 9 {}" +
-             "      }" +
-             "    }" +
-             "  }" +
-             "}", getTaskTree(DefaultGuiElementSequenceDetectionRule.class, null));
-    }
-
-}
Index: trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiEventSequenceDetectionRuleTest.java
===================================================================
--- trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiEventSequenceDetectionRuleTest.java	(revision 1126)
+++ 	(revision )
@@ -1,347 +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 org.junit.Test;
-
-import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
-import de.ugoe.cs.autoquest.tasktrees.TaskTreeChecker;
-import de.ugoe.cs.autoquest.test.DummyGUIElement;
-import de.ugoe.cs.autoquest.test.DummyInteraction;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: $
- * @author 2011, last modified by $Author: $
- */
-public class DefaultGuiEventSequenceDetectionRuleTest extends AbstractTemporalRelationshipTC {
-    
-    /**
-     *
-     */
-    @Test
-    public void test_01() {
-        IGUIElement elem1 = new DummyGUIElement("elem1");
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("end", 1), elem1);
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence {" +
-             "  Event start {}" +
-             "  Event end {}" +
-             "}", getTaskTree(DefaultGuiEventSequenceDetectionRule.class, null));
-    }
-    
-    
-    /**
-     *
-     */
-    @Test
-    public void test_02() {
-        IGUIElement elem1 = new DummyGUIElement("elem1");
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new DummyInteraction("bla", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("end", 1), elem1);
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence {" +
-             "  Event start {}" +
-             "  Event bla {}" +
-             "  Event end {}" +
-             "}", getTaskTree(DefaultGuiEventSequenceDetectionRule.class, null));
-    }
-    
-    /**
-     *
-     */
-    @Test
-    public void test_03() {
-        IGUIElement elem1 = new DummyGUIElement("elem1");
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new DummyInteraction("bla", 1), elem1);
-        simulateEvent(new DummyInteraction("bli", 1), elem1);
-        simulateEvent(new DummyInteraction("blup", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("end", 1), elem1);
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new DummyInteraction("bla", 1), elem1);
-        simulateEvent(new DummyInteraction("bli", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("end", 1), elem1);
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence0 {" +
-             "  Sequence sequence1 {" +
-             "    Event start {}" +
-             "    Event bla {}" +
-             "    Event bli {}" +
-             "    Event blup {}" +
-             "    Event end {}" +
-             "  }" +
-             "  Sequence sequence2 {" +
-             "    Event start {}" +
-             "    Event bla {}" +
-             "    Event bli {}" +
-             "    Event end {}" +
-             "  }" +
-             "}", getTaskTree(DefaultGuiEventSequenceDetectionRule.class, null));
-    }
-    
-    /**
-     *
-     */
-    @Test
-    public void test_04() {
-        IGUIElement elem1 = new DummyGUIElement("elem1");
-        simulateEvent(new StartAndFinishSequenceInteraction("startFinish", 1), elem1);
-        simulateEvent(new DummyInteraction("bla", 1), elem1);
-        simulateEvent(new DummyInteraction("bli", 1), elem1);
-        simulateEvent(new DummyInteraction("blup", 1), elem1);
-        simulateEvent(new StartAndFinishSequenceInteraction("startFinish", 1), elem1);
-        simulateEvent(new DummyInteraction("bla", 1), elem1);
-        simulateEvent(new DummyInteraction("bli", 1), elem1);
-        simulateEvent(new StartAndFinishSequenceInteraction("startFinish", 1), elem1);
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence0 {" +
-             "  Sequence sequence1 {" +
-             "    Event startFinish {}" +
-             "    Event bla {}" +
-             "    Event bli {}" +
-             "    Event blup {}" +
-             "  }" +
-             "  Sequence sequence2 {" +
-             "    Event startFinish {}" +
-             "    Event bla {}" +
-             "    Event bli {}" +
-             "  }" +
-             "  Event startFinish {}" +
-             "}", getTaskTree(DefaultGuiEventSequenceDetectionRule.class, null));
-    }
-
-    /**
-     *
-     */
-    @Test
-    public void test_05() {
-        IGUIElement elem1 = new DummyGUIElement("elem1");
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new DummyInteraction("bla", 1), elem1);
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new DummyInteraction("bli", 1), elem1);
-        simulateEvent(new DummyInteraction("blup", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-        simulateEvent(new DummyInteraction("bla", 1), elem1);
-        simulateEvent(new DummyInteraction("bli", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new DummyInteraction("blup", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence0 {" +
-             "  Sequence sequence1 {" +
-             "    Event start {}" +
-             "    Event bla {}" +
-             "    Sequence sequence2 {" +
-             "      Event start {}" +
-             "      Sequence sequence3 {" +
-             "        Event start {}" +
-             "        Event bli {}" +
-             "        Event blup {}" +
-             "        Event finish {}" +
-             "      }" +
-             "      Event bla {}" +
-             "      Event bli {}" +
-             "      Event finish {}" +
-             "    }" +
-             "    Sequence sequence4 {" +
-             "      Event start {}" +
-             "      Sequence sequence5 {" +
-             "        Event start {}" +
-             "        Sequence sequence6 {" +
-             "          Event start {}" +
-             "          Event blup {}" +
-             "          Event finish {}" +
-             "        }" +
-             "        Event finish {}" +
-             "      }" +
-             "      Event finish {}" +
-             "    }" +
-             "    Event finish {}" +
-             "  }" +
-             "  Event finish {}" +
-             "}", getTaskTree(DefaultGuiEventSequenceDetectionRule.class, null));
-    }
-
-    /**
-     *
-     */
-    @Test
-    public void test_06() {
-        IGUIElement elem1 = new DummyGUIElement("elem1");
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new DummyInteraction("bla", 1), elem1);
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new DummyInteraction("bli", 1), elem1);
-        simulateEvent(new DummyInteraction("blup", 1), elem1);
-        simulateEvent(new StartAndFinishSequenceInteraction("startFinish", 1), elem1);
-        simulateEvent(new DummyInteraction("bla", 1), elem1);
-        simulateEvent(new DummyInteraction("bli", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
-        simulateEvent(new DummyInteraction("blup", 1), elem1);
-        simulateEvent(new StartAndFinishSequenceInteraction("startFinish", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence0 {" +
-             "  Sequence sequence1 {" +
-             "    Event start {}" +
-             "    Event bla {}" +
-             "    Sequence sequence2 {" +
-             "      Event start {}" +
-             "      Sequence sequence3 {" +
-             "        Event start {}" +
-             "        Event bli {}" +
-             "        Event blup {}" +
-             "      }" +
-             "      Sequence sequence4 {" +
-             "        Event startFinish {}" +
-             "        Event bla {}" +
-             "        Event bli {}" +
-             "        Event finish {}" +
-             "      }" +
-             "      Sequence sequence5 {" +
-             "        Event start {}" +
-             "        Sequence sequence6 {" +
-             "          Event start {}" +
-             "          Sequence sequence7 {" +
-             "            Event start {}" +
-             "            Event blup {}" +
-             "          }" +
-             "          Sequence sequence8 {" +
-             "            Event startFinish {}" +
-             "            Event finish {}" +
-             "          }" +
-             "          Event finish {}" +
-             "        }" +
-             "        Event finish {}" +
-             "      }" +
-             "      Event finish {}" +
-             "    }" +
-             "    Event finish {}" +
-             "  }" +
-             "  Event finish {}" +
-             "}", getTaskTree(DefaultGuiEventSequenceDetectionRule.class, null));
-    }
-    
-    /**
-     *
-     */
-    private class StartSequenceInteraction extends DummyInteraction {
-
-        /**  */
-        private static final long serialVersionUID = 1L;
-
-        /**
-         *
-         */
-        public StartSequenceInteraction(String interactionType, int interactionNumber) {
-            super(interactionType, interactionNumber);
-        }
-
-        /* (non-Javadoc)
-         * @see de.ugoe.cs.autoquest.test.DummyInteraction#startsLogicalSequence()
-         */
-        @Override
-        public boolean startsLogicalSequence() {
-            return true;
-        }
-        
-    }
-
-    /**
-     *
-     */
-    private class FinishSequenceInteraction extends DummyInteraction {
-
-        /**  */
-        private static final long serialVersionUID = 1L;
-
-        /**
-         *
-         */
-        public FinishSequenceInteraction(String interactionType, int interactionNumber) {
-            super(interactionType, interactionNumber);
-        }
- 
-        /* (non-Javadoc)
-         * @see de.ugoe.cs.autoquest.test.DummyInteraction#finishesLogicalSequence()
-         */
-        @Override
-        public boolean finishesLogicalSequence() {
-            return true;
-        }
-       
-    }
-
-    /**
-     *
-     */
-    private class StartAndFinishSequenceInteraction extends DummyInteraction {
-
-        /**  */
-        private static final long serialVersionUID = 1L;
-
-        /**
-         *
-         */
-        public StartAndFinishSequenceInteraction(String interactionType, int interactionNumber) {
-            super(interactionType, interactionNumber);
-        }
- 
-        /* (non-Javadoc)
-         * @see de.ugoe.cs.autoquest.test.DummyInteraction#startsLogicalSequence()
-         */
-        @Override
-        public boolean startsLogicalSequence() {
-            return true;
-        }
-        
-        /* (non-Javadoc)
-         * @see de.ugoe.cs.autoquest.test.DummyInteraction#finishesLogicalSequence()
-         */
-        @Override
-        public boolean finishesLogicalSequence() {
-            return true;
-        }
-       
-    }
-}
Index: trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultIterationDetectionRuleTest.java
===================================================================
--- trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultIterationDetectionRuleTest.java	(revision 1126)
+++ 	(revision )
@@ -1,315 +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 org.junit.Test;
-
-import de.ugoe.cs.autoquest.eventcore.IEventTarget;
-import de.ugoe.cs.autoquest.eventcore.IEventType;
-import de.ugoe.cs.autoquest.tasktrees.TaskTreeChecker;
-import de.ugoe.cs.autoquest.test.DummyGUIElement;
-import de.ugoe.cs.autoquest.test.DummyInteraction;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: 28.04.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-public class DefaultIterationDetectionRuleTest extends AbstractTemporalRelationshipTC {
-
-    /**
-     *
-     */
-    @Test
-    public void testInteractionIterationDetection() throws Exception {
-        IEventTarget element1 = new DummyGUIElement("elem1");
-        IEventType event1 = new DummyInteraction("bla", 1);
-        simulateEvent(event1, element1);
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence1 {" +
-             "  Event bla {}" +
-             "}", getTaskTree(DefaultIterationDetectionRule.class, null));
-
-        simulateEvent(event1, element1);
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence1 {" +
-             "  Iteration iteration1 {" +
-             "    Event bla {}" +
-             "  }" +
-             "}", getTaskTree(DefaultIterationDetectionRule.class, null));
-
-        simulateEvent(event1, element1);
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence1 {" +
-             "  Iteration iteration1 {" +
-             "    Event bla {}" +
-             "  }" +
-             "}", getTaskTree(DefaultIterationDetectionRule.class, null));
-
-        for (int i = 0; i < 10; i++) {
-            simulateEvent(event1, element1);
-        }
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence1 {" +
-             "  Iteration iteration1 {" +
-             "    Event bla {}" +
-             "  }" +
-             "}", getTaskTree(DefaultIterationDetectionRule.class, null));
-
-        // now test with preceding and trailing other events
-        IEventType event2 = new DummyInteraction("bli", 1);
-        IEventType event3 = new DummyInteraction("blup", 1);
-
-        simulateEvent(event2, element1);
-        simulateEvent(event3, element1);
-        for (int i = 0; i < 10; i++) {
-            simulateEvent(event1, element1);
-        }
-        simulateEvent(event3, element1);
-        simulateEvent(event2, element1);
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence1 {" +
-             "  Iteration iteration1 {" +
-             "    Event bla {}" +
-             "  }" +
-             "  Event bli {}" +
-             "  Event blup {}" +
-             "  Iteration iteration2 {" +
-             "    Event bla {}" +
-             "  }" +
-             "  Event blup {}" +
-             "  Event bli {}" +
-             "}", getTaskTree(DefaultIterationDetectionRule.class, null));
-
-        // now test with iterations of iterations
-
-        for (int i = 0; i < 10; i++) {
-            for (int j = 0; j < 5; j++) {
-                simulateEvent(event1, element1);
-            }
-            for (int j = 0; j < 5; j++) {
-                simulateEvent(event2, element1);
-            }
-            for (int j = 0; j < 5; j++) {
-                simulateEvent(event3, element1);
-            }
-        }
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence1 {" +
-             "  Iteration iteration1 {" +
-             "    Event bla {}" +
-             "  }" +
-             "  Event bli {}" +
-             "  Event blup {}" +
-             "  Iteration iteration2 {" +
-             "    Event bla {}" +
-             "  }" +
-             "  Event blup {}" +
-             "  Event bli {}" +
-             "  Iteration iteration3 {" +
-             "    Sequence sequence2 {" +
-             "      Iteration iteration4 {" +
-             "        Event bla {}" +
-             "      }" +
-             "      Iteration iteration5 {" +
-             "        Event bli {}" +
-             "      }" +
-             "      Iteration iteration6 {" +
-             "        Event blup {}" +
-             "      }" +
-             "    }" +
-             "  }" +
-             "}", getTaskTree(DefaultIterationDetectionRule.class, null));
-
-    }
-
-    /**
-     *
-     */
-    @Test
-    public void testSequenceIterationDetection() throws Exception {
-        IEventTarget element1 = new DummyGUIElement("elem1");
-        IEventType event1 = new DummyInteraction("bla", 1);
-        IEventType event2 = new DummyInteraction("bli", 1);
-        IEventType event3 = new DummyInteraction("blup", 1);
-        simulateEvent(event1, element1);
-        simulateEvent(event2, element1);
-        simulateEvent(event3, element1);
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence1 {" +
-             "  Event bla {}" +
-             "  Event bli {}" +
-             "  Event blup {}" +
-             "}", getTaskTree(DefaultIterationDetectionRule.class, null));
-
-        simulateEvent(event1, element1);
-        simulateEvent(event2, element1);
-        simulateEvent(event3, element1);
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence1 {" +
-             "  Iteration iteration1 {" +
-             "    Sequence sequence2 {" +
-             "      Event bla {}" +
-             "      Event bli {}" +
-             "      Event blup {}" +
-             "    }" +
-             "  }" +
-             "}", getTaskTree(DefaultIterationDetectionRule.class, null));
-
-        simulateEvent(event1, element1);
-        simulateEvent(event2, element1);
-        simulateEvent(event3, element1);
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence1 {" +
-             "  Iteration iteration1 {" +
-             "    Sequence sequence2 {" +
-             "      Event bla {}" +
-             "      Event bli {}" +
-             "      Event blup {}" +
-             "    }" +
-             "  }" +
-             "}", getTaskTree(DefaultIterationDetectionRule.class, null));
-
-        for (int i = 0; i < 10; i++) {
-            simulateEvent(event1, element1);
-            simulateEvent(event2, element1);
-            simulateEvent(event3, element1);
-        }
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence1 {" +
-             "  Iteration iteration1 {" +
-             "    Sequence sequence2 {" +
-             "      Event bla {}" +
-             "      Event bli {}" +
-             "      Event blup {}" +
-             "    }" +
-             "  }" +
-             "}", getTaskTree(DefaultIterationDetectionRule.class, null));
-
-        // now test with preceding and trailing other events
-        IEventType event4 = new DummyInteraction("ble", 1);
-        IEventType event5 = new DummyInteraction("blo", 1);
-        IEventType event6 = new DummyInteraction("blu", 1);
-        simulateEvent(event4, element1);
-        simulateEvent(event5, element1);
-        simulateEvent(event6, element1);
-        for (int i = 0; i < 10; i++) {
-            simulateEvent(event1, element1);
-            simulateEvent(event2, element1);
-            simulateEvent(event3, element1);
-        }
-        simulateEvent(event6, element1);
-        simulateEvent(event5, element1);
-        simulateEvent(event4, element1);
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence1 {" +
-             "  Iteration iteration1 {" +
-             "    Sequence sequence2 {" +
-             "      Event bla {}" +
-             "      Event bli {}" +
-             "      Event blup {}" +
-             "    }" +
-             "  }" +
-             "  Event ble {}" +
-             "  Event blo {}" +
-             "  Event blu {}" +
-             "  Iteration iteration2 {" +
-             "    Sequence sequence3 {" +
-             "      Event bla {}" +
-             "      Event bli {}" +
-             "      Event blup {}" +
-             "    }" +
-             "  }" +
-             "  Event blu {}" +
-             "  Event blo {}" +
-             "  Event ble {}" +
-             "}", getTaskTree(DefaultIterationDetectionRule.class, null));
-
-        // now test with iterations of iterations
-        for (int i = 0; i < 10; i++) {
-            for (int j = 0; j < 5; j++) {
-                simulateEvent(event1, element1);
-                simulateEvent(event2, element1);
-                simulateEvent(event3, element1);
-            }
-            for (int j = 0; j < 5; j++) {
-                simulateEvent(event2, element1);
-                simulateEvent(event1, element1);
-                simulateEvent(event3, element1);
-            }
-            for (int j = 0; j < 5; j++) {
-                simulateEvent(event1, element1);
-                simulateEvent(event2, element1);
-                simulateEvent(event3, element1);
-            }
-        }
-
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence1 {" +
-             "  Iteration iteration1 {" +
-             "    Sequence sequence2 {" +
-             "      Event bla {}" +
-             "      Event bli {}" +
-             "      Event blup {}" +
-             "    }" +
-             "  }" +
-             "  Event ble {}" +
-             "  Event blo {}" +
-             "  Event blu {}" +
-             "  Iteration iteration2 {" +
-             "    Sequence sequence3 {" +
-             "      Event bla {}" +
-             "      Event bli {}" +
-             "      Event blup {}" +
-             "    }" +
-             "  }" +
-             "  Event blu {}" +
-             "  Event blo {}" +
-             "  Event ble {}" +
-             "  Iteration iteration3 {" +
-             "    Sequence sequence4 {" +
-             "      Iteration iteration4 {" +
-             "        Sequence sequence4 {" +
-             "          Event bla {}" +
-             "          Event bli {}" +
-             "          Event blup {}" +
-             "        }" +
-             "      }" +
-             "      Iteration iteration5 {" +
-             "        Sequence sequence5 {" +
-             "          Event bli {}" +
-             "          Event bla {}" +
-             "          Event blup {}" +
-             "        }" +
-             "      }" +
-             "      Iteration iteration6 {" +
-             "        Sequence sequence6 {" +
-             "          Event bla {}" +
-             "          Event bli {}" +
-             "          Event blup {}" +
-             "        }" +
-             "      }" +
-             "    }" +
-             "  }" +
-             "}", getTaskTree(DefaultIterationDetectionRule.class, null));
-    }
-
-}
Index: trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultTaskSequenceDetectionRuleTest.java
===================================================================
--- trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultTaskSequenceDetectionRuleTest.java	(revision 1126)
+++ 	(revision )
@@ -1,100 +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 org.junit.Test;
-
-import de.ugoe.cs.autoquest.eventcore.IEventTarget;
-import de.ugoe.cs.autoquest.eventcore.gui.IInteraction;
-import de.ugoe.cs.autoquest.tasktrees.TaskTreeChecker;
-import de.ugoe.cs.autoquest.test.DummyGUIElement;
-import de.ugoe.cs.autoquest.test.DummyInteraction;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: 28.04.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-public class DefaultTaskSequenceDetectionRuleTest extends AbstractTemporalRelationshipTC {
-
-    /**
-     *
-     */
-    @Test
-    public void testTaskDetection() throws Exception {
-        IEventTarget element1 = new DummyGUIElement("elem1");
-        
-        IInteraction action1 = new DummyInteraction("action1", 1);
-        IInteraction action2 = new DummyInteraction("action2", 1);
-        IInteraction action3 = new DummyInteraction("action3", 1);
-        IInteraction action4 = new DummyInteraction("action4", 1);
-        
-        simulateEvent(new DummyInteraction("noise0", 1), element1);
-        simulateEvent(action1, element1);
-        simulateEvent(action2, element1);
-        simulateEvent(action3, element1);
-        simulateEvent(action4, element1);
-        simulateEvent(new DummyInteraction("noise1", 1), element1);
-        simulateEvent(new DummyInteraction("noise2", 1), element1);
-        simulateEvent(action1, element1);
-        simulateEvent(action2, element1);
-        simulateEvent(action3, element1);
-        simulateEvent(action4, element1);
-        simulateEvent(new DummyInteraction("noise3", 1), element1);
-        simulateEvent(new DummyInteraction("noise4", 1), element1);
-        simulateEvent(new DummyInteraction("noise5", 1), element1);
-        simulateEvent(new DummyInteraction("noise6", 1), element1);
-        simulateEvent(action1, element1);
-        simulateEvent(action2, element1);
-        simulateEvent(action3, element1);
-        simulateEvent(action4, element1);
-        simulateEvent(new DummyInteraction("noise7", 1), element1);
-        simulateEvent(new DummyInteraction("noise8", 1), element1);
-        
-        new TaskTreeChecker().assertTaskTree
-            ("Sequence sequence1 {" +
-             "  Event noise0 {}" +
-             "  Sequence sequence2 {" +
-             "    Event action1 {}" +
-             "    Event action2 {}" +
-             "    Event action3 {}" +
-             "    Event action4 {}" +
-             "  }" +
-             "  Event noise1 {}" +
-             "  Event noise2 {}" +
-             "  Sequence sequence2 {" +
-             "    Event action1 {}" +
-             "    Event action2 {}" +
-             "    Event action3 {}" +
-             "    Event action4 {}" +
-             "  }" +
-             "  Event noise3 {}" +
-             "  Event noise4 {}" +
-             "  Event noise5 {}" +
-             "  Event noise6 {}" +
-             "  Sequence sequence2 {" +
-             "    Event action1 {}" +
-             "    Event action2 {}" +
-             "    Event action3 {}" +
-             "    Event action4 {}" +
-             "  }" +
-             "  Event noise7 {}" +
-             "  Event noise8 {}" +
-             "}", getTaskTree());
-
-    }
-
-}
Index: trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/IterationOfSubtreesDetectionRuleTest.java
===================================================================
--- trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/IterationOfSubtreesDetectionRuleTest.java	(revision 1127)
+++ trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/IterationOfSubtreesDetectionRuleTest.java	(revision 1127)
@@ -0,0 +1,315 @@
+//   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 org.junit.Test;
+
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+import de.ugoe.cs.autoquest.eventcore.IEventType;
+import de.ugoe.cs.autoquest.tasktrees.TaskTreeChecker;
+import de.ugoe.cs.autoquest.test.DummyGUIElement;
+import de.ugoe.cs.autoquest.test.DummyInteraction;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class IterationOfSubtreesDetectionRuleTest extends AbstractTemporalRelationshipTC {
+
+    /**
+     *
+     */
+    @Test
+    public void testInteractionIterationDetection() throws Exception {
+        IEventTarget element1 = new DummyGUIElement("elem1");
+        IEventType event1 = new DummyInteraction("bla", 1);
+        simulateEvent(event1, element1);
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Event bla {}" +
+             "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null));
+
+        simulateEvent(event1, element1);
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Event bla {}" +
+             "  }" +
+             "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null));
+
+        simulateEvent(event1, element1);
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Event bla {}" +
+             "  }" +
+             "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null));
+
+        for (int i = 0; i < 10; i++) {
+            simulateEvent(event1, element1);
+        }
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Event bla {}" +
+             "  }" +
+             "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null));
+
+        // now test with preceding and trailing other events
+        IEventType event2 = new DummyInteraction("bli", 1);
+        IEventType event3 = new DummyInteraction("blup", 1);
+
+        simulateEvent(event2, element1);
+        simulateEvent(event3, element1);
+        for (int i = 0; i < 10; i++) {
+            simulateEvent(event1, element1);
+        }
+        simulateEvent(event3, element1);
+        simulateEvent(event2, element1);
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Event bli {}" +
+             "  Event blup {}" +
+             "  Iteration iteration2 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Event blup {}" +
+             "  Event bli {}" +
+             "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null));
+
+        // now test with iterations of iterations
+
+        for (int i = 0; i < 10; i++) {
+            for (int j = 0; j < 5; j++) {
+                simulateEvent(event1, element1);
+            }
+            for (int j = 0; j < 5; j++) {
+                simulateEvent(event2, element1);
+            }
+            for (int j = 0; j < 5; j++) {
+                simulateEvent(event3, element1);
+            }
+        }
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Event bli {}" +
+             "  Event blup {}" +
+             "  Iteration iteration2 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Event blup {}" +
+             "  Event bli {}" +
+             "  Iteration iteration3 {" +
+             "    Sequence sequence2 {" +
+             "      Iteration iteration4 {" +
+             "        Event bla {}" +
+             "      }" +
+             "      Iteration iteration5 {" +
+             "        Event bli {}" +
+             "      }" +
+             "      Iteration iteration6 {" +
+             "        Event blup {}" +
+             "      }" +
+             "    }" +
+             "  }" +
+             "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null));
+
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void testSequenceIterationDetection() throws Exception {
+        IEventTarget element1 = new DummyGUIElement("elem1");
+        IEventType event1 = new DummyInteraction("bla", 1);
+        IEventType event2 = new DummyInteraction("bli", 1);
+        IEventType event3 = new DummyInteraction("blup", 1);
+        simulateEvent(event1, element1);
+        simulateEvent(event2, element1);
+        simulateEvent(event3, element1);
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Event bla {}" +
+             "  Event bli {}" +
+             "  Event blup {}" +
+             "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null));
+
+        simulateEvent(event1, element1);
+        simulateEvent(event2, element1);
+        simulateEvent(event3, element1);
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Sequence sequence2 {" +
+             "      Event bla {}" +
+             "      Event bli {}" +
+             "      Event blup {}" +
+             "    }" +
+             "  }" +
+             "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null));
+
+        simulateEvent(event1, element1);
+        simulateEvent(event2, element1);
+        simulateEvent(event3, element1);
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Sequence sequence2 {" +
+             "      Event bla {}" +
+             "      Event bli {}" +
+             "      Event blup {}" +
+             "    }" +
+             "  }" +
+             "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null));
+
+        for (int i = 0; i < 10; i++) {
+            simulateEvent(event1, element1);
+            simulateEvent(event2, element1);
+            simulateEvent(event3, element1);
+        }
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Sequence sequence2 {" +
+             "      Event bla {}" +
+             "      Event bli {}" +
+             "      Event blup {}" +
+             "    }" +
+             "  }" +
+             "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null));
+
+        // now test with preceding and trailing other events
+        IEventType event4 = new DummyInteraction("ble", 1);
+        IEventType event5 = new DummyInteraction("blo", 1);
+        IEventType event6 = new DummyInteraction("blu", 1);
+        simulateEvent(event4, element1);
+        simulateEvent(event5, element1);
+        simulateEvent(event6, element1);
+        for (int i = 0; i < 10; i++) {
+            simulateEvent(event1, element1);
+            simulateEvent(event2, element1);
+            simulateEvent(event3, element1);
+        }
+        simulateEvent(event6, element1);
+        simulateEvent(event5, element1);
+        simulateEvent(event4, element1);
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Sequence sequence2 {" +
+             "      Event bla {}" +
+             "      Event bli {}" +
+             "      Event blup {}" +
+             "    }" +
+             "  }" +
+             "  Event ble {}" +
+             "  Event blo {}" +
+             "  Event blu {}" +
+             "  Iteration iteration2 {" +
+             "    Sequence sequence3 {" +
+             "      Event bla {}" +
+             "      Event bli {}" +
+             "      Event blup {}" +
+             "    }" +
+             "  }" +
+             "  Event blu {}" +
+             "  Event blo {}" +
+             "  Event ble {}" +
+             "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null));
+
+        // now test with iterations of iterations
+        for (int i = 0; i < 10; i++) {
+            for (int j = 0; j < 5; j++) {
+                simulateEvent(event1, element1);
+                simulateEvent(event2, element1);
+                simulateEvent(event3, element1);
+            }
+            for (int j = 0; j < 5; j++) {
+                simulateEvent(event2, element1);
+                simulateEvent(event1, element1);
+                simulateEvent(event3, element1);
+            }
+            for (int j = 0; j < 5; j++) {
+                simulateEvent(event1, element1);
+                simulateEvent(event2, element1);
+                simulateEvent(event3, element1);
+            }
+        }
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Sequence sequence2 {" +
+             "      Event bla {}" +
+             "      Event bli {}" +
+             "      Event blup {}" +
+             "    }" +
+             "  }" +
+             "  Event ble {}" +
+             "  Event blo {}" +
+             "  Event blu {}" +
+             "  Iteration iteration2 {" +
+             "    Sequence sequence3 {" +
+             "      Event bla {}" +
+             "      Event bli {}" +
+             "      Event blup {}" +
+             "    }" +
+             "  }" +
+             "  Event blu {}" +
+             "  Event blo {}" +
+             "  Event ble {}" +
+             "  Iteration iteration3 {" +
+             "    Sequence sequence4 {" +
+             "      Iteration iteration4 {" +
+             "        Sequence sequence4 {" +
+             "          Event bla {}" +
+             "          Event bli {}" +
+             "          Event blup {}" +
+             "        }" +
+             "      }" +
+             "      Iteration iteration5 {" +
+             "        Sequence sequence5 {" +
+             "          Event bli {}" +
+             "          Event bla {}" +
+             "          Event blup {}" +
+             "        }" +
+             "      }" +
+             "      Iteration iteration6 {" +
+             "        Sequence sequence6 {" +
+             "          Event bla {}" +
+             "          Event bli {}" +
+             "          Event blup {}" +
+             "        }" +
+             "      }" +
+             "    }" +
+             "  }" +
+             "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null));
+    }
+
+}
Index: trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceDependingOnEventTypeDetectionRuleTest.java
===================================================================
--- trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceDependingOnEventTypeDetectionRuleTest.java	(revision 1127)
+++ trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceDependingOnEventTypeDetectionRuleTest.java	(revision 1127)
@@ -0,0 +1,347 @@
+//   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 org.junit.Test;
+
+import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
+import de.ugoe.cs.autoquest.tasktrees.TaskTreeChecker;
+import de.ugoe.cs.autoquest.test.DummyGUIElement;
+import de.ugoe.cs.autoquest.test.DummyInteraction;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: $
+ * @author 2011, last modified by $Author: $
+ */
+public class SequenceDependingOnEventTypeDetectionRuleTest extends AbstractTemporalRelationshipTC {
+    
+    /**
+     *
+     */
+    @Test
+    public void test_01() {
+        IGUIElement elem1 = new DummyGUIElement("elem1");
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("end", 1), elem1);
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence {" +
+             "  Event start {}" +
+             "  Event end {}" +
+             "}", getTaskTree(SequenceDependingOnEventTypeDetectionRule.class, null));
+    }
+    
+    
+    /**
+     *
+     */
+    @Test
+    public void test_02() {
+        IGUIElement elem1 = new DummyGUIElement("elem1");
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new DummyInteraction("bla", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("end", 1), elem1);
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence {" +
+             "  Event start {}" +
+             "  Event bla {}" +
+             "  Event end {}" +
+             "}", getTaskTree(SequenceDependingOnEventTypeDetectionRule.class, null));
+    }
+    
+    /**
+     *
+     */
+    @Test
+    public void test_03() {
+        IGUIElement elem1 = new DummyGUIElement("elem1");
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new DummyInteraction("bla", 1), elem1);
+        simulateEvent(new DummyInteraction("bli", 1), elem1);
+        simulateEvent(new DummyInteraction("blup", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("end", 1), elem1);
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new DummyInteraction("bla", 1), elem1);
+        simulateEvent(new DummyInteraction("bli", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("end", 1), elem1);
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence0 {" +
+             "  Sequence sequence1 {" +
+             "    Event start {}" +
+             "    Event bla {}" +
+             "    Event bli {}" +
+             "    Event blup {}" +
+             "    Event end {}" +
+             "  }" +
+             "  Sequence sequence2 {" +
+             "    Event start {}" +
+             "    Event bla {}" +
+             "    Event bli {}" +
+             "    Event end {}" +
+             "  }" +
+             "}", getTaskTree(SequenceDependingOnEventTypeDetectionRule.class, null));
+    }
+    
+    /**
+     *
+     */
+    @Test
+    public void test_04() {
+        IGUIElement elem1 = new DummyGUIElement("elem1");
+        simulateEvent(new StartAndFinishSequenceInteraction("startFinish", 1), elem1);
+        simulateEvent(new DummyInteraction("bla", 1), elem1);
+        simulateEvent(new DummyInteraction("bli", 1), elem1);
+        simulateEvent(new DummyInteraction("blup", 1), elem1);
+        simulateEvent(new StartAndFinishSequenceInteraction("startFinish", 1), elem1);
+        simulateEvent(new DummyInteraction("bla", 1), elem1);
+        simulateEvent(new DummyInteraction("bli", 1), elem1);
+        simulateEvent(new StartAndFinishSequenceInteraction("startFinish", 1), elem1);
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence0 {" +
+             "  Sequence sequence1 {" +
+             "    Event startFinish {}" +
+             "    Event bla {}" +
+             "    Event bli {}" +
+             "    Event blup {}" +
+             "  }" +
+             "  Sequence sequence2 {" +
+             "    Event startFinish {}" +
+             "    Event bla {}" +
+             "    Event bli {}" +
+             "  }" +
+             "  Event startFinish {}" +
+             "}", getTaskTree(SequenceDependingOnEventTypeDetectionRule.class, null));
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_05() {
+        IGUIElement elem1 = new DummyGUIElement("elem1");
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new DummyInteraction("bla", 1), elem1);
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new DummyInteraction("bli", 1), elem1);
+        simulateEvent(new DummyInteraction("blup", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+        simulateEvent(new DummyInteraction("bla", 1), elem1);
+        simulateEvent(new DummyInteraction("bli", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new DummyInteraction("blup", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence0 {" +
+             "  Sequence sequence1 {" +
+             "    Event start {}" +
+             "    Event bla {}" +
+             "    Sequence sequence2 {" +
+             "      Event start {}" +
+             "      Sequence sequence3 {" +
+             "        Event start {}" +
+             "        Event bli {}" +
+             "        Event blup {}" +
+             "        Event finish {}" +
+             "      }" +
+             "      Event bla {}" +
+             "      Event bli {}" +
+             "      Event finish {}" +
+             "    }" +
+             "    Sequence sequence4 {" +
+             "      Event start {}" +
+             "      Sequence sequence5 {" +
+             "        Event start {}" +
+             "        Sequence sequence6 {" +
+             "          Event start {}" +
+             "          Event blup {}" +
+             "          Event finish {}" +
+             "        }" +
+             "        Event finish {}" +
+             "      }" +
+             "      Event finish {}" +
+             "    }" +
+             "    Event finish {}" +
+             "  }" +
+             "  Event finish {}" +
+             "}", getTaskTree(SequenceDependingOnEventTypeDetectionRule.class, null));
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void test_06() {
+        IGUIElement elem1 = new DummyGUIElement("elem1");
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new DummyInteraction("bla", 1), elem1);
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new DummyInteraction("bli", 1), elem1);
+        simulateEvent(new DummyInteraction("blup", 1), elem1);
+        simulateEvent(new StartAndFinishSequenceInteraction("startFinish", 1), elem1);
+        simulateEvent(new DummyInteraction("bla", 1), elem1);
+        simulateEvent(new DummyInteraction("bli", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new StartSequenceInteraction("start", 1), elem1);
+        simulateEvent(new DummyInteraction("blup", 1), elem1);
+        simulateEvent(new StartAndFinishSequenceInteraction("startFinish", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+        simulateEvent(new FinishSequenceInteraction("finish", 1), elem1);
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence0 {" +
+             "  Sequence sequence1 {" +
+             "    Event start {}" +
+             "    Event bla {}" +
+             "    Sequence sequence2 {" +
+             "      Event start {}" +
+             "      Sequence sequence3 {" +
+             "        Event start {}" +
+             "        Event bli {}" +
+             "        Event blup {}" +
+             "      }" +
+             "      Sequence sequence4 {" +
+             "        Event startFinish {}" +
+             "        Event bla {}" +
+             "        Event bli {}" +
+             "        Event finish {}" +
+             "      }" +
+             "      Sequence sequence5 {" +
+             "        Event start {}" +
+             "        Sequence sequence6 {" +
+             "          Event start {}" +
+             "          Sequence sequence7 {" +
+             "            Event start {}" +
+             "            Event blup {}" +
+             "          }" +
+             "          Sequence sequence8 {" +
+             "            Event startFinish {}" +
+             "            Event finish {}" +
+             "          }" +
+             "          Event finish {}" +
+             "        }" +
+             "        Event finish {}" +
+             "      }" +
+             "      Event finish {}" +
+             "    }" +
+             "    Event finish {}" +
+             "  }" +
+             "  Event finish {}" +
+             "}", getTaskTree(SequenceDependingOnEventTypeDetectionRule.class, null));
+    }
+    
+    /**
+     *
+     */
+    private class StartSequenceInteraction extends DummyInteraction {
+
+        /**  */
+        private static final long serialVersionUID = 1L;
+
+        /**
+         *
+         */
+        public StartSequenceInteraction(String interactionType, int interactionNumber) {
+            super(interactionType, interactionNumber);
+        }
+
+        /* (non-Javadoc)
+         * @see de.ugoe.cs.autoquest.test.DummyInteraction#startsLogicalSequence()
+         */
+        @Override
+        public boolean startsLogicalSequence() {
+            return true;
+        }
+        
+    }
+
+    /**
+     *
+     */
+    private class FinishSequenceInteraction extends DummyInteraction {
+
+        /**  */
+        private static final long serialVersionUID = 1L;
+
+        /**
+         *
+         */
+        public FinishSequenceInteraction(String interactionType, int interactionNumber) {
+            super(interactionType, interactionNumber);
+        }
+ 
+        /* (non-Javadoc)
+         * @see de.ugoe.cs.autoquest.test.DummyInteraction#finishesLogicalSequence()
+         */
+        @Override
+        public boolean finishesLogicalSequence() {
+            return true;
+        }
+       
+    }
+
+    /**
+     *
+     */
+    private class StartAndFinishSequenceInteraction extends DummyInteraction {
+
+        /**  */
+        private static final long serialVersionUID = 1L;
+
+        /**
+         *
+         */
+        public StartAndFinishSequenceInteraction(String interactionType, int interactionNumber) {
+            super(interactionType, interactionNumber);
+        }
+ 
+        /* (non-Javadoc)
+         * @see de.ugoe.cs.autoquest.test.DummyInteraction#startsLogicalSequence()
+         */
+        @Override
+        public boolean startsLogicalSequence() {
+            return true;
+        }
+        
+        /* (non-Javadoc)
+         * @see de.ugoe.cs.autoquest.test.DummyInteraction#finishesLogicalSequence()
+         */
+        @Override
+        public boolean finishesLogicalSequence() {
+            return true;
+        }
+       
+    }
+}
Index: trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRuleTest.java
===================================================================
--- trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRuleTest.java	(revision 1127)
+++ trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRuleTest.java	(revision 1127)
@@ -0,0 +1,103 @@
+//   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 org.junit.Test;
+
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+import de.ugoe.cs.autoquest.eventcore.gui.IInteraction;
+import de.ugoe.cs.autoquest.tasktrees.TaskTreeChecker;
+import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality;
+import de.ugoe.cs.autoquest.test.DummyGUIElement;
+import de.ugoe.cs.autoquest.test.DummyInteraction;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class SequenceForTaskDetectionRuleTest extends AbstractTemporalRelationshipTC {
+
+    /**
+     *
+     */
+    @Test
+    public void testTaskDetection() throws Exception {
+        IEventTarget element1 = new DummyGUIElement("elem1");
+        
+        IInteraction action1 = new DummyInteraction("action1", 1);
+        IInteraction action2 = new DummyInteraction("action2", 1);
+        IInteraction action3 = new DummyInteraction("action3", 1);
+        IInteraction action4 = new DummyInteraction("action4", 1);
+        
+        simulateEvent(new DummyInteraction("noise0", 1), element1);
+        simulateEvent(action1, element1);
+        simulateEvent(action2, element1);
+        simulateEvent(action3, element1);
+        simulateEvent(action4, element1);
+        simulateEvent(new DummyInteraction("noise1", 1), element1);
+        simulateEvent(new DummyInteraction("noise2", 1), element1);
+        simulateEvent(action1, element1);
+        simulateEvent(action2, element1);
+        simulateEvent(action3, element1);
+        simulateEvent(action4, element1);
+        simulateEvent(new DummyInteraction("noise3", 1), element1);
+        simulateEvent(new DummyInteraction("noise4", 1), element1);
+        simulateEvent(new DummyInteraction("noise5", 1), element1);
+        simulateEvent(new DummyInteraction("noise6", 1), element1);
+        simulateEvent(action1, element1);
+        simulateEvent(action2, element1);
+        simulateEvent(action3, element1);
+        simulateEvent(action4, element1);
+        simulateEvent(new DummyInteraction("noise7", 1), element1);
+        simulateEvent(new DummyInteraction("noise8", 1), element1);
+        
+        new TaskTreeChecker(true).assertTaskTree
+            ("Sequence root {" +
+             "  Sequence session1 {" +
+             "    Event noise0 {}" +
+             "    Sequence sequence2 {" +
+             "      Event action1 {}" +
+             "      Event action2 {}" +
+             "      Event action3 {}" +
+             "      Event action4 {}" +
+             "    }" +
+             "    Event noise1 {}" +
+             "    Event noise2 {}" +
+             "    Sequence sequence2 {" +
+             "      Event action1 {}" +
+             "      Event action2 {}" +
+             "      Event action3 {}" +
+             "      Event action4 {}" +
+             "    }" +
+             "    Event noise3 {}" +
+             "    Event noise4 {}" +
+             "    Event noise5 {}" +
+             "    Event noise6 {}" +
+             "    Sequence sequence2 {" +
+             "      Event action1 {}" +
+             "      Event action2 {}" +
+             "      Event action3 {}" +
+             "      Event action4 {}" +
+             "    }" +
+             "    Event noise7 {}" +
+             "    Event noise8 {}" +
+             "  }" +
+             "}", getTaskTree(SequenceForTaskDetectionRule.class, NodeEquality.LEXICALLY_EQUAL));
+
+    }
+
+}
Index: trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceOnGuiElementDetectionRuleTest.java
===================================================================
--- trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceOnGuiElementDetectionRuleTest.java	(revision 1127)
+++ trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceOnGuiElementDetectionRuleTest.java	(revision 1127)
@@ -0,0 +1,238 @@
+//   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 org.junit.Test;
+
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+import de.ugoe.cs.autoquest.tasktrees.TaskTreeChecker;
+import de.ugoe.cs.autoquest.test.DummyGUIElement;
+import de.ugoe.cs.autoquest.test.DummyInteraction;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: $
+ * @author 2011, last modified by $Author: $
+ */
+public class SequenceOnGuiElementDetectionRuleTest extends AbstractTemporalRelationshipTC {
+    
+    /**
+     *
+     */
+    @Test
+    public void testOneInteractionOnOneElement() {
+        simulateEvent(new DummyInteraction("bla", 1), new DummyGUIElement("elem1"));
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence {" +
+             "  Event bla {}" +
+             "}", getTaskTree());
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void testManyInteractionsOnOneElement() {
+        IEventTarget eventTarget = new DummyGUIElement("elem1");
+        simulateEvent(new DummyInteraction("bla", 1), eventTarget);
+        simulateEvent(new DummyInteraction("bli", 1), eventTarget);
+        simulateEvent(new DummyInteraction("blo", 1), eventTarget);
+        simulateEvent(new DummyInteraction("blu", 1), eventTarget);
+        simulateEvent(new DummyInteraction("bla", 1), eventTarget);
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence {" +
+             "  Event bla {}" +
+             "  Event bli {}" +
+             "  Event blo {}" +
+             "  Event blu {}" +
+             "  Event bla {}" +
+             "}", getTaskTree(SequenceOnGuiElementDetectionRule.class, null));
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void testOneInteractionOnManyElements() {
+        IEventTarget eventTarget1 = new DummyGUIElement("elem1");
+        IEventTarget eventTarget2 = new DummyGUIElement("elem2");
+        IEventTarget eventTarget3 = new DummyGUIElement("elem3");
+        IEventTarget eventTarget4 = new DummyGUIElement("elem4");
+        IEventTarget eventTarget5 = new DummyGUIElement("elem5");
+        IEventTarget eventTarget6 = new DummyGUIElement("elem6");
+        simulateEvent(new DummyInteraction("bla", 1), eventTarget1);
+        simulateEvent(new DummyInteraction("bli", 1), eventTarget2);
+        simulateEvent(new DummyInteraction("bla", 1), eventTarget3);
+        simulateEvent(new DummyInteraction("bli", 1), eventTarget4);
+        simulateEvent(new DummyInteraction("blo", 1), eventTarget5);
+        simulateEvent(new DummyInteraction("bla", 1), eventTarget6);
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence0 {" +
+             "  Sequence sequence1 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Sequence sequence2 {" +
+             "    Event bli {}" +
+             "  }" +
+             "  Sequence sequence3 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Sequence sequence4 {" +
+             "    Event bli {}" +
+             "  }" +
+             "  Sequence sequence5 {" +
+             "    Event blo {}" +
+             "  }" +
+             "  Sequence sequence6 {" +
+             "    Event bla {}" +
+             "  }" +
+             "}", getTaskTree(SequenceOnGuiElementDetectionRule.class, null));
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void testManyInteractionsOnManyElementsWithoutHierarchy() {
+        IEventTarget eventTarget1 = new DummyGUIElement("elem1");
+        IEventTarget eventTarget2 = new DummyGUIElement("elem2");
+        IEventTarget eventTarget3 = new DummyGUIElement("elem3");
+        IEventTarget eventTarget4 = new DummyGUIElement("elem4");
+        IEventTarget eventTarget5 = new DummyGUIElement("elem5");
+        IEventTarget eventTarget6 = new DummyGUIElement("elem6");
+        simulateEvent(new DummyInteraction("bla", 1), eventTarget1);
+        simulateEvent(new DummyInteraction("bli", 1), eventTarget1);
+        simulateEvent(new DummyInteraction("bla", 1), eventTarget1);
+        simulateEvent(new DummyInteraction("bli", 1), eventTarget2);
+        simulateEvent(new DummyInteraction("blo", 1), eventTarget2);
+        simulateEvent(new DummyInteraction("bla", 1), eventTarget3);
+        simulateEvent(new DummyInteraction("bli", 1), eventTarget4);
+        simulateEvent(new DummyInteraction("bla", 1), eventTarget4);
+        simulateEvent(new DummyInteraction("bli", 1), eventTarget4);
+        simulateEvent(new DummyInteraction("blo", 1), eventTarget4);
+        simulateEvent(new DummyInteraction("bla", 1), eventTarget5);
+        simulateEvent(new DummyInteraction("bli", 1), eventTarget6);
+        simulateEvent(new DummyInteraction("bla", 1), eventTarget6);
+        simulateEvent(new DummyInteraction("bli", 1), eventTarget6);
+        simulateEvent(new DummyInteraction("blo", 1), eventTarget6);
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence0 {" +
+             "  Sequence sequence1 {" +
+             "    Event bla {}" +
+             "    Event bli {}" +
+             "    Event bla {}" +
+             "  }" +
+             "  Sequence sequence2 {" +
+             "    Event bli {}" +
+             "    Event blo {}" +
+             "  }" +
+             "  Sequence sequence3 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Sequence sequence4 {" +
+             "    Event bli {}" +
+             "    Event bla {}" +
+             "    Event bli {}" +
+             "    Event blo {}" +
+             "  }" +
+             "  Sequence sequence5 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Sequence sequence6 {" +
+             "    Event bli {}" +
+             "    Event bla {}" +
+             "    Event bli {}" +
+             "    Event blo {}" +
+             "  }" +
+             "}", getTaskTree(SequenceOnGuiElementDetectionRule.class, null));
+    }
+
+    /**
+     *
+     */
+    @Test
+    public void testManyInteractionsOnManyElementsWithHierarchy() {
+        DummyGUIElement parentA = new DummyGUIElement("A");
+        DummyGUIElement parentB = new DummyGUIElement("B", parentA);
+        DummyGUIElement parentC = new DummyGUIElement("C", parentB);
+        DummyGUIElement parentF = new DummyGUIElement("F", parentB);
+        DummyGUIElement parentH = new DummyGUIElement("H", parentA);
+        DummyGUIElement parentI = new DummyGUIElement("I", parentH);
+        
+        DummyGUIElement eventTargetD = new DummyGUIElement("D", parentC);
+        DummyGUIElement eventTargetE = new DummyGUIElement("E", parentC);
+        DummyGUIElement eventTargetG = new DummyGUIElement("G", parentF);
+        DummyGUIElement eventTargetJ = new DummyGUIElement("J", parentI);
+        
+        simulateEvent(new DummyInteraction("1", 1), eventTargetD);
+        simulateEvent(new DummyInteraction("2", 1), eventTargetD);
+        simulateEvent(new DummyInteraction("3", 1), eventTargetE);
+        simulateEvent(new DummyInteraction("4", 1), eventTargetD);
+        simulateEvent(new DummyInteraction("5", 1), eventTargetG);
+        simulateEvent(new DummyInteraction("6", 1), eventTargetG);
+        simulateEvent(new DummyInteraction("7", 1), eventTargetD);
+        simulateEvent(new DummyInteraction("8", 1), eventTargetJ);
+        simulateEvent(new DummyInteraction("9", 1), eventTargetG);
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence0 {" +
+             "  Sequence sequence1 {" +
+             "    Sequence sequence2 {" +
+             "      Sequence sequence3 {" +
+             "        Event 1 {}" +
+             "        Event 2 {}" +
+             "      }" +
+             "      Sequence sequence4 {" +
+             "        Event 3 {}" +
+             "      }" +
+             "      Sequence sequence5 {" +
+             "        Event 4 {}" +
+             "      }" +
+             "    }" +
+             "    Sequence sequence6 {" +
+             "      Sequence sequence7 {" +
+             "        Event 5 {}" +
+             "        Event 6 {}" +
+             "      }" +
+             "    }" +
+             "    Sequence sequence8 {" +
+             "      Sequence sequence9 {" +
+             "        Event 7 {}" +
+             "      }" +
+             "    }" +
+             "  }" +
+             "  Sequence sequence10 {" +
+             "    Sequence sequence11 {" +
+             "      Sequence sequence12 {" +
+             "        Event 8 {}" +
+             "      }" +
+             "    }" +
+             "  }" +
+             "  Sequence sequence13 {" +
+             "    Sequence sequence14 {" +
+             "      Sequence sequence15 {" +
+             "        Event 9 {}" +
+             "      }" +
+             "    }" +
+             "  }" +
+             "}", getTaskTree(SequenceOnGuiElementDetectionRule.class, null));
+    }
+
+}
Index: trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SimpleIterationDetectionRuleTest.java
===================================================================
--- trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SimpleIterationDetectionRuleTest.java	(revision 1127)
+++ trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SimpleIterationDetectionRuleTest.java	(revision 1127)
@@ -0,0 +1,174 @@
+//   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 org.junit.Test;
+
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+import de.ugoe.cs.autoquest.eventcore.IEventType;
+import de.ugoe.cs.autoquest.tasktrees.TaskTreeChecker;
+import de.ugoe.cs.autoquest.test.DummyGUIElement;
+import de.ugoe.cs.autoquest.test.DummyInteraction;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 28.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class SimpleIterationDetectionRuleTest extends AbstractTemporalRelationshipTC {
+
+    /**
+     *
+     */
+    @Test
+    public void testInteractionIterationDetection() throws Exception {
+        IEventTarget element1 = new DummyGUIElement("elem1");
+        IEventType event1 = new DummyInteraction("bla", 1);
+        simulateEvent(event1, element1);
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Event bla {}" +
+             "}", getTaskTree(SimpleIterationDetectionRule.class, null));
+
+        simulateEvent(event1, element1);
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Event bla {}" +
+             "  }" +
+             "}", getTaskTree(SimpleIterationDetectionRule.class, null));
+
+        simulateEvent(event1, element1);
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Event bla {}" +
+             "  }" +
+             "}", getTaskTree(SimpleIterationDetectionRule.class, null));
+
+        for (int i = 0; i < 10; i++) {
+            simulateEvent(event1, element1);
+        }
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Event bla {}" +
+             "  }" +
+             "}", getTaskTree(SimpleIterationDetectionRule.class, null));
+
+        // now test with preceding and trailing other events
+        IEventType event2 = new DummyInteraction("bli", 1);
+        IEventType event3 = new DummyInteraction("blup", 1);
+
+        simulateEvent(event2, element1);
+        simulateEvent(event3, element1);
+        for (int i = 0; i < 10; i++) {
+            simulateEvent(event1, element1);
+        }
+        simulateEvent(event3, element1);
+        simulateEvent(event2, element1);
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Event bli {}" +
+             "  Event blup {}" +
+             "  Iteration iteration2 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Event blup {}" +
+             "  Event bli {}" +
+             "}", getTaskTree(SimpleIterationDetectionRule.class, null));
+
+        // now test with iterations of iterations
+
+        for (int i = 0; i < 5; i++) {
+            for (int j = 0; j < 5; j++) {
+                simulateEvent(event1, element1);
+            }
+            for (int j = 0; j < 5; j++) {
+                simulateEvent(event2, element1);
+            }
+            for (int j = 0; j < 5; j++) {
+                simulateEvent(event3, element1);
+            }
+        }
+
+        new TaskTreeChecker().assertTaskTree
+            ("Sequence sequence1 {" +
+             "  Iteration iteration1 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Event bli {}" +
+             "  Event blup {}" +
+             "  Iteration iteration2 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Event blup {}" +
+             "  Event bli {}" +
+             "  Iteration iteration4 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Iteration iteration5 {" +
+             "    Event bli {}" +
+             "  }" +
+             "  Iteration iteration6 {" +
+             "    Event blup {}" +
+             "  }" +
+             "  Iteration iteration7 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Iteration iteration8 {" +
+             "    Event bli {}" +
+             "  }" +
+             "  Iteration iteration9 {" +
+             "    Event blup {}" +
+             "  }" +
+             "  Iteration iteration10 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Iteration iteration11 {" +
+             "    Event bli {}" +
+             "  }" +
+             "  Iteration iteration12 {" +
+             "    Event blup {}" +
+             "  }" +
+             "  Iteration iteration13 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Iteration iteration14 {" +
+             "    Event bli {}" +
+             "  }" +
+             "  Iteration iteration15 {" +
+             "    Event blup {}" +
+             "  }" +
+             "  Iteration iteration16 {" +
+             "    Event bla {}" +
+             "  }" +
+             "  Iteration iteration17 {" +
+             "    Event bli {}" +
+             "  }" +
+             "  Iteration iteration18 {" +
+             "    Event blup {}" +
+             "  }" +
+             "}", getTaskTree(SimpleIterationDetectionRule.class, null));
+
+    }
+
+}
Index: trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskTreeNodeMergerTest.java
===================================================================
--- trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskTreeNodeMergerTest.java	(revision 1127)
+++ trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskTreeNodeMergerTest.java	(revision 1127)
@@ -0,0 +1,1194 @@
+//   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 org.junit.Test;
+
+import de.ugoe.cs.autoquest.tasktrees.TaskTreeChecker;
+import de.ugoe.cs.autoquest.tasktrees.TaskTreeInstantiator;
+import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality;
+import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager;
+import de.ugoe.cs.autoquest.tasktrees.testutils.Utilities;
+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.treeimpl.TaskTreeBuilder;
+import de.ugoe.cs.autoquest.tasktrees.treeimpl.TaskTreeNodeFactory;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public class TaskTreeNodeMergerTest {
+
+    /** */
+    private ITaskTreeBuilder taskTreeBuilder = new TaskTreeBuilder();
+
+    /** */
+    private ITaskTreeNodeFactory taskTreeNodeFactory = new TaskTreeNodeFactory();
+
+    /** */
+    private NodeEqualityRuleManager nodeEqualityRuleManager =
+        Utilities.getNodeEqualityRuleManagerForTests();
+
+    /**
+     * 
+     */
+    @Test
+    public void test_EventTaskMerge_1() {
+        String spec1 = "EventTask target1 {}";
+        String spec2 = "EventTask target1 {}";
+        
+        String oracleSpec = "EventTask target1 {}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_EventTaskMerge_2() {
+        String spec1 = "EventTask target1 {}";
+        String spec2 = "EventTask target2 {}";
+        
+        String oracleSpec =
+            "Selection {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_EventTaskMerge_3() {
+        String spec1 =
+            "Selection {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "}";
+
+        String spec2 = "EventTask target2 {}";
+        
+        String oracleSpec =
+            "Selection {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_EventTaskMerge_4() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Selection {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Selection {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_EventTaskMerge_5() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Iteration {" +
+            "  EventTask target1 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Iteration {" +
+            "  EventTask target1 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_EventTaskMerge_6() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Iteration {" +
+            "  Selection {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Iteration {" +
+            "  Selection {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_EventTaskMerge_7() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Iteration {" +
+            "  Selection {" +
+            "    EventTask target2 {}" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Iteration {" +
+            "  Selection {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_EventTaskMerge_8() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Sequence {" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Selection {" +
+            "  EventTask target1 {}" +
+            "  Sequence {" +
+            "    EventTask target2 {}" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_EventTaskMerge_9() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  Optional {" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SequenceMerge_1() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+
+        String spec2 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SequenceMerge_2() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+
+        String spec2 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target4 {}" +
+            "  EventTask target3 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  Selection {" +
+            "    EventTask target2 {}" +
+            "    EventTask target4 {}" +
+            "  }" +
+            "  EventTask target3 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SequenceMerge_3() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+
+        String spec2 =
+            "Sequence {" +
+            "  EventTask target4 {}" +
+            "  EventTask target5 {}" +
+            "  EventTask target6 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Selection {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "  Sequence {" +
+            "    EventTask target4 {}" +
+            "    EventTask target5 {}" +
+            "    EventTask target6 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SequenceMerge_4() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+
+        String spec2 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target4 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  Selection {" +
+            "    EventTask target3 {}" +
+            "    EventTask target4 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SequenceMerge_5() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+
+        String spec2 =
+            "Sequence {" +
+            "  EventTask target4 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Sequence {" +
+            "  Selection {" +
+            "    EventTask target1 {}" +
+            "    EventTask target4 {}" +
+            "  }" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SequenceMerge_6() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+
+        String spec2 =
+            "Sequence {" +
+            "  EventTask target4 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target5 {}" +
+            "}";
+
+        String oracleSpec =
+            "Sequence {" +
+            "  Selection {" +
+            "    EventTask target1 {}" +
+            "    EventTask target4 {}" +
+            "  }" +
+            "  EventTask target2 {}" +
+            "  Selection {" +
+            "    EventTask target3 {}" +
+            "    EventTask target5 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SequenceMerge_7() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+
+        String spec2 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target3 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  Optional {" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "  EventTask target3 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SequenceMerge_8() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+
+        String spec2 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  Optional {" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SequenceMerge_9() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+
+        String spec2 =
+            "Sequence {" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Sequence {" +
+            "  Optional {" +
+            "    EventTask target1 {}" +
+            "  }" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SequenceMerge_10() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+
+        String spec2 =
+            "Sequence {" +
+            "  EventTask target2 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Sequence {" +
+            "  Optional {" +
+            "    EventTask target1 {}" +
+            "  }" +
+            "  EventTask target2 {}" +
+            "  Optional {" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SequenceMerge_11() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "  EventTask target4 {}" +
+            "  EventTask target5 {}" +
+            "  EventTask target6 {}" +
+            "  EventTask target7 {}" +
+            "}";
+
+        String spec2 =
+            "Sequence {" +
+            "  EventTask target4 {}" +
+            "  EventTask target3 {}" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "  EventTask target4 {}" +
+            "  EventTask target4 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target6 {}" +
+            "  EventTask target7 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Sequence {" +
+            "  Optional {" +
+            "    Sequence {" +
+            "      EventTask target4 {}" +
+            "      EventTask target3 {}" +
+            "    }" +
+            "  }" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "  EventTask target4 {}" +
+            "  Selection {" +
+            "    EventTask target5 {}" +
+            "    Sequence {" +
+            "      EventTask target4 {}" +
+            "      EventTask target2 {}" +
+            "    }" +
+            "  }" +
+            "  EventTask target6 {}" +
+            "  EventTask target7 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SelectionMerge_1() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Selection {" +
+            "  EventTask target1 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Selection {" +
+            "  EventTask target1 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SelectionMerge_2() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Selection {" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Selection {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "  EventTask target3 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SelectionMerge_3() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Selection {" +
+            "  Sequence {" +
+            "    EventTask target2 {}" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Selection {" +
+            "  EventTask target1 {}" +
+            "  Sequence {" +
+            "    EventTask target2 {}" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+    
+    /**
+     * 
+     */
+    @Test
+    public void test_SelectionMerge_4() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Selection {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Selection {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    Optional {" +
+            "      EventTask target2 {}" +
+            "    }" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_SelectionMerge_5() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "}";
+
+        String spec2 =
+            "Selection {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Selection {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+    
+    /**
+     * 
+     */
+    @Test
+    public void test_SelectionMerge_6() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "}";
+
+        String spec2 =
+            "Selection {" +
+            "  Sequence {" +
+            "    EventTask target3 {}" +
+            "    EventTask target4 {}" +
+            "  }" +
+            "  Sequence {" +
+            "    EventTask target5 {}" +
+            "    EventTask target6 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Selection {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "  Sequence {" +
+            "    EventTask target3 {}" +
+            "    EventTask target4 {}" +
+            "  }" +
+            "  Sequence {" +
+            "    EventTask target5 {}" +
+            "    EventTask target6 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+    
+    /**
+     * 
+     */
+    @Test
+    public void test_IterationMerge_1() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Iteration {" +
+            "  EventTask target1 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Iteration {" +
+            "  EventTask target1 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_IterationMerge_2() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Iteration {" +
+            "  Selection {" +
+            "    EventTask target2 {}" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Iteration {" +
+            "  Selection {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_IterationMerge_3() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Iteration {" +
+            "  Sequence {" +
+            "    EventTask target2 {}" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Iteration {" +
+            "  Selection {" +
+            "    EventTask target1 {}" +
+            "    Sequence {" +
+            "      EventTask target2 {}" +
+            "      EventTask target3 {}" +
+            "    }" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+    
+    /**
+     * 
+     */
+    @Test
+    public void test_IterationMerge_4() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Iteration {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Iteration {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    Optional {" +
+            "      EventTask target2 {}" +
+            "    }" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_IterationMerge_5() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "}";
+
+        String spec2 =
+            "Iteration {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Iteration {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+    
+    /**
+     * 
+     */
+    @Test
+    public void test_IterationMerge_6() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "}";
+
+        String spec2 =
+            "Iteration {" +
+            "  Selection {" +
+            "    Sequence {" +
+            "      EventTask target3 {}" +
+            "      EventTask target4 {}" +
+            "    }" +
+            "    Sequence {" +
+            "      EventTask target5 {}" +
+            "      EventTask target6 {}" +
+            "    }" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Iteration {" +
+            "  Selection {" +
+            "    Sequence {" +
+            "      EventTask target1 {}" +
+            "      EventTask target2 {}" +
+            "    }" +
+            "    Sequence {" +
+            "      EventTask target3 {}" +
+            "      EventTask target4 {}" +
+            "    }" +
+            "    Sequence {" +
+            "      EventTask target5 {}" +
+            "      EventTask target6 {}" +
+            "    }" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+    
+    /**
+     * 
+     */
+    @Test
+    public void test_OptionalMerge_1() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Optional {" +
+            "  EventTask target1 {}" +
+            "}";
+        
+        String oracleSpec =
+            "Optional {" +
+            "  EventTask target1 {}" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_OptionalMerge_2() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Optional {" +
+            "  Selection {" +
+            "    EventTask target2 {}" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Optional {" +
+            "  Selection {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_OptionalMerge_3() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Optional {" +
+            "  Sequence {" +
+            "    EventTask target2 {}" +
+            "    EventTask target3 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Optional {" +
+            "  Selection {" +
+            "    EventTask target1 {}" +
+            "    Sequence {" +
+            "      EventTask target2 {}" +
+            "      EventTask target3 {}" +
+            "    }" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+    
+    /**
+     * 
+     */
+    @Test
+    public void test_OptionalMerge_4() {
+        String spec1 = "EventTask target1 {}";
+        
+        String spec2 =
+            "Optional {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Optional {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    Optional {" +
+            "      EventTask target2 {}" +
+            "    }" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void test_OptionalMerge_5() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "}";
+
+        String spec2 =
+            "Optional {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Optional {" +
+            "  Sequence {" +
+            "    EventTask target1 {}" +
+            "    EventTask target2 {}" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+    
+    /**
+     * 
+     */
+    @Test
+    public void test_OptionalMerge_6() {
+        String spec1 =
+            "Sequence {" +
+            "  EventTask target1 {}" +
+            "  EventTask target2 {}" +
+            "}";
+
+        String spec2 =
+            "Optional {" +
+            "  Selection {" +
+            "    Sequence {" +
+            "      EventTask target3 {}" +
+            "      EventTask target4 {}" +
+            "    }" +
+            "    Sequence {" +
+            "      EventTask target5 {}" +
+            "      EventTask target6 {}" +
+            "    }" +
+            "  }" +
+            "}";
+        
+        String oracleSpec =
+            "Optional {" +
+            "  Selection {" +
+            "    Sequence {" +
+            "      EventTask target1 {}" +
+            "      EventTask target2 {}" +
+            "    }" +
+            "    Sequence {" +
+            "      EventTask target3 {}" +
+            "      EventTask target4 {}" +
+            "    }" +
+            "    Sequence {" +
+            "      EventTask target5 {}" +
+            "      EventTask target6 {}" +
+            "    }" +
+            "  }" +
+            "}";
+        
+        performTest(spec1, spec2, oracleSpec);
+    }
+    
+    /**
+     * 
+     */
+    private void performTest(String spec1, String spec2, String specOracle) {
+        TaskTreeInstantiator instantiator =
+                new TaskTreeInstantiator(taskTreeNodeFactory, taskTreeBuilder);
+            
+        ITaskTreeNode node1 = instantiator.instantiateTaskTree(spec1);
+        ITaskTreeNode node2 = instantiator.instantiateTaskTree(spec2);
+        ITaskTreeNode oracle = instantiator.instantiateTaskTree(specOracle);
+        
+        TaskTreeNodeComparator comparator =
+            new TaskTreeNodeComparator(nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL);
+        
+        TaskTreeNodeMerger merger = new TaskTreeNodeMerger
+            (taskTreeNodeFactory, taskTreeBuilder, comparator);
+        
+        try {
+            ITaskTreeNode result = merger.mergeTaskNodes(node1, node2);
+            new TaskTreeChecker().assertTaskNodesEqual(oracle, result);
+        }
+        catch (AssertionError e) {
+            AssertionError toThrow = new AssertionError("first check: " + e.getMessage());
+            toThrow.setStackTrace(e.getStackTrace());
+            throw toThrow;
+        }
+        
+        node1 = instantiator.instantiateTaskTree(spec1);
+        node2 = instantiator.instantiateTaskTree(spec2);
+        oracle = instantiator.instantiateTaskTree(specOracle);
+        
+        comparator =
+            new TaskTreeNodeComparator(nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL);
+        
+        merger = new TaskTreeNodeMerger(taskTreeNodeFactory, taskTreeBuilder, comparator);
+            
+        try {
+            ITaskTreeNode result = merger.mergeTaskNodes(node2, node1);
+            new TaskTreeChecker().assertTaskNodesEqual(oracle, result);
+        }
+        catch (AssertionError e) {
+            AssertionError toThrow = new AssertionError("second check: " + e.getMessage());
+            toThrow.setStackTrace(e.getStackTrace());
+            throw toThrow;
+        }
+    }
+}
Index: trunk/autoquest-core-tasktrees/pom.xml
===================================================================
--- trunk/autoquest-core-tasktrees/pom.xml	(revision 1126)
+++ trunk/autoquest-core-tasktrees/pom.xml	(revision 1127)
@@ -28,4 +28,9 @@
       <version>${project.parent.version}</version>
     </dependency>
+    <dependency>
+      <groupId>com.googlecode.java-diff-utils</groupId>
+      <artifactId>diffutils</artifactId>
+      <version>1.2.1</version>
+    </dependency>
   </dependencies>
 </project>
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultEventTargetSequenceDetectionRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultEventTargetSequenceDetectionRule.java	(revision 1126)
+++ 	(revision )
@@ -1,201 +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.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 DefaultEventTargetSequenceDetectionRule 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
-     */
-    DefaultEventTargetSequenceDetectionRule(ITaskTreeNodeFactory taskTreeNodeFactory,
-                                            ITaskTreeBuilder     taskTreeBuilder)
-    {
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-    }
-    
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return "DefaultEventTargetSequenceDetectionRule";
-    }
-
-    /*
-     * (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;
-        while (index < parent.getChildren().size()) {
-            ITaskTreeNode child = parent.getChildren().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) ||
-                        (!(parent.getChildren().get(startingIndex) instanceof ISequence)))
-                    {
-                        handleEventTargetSequence
-                            (parent, currentEventTarget, startingIndex, endIndex, result);
-
-                        result.setRuleApplicationStatus
-                            (RuleApplicationStatus.RULE_APPLICATION_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 = parent.getChildren().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) ||
-                     (!(parent.getChildren().get(startingIndex) instanceof ISequence))))
-                {
-                    handleEventTargetSequence
-                        (parent, currentEventTarget, startingIndex, endIndex, result);
-                
-                    result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);
-                }
-            }
-            else {
-                result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_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/DefaultGuiElementSequenceDetectionRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiElementSequenceDetectionRule.java	(revision 1126)
+++ 	(revision )
@@ -1,498 +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 DefaultGuiElementSequenceDetectionRule 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
-     */
-    DefaultGuiElementSequenceDetectionRule(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
-     */
-    DefaultGuiElementSequenceDetectionRule(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 "DefaultGuiElementSequenceDetectionRule";
-    }
-
-    /*
-     * (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.RULE_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.RULE_NOT_APPLIED;
-        boolean subsequenceHasStarted = false;
-        boolean exceedingGuiHierarchyDepth = false;
-        boolean nextGuiElementDiffers = false;
-       
-        currentParent = null;
-        startingIndex = -1;
-
-        int index = 0;
-        while (index < parent.getChildren().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);
-
-                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,
-                     parent.getChildren().size() - 1, result);
-            }
-            else if (status != RuleApplicationStatus.RULE_APPLICATION_FINISHED) {
-                status = RuleApplicationStatus.RULE_NOT_APPLIED;
-            }
-        }
-        else {
-            if ((currentParent != null) &&
-                (status != RuleApplicationStatus.RULE_APPLICATION_FINISHED))
-            {
-                status = RuleApplicationStatus.RULE_APPLICATION_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;
-        boolean singleChildIsSequence = onlyASingleChildToReduce &&
-            parent.getChildren().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, parent.getChildren().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.RULE_APPLICATION_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/DefaultGuiEventSequenceDetectionRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiEventSequenceDetectionRule.java	(revision 1126)
+++ 	(revision )
@@ -1,199 +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.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 DefaultGuiEventSequenceDetectionRule 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
-     */
-    DefaultGuiEventSequenceDetectionRule(ITaskTreeNodeFactory taskTreeNodeFactory,
-                                         ITaskTreeBuilder     taskTreeBuilder)
-    {
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-    }
-    
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return "DefaultGuiEventSequenceDetectionRule";
-    }
-
-    /*
-     * (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>();
-
-        int index = 0;
-        while (index < parent.getChildren().size()) {
-            ITaskTreeNode child = parent.getChildren().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);
-                }
-
-                if (eventType.startsLogicalSequence()) {
-                    sequenceStartingIndex.push(index);
-                }
-            }
-
-            index++;
-        }
-
-        if (sequenceStartingIndex.size() > 0) {
-            if (!finalize) {
-                result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);
-            }
-            else {
-                ITaskTreeNode lastChild = parent.getChildren().get(parent.getChildren().size() - 1);
-                
-                if (lastChild instanceof IEventTask) {
-                    handleLogicalSequence
-                        (sequenceStartingIndex, parent.getChildren().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;
-        IInteraction eventType =
-            (IInteraction) ((IEventTask) parent.getChildren().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 == (parent.getChildren().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, parent.getChildren().get(startIndex));
-                taskTreeBuilder.removeChild((ISequence) parent, startIndex);
-            }
-
-            if (!eventType.startsLogicalSequence()) {
-                taskTreeBuilder.addChild(sequence, parent.getChildren().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.RULE_APPLICATION_FINISHED);
-        }
-        
-        return newIndex;
-    }
-
-}
Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultIterationDetectionRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultIterationDetectionRule.java	(revision 1126)
+++ 	(revision )
@@ -1,739 +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 DefaultIterationDetectionRule 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 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;
-
-    /**
-     * <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>
-     */
-    DefaultIterationDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager,
-                                  NodeEquality            minimalNodeEquality,
-                                  ITaskTreeNodeFactory    taskTreeNodeFactory,
-                                  ITaskTreeBuilder        taskTreeBuilder)
-    {
-        this.nodeEqualityRuleManager = nodeEqualityRuleManager;
-        this.minimalNodeEquality = minimalNodeEquality;
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-    }
-
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return "DefaultIterationDetectionRule";
-    }
-
-    /*
-     * (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.RULE_APPLICATION_FEASIBLE);
-            return result;
-        }
-
-        // parent must already have at least 2 children
-        if ((parent.getChildren() == null) || (parent.getChildren().size() < 2)) {
-            return null;
-        }
-        
-        
-        SubSequences subSequences = getEqualSubsequences(parent);
-
-        if (subSequences != null) {
-            RuleApplicationResult result = new RuleApplicationResult();
-
-            mergeEqualNodes(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.RULE_APPLICATION_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 all children in the parent node 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 parent      the parent node in which iterations of children 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(ITaskTreeNode parent) {
-        SubSequences subSequences = null;
-
-        // to find longer iterations first, start with long sequences
-        FIND_ITERATION:
-        for (int end = parent.getChildren().size(); end > 0; end--) {
-            for (int start = 0; start < end; start++) {
-                boolean useEqualSublistLengths = equalSublistLengthsCanBeUsed(parent, start, end);
-
-                subSequences = new SubSequences();
-                subSequences.start = start;
-
-                boolean foundFurtherVariants = findFurtherVariants
-                    (subSequences, parent, 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 children of the parent 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 children of the parent in which an iteration shall be searched for are event
-     * tasks.
-     * </p>
-     *
-     * @param parent the parent node to search for iterations of its children
-     * @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(ITaskTreeNode parent, int start, int end) {
-        boolean equalLengthsCanBeUsed = minimalNodeEquality.isAtLeast(NodeEquality.LEXICALLY_EQUAL);
-        
-        if (equalLengthsCanBeUsed) {
-            for (int i = start; i < end; i++) {
-                if (!(parent.getChildren().get(i) instanceof IEventTask)) {
-                    equalLengthsCanBeUsed = false;
-                    break;
-                }
-            }
-        }
-
-        return equalLengthsCanBeUsed;
-    }
-
-    /**
-     * <p>
-     * this method starts at a specific position in the list of children of the provided parent
-     * 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 children is not yet reached.
-     * </p>
-     * 
-     * @param subSequences           the sublist found so far against which equality of the next
-     *                               sublist must be checked
-     * @param parent                 the parent node of which the children are analyzed
-     * @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 children
-     *                               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,
-                                        ITaskTreeNode        parent,
-                                        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, parent.getChildren().get(j));
-            }
-            
-            boolean allVariantsEqual = true;
-            
-            for (ITaskTreeNode equalVariant : subSequences.equalVariants) {
-                NodeEquality nodeEquality =
-                    nodeEqualityRuleManager.applyRules(equalVariant, furtherVariant);
-                
-                if (!nodeEquality.isAtLeast(minimalNodeEquality)) {
-                    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, parent, start + childCount, end, useEqualSublistLengths);
-
-                if (foundFurtherVariants) {
-                    subSequences.end = end;
-                    break;
-                }
-                else {
-                    subSequences.equalVariants.remove(index);
-                }
-            }
-        }
-        
-        return foundFurtherVariants;
-    }
-
-    /**
-     * <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 #mergeEqualTasks(ITaskTreeNode, ITaskTreeNode, ITaskTreeBuilder, ITaskTreeNodeFactory)}
-     * 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
-     */
-    private void mergeEqualNodes(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 = mergeEqualTasks(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 equal 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
-     */
-    private ITaskTreeNode mergeEqualTasks(ITaskTreeNode node1, ITaskTreeNode node2) {
-        ITaskTreeNode mergeResult = null;
-        
-        if ((node1 instanceof ISequence) && (node2 instanceof ISequence)) {
-            mergeResult = mergeEqualSequences((ISequence) node1, (ISequence) node2);
-        }
-        else if ((node1 instanceof ISelection) && (node2 instanceof ISelection)) {
-            mergeResult = mergeEqualSelections((ISelection) node1, (ISelection) node2);
-        }
-        else if ((node1 instanceof IIteration) && (node2 instanceof IIteration)) {
-            mergeResult = mergeEqualIterations((IIteration) node1, (IIteration) node2);
-        }
-        else if (node1 instanceof ISelection) {
-            taskTreeBuilder.addChild((ISelection) node1, node2);
-            mergeResult = node1;
-        }
-        else if (node2 instanceof ISelection) {
-            taskTreeBuilder.addChild((ISelection) node2, node1);
-            mergeResult = node2;
-        }
-        else if (node1 instanceof IIteration) {
-            mergeResult = mergeEqualTasks(((IIteration) node1).getChildren().get(0), node2);
-            
-            if (mergeResult != null) {
-                IIteration iteration = taskTreeNodeFactory.createNewIteration();
-                taskTreeBuilder.setChild(iteration, mergeResult);
-                mergeResult = iteration;
-            }
-        }
-        else if (node2 instanceof IIteration) {
-            mergeResult = mergeEqualTasks(((IIteration) node2).getChildren().get(0), node1);
-            
-            if (mergeResult != null) {
-                IIteration iteration = taskTreeNodeFactory.createNewIteration();
-                taskTreeBuilder.setChild(iteration, mergeResult);
-                mergeResult = iteration;
-            }
-        }
-        else {
-            NodeEquality nodeEquality = nodeEqualityRuleManager.applyRules(node1, node2);
-            
-            if (nodeEquality.isAtLeast(NodeEquality.LEXICALLY_EQUAL)) {
-                mergeResult = node1;
-            }
-        }
-
-        if (mergeResult == null) {
-            mergeResult = taskTreeNodeFactory.createNewSelection();
-            taskTreeBuilder.addChild((ISelection) mergeResult, node1);
-            taskTreeBuilder.addChild((ISelection) mergeResult, node2);
-        }
-        
-        return mergeResult;
-    }
-
-    /**
-     * <p>
-     * merges equal sequences. This is done through trying to merge each node of sequence 1 with
-     * the node in sequence 2 being located at the same position. If not all children can be merged
-     * or if the sequences have different lengths, null is returned to indicate, that merging is
-     * not possible. For merging children, the
-     * {@link #mergeEqualTasks(ITaskTreeNode, ITaskTreeNode, ITaskTreeBuilder, ITaskTreeNodeFactory)}
-     * method is called.
-     * </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
-     */
-    private ISequence mergeEqualSequences(ISequence sequence1, ISequence sequence2) {
-        ISequence mergeResult = null;
-        
-        if (sequence1.getChildren().size() == sequence2.getChildren().size()) {
-            mergeResult = taskTreeNodeFactory.createNewSequence();
-            
-            for (int i = 0; i < sequence1.getChildren().size(); i++) {
-                ITaskTreeNode mergedNode = mergeEqualTasks
-                    (sequence1.getChildren().get(i), sequence2.getChildren().get(i));
-                
-                if (mergedNode != null) {
-                    taskTreeBuilder.addChild(mergeResult, mergedNode);
-                }
-                else {
-                    mergeResult = null;
-                    break;
-                }
-            }
-        }
-        
-        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
-     */
-    private ITaskTreeNode mergeEqualSelections(ISelection selection1, ISelection selection2) {
-        ISelection mergeResult = selection1;
-        
-        ITaskTreeNode childToMerge = null;
-        ITaskTreeNode mergedChild = null;
-        
-        // 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 < selection2.getChildren().size(); i++) {
-            childToMerge = selection2.getChildren().get(i);
-            for (int j = 0; j < selection1.getChildren().size(); j++) {
-                mergedChild = mergeEqualTasks(selection1.getChildren().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)) ||
-                     (selection1.getChildren().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, selection1.getChildren().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 selection1  the first iteration to be merged
-     * @param selection2  the second iteration to be merged
-     * 
-     * @return the result of the merge or null if merging is not possible
-     */
-    private ITaskTreeNode mergeEqualIterations(IIteration iteration1, IIteration iteration2) {
-        ITaskTreeNode mergedChild = mergeEqualTasks
-            (iteration1.getChildren().get(0), iteration2.getChildren().get(0));
-        
-        IIteration mergeResult = null;
-        
-        if (mergedChild != null) {
-            mergeResult = taskTreeNodeFactory.createNewIteration();
-            taskTreeBuilder.setChild(mergeResult, mergedChild);
-        }
-        
-        return mergeResult;
-    }
-
-    /**
-     * <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>();
-        
-        if (subtree.getChildren().size() > 0) {
-            parentNodes.add(subtree);
-            
-            for (ITaskTreeNode child : subtree.getChildren()) {
-                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/DefaultTaskSequenceDetectionRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultTaskSequenceDetectionRule.java	(revision 1126)
+++ 	(revision )
@@ -1,710 +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.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.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.usageprofiles.SymbolComparator;
-import de.ugoe.cs.autoquest.usageprofiles.Trie;
-import de.ugoe.cs.autoquest.usageprofiles.TrieProcessor;
-
-/**
- * <p>
- * TODO comment
- * </p>
- * 
- * @author Patrick Harms
- */
-class DefaultTaskSequenceDetectionRule 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 to be used for comparing task tree nodes
-     * </p>
-     */
-    private SymbolComparator<ITaskTreeNode> 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>
-     */
-    DefaultTaskSequenceDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager,
-                                     NodeEquality            minimalNodeEquality,
-                                     ITaskTreeNodeFactory    taskTreeNodeFactory,
-                                     ITaskTreeBuilder        taskTreeBuilder)
-    {
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-        
-        this.nodeComparator =
-            new TaskTreeNodeComparator(nodeEqualityRuleManager, minimalNodeEquality);
-    }
-
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return "DefaultTaskSequenceDetectionRule";
-    }
-
-    /*
-     * (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 tasks may occur at any time
-            RuleApplicationResult result = new RuleApplicationResult();
-            result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);
-            return result;
-        }
-
-        RuleApplicationData<ITaskTreeNode> appData = new RuleApplicationData<ITaskTreeNode>(parent);
-        
-        appData.getStopWatch().start("whole rule application");
-        
-        do {
-            getSequencesOccuringMostOften(appData);
-            
-            if ((appData.getLastFoundSequences().size() > 0) &&
-                (appData.getLastFoundSequences().getOccurrenceCount() > 1))
-            {
-                System.out.println("found " + appData.getLastFoundSequences().size() +
-                                   " tasks occurring " +
-                                   appData.getLastFoundSequences().getOccurrenceCount() + " times");
-
-                for (List<ITaskTreeNode> task : appData.getLastFoundSequences()) {
-                    // only tasks occurring more often than once are of interest
-                    appData.stopWatch.start("creating task sequences");
-
-                    String taskId = "task " + RuleUtils.getNewId();
-                    System.out.println(taskId + ": " + task);
-                    
-                    appData.resetReplacementCounter();
-                    createSequenceForTaskOccurrences(taskId, task, parent, appData);
-                    
-                    if (appData.getReplacementCounter() <
-                        appData.getLastFoundSequences().getOccurrenceCount())
-                    {
-                        System.out.println(taskId + ": replaced task only " +
-                                           appData.getReplacementCounter() +
-                                           " times instead of expected " +
-                                           appData.getLastFoundSequences().getOccurrenceCount());
-                        
-                    }
-
-                    appData.stopWatch.stop("creating task sequences");
-                }
-            }
-            
-        }
-        while (appData.getLastFoundSequences().getOccurrenceCount() > 2);
-        
-        appData.getStopWatch().stop("whole rule application");
-        appData.getStopWatch().dumpStatistics(System.out);
-        
-        if (appData.getResult().getNewlyCreatedParentNodes().size() > 0) {
-            appData.getResult().setRuleApplicationStatus
-                (RuleApplicationStatus.RULE_APPLICATION_FINISHED);
-        }
-        
-        System.out.println(appData.getResult().getNewlyCreatedParentNodes().size());
-        
-        for (ITaskTreeNode node : appData.getResult().getNewlyCreatedParentNodes()) {
-            for (ITaskTreeNode child : node.getChildren()) {
-                System.out.println(child);
-            }
-            System.out.println();
-        }
-        
-        return appData.getResult();
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param i
-     * @return
-     */
-    private void getSequencesOccuringMostOften(RuleApplicationData<ITaskTreeNode> appData) {
-        System.out.println("determining most prominent tasks with a maximum of " +
-                           (appData.getLastFoundSequences().getOccurrenceCount() - 1) +
-                           " occurrences");
-
-        Sequences<ITaskTreeNode> sequences;
-        boolean createNewTrie = (appData.getLastTrie() == null) ||
-            appData.getReplacementCounter() > 0; // tree has changed
-        
-        do {
-            if (createNewTrie) {
-                createNewTrie(appData);
-            }
-            
-            /*PathDumper dumper = new PathDumper();
-            trie.process(dumper);
-        
-            dumper.dump();*/
-        
-            appData.getStopWatch().start("determining tasks");
-
-            MaxCountAndLongestSequenceFinder finder = new MaxCountAndLongestSequenceFinder
-                  (appData.getLastFoundSequences().getOccurrenceCount() - 1);
-            appData.getLastTrie().process(finder);
-        
-            sequences = finder.getFoundSequences();
-            
-            createNewTrie = false;
-            
-            for (List<ITaskTreeNode> task : sequences) {
-                if (task.size() >= appData.getTrainedSequenceLength()) {
-                    // Trie must be recreated with a longer sequence length to be sure that
-                    // the found sequences occurring most often are found in their whole length
-                    appData.setTrainedSequenceLength(appData.getTrainedSequenceLength() + 1);
-                    createNewTrie = true;
-                    break;
-                }
-            }
-            
-            appData.getStopWatch().stop("determining tasks");
-        }
-        while (createNewTrie);
-        
-        appData.setLastFoundSequences(sequences);
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param parent
-     * @return
-     */
-    private void createNewTrie(RuleApplicationData<ITaskTreeNode> appData) {
-        System.out.println("training trie with a maximum sequence length of " +
-                           appData.getTrainedSequenceLength());
-
-        appData.getStopWatch().start("training trie");
-        appData.setLastTrie(new Trie<ITaskTreeNode>(nodeComparator));
-    
-        trainTrie(appData.getTree(), appData);
-        appData.getStopWatch().stop("training trie");
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param trie
-     * @param parent
-     */
-    private void trainTrie(ITaskTreeNode parent, RuleApplicationData<ITaskTreeNode> appData) {
-        // prevent training of already replaces sequences as those shall not be replaced anymore
-        if (!appData.getResult().getNewlyCreatedParentNodes().contains(parent)) {
-            List<ITaskTreeNode> children = parent.getChildren();
-        
-            if ((children != null) && (children.size() > 0)) {
-                
-                /*System.out.println();
-                for (int i = 0; i < children.size(); i++) {
-                    System.out.println(children.get(i));
-                }*/
-                
-                appData.getLastTrie().train(children, appData.getTrainedSequenceLength());
-            
-                for (ITaskTreeNode child : children) {
-                    trainTrie(child, appData);
-                }
-            }
-        }
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param task
-     * @param parent
-     * @param treeBuilder
-     * @param nodeFactory
-     * @param result
-     */
-    private void createSequenceForTaskOccurrences(String                             taskId,
-                                                  List<ITaskTreeNode>                task,
-                                                  ITaskTreeNode                      parent,
-                                                  RuleApplicationData<ITaskTreeNode> appData)
-    {
-        List<ITaskTreeNode> children = parent.getChildren();
-        
-        if ((children == null) || (children.size() == 0)) {
-            return;
-        }
-        
-        // first traverse the children
-        for (ITaskTreeNode child : children) {
-            createSequenceForTaskOccurrences(taskId, task, child, appData);
-        }
-        
-        // now check the children themselves for an occurrence of the task
-        int index = -1;
-        
-        do {
-            index = getSubListIndex(children, task, ++index);
-            
-            if (index > -1) {
-                if (task.size() < children.size()) {
-                    ISequence sequence = RuleUtils.createNewSubSequenceInRange
-                        (parent, index, index + task.size() - 1, taskId,
-                         taskTreeNodeFactory, taskTreeBuilder);
-                    
-                    appData.getResult().addNewlyCreatedParentNode(sequence);
-                    appData.incrementReplacementCounter();
-                 
-                    children = parent.getChildren();
-                }
-                else {
-                    // the whole list of children is an occurrence of this task. Just set the
-                    // description of the parent and break up
-                    String description = parent.getDescription();
-                    
-                    if ((description != null) && (description.length() > 0)) {
-                        description += "; " + taskId;
-                    }
-                    else {
-                        description = taskId;
-                    }
-                    
-                    taskTreeBuilder.setDescription(parent, description);
-                    break;
-                }
-            }
-        }
-        while (index > -1);
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param trie
-     * @param object
-     * @return
-     */
-    private int getSubListIndex(List<ITaskTreeNode> list,
-                                List<ITaskTreeNode> 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 (!nodeComparator.equals(list.get(i + j), subList.get(j))) {
-                    matchFound = false;
-                    break;
-                }
-                else if (!nodeComparator.equals(subList.get(j), list.get(i + j))){
-                    throw new RuntimeException("comparator not commutative");
-                }
-            }
-            
-            if (matchFound) {
-                result = i;
-                break;
-            }
-        }
-        
-        return result;
-    }
-    
-    /**
-     * <p>
-     * TODO comment
-     * </p>
-     * 
-     * @author Patrick Harms
-     */
-    private class MaxCountAndLongestSequenceFinder implements TrieProcessor<ITaskTreeNode> {
-        
-        /**
-         * 
-         */
-        private int maxCount;
-        
-        /**
-         * 
-         */
-        private int currentCount;
-        
-        /**
-         * 
-         */
-        private List<List<ITaskTreeNode>> foundSequences = new LinkedList<List<ITaskTreeNode>>();
-
-        /**
-         * <p>
-         * TODO: comment
-         * </p>
-         *
-         * @param maxCount
-         */
-        public MaxCountAndLongestSequenceFinder(int maxCount) {
-            super();
-            this.maxCount = maxCount;
-            this.currentCount = 0;
-        }
-
-        /* (non-Javadoc)
-         * @see de.ugoe.cs.autoquest.usageprofiles.TrieProcessor#process(java.util.List, int)
-         */
-        @Override
-        public TrieProcessor.Result process(List<ITaskTreeNode> sequence, int count) {
-            if (sequence.size() < 2) {
-                // ignore single nodes
-                return TrieProcessor.Result.CONTINUE;
-            }
-            
-            if (count < 2) {
-                // ignore singular occurrences
-                return TrieProcessor.Result.SKIP_NODE;
-            }
-
-            if (count > this.maxCount) {
-                // ignore sequences that occur too often
-                return TrieProcessor.Result.CONTINUE;
-            }
-            
-            if (this.currentCount > count) {
-                // ignore this children of this node, as they may have only smaller counts than
-                // the already found sequences
-                return TrieProcessor.Result.SKIP_NODE;
-            }
-            
-            if (this.currentCount < count) {
-                // the provided sequence occurs more often that all sequences found so far.
-                // clear all found sequences and use the new count as the one searched for
-                foundSequences.clear();
-                this.currentCount = count;
-            }
-            
-            if (this.currentCount == count) {
-                // the sequence is of interest. Sort it into the other found sequences so that
-                // the longest come first
-                boolean added = false;
-                for (int i = 0; i < foundSequences.size(); i++) {
-                    if (foundSequences.get(i).size() < sequence.size()) {
-                        // defensive copy
-                        foundSequences.add(i, new LinkedList<ITaskTreeNode>(sequence)); // defensive copy
-                        added = true;
-                        break;
-                    }
-                }
-                
-                if (!added) {
-                    foundSequences.add(new LinkedList<ITaskTreeNode>(sequence)); // defensive copy
-                }
-            }
-            
-            return TrieProcessor.Result.CONTINUE;
-        }
-
-        /**
-         * <p>
-         * TODO: comment
-         * </p>
-         *
-         * @return
-         */
-        public Sequences<ITaskTreeNode> getFoundSequences() {
-            removePermutationsOfShorterTasks();
-            return new Sequences<ITaskTreeNode>(currentCount, foundSequences);
-        }
-
-        /**
-         * <p>
-         * TODO: comment
-         * </p>
-         *
-         */
-        private void removePermutationsOfShorterTasks() {
-            // now iterate the sorted list and for each task remove all other tasks that are shorter
-            // (i.e. come later in the sorted list) and that represent a subpart of the task
-            for (int i = 0; i < foundSequences.size(); i++) {
-                for (int j = i + 1; j < foundSequences.size();) {
-                    if (foundSequences.get(j).size() < foundSequences.get(i).size()) {
-                        // found a task that is a potential subtask. Check for this and remove the
-                        // subtask if needed
-                        List<ITaskTreeNode> longTask = foundSequences.get(i);
-                        List<ITaskTreeNode> shortTask = foundSequences.get(j);
-                        
-                        if (getSubListIndex(longTask, shortTask, 0) > -1) {
-                            foundSequences.remove(j);
-                        }
-                        else {
-                            j++;
-                        }
-                    }
-                    else {
-                        j++;
-                    }
-                }
-            }
-        }
-
-    }
-    
-    /**
-     * 
-     */
-    private class RuleApplicationData<T> {
-        
-        /**
-         * 
-         */
-        private T tree;
-        
-        /**
-         * 
-         */
-        private RuleApplicationResult result = new RuleApplicationResult();
-        
-        /**
-         * 
-         */
-        private Sequences<T> lastFoundSequences = new Sequences<T>(Integer.MAX_VALUE, null);
-        
-        /**
-         * 
-         */
-        private Trie<T> lastTrie;
-        
-        /**
-         * default and minimum trained sequence length is 3
-         */
-        private int trainedSequenceLength = 3;
-        
-        /**
-         * 
-         */
-        private int replacementCounter;
-        
-        /**
-         * 
-         */
-        private StopWatch stopWatch = new StopWatch();
-        
-        /**
-         * 
-         */
-        private RuleApplicationData(T tree) {
-            this.tree = tree;
-        }
-
-        /**
-         * @return the lastFoundSequences
-         */
-        private Sequences<T> getLastFoundSequences() {
-            return lastFoundSequences;
-        }
-
-        /**
-         * @param lastFoundSequences the lastFoundSequences to set
-         */
-        private void setLastFoundSequences(Sequences<T> lastFoundSequences) {
-            this.lastFoundSequences = lastFoundSequences;
-        }
-
-        /**
-         * @return the lastTrie
-         */
-        private Trie<T> getLastTrie() {
-            return lastTrie;
-        }
-
-        /**
-         * @return the trainedSequenceLength
-         */
-        private int getTrainedSequenceLength() {
-            return trainedSequenceLength;
-        }
-
-        /**
-         * @param trainedSequenceLength the trainedSequenceLength to set
-         */
-        private void setTrainedSequenceLength(int trainedSequenceLength) {
-            this.trainedSequenceLength = trainedSequenceLength;
-        }
-
-        /**
-         * @param lastTrie the lastTrie to set
-         */
-        private void setLastTrie(Trie<T> lastTrie) {
-            this.lastTrie = lastTrie;
-        }
-
-        /**
-         * @return the tree
-         */
-        private T getTree() {
-            return tree;
-        }
-
-        /**
-         * @return the result
-         */
-        private RuleApplicationResult getResult() {
-            return result;
-        }
-
-        /**
-         * @return the stopWatch
-         */
-        private StopWatch getStopWatch() {
-            return stopWatch;
-        }
-
-        /**
-         *
-         */
-        private void resetReplacementCounter() {
-            replacementCounter = 0;
-        }
-
-        /**
-         *
-         */
-        private void incrementReplacementCounter() {
-            replacementCounter++;
-        }
-
-        /**
-         *
-         */
-        private int getReplacementCounter() {
-            return replacementCounter;
-        }
-    }
-    
-
-    /**
-     * <p>
-     * TODO comment
-     * </p>
-     * 
-     * @author Patrick Harms
-     */
-    private class Sequences<T> implements Iterable<List<T>> {
-        
-        /**
-         * 
-         */
-        private int occurrenceCount;
-        
-        /**
-         * 
-         */
-        private List<List<T>> sequences;
-
-        /**
-         * <p>
-         * TODO: comment
-         * </p>
-         *
-         * @param occurrenceCount
-         * @param sequences
-         */
-        private Sequences(int occurrenceCount, List<List<T>> sequences) {
-            super();
-            this.occurrenceCount = occurrenceCount;
-            this.sequences = sequences;
-        }
-
-        /**
-         * <p>
-         * TODO: comment
-         * </p>
-         *
-         * @return
-         */
-        private int getOccurrenceCount() {
-            return occurrenceCount;
-        }
-
-        /**
-         * <p>
-         * TODO: comment
-         * </p>
-         *
-         * @return
-         */
-        private int size() {
-            return this.sequences.size();
-        }
-
-        /**
-         * 
-         */
-
-        /* (non-Javadoc)
-         * @see java.lang.Iterable#iterator()
-         */
-        @Override
-        public Iterator<List<T>> iterator() {
-            return this.sequences.iterator();
-        }
-
-    }
-
-}
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 1127)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/IterationOfSubtreesDetectionRule.java	(revision 1127)
@@ -0,0 +1,525 @@
+//   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 1126)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationResult.java	(revision 1127)
@@ -33,5 +33,5 @@
 
     /** */
-    private RuleApplicationStatus status = RuleApplicationStatus.RULE_NOT_APPLIED;
+    private RuleApplicationStatus status = RuleApplicationStatus.NOT_APPLIED;
 
     /** */
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 1126)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationStatus.java	(revision 1127)
@@ -24,6 +24,6 @@
  */
 enum RuleApplicationStatus {
-    RULE_APPLICATION_FINISHED,
-    RULE_APPLICATION_FEASIBLE,
-    RULE_NOT_APPLIED;
+    FINISHED,
+    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 1126)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleUtils.java	(revision 1127)
@@ -35,4 +35,26 @@
      * 
      */
+    static ISequence getSubSequenceInRange(ITaskTreeNode         parent,
+                                           int                   startIndex,
+                                           int                   endIndex,
+                                           String                description,
+                                           ITaskTreeNodeFactory  nodeFactory,
+                                           ITaskTreeBuilder      builder)
+    {
+        ISequence sequence = nodeFactory.createNewSequence();
+        if (description != null) {
+            builder.setDescription(sequence, description);
+        }
+
+        for (int i = startIndex; i <= endIndex; i++) {
+            builder.addChild(sequence, parent.getChildren().get(i));
+        }
+
+        return sequence;
+    }
+
+    /**
+     * 
+     */
     static ISequence createNewSubSequenceInRange(ITaskTreeNode         parent,
                                                  int                   startIndex,
@@ -60,5 +82,5 @@
      *
      */
-    public static synchronized String getNewId() {
+    static synchronized String getNewId() {
         return Integer.toString(idCounter++);
     }
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 1127)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceDependingOnEventTypeDetectionRule.java	(revision 1127)
@@ -0,0 +1,207 @@
+//   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 1127)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRule.java	(revision 1127)
@@ -0,0 +1,967 @@
+//   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.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.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.usageprofiles.Trie;
+import de.ugoe.cs.autoquest.usageprofiles.TrieProcessor;
+import de.ugoe.cs.util.console.Console;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+class SequenceForTaskDetectionRule 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 to be used for comparing task tree nodes
+     * </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>
+     */
+    SequenceForTaskDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager,
+                                 NodeEquality            minimalNodeEquality,
+                                 ITaskTreeNodeFactory    taskTreeNodeFactory,
+                                 ITaskTreeBuilder        taskTreeBuilder)
+    {
+        this.taskTreeNodeFactory = taskTreeNodeFactory;
+        this.taskTreeBuilder = taskTreeBuilder;
+        
+        this.nodeComparator =
+            new TaskTreeNodeComparator(nodeEqualityRuleManager, minimalNodeEquality);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "SequenceForTaskDetectionRule";
+    }
+
+    /*
+     * (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 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;
+            }
+        }
+        
+        RuleApplicationData appData = new RuleApplicationData(sessions);
+
+        boolean finished = false;
+        
+        // this is the real rule application. Loop while something is replaced.
+        do {
+            System.out.println();
+            
+            appData.getStopWatch().start("whole loop");
+            detectAndReplaceIterations(appData);
+            //mergeEqualTasks(appData);
+            appData.getStopWatch().start("task replacement");
+            detectAndReplaceTasks(appData);
+            appData.getStopWatch().stop("task replacement");
+            appData.getStopWatch().stop("whole loop");
+            
+            //((TaskTreeNodeComparator) nodeComparator).getStopWatch().dumpStatistics(System.out);
+            //((TaskTreeNodeComparator) nodeComparator).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) {
+            appData.getResult().setRuleApplicationStatus(RuleApplicationStatus.FINISHED);
+        }
+        
+        return appData.getResult();
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param appData
+     */
+    private void detectAndReplaceIterations(RuleApplicationData appData) {
+        System.out.print("detecting iterations");
+        appData.getStopWatch().start("detecting iterations");
+        
+        List<ISequence> sessions = appData.getSessions();
+        int foundIterations = 0;
+        
+        for (ISequence session : sessions) {
+            foundIterations += detectAndReplaceIterations(session, appData);
+        }
+        
+        appData.getStopWatch().stop("detecting iterations");
+        System.out.println(" --> found " + foundIterations);
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param appData
+     */
+    private int detectAndReplaceIterations(ISequence           session,
+                                           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;
+    }
+
+//    /**
+//     * <p>
+//     * TODO: comment
+//     * </p>
+//     *
+//     * @param appData
+//     */
+//    private void mergeEqualTasks(RuleApplicationData appData) {
+//        System.out.println("merging equal tasks");
+//        appData.getStopWatch().start("merging equal tasks");
+//        
+//        int replacements = 0;
+//        List<ISequence> sessions = appData.getSessions();
+//        
+//        IdentityHashMap<ITaskTreeNode, ITaskTreeNode> replacedChildren =
+//            new IdentityHashMap<ITaskTreeNode, ITaskTreeNode>();
+//        
+//        for (int sessionIdx1 = 0; sessionIdx1 < sessions.size(); sessionIdx1++) {
+//            List<ITaskTreeNode> children1 = appData.getSessions().get(sessionIdx1).getChildren();
+//            for (int childIdx1 = 0; childIdx1 < children1.size(); childIdx1++) {
+//                // this is the child of which we search equal other children to merge and to
+//                // replace with one single unique node
+//                ITaskTreeNode child1 = children1.get(childIdx1);
+//                
+//                if (replacedChildren.containsKey(child1)) {
+//                    continue;
+//                }
+//                
+//                // now search for all other children that are equal. Also record the session they
+//                // belong to as well as the index in that session
+//                List<ITaskTreeNode> equalChildren = new LinkedList<ITaskTreeNode>();
+//                List<Integer> sessionIndexes = new LinkedList<Integer>();
+//                List<Integer> childIndexes = new LinkedList<Integer>();
+//
+//                // add all information about the current child
+//                equalChildren.add(child1);
+//                sessionIndexes.add(sessionIdx1);
+//                childIndexes.add(childIdx1);
+//                
+//                for (int sessionIdx2 = sessionIdx1; sessionIdx2 < sessions.size(); sessionIdx2++) {
+//                    List<ITaskTreeNode> children2 =
+//                          appData.getSessions().get(sessionIdx2).getChildren();
+//                    
+//                    int startIndex = (sessionIdx1 == sessionIdx2) ? childIdx1 + 1 : 0;
+//                    
+//                    for (int childIdx2 = startIndex; childIdx2 < children2.size(); childIdx2++) {
+//                        ITaskTreeNode child2 = children2.get(childIdx2);
+//                        
+//                        if ((child1 != child2) && (nodeComparator.equals(child1, child2))) {
+//                            // this is an equal child --> record its occurrence
+//                            equalChildren.add(child2);
+//                            sessionIndexes.add(sessionIdx2);
+//                            childIndexes.add(childIdx2);
+//                        }
+//                    }
+//                }
+//                
+//                // now merge the found children
+//                if (equalChildren.size() > 1) {
+//                    ITaskTreeNode replacement =
+//                        mergeVariantsOfTasks(child1.toString(), equalChildren);
+//
+//                    for (int i = 0; i < sessionIndexes.size(); i++) {
+//                        taskTreeBuilder.setChild(appData.getSessions().get(sessionIndexes.get(i)),
+//                                                 childIndexes.get(i), replacement);
+//                    
+//                        replacements++;
+//                    }
+//                    
+//                    // remember the replacement to prevent comparison of merged nodes
+//                    replacedChildren.put(replacement, replacement);
+//                    
+//                    System.out.println
+//                        ("replaced " + sessionIndexes.size() + " occurrences of " + child1);
+//                }
+//            }
+//        }
+//
+//        appData.getStopWatch().stop("merging equal tasks");
+//        
+//        System.out.println("replaced " + replacements + " equal tasks with unique replacements");
+//    }
+//
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param appData
+     */
+    private void detectAndReplaceTasks(RuleApplicationData appData) {
+        System.out.println("detecting and replacing tasks");
+        appData.getStopWatch().start("detecting tasks");
+        
+        getSequencesOccuringMostOften(appData);
+
+        appData.getStopWatch().stop("detecting tasks");
+        appData.getStopWatch().start("replacing tasks");
+        
+        replaceSequencesOccurringMostOften(appData);
+        
+        appData.getStopWatch().stop("replacing tasks");
+        System.out.println("detected and replaced " + appData.getLastFoundTasks().size() + " tasks");
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param i
+     * @return
+     */
+    private void getSequencesOccuringMostOften(RuleApplicationData appData) {
+        System.out.println("determining most prominent tasks");
+
+        Tasks tasks;
+        boolean createNewTrie = (appData.getLastTrie() == null) ||
+            appData.getReplacementCounter() > 0; // tree has changed
+        
+        do {
+            if (createNewTrie) {
+                createNewTrie(appData);
+            }
+            
+            MaxCountAndLongestTasksFinder finder = new MaxCountAndLongestTasksFinder();
+            appData.getLastTrie().process(finder);
+        
+            tasks = finder.getFoundTasks();
+            
+            createNewTrie = false;
+            
+            for (List<ITaskTreeNode> task : tasks) {
+                if (task.size() >= appData.getTrainedSequenceLength()) {
+                    // Trie must be recreated with a longer sequence length to be sure that
+                    // the found sequences occurring most often are found in their whole length
+                    appData.setTrainedSequenceLength(appData.getTrainedSequenceLength() + 1);
+                    createNewTrie = true;
+                    break;
+                }
+            }
+        }
+        while (createNewTrie);
+        
+        appData.setLastFoundTasks(tasks);
+
+        System.out.println("found " + appData.getLastFoundTasks().size() + " tasks occurring " +
+                           appData.getLastFoundTasks().getOccurrenceCount() + " times");
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param parent
+     * @return
+     */
+    private void createNewTrie(RuleApplicationData appData) {
+        System.out.println("training trie with a maximum sequence length of " +
+                           appData.getTrainedSequenceLength());
+
+        appData.getStopWatch().start("training trie");
+        appData.setLastTrie(new Trie<ITaskTreeNode>(nodeComparator));
+    
+        List<ISequence> sessions = appData.getSessions();
+        
+        for (ISequence session : sessions) {
+            trainTrie(session, appData);
+        }
+        
+        appData.getStopWatch().stop("training trie");
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param trie
+     * @param parent
+     */
+    private void trainTrie(ISequence session, RuleApplicationData appData) {
+        List<ITaskTreeNode> children = session.getChildren();
+        
+        if ((children != null) && (children.size() > 0)) {
+            appData.getLastTrie().train(children, appData.getTrainedSequenceLength());
+        }
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param appData
+     */
+    private void replaceSequencesOccurringMostOften(RuleApplicationData appData) {
+        appData.resetReplacementCounter();
+
+        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 " +
+                                       appData.getLastFoundTasks().getOccurrenceCount());
+                }
+            }
+        }
+        
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param tree
+     */
+    private void determineVariantsOfTaskOccurrences(List<ITaskTreeNode> task,
+                                                    List<ISequence>     sessions,
+                                                    RuleApplicationData appData)
+    {
+        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);
+        }
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param appData
+     * @return
+     */
+    private ITaskTreeNode mergeVariantsOfTaskOccurrence(String              taskId,
+                                                        RuleApplicationData appData)
+    {
+        return mergeVariantsOfTasks(taskId, appData.getTaskOccurrences());
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @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;
+        }
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @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();
+                        break;
+                    }
+                }
+            }
+            while (index > -1);
+        }
+    }
+
+    /**
+     * <p>
+     * TODO: comment
+     * </p>
+     *
+     * @param trie
+     * @param object
+     * @return
+     */
+    private int getSubListIndex(List<ITaskTreeNode> list,
+                                List<ITaskTreeNode> 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 (!nodeComparator.equals(list.get(i + j), subList.get(j))) {
+                    matchFound = false;
+                    break;
+                }
+            }
+            
+            if (matchFound) {
+                result = i;
+                break;
+            }
+        }
+        
+        return result;
+    }
+    
+    /**
+     * <p>
+     * TODO comment
+     * </p>
+     * 
+     * @author Patrick Harms
+     */
+    private class MaxCountAndLongestTasksFinder implements TrieProcessor<ITaskTreeNode> {
+        
+        /**
+         * 
+         */
+        private int currentCount;
+        
+        /**
+         * 
+         */
+        private List<List<ITaskTreeNode>> foundTasks = new LinkedList<List<ITaskTreeNode>>();
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @param maxCount
+         */
+        public MaxCountAndLongestTasksFinder() {
+            super();
+            this.currentCount = 0;
+        }
+
+        /* (non-Javadoc)
+         * @see de.ugoe.cs.autoquest.usageprofiles.TrieProcessor#process(java.util.List, int)
+         */
+        @Override
+        public TrieProcessor.Result process(List<ITaskTreeNode> task, int count) {
+            if (task.size() < 2) {
+                // ignore single nodes
+                return TrieProcessor.Result.CONTINUE;
+            }
+            
+            if (count < 2) {
+                // ignore singular occurrences
+                return TrieProcessor.Result.SKIP_NODE;
+            }
+
+            if (this.currentCount > count) {
+                // ignore this children of this node, as they may have only smaller counts than
+                // the already found tasks
+                return TrieProcessor.Result.SKIP_NODE;
+            }
+            
+            if (this.currentCount < count) {
+                // the provided task occurs more often that all tasks found so far.
+                // clear all found tasks and use the new count as the one searched for
+                foundTasks.clear();
+                this.currentCount = count;
+            }
+            
+            if (this.currentCount == count) {
+                // the task is of interest. Sort it into the other found tasks so that
+                // the longest come first
+                boolean added = false;
+                for (int i = 0; i < foundTasks.size(); i++) {
+                    if (foundTasks.get(i).size() < task.size()) {
+                        // defensive copy
+                        foundTasks.add(i, new LinkedList<ITaskTreeNode>(task)); // defensive copy
+                        added = true;
+                        break;
+                    }
+                }
+                
+                if (!added) {
+                    foundTasks.add(new LinkedList<ITaskTreeNode>(task)); // defensive copy
+                }
+            }
+            
+            return TrieProcessor.Result.CONTINUE;
+        }
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @return
+         */
+        public Tasks getFoundTasks() {
+            removePermutationsOfShorterTasks();
+            return new Tasks(currentCount, foundTasks);
+        }
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         */
+        private void removePermutationsOfShorterTasks() {
+            // now iterate the sorted list and for each task remove all other tasks that are shorter
+            // (i.e. come later in the sorted list) and that represent a subpart of the task
+            for (int i = 0; i < foundTasks.size(); i++) {
+                for (int j = i + 1; j < foundTasks.size();) {
+                    if (foundTasks.get(j).size() < foundTasks.get(i).size()) {
+                        // 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);
+                        
+                        if (getSubListIndex(longTask, shortTask, 0) > -1) {
+                            foundTasks.remove(j);
+                        }
+                        else {
+                            j++;
+                        }
+                    }
+                    else {
+                        j++;
+                    }
+                }
+            }
+        }
+
+    }
+    
+    /**
+     * 
+     */
+    private class RuleApplicationData {
+        
+        /**
+         * 
+         */
+        private List<ISequence> sessions;
+        
+        /**
+         * 
+         */
+        private Trie<ITaskTreeNode> lastTrie;
+        
+        /**
+         * default and minimum trained sequence length is 3
+         */
+        private int trainedSequenceLength = 3;
+        
+        /**
+         * 
+         */
+        private Tasks lastFoundTasks = new Tasks(Integer.MAX_VALUE, null);
+        
+        /**
+         * 
+         */
+        private List<ITaskTreeNode> taskOccurrences = new LinkedList<ITaskTreeNode>();
+        
+        /**
+         * 
+         */
+        private int replacementCounter;
+        
+        /**
+         * 
+         */
+        private RuleApplicationResult result = new RuleApplicationResult();
+        
+        /**
+         * 
+         */
+        private StopWatch stopWatch = new StopWatch();
+        
+        /**
+         * 
+         */
+        private RuleApplicationData(List<ISequence> sessions) {
+            this.sessions = sessions;
+        }
+
+        /**
+         * @return the tree
+         */
+        private List<ISequence> getSessions() {
+            return sessions;
+        }
+
+        /**
+         * @param lastTrie the lastTrie to set
+         */
+        private void setLastTrie(Trie<ITaskTreeNode> lastTrie) {
+            this.lastTrie = lastTrie;
+        }
+
+        /**
+         * @return the lastTrie
+         */
+        private Trie<ITaskTreeNode> getLastTrie() {
+            return lastTrie;
+        }
+
+        /**
+         * @param trainedSequenceLength the trainedSequenceLength to set
+         */
+        private void setTrainedSequenceLength(int trainedSequenceLength) {
+            this.trainedSequenceLength = trainedSequenceLength;
+        }
+
+        /**
+         * @return the trainedSequenceLength
+         */
+        private int getTrainedSequenceLength() {
+            return trainedSequenceLength;
+        }
+
+        /**
+         * @param lastFoundSequences the lastFoundSequences to set
+         */
+        private void setLastFoundTasks(Tasks lastFoundSequences) {
+            this.lastFoundTasks = lastFoundSequences;
+        }
+
+        /**
+         * @return the lastFoundSequences
+         */
+        private Tasks getLastFoundTasks() {
+            return lastFoundTasks;
+        }
+
+        /**
+         * @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 incrementReplacementCounter() {
+            replacementCounter++;
+        }
+
+        /**
+         *
+         */
+        private int getReplacementCounter() {
+            return replacementCounter;
+        }
+        
+        /**
+         * @return the result
+         */
+        private RuleApplicationResult getResult() {
+            return result;
+        }
+
+        /**
+         * @return the stopWatch
+         */
+        private StopWatch getStopWatch() {
+            return stopWatch;
+        }
+
+    }
+    
+
+    /**
+     * <p>
+     * TODO comment
+     * </p>
+     * 
+     * @author Patrick Harms
+     */
+    private class Tasks implements Iterable<List<ITaskTreeNode>> {
+        
+        /**
+         * 
+         */
+        private int occurrenceCount;
+        
+        /**
+         * 
+         */
+        private List<List<ITaskTreeNode>> sequences;
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @param occurrenceCount
+         * @param sequences
+         */
+        private Tasks(int occurrenceCount, List<List<ITaskTreeNode>> sequences) {
+            super();
+            this.occurrenceCount = occurrenceCount;
+            this.sequences = sequences;
+        }
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @return
+         */
+        private int getOccurrenceCount() {
+            return occurrenceCount;
+        }
+
+        /**
+         * <p>
+         * TODO: comment
+         * </p>
+         *
+         * @return
+         */
+        private int size() {
+            return this.sequences.size();
+        }
+
+        /**
+         * 
+         */
+
+        /* (non-Javadoc)
+         * @see java.lang.Iterable#iterator()
+         */
+        @Override
+        public Iterator<List<ITaskTreeNode>> iterator() {
+            return this.sequences.iterator();
+        }
+
+    }
+
+}
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 1127)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceOnGuiElementDetectionRule.java	(revision 1127)
@@ -0,0 +1,504 @@
+//   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 1127)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceOnSameTargetDetectionRule.java	(revision 1127)
@@ -0,0 +1,204 @@
+//   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 1127)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SimpleIterationDetectionRule.java	(revision 1127)
@@ -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.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 1126)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskTreeNodeComparator.java	(revision 1127)
@@ -15,4 +15,6 @@
 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;
@@ -44,5 +46,13 @@
     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;
 
     /**
@@ -60,7 +70,27 @@
         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)
@@ -69,6 +99,147 @@
     @Override
     public boolean equals(ITaskTreeNode symbol1, ITaskTreeNode symbol2) {
-        return nodeEqualityRuleManager.applyRules(symbol1, symbol2).isAtLeast(minimalNodeEquality);
-    }
-
+        //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 1127)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskTreeNodeMerger.java	(revision 1127)
@@ -0,0 +1,590 @@
+//   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/TemporalRelationshipRuleManager.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java	(revision 1126)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java	(revision 1127)
@@ -157,7 +157,25 @@
 
         treeScopeRules = new TemporalRelationshipRule[] {
+            new SequenceForTaskDetectionRule
+                (nodeEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL,
+                 taskTreeNodeFactory, taskTreeBuilder),
+            /*new DefaultTaskSequenceDetectionRule
+                (nodeEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL,
+                 taskTreeNodeFactory, taskTreeBuilder),
             new DefaultTaskSequenceDetectionRule
-                (nodeEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL,
-                 taskTreeNodeFactory, taskTreeBuilder)
+                (nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL,
+                 taskTreeNodeFactory, taskTreeBuilder),*/
+            /*new TreeScopeWrapperRule
+                (new DefaultIterationDetectionRule
+                    (nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL,
+                     taskTreeNodeFactory, taskTreeBuilder)),
+            new TreeScopeWrapperRule
+                (new DefaultIterationDetectionRule
+                    (nodeEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL,
+                     taskTreeNodeFactory, taskTreeBuilder)),
+            new TreeScopeWrapperRule
+                (new DefaultIterationDetectionRule
+                    (nodeEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL,
+                     taskTreeNodeFactory, taskTreeBuilder))*/
         };
         
@@ -165,18 +183,9 @@
 
         nodeScopeRules = new TemporalRelationshipRule[] {
-            //new DefaultGuiElementSequenceDetectionRule(taskTreeNodeFactory, taskTreeBuilder),
-            //new DefaultEventTargetSequenceDetectionRule(taskTreeNodeFactory, taskTreeBuilder),
+            //new SequenceOnGuiElementDetectionRule(taskTreeNodeFactory, taskTreeBuilder),
+            //new EventSequenceOnSameTargetDetectionRule(taskTreeNodeFactory, taskTreeBuilder),
             new TrackBarSelectionDetectionRule
                 (nodeEqualityRuleManager, taskTreeNodeFactory, taskTreeBuilder),
             //new DefaultGuiEventSequenceDetectionRule(taskTreeNodeFactory, taskTreeBuilder),
-            new DefaultIterationDetectionRule
-                (nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL,
-                 taskTreeNodeFactory, taskTreeBuilder),
-            new DefaultIterationDetectionRule
-                (nodeEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL,
-                 taskTreeNodeFactory, taskTreeBuilder),
-            new DefaultIterationDetectionRule
-                (nodeEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL,
-                 taskTreeNodeFactory, taskTreeBuilder)
         };
 
@@ -245,6 +254,5 @@
 
                 if ((result != null) &&
-                    (result.getRuleApplicationStatus() ==
-                     RuleApplicationStatus.RULE_APPLICATION_FINISHED))
+                    (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED))
                 {
                     Console.traceln
@@ -252,5 +260,5 @@
                     noOfRuleApplications++;
                     
-                    dumpTask(parent, "");
+                    //dumpTask(parent, "");
 
                     for (ITaskTreeNode newParent : result.getNewlyCreatedParentNodes()) {
@@ -261,11 +269,9 @@
             }
             while ((result != null) &&
-                   (result.getRuleApplicationStatus() ==
-                    RuleApplicationStatus.RULE_APPLICATION_FINISHED));
+                   (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED));
 
             if ((!finalize) &&
                 (result != null) &&
-                (result.getRuleApplicationStatus() ==
-                 RuleApplicationStatus.RULE_APPLICATION_FEASIBLE))
+                (result.getRuleApplicationStatus() == RuleApplicationStatus.FEASIBLE))
             {
                 // in this case, don't go on applying rules, which should not be applied yet
@@ -275,5 +281,5 @@
 
         if (noOfRuleApplications <= 0) {
-            Console.traceln(Level.INFO, logIndent + "no rules applied --> no temporal " +
+            Console.traceln(Level.FINE, logIndent + "no rules applied --> no temporal " +
                             "relationship generated");
         }
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 1126)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TrackBarSelectionDetectionRule.java	(revision 1127)
@@ -15,7 +15,8 @@
 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.NodeEquality;
 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
@@ -97,6 +98,8 @@
 
         int index = 0;
-        while (index < parent.getChildren().size()) {
-            ITaskTreeNode child = parent.getChildren().get(index);
+        List<ITaskTreeNode> children = parent.getChildren();
+        
+        while (index < children.size()) {
+            ITaskTreeNode child = children.get(index);
 
             if ((child instanceof IEventTask) &&
@@ -128,8 +131,8 @@
             if (finalize) {
                 handleValueSelections(parent, currentTrackBar, valueSelectionStartIndex,
-                                      parent.getChildren().size() - 1, result);
+                                      children.size() - 1, result);
             }
             else {
-                result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);
+                result.setRuleApplicationStatus(RuleApplicationStatus.FEASIBLE);
             }
         }
@@ -156,6 +159,8 @@
         taskTreeBuilder.setChild(iteration, selection);
 
+        List<ITaskTreeNode> children = parent.getChildren();
+        
         for (int i = endIndex - startIndex; i >= 0; i--) {
-            addChildIfNecessary(selection, parent.getChildren().get(startIndex), result);
+            addChildIfNecessary(selection, children.get(startIndex), result);
             taskTreeBuilder.removeChild((ISequence) parent, startIndex);
         }
@@ -163,5 +168,5 @@
         taskTreeBuilder.addChild((ISequence) parent, startIndex, iteration);
 
-        result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);
+        result.setRuleApplicationStatus(RuleApplicationStatus.FINISHED);
     }
 
@@ -173,10 +178,11 @@
                                      RuleApplicationResult result)
     {
-        for (int i = 0; i < parentSelection.getChildren().size(); i++) {
-            ITaskTreeNode child = parentSelection.getChildren().get(i);
+        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
-            NodeEquality nodeEquality = nodeEqualityRuleManager.applyRules(child, node);
-            if (nodeEquality.isAtLeast(NodeEquality.SYNTACTICALLY_EQUAL)) {
+            if (nodeEqualityRuleManager.areSyntacticallyEqual(child, node)) {
                 return;
             }
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 1126)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TreeScopeWrapperRule.java	(revision 1127)
@@ -14,4 +14,6 @@
 
 package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
+
+import java.util.List;
 
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
@@ -69,6 +71,7 @@
             result = new RuleApplicationResult();
             
-            if (parent.getChildren() != null) {
-                for (ITaskTreeNode child : parent.getChildren()) {
+            List<ITaskTreeNode> children = parent.getChildren();
+            if (children != null) {
+                for (ITaskTreeNode child : children) {
                     merge(result, apply(child, finalize));
                 }
@@ -97,7 +100,7 @@
         RuleApplicationStatus intermediateStatus = intermediate.getRuleApplicationStatus();
         
-        if ((intermediateStatus == RuleApplicationStatus.RULE_APPLICATION_FINISHED) ||
-            ((intermediateStatus == RuleApplicationStatus.RULE_APPLICATION_FEASIBLE) &&
-             (overallStatus == RuleApplicationStatus.RULE_NOT_APPLIED)))
+        if ((intermediateStatus == RuleApplicationStatus.FINISHED) ||
+            ((intermediateStatus == RuleApplicationStatus.FEASIBLE) &&
+             (overallStatus == RuleApplicationStatus.NOT_APPLIED)))
         {
             overallResult.setRuleApplicationStatus(intermediateStatus);
