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 986)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiElementSequenceDetectionRule.java	(revision 987)
@@ -12,8 +12,8 @@
 
 /**
- * This rule generates sequences depending on a GUI model. All actions occurring on the same GUI
- * element are put together in a sequence. All sequences and actions within a common panel are also
- * put together to a sequence. Through this, an event sequence gets a logical structure and shows,
- * which interactions that happen together also happen in the same GUI context.
+ * 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$
@@ -21,4 +21,33 @@
  */
 public class DefaultGuiElementSequenceDetectionRule implements TemporalRelationshipRule {
+
+    /**
+     * <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 without a GUI element filter
+     * </p>
+     */
+    DefaultGuiElementSequenceDetectionRule() {
+        this.guiElementFilter = null;
+    }
+
+    /**
+     * <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
+     */
+    DefaultGuiElementSequenceDetectionRule(List<Class<? extends IGUIElement>> guiElementFilter) {
+        this.guiElementFilter = guiElementFilter;
+    }
 
     /*
@@ -39,200 +68,220 @@
 
         RuleApplicationResult result = new RuleApplicationResult();
-        
-        IGUIElement lastGuiElement = null;
+        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;
+        if (initialHierarchyLevel < maxHierarchyDepth) {
+            status = generateSubSequences(parent, hierarchies, initialHierarchyLevel, finalize,
+                                          builder, nodeFactory, result);
+        }
+        else {
+            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 builder           the builder to use for generating the tree structure
+     * @param nodeFactory       the node factory to use for generating the tree structure
+     * @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,
+                                                       ITaskTreeBuilder        builder,
+                                                       ITaskTreeNodeFactory    nodeFactory,
+                                                       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()) {
-            ITaskTreeNode child = parent.getChildren().get(index);
-            IGUIElement currentGuiElement = getGUIElement(child);
-            if ((index > 0) && (!lastGuiElement.equals(currentGuiElement))) {
-                ReducableCommonDenominator commonDenominator =
-                    getNextReducableCommonDenominator(parent, index - 1);
-                    
-                if (commonDenominator != null) {
-                    // condense only if not all children would be condensed or if we can be sure,
-                    // that there will be no further child that should be included in the condensed
-                    // sequence
-                    if ((commonDenominator.noOfTasks < parent.getChildren().size()) &&
-                        (!isOnGuiElementPath(commonDenominator.commonGuiElement, currentGuiElement)))
-                    {
-                        condenseTasksToSequence(parent, index, commonDenominator.noOfTasks,
-                                                builder, nodeFactory, result);
-
-                        result.setRuleApplicationStatus
-                            (RuleApplicationStatus.RULE_APPLICATION_FINISHED);
-                        return result;
-                    }
-                    else {
-                        // the common denominator is on the parent path of the next GUI element.
-                        // Therefore, the current sequences is not finished yet. So break up.
-                        result.setRuleApplicationStatus
-                            (RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);
-                    }
-                }
-            }
-
-            lastGuiElement = currentGuiElement;
+            hierarchy = hierarchies.get(index);
+
+            exceedingGuiHierarchyDepth = hierarchyLevel >= hierarchy.size();
+            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, builder, nodeFactory, 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++;
         }
 
-        ReducableCommonDenominator commonDenominator =
-            getNextReducableCommonDenominator(parent, parent.getChildren().size() - 1);
-        
-        if ((commonDenominator != null) &&
-            (commonDenominator.noOfTasks < parent.getChildren().size()))
-        {
-            if (finalize) {
-                condenseTasksToSequence
-                    (parent, index, commonDenominator.noOfTasks, builder, nodeFactory, result);
+        if (finalize) {
+            if (subsequenceHasStarted) {
+                status = condenseSequence
+                    (parent, hierarchies, hierarchyLevel, startingIndex,
+                     parent.getChildren().size() - 1, builder, nodeFactory, 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 builder        the builder to use for generating the tree structure
+     * @param nodeFactory    the node factory to use for generating the tree structure
+     * @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,
+                                                   ITaskTreeBuilder        builder,
+                                                   ITaskTreeNodeFactory    nodeFactory,
+                                                   RuleApplicationResult   result)
+    {
+        boolean onlyASingleChildToReduce = (endIndex - startIndex) == 0;
+        boolean singleChildIsSequence = onlyASingleChildToReduce &&
+            parent.getChildren().get(startIndex) instanceof ISequence;
+
+        if (!onlyASingleChildToReduce || !singleChildIsSequence) {
+            ISequence sequence = nodeFactory.createNewSequence();
+            
+            List<List<IGUIElement>> subHierarchies = new ArrayList<List<IGUIElement>>();
+            List<IGUIElement> newHierarchy =
+                hierarchies.get(startIndex).subList(0, hierarchyLevel + 1);
+            builder.setDescription(sequence, "interactions on " +
+                                   newHierarchy.get(newHierarchy.size() - 1).getStringIdentifier());
+
+            for (int i = startIndex; i <= endIndex; i++) {
+                builder.addChild(sequence, parent.getChildren().get(startIndex));
+                builder.removeChild((ISequence) parent, startIndex);
                 
-                result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);
-                
-                return result;
-            }
-            else {
-                result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE);
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param guiElement
-     * @param detectedTasks
-     * @param parent
-     * @param index
-     * @param builder
-     * @param nodeFactory
-     * @return
-     */
-    private void condenseTasksToSequence(ITaskTreeNode         parent,
-                                         int                   parentIndex,
-                                         int                   noOfTasks,
-                                         ITaskTreeBuilder      builder,
-                                         ITaskTreeNodeFactory  nodeFactory,
-                                         RuleApplicationResult result)
-    {
-        ISequence newSequence = nodeFactory.createNewSequence();
-        for (int i = 0; i < noOfTasks; i++) {
-            builder.addChild(newSequence, parent.getChildren().get(parentIndex - noOfTasks));
-            // remove exactly the same number of children from the parent.
-            builder.removeChild((ISequence) parent, parentIndex - noOfTasks);
-        }
-                
-        builder.addChild((ISequence) parent, parentIndex - noOfTasks, newSequence);
-        result.addNewlyCreatedParentNode(newSequence);
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param detectedTasks
-     * @return
-     */
-    private ReducableCommonDenominator getNextReducableCommonDenominator(ITaskTreeNode parent,
-                                                                         int           childIndex)
-    {
-        ReducableCommonDenominator commonDenominator = null;
-        
-        // a common denominator can only exist for at least two task tree nodes
-        if (childIndex > 0) {
-            // start with the last one
-            int pos = childIndex;
-
-            commonDenominator = new ReducableCommonDenominator();
-            
-            // check for further predecessors, if they match the same common denominator
-            IGUIElement currentCommonDenominator = null;
-            do {
-                if (--pos < 0) {
-                    currentCommonDenominator = null;
-                }
-                else {
-                    currentCommonDenominator = getCommonDenominator
-                        (getGUIElement(parent.getChildren().get(pos)),
-                         getGUIElement(parent.getChildren().get(pos + 1)));
-                }
-                
-                if (commonDenominator.commonGuiElement == null) {
-                    commonDenominator.commonGuiElement = currentCommonDenominator;
-                }
-            }
-            while ((commonDenominator.commonGuiElement != null) &&
-                   (commonDenominator.commonGuiElement.equals(currentCommonDenominator)));
-            
-            if (commonDenominator.commonGuiElement != null) {
-                // pos points to the last element, that has not the same common denominator.
-                // This one must be subtracted from the task number as well
-                commonDenominator.noOfTasks = childIndex - pos;
-            }
-            else {
-                commonDenominator = null;
-            }
-        }
-        
-        return commonDenominator;
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param child
-     * @return
-     */
-    private IGUIElement getGUIElement(ITaskTreeNode node) {
-        List<IGUIElement> terminalGUIElements = new ArrayList<IGUIElement>();
-        getTerminalGUIElements(node, terminalGUIElements);
-        return getCommonDenominator(terminalGUIElements);
-    }
-        
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param detectedTaskGroups
-     * @return
-     */
-    /*private IGUIElement getCommonDenominator(Stack<Task> detectedTasks, int start) {
-        List<IGUIElement> allGUIElements = new ArrayList<IGUIElement>();
-        
-        for (int i = start; i < detectedTasks.size(); i++) {
-            allGUIElements.add(detectedTasks.get(i).commonGuiElement);
-        }
-        
-        return getCommonDenominator(allGUIElements);
-    }*/
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param child
-     * @return
-     */
-    private IGUIElement getCommonDenominator(IGUIElement guiElement1, IGUIElement guiElement2) {
-        List<IGUIElement> allGUIElements = new ArrayList<IGUIElement>();
-        allGUIElements.add(guiElement1);
-        allGUIElements.add(guiElement2);
-        return getCommonDenominator(allGUIElements);
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param child
-     * @return
+                subHierarchies.add(hierarchies.remove(startIndex));
+            }
+
+            builder.addChild((ISequence) parent, startIndex, sequence);
+            
+            hierarchies.add(startIndex, newHierarchy);
+            
+            generateSubSequences
+                (sequence, subHierarchies, hierarchyLevel + 1, true, builder, nodeFactory, 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) {
@@ -245,6 +294,12 @@
             IGUIElement guiElement = guiElements.get(0);
             while (guiElement != null) {
-                commonDenominatorPath.add(0, guiElement);
+                if (guiElementMatchesConsideredTypes(guiElement)) {
+                    commonDenominatorPath.add(0, guiElement);
+                }
                 guiElement = guiElement.getParent();
+            }
+            
+            if (commonDenominatorPath.size() == 0) {
+                return null;
             }
             
@@ -257,5 +312,7 @@
                 guiElement = guiElements.get(i);
                 while (guiElement != null) {
-                    currentPath.add(0, guiElement);
+                    if (guiElementMatchesConsideredTypes(guiElement)) {
+                        currentPath.add(0, guiElement);
+                    }
                     guiElement = guiElement.getParent();
                 }
@@ -285,64 +342,111 @@
     /**
      * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param child
-     * @return
-     */
-    private void getTerminalGUIElements(ITaskTreeNode node, List<IGUIElement> terminalGUIElements) {
+     * 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) {
-                terminalGUIElements.add((IGUIElement) ((IEventTask) node).getEventTarget());
+                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>
-     * TODO: comment
-     * </p>
-     *
-     * @param currentCommonDenominator
-     * @param guiElement
-     * @return
-     */
-    private boolean isOnGuiElementPath(IGUIElement potentialPathElement, IGUIElement child) {
-        IGUIElement guiElement = child;
-        
-        while (guiElement != null) {
-            if (guiElement.equals(potentialPathElement)) {
-                return true;
-            }
-            guiElement = guiElement.getParent();
-        }
-        
-        return false;
-    }
-
-    /**
-     * 
-     */
-    private static class ReducableCommonDenominator {
-        
-        /** the GUI element being the common denominator */
-        private IGUIElement commonGuiElement;
-        
-        /** the number of tasks that match the common denominator */
-        private int noOfTasks;
-
-        /* (non-Javadoc)
-         * @see java.lang.Object#toString()
-         */
-        @Override
-        public String toString() {
-            return noOfTasks + " tasks on " + commonGuiElement;
-        }
-        
-    }
+                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/DefaultGuiElementSequenceDetectionRuleBad.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiElementSequenceDetectionRuleBad.java	(revision 987)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiElementSequenceDetectionRuleBad.java	(revision 987)
@@ -0,0 +1,651 @@
+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;
+
+/**
+ * TODO: comment or delete
+ * 
+ * @version $Revision: $ $Date: 18.03.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class DefaultGuiElementSequenceDetectionRuleBad implements TemporalRelationshipRule {
+
+    /**
+     * 
+     */
+    private List<Class<? extends IGUIElement>> guiElementFilter;
+
+    /**
+     * 
+     */
+    DefaultGuiElementSequenceDetectionRuleBad() {
+        this.guiElementFilter = null;
+    }
+
+    /**
+     * 
+     */
+    DefaultGuiElementSequenceDetectionRuleBad(List<Class<? extends IGUIElement>> guiElementFilter) {
+        this.guiElementFilter = guiElementFilter;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode,
+     * TaskTreeBuilder, TaskTreeNodeFactory)
+     */
+    @Override
+    public RuleApplicationResult apply(ITaskTreeNode        parent,
+                                       ITaskTreeBuilder     builder,
+                                       ITaskTreeNodeFactory nodeFactory,
+                                       boolean              finalize)
+    {
+        if (!(parent instanceof ISequence)) {
+            return null;
+        }
+
+        List<ITaskTreeNode> children = parent.getChildren();
+        RuleApplicationResult result = new RuleApplicationResult();
+        
+        IGUIElement lastGuiElement = null;
+        int index = 0;
+        while (index <= children.size()) {
+            ITaskTreeNode child = index < children.size() ? children.get(index) : null;
+            IGUIElement currentGuiElement = getGuiElement(child);
+            if ((index > 0) && (!guiElementsEqual(lastGuiElement, currentGuiElement))) {
+                ReducableCommonDenominator commonDenominator =
+                    getNextReducableCommonDenominator(parent, index - 1);
+                
+                RuleApplicationStatus status = handleCommonDenominator
+                    (commonDenominator, parent, index, lastGuiElement, currentGuiElement, builder,
+                     nodeFactory, finalize, result);
+                
+                if (status != null) {
+                    result.setRuleApplicationStatus(status);
+                    return result;
+                }
+                // else go on
+            }
+
+            lastGuiElement = currentGuiElement;
+            index++;
+        }
+
+        return result;
+    }
+
+    /**
+     * 
+     */
+    private ReducableCommonDenominator getNextReducableCommonDenominator(ITaskTreeNode parent,
+                                                                         int           childIndex)
+    {
+        ReducableCommonDenominator commonDenominator = null;
+        
+        // a common denominator can only exist for at least two task tree nodes
+        if (childIndex > 0) {
+            // start with the last one
+            int pos = childIndex;
+
+            commonDenominator = new ReducableCommonDenominator();
+            
+            // check for further predecessors, if they match the same common denominator
+            IGUIElement currentCommonDenominator = null;
+            do {
+                if (--pos < 0) {
+                    currentCommonDenominator = null;
+                }
+                else {
+                    currentCommonDenominator = getCommonDenominator
+                        (getGuiElement(parent.getChildren().get(pos)),
+                         getGuiElement(parent.getChildren().get(pos + 1)));
+                }
+                
+                if (commonDenominator.commonGuiElement == null) {
+                    commonDenominator.commonGuiElement = currentCommonDenominator;
+                }
+            }
+            while ((commonDenominator.commonGuiElement != null) &&
+                   (commonDenominator.commonGuiElement.equals(currentCommonDenominator)));
+            
+            if (commonDenominator.commonGuiElement != null) {
+                // pos points to the last element, that has not the same common denominator.
+                // This one must be subtracted from the task number as well
+                commonDenominator.noOfTasks = childIndex - pos;
+            }
+            else {
+                commonDenominator = null;
+            }
+        }
+        
+        return commonDenominator;
+    }
+
+    /**
+     * 
+     */
+    private RuleApplicationStatus handleCommonDenominator(ReducableCommonDenominator commonDenominator,
+                                                          ITaskTreeNode              parent,
+                                                          int                        currentIndex,
+                                                          IGUIElement                lastGuiElement,
+                                                          IGUIElement                currentGuiElement,
+                                                          ITaskTreeBuilder           builder,
+                                                          ITaskTreeNodeFactory       nodeFactory,
+                                                          boolean                    finalize,
+                                                          RuleApplicationResult      result)
+    {
+        List<ITaskTreeNode> children = parent.getChildren();
+        
+        boolean sequenceHasOnlyOneChild = children.size() == 1;
+        boolean reachedEndOfSequence = currentIndex == children.size();
+        boolean haveCommonDenominator = commonDenominator != null;
+        boolean allChildrenShareDenominator =
+            haveCommonDenominator && commonDenominator.noOfTasks == children.size();
+        boolean nextChildSharesDenominator =
+            haveCommonDenominator && !reachedEndOfSequence &&
+            isOnGuiElementPath(commonDenominator.commonGuiElement, currentGuiElement);
+        
+        IGUIElement denominatorOfPreviousAndCurrentChild =
+            !reachedEndOfSequence ? getCommonDenominator(lastGuiElement, currentGuiElement) : null;
+        
+        boolean previousAndCurrentChildHaveDenominator =
+            denominatorOfPreviousAndCurrentChild != null;
+
+        if (haveCommonDenominator) {
+            if (!reachedEndOfSequence) {
+                if (nextChildSharesDenominator) {
+                    // the last child, although matching the identified common denominator, may
+                    // stand on its own because it is even deeper in the hierarchy, than the
+                    // common denominator as well as the common denominator with the next child.
+                    // So there need to appropriate subsequences to distinguish the child from
+                    // the hierarchy of the next one.
+                    if (isOnGuiElementPath(denominatorOfPreviousAndCurrentChild, lastGuiElement)) {
+                        return condenseChildToSequencesRepresentingHierarchy
+                            (parent, lastGuiElement, denominatorOfPreviousAndCurrentChild,
+                             currentIndex - 1, builder, nodeFactory, result);
+                    }
+                    else {
+                        // go on
+                        return null;
+                    }
+                }
+                else {
+                    condenseTasksToSequencesRepresentingHierarchy
+                        (commonDenominator.commonGuiElement, currentGuiElement, parent,
+                         currentIndex, commonDenominator.noOfTasks, builder, nodeFactory, result);
+
+                    return RuleApplicationStatus.RULE_APPLICATION_FINISHED;
+                }
+            }
+            else {
+                // end of sequence is reached and denominator is found
+                if (!allChildrenShareDenominator) {
+                    condenseTasksToSequencesRepresentingHierarchy
+                        (commonDenominator.commonGuiElement, currentGuiElement, parent,
+                         currentIndex, commonDenominator.noOfTasks, builder, nodeFactory, result);
+
+                    return RuleApplicationStatus.RULE_APPLICATION_FINISHED;
+                }
+                else {
+                    // all children share denominator
+                    if (finalize) {
+                        if (ensureSequencesRepresentingHierarchy
+                                (parent, commonDenominator.commonGuiElement,
+                                 builder, nodeFactory, result))
+                        {
+                            return RuleApplicationStatus.RULE_APPLICATION_FINISHED;
+                        }
+                        else {
+                            return condenseChildToSequencesRepresentingHierarchy
+                                (parent, lastGuiElement, getGuiElement(parent), currentIndex - 1,
+                                 builder, nodeFactory, result);
+                        }
+                    }
+                    else {
+                        return RuleApplicationStatus.RULE_APPLICATION_FEASIBLE;
+                    }
+                }
+            }
+        }
+        else {
+            // no common denominator found
+            if (!reachedEndOfSequence) {
+                if (previousAndCurrentChildHaveDenominator) {
+                    // go on
+                    return null;
+                }
+                else {
+                    return condenseChildToSequencesRepresentingHierarchy
+                        (parent, lastGuiElement, getGuiElement(parent), currentIndex - 1,
+                         builder, nodeFactory, result);
+                }
+            }
+            else {
+                // last child has its own GUI hierarchy
+                if (sequenceHasOnlyOneChild) {
+                    if (finalize) {
+                        if (ensureSequencesRepresentingHierarchy
+                                (parent, lastGuiElement, builder, nodeFactory, result))
+                        {
+                            return RuleApplicationStatus.RULE_APPLICATION_FINISHED;
+                        }
+                        else {
+                            return RuleApplicationStatus.RULE_NOT_APPLIED;
+                        }
+                    }
+                    else {
+                        return RuleApplicationStatus.RULE_APPLICATION_FEASIBLE;
+                    }
+                }
+                else {
+                    if (finalize) {
+                        return condenseChildToSequencesRepresentingHierarchy
+                            (parent, lastGuiElement, getGuiElement(parent), currentIndex - 1,
+                             builder, nodeFactory, result);
+                    }
+                    else {
+                        return RuleApplicationStatus.RULE_APPLICATION_FEASIBLE;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 
+     */
+    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;
+    }
+
+    /**
+     * 
+     */
+    private IGUIElement getCommonDenominator(IGUIElement guiElement1, IGUIElement guiElement2) {
+        if ((guiElement1 == null) || (guiElement2 == null)) {
+            return null;
+        }
+    
+        List<IGUIElement> allGuiElements = new ArrayList<IGUIElement>();
+        allGuiElements.add(guiElement1);
+        allGuiElements.add(guiElement2);
+        return getCommonDenominator(allGuiElements);
+    }
+
+    /**
+     * 
+     */
+    private void condenseTasksToSequencesRepresentingHierarchy(IGUIElement           lastGuiElement,
+                                                               IGUIElement           currentGuiElement,
+                                                               ITaskTreeNode         parent,
+                                                               int                   parentIndex,
+                                                               int                   noOfTasks,
+                                                               ITaskTreeBuilder      builder,
+                                                               ITaskTreeNodeFactory  nodeFactory,
+                                                               RuleApplicationResult result)
+    {
+        List<IGUIElement> lastHierarchy = getGuiElementHierarchy(lastGuiElement);
+        List<IGUIElement> currentHierarchy = getGuiElementHierarchy(currentGuiElement);
+        int index = parentIndex;
+        
+        ITaskTreeNode generatedSequence = parent;
+        
+        for (int i = 0; i < lastHierarchy.size(); i++) {
+            // add sequence for each element in the previous hierarchy, that does not occur in the
+            // current hierarchy
+            if ((currentHierarchy == null) || (i >= currentHierarchy.size()) ||
+                (!currentHierarchy.get(i).equals(lastHierarchy.get(i))))
+            {
+                condenseTasksToSequence(generatedSequence, lastHierarchy.get(i), index,
+                                        noOfTasks, builder, nodeFactory, result);
+                
+                // only in the first iteration, we condense tasks in the parent. Afterwards,
+                // we always condense all tasks in the created sequence to a new subsequence.
+                // Therefore, adapt all indexes appropriately
+                generatedSequence = generatedSequence.getChildren().get(index - noOfTasks);
+                index = noOfTasks;
+            }
+        }
+    }
+
+    /**
+     * 
+     */
+    private boolean ensureSequencesRepresentingHierarchy(ITaskTreeNode         parent,
+                                                         IGUIElement           elementToRepresent,
+                                                         ITaskTreeBuilder      builder,
+                                                         ITaskTreeNodeFactory  nodeFactory,
+                                                         RuleApplicationResult result)
+    {
+        boolean applied = false;
+        IGUIElement currentlyConsideredElement = elementToRepresent;
+        IGUIElement elementRepresentedByParent = getGuiElement(parent);
+
+        while ((currentlyConsideredElement != null) &&
+               (!currentlyConsideredElement.equals(elementRepresentedByParent)))
+        {
+            condenseTasksToSequence(parent, currentlyConsideredElement, parent.getChildren().size(),
+                                    parent.getChildren().size(), builder, nodeFactory, result);
+            applied = true;
+            currentlyConsideredElement = currentlyConsideredElement.getParent();
+        }
+        
+        if (currentlyConsideredElement != null) {
+            applied |= updateDescription(parent, currentlyConsideredElement, builder);
+        }
+        
+        return applied;
+    }
+
+    /**
+     * 
+     */
+    private RuleApplicationStatus condenseChildToSequencesRepresentingHierarchy(ITaskTreeNode         parent,
+                                                                                IGUIElement           childGuiElement,
+                                                                                IGUIElement           parentGuiElement,
+                                                                                int                   childIndex,
+                                                                                ITaskTreeBuilder      builder,
+                                                                                ITaskTreeNodeFactory  nodeFactory,
+                                                                                RuleApplicationResult result)
+    {
+        ITaskTreeNode child = parent.getChildren().get(childIndex);
+        boolean childIsSequence = child instanceof ISequence;
+        boolean childHasGuiElement = childGuiElement != null;
+        
+        if (childIsSequence) {
+            if (childHasGuiElement) {
+                if (updateDescription(child, childGuiElement, builder)) {
+                    return RuleApplicationStatus.RULE_APPLICATION_FINISHED;
+                }
+            }
+        }
+        else {
+            boolean applied = false;
+            IGUIElement currentlyConsideredElement = childGuiElement;
+
+            while ((currentlyConsideredElement != null) &&
+                   (!currentlyConsideredElement.equals(parentGuiElement)))
+            {
+                condenseTasksToSequence(parent, currentlyConsideredElement, childIndex + 1, 1,
+                                        builder, nodeFactory, result);
+                applied = true;
+                currentlyConsideredElement = currentlyConsideredElement.getParent();
+            }
+            
+            if (currentlyConsideredElement != null) {
+                IGUIElement parentCommonDenominator = getGuiElement(parent);
+                if (currentlyConsideredElement.equals(parentCommonDenominator)) {
+                    applied |= updateDescription(parent, currentlyConsideredElement, builder);
+                }
+            }
+
+            if (applied) {
+                return RuleApplicationStatus.RULE_APPLICATION_FINISHED;
+            }
+        }
+        
+        return null;
+    }
+
+    /**
+     * <p>
+     * condensed a subsequence of the children of the provided parent to a sequence. The
+     * subsequence in the list of children defined by the index of the succeeding child
+     * (parentIndex) and the number of tasks to be condensed (noOfTasks).
+     * </p>
+     *
+     * @param parent      the parent node whose children are to be condensed
+     * @param target      the GUI element in which all condensed interactions take place
+     * @param parentIndex the index of the child in the parent, which follows the children
+     *                    to be condensed
+     * @param noOfTasks   the number of children to be condensed
+     * @param builder     the builder to create the new subsequence
+     * @param nodeFactory the node factory to instantiate the new subsequence
+     * @param result      the result of the rule application to store newly created parent nodes
+     */
+    private void condenseTasksToSequence(ITaskTreeNode         parent,
+                                         IGUIElement           target,          
+                                         int                   parentIndex,
+                                         int                   noOfTasks,
+                                         ITaskTreeBuilder      builder,
+                                         ITaskTreeNodeFactory  nodeFactory,
+                                         RuleApplicationResult result)
+    {
+        ISequence newSequence = nodeFactory.createNewSequence();
+        updateDescription(newSequence, target, builder);
+        
+        for (int i = 0; i < noOfTasks; i++) {
+            builder.addChild(newSequence, parent.getChildren().get(parentIndex - noOfTasks));
+            // remove exactly the same number of children from the parent.
+            builder.removeChild((ISequence) parent, parentIndex - noOfTasks);
+        }
+                
+        builder.addChild((ISequence) parent, parentIndex - noOfTasks, newSequence);
+        result.addNewlyCreatedParentNode(newSequence);
+    }
+
+    /**
+     * 
+     */
+    private boolean updateDescription(ITaskTreeNode    node,
+                                      IGUIElement      commonGuiElement,
+                                      ITaskTreeBuilder builder)
+    {
+        String newDescription = "interactions on " + commonGuiElement.getStringIdentifier();
+
+        String currentDescription = node.getDescription();
+        
+        if ((currentDescription == null) || (currentDescription.indexOf(newDescription) == -1)) {
+            if ((currentDescription != null) && (!"".equals(currentDescription))) {
+                newDescription = currentDescription + "; " + newDescription;
+            }
+            
+            builder.setDescription(node, newDescription);
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    /**
+     * 
+     */
+    private IGUIElement getGuiElement(ITaskTreeNode node) {
+        if (node != null) {
+            List<IGUIElement> terminalGuiElements = new ArrayList<IGUIElement>();
+            getTerminalGuiElements(node, terminalGuiElements);
+            return getCommonDenominator(terminalGuiElements);
+        }
+        else {
+            return null;
+        }
+    }
+        
+    /**
+     * 
+     */
+    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);
+            }
+        }
+    }
+
+    /**
+     * 
+     */
+    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;
+        }
+    }
+
+    /**
+     * 
+     */
+    private IGUIElement searchHierarchyForGuiElementWithConsideredType(IGUIElement guiElement) {
+        IGUIElement returnValue = guiElement;
+        
+        while ((returnValue != null) && !guiElementMatchesConsideredTypes(returnValue)) {
+            returnValue = returnValue.getParent();
+        }
+        
+        return returnValue;
+    }
+
+    /**
+     * 
+     */
+    private boolean guiElementsEqual(IGUIElement guiElement1, IGUIElement guiElement2) {
+        if (guiElement1 == null) {
+            return guiElement2 == null;
+        }
+        else {
+            return guiElement1.equals(guiElement2);
+        }
+    }
+
+    /**
+     * 
+     */
+    private boolean isOnGuiElementPath(IGUIElement potentialPathElement, IGUIElement child) {
+        IGUIElement guiElement = child;
+        
+        while (guiElement != null) {
+            if (guiElement.equals(potentialPathElement)) {
+                return true;
+            }
+            guiElement = guiElement.getParent();
+        }
+        
+        return false;
+    }
+
+    /**
+     * 
+     */
+    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;
+        }
+    }
+
+    /**
+     * 
+     */
+    static class ReducableCommonDenominator {
+        
+        /** the GUI element being the common denominator */
+        IGUIElement commonGuiElement;
+        
+        /** the number of tasks that match the common denominator */
+        int noOfTasks;
+
+        /* (non-Javadoc)
+         * @see java.lang.Object#toString()
+         */
+        @Override
+        public String toString() {
+            return noOfTasks + " tasks on " + commonGuiElement;
+        }
+        
+    }
+}
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 986)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/DefaultGuiEventSequenceDetectionRule.java	(revision 987)
@@ -98,4 +98,8 @@
 
                             result.addNewlyCreatedParentNode(sequence);
+                            
+                            builder.setDescription
+                                (sequence, "logical sequence started by the first event");
+                            
                             result.setRuleApplicationStatus
                                 (RuleApplicationStatus.RULE_APPLICATION_FINISHED);
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 986)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java	(revision 987)
@@ -5,4 +5,7 @@
 import java.util.logging.Level;
 
+import de.ugoe.cs.autoquest.eventcore.guimodel.IDialog;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IFrame;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality;
 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager;
@@ -100,8 +103,14 @@
      */
     public void init() {
+        List<Class<? extends IGUIElement>> frameFilter =
+            new ArrayList<Class<? extends IGUIElement>>();
+        frameFilter.add(IFrame.class);
+        frameFilter.add(IDialog.class);
+
+        rules.add(new DefaultGuiElementSequenceDetectionRule(frameFilter));
         rules.add(new DefaultGuiElementSequenceDetectionRule());
         rules.add(new DefaultEventTargetSequenceDetectionRule());
         rules.add(new TrackBarSelectionDetectionRule(nodeEqualityRuleManager));
-        rules.add(new DefaultGuiEventSequenceDetectionRule());
+        //rules.add(new DefaultGuiEventSequenceDetectionRule());
         
         rules.add(new DefaultIterationDetectionRule
@@ -153,5 +162,5 @@
      * @param finalize     used to indicate, if the rule application shall break up if a rule would
      *                     be feasible if further data was available, or not.
-     * @param logIndent    simply used for loggin purposes to indent the log messages depending
+     * @param logIndent    simply used for logging purposes to indent the log messages depending
      *                     on the recursion depth of calling this method.
      */
@@ -169,5 +178,5 @@
             RuleApplicationResult result;
             do {
-                // LOG.info(logIndent + "trying to apply rule " + rule + " on " + parent);
+                Console.traceln(Level.FINER, logIndent + "trying rule " + rule + " on " + parent);
                 result = rule.apply(parent, builder, nodeFactory, finalize);
 
@@ -179,4 +188,6 @@
                         (Level.FINE, logIndent + "applied rule " + rule + " on " + parent);
                     noOfRuleApplications++;
+                    
+                    dumpTask(parent, "");
 
                     for (ITaskTreeNode newParent : result.getNewlyCreatedParentNodes()) {
@@ -211,11 +222,22 @@
      *
      */
-    /*
-     * private void dumpTask(TaskTreeNode task, String indent) { System.err.print(indent);
-     * System.err.print(task); System.err.println(" ");
-     * 
-     * if ((task.getChildren() != null) && (task.getChildren().size() > 0)) { for (TaskTreeNode
-     * child : task.getChildren()) { dumpTask(child, indent + "  "); } } }
-     */
+    private void dumpTask(ITaskTreeNode task, String indent) {
+        StringBuffer message = new StringBuffer();
+        message.append(indent);
+        message.append(task);
+        if (task.getDescription() != null) {
+            message.append('(');
+            message.append(task.getDescription());
+            message.append(')');
+        }
+        
+        Console.traceln(Level.FINER, message.toString());
+        
+        if ((task.getChildren() != null) && (task.getChildren().size() > 0)) {
+            for (ITaskTreeNode child : task.getChildren()) {
+                dumpTask(child, indent + "  ");
+            }
+        }
+    }
 
 }
