Index: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/CondenseSimilarTasksRule.java
===================================================================
--- trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/CondenseSimilarTasksRule.java	(revision 1970)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/CondenseSimilarTasksRule.java	(revision 1971)
@@ -27,4 +27,5 @@
 import de.ugoe.cs.autoquest.tasktrees.temporalrelation.utils.SimilarTasks;
 import de.ugoe.cs.autoquest.tasktrees.temporalrelation.utils.TaskTraversal;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance;
@@ -225,4 +226,5 @@
             }
             
+            harmonizeMarkingTemporalRelationships(sessions);
         }
         while (appData.getMostSimilarTasks() != null);
@@ -268,4 +270,145 @@
         
         return appData.finalizeRuleApplicationResult();
+    }
+
+    /**
+     *
+     */
+    private void harmonizeMarkingTemporalRelationships(List<IUserSession> sessions) {
+        final Map<ITask, IIteration> harmonizedIterations = new HashMap<>();
+        final Map<ITask, IOptional> harmonizedOptionals = new HashMap<>();
+        
+        for (IUserSession session : sessions) {
+            for (ITaskInstance instance : session) {
+                instance.accept(new DefaultTaskInstanceTraversingVisitor() {
+                    
+                    @Override
+                    public void visit(IIterationInstance iterationInstance) {
+                        // visit the children
+                        super.visit(iterationInstance);
+                        
+                        // there may have been a model update at the children. If so, set the
+                        // new marked task
+                        IIteration iteration = iterationInstance.getIteration();
+                        ITask newChildTask = iterationInstance.get(0).getTask();
+                        
+                        if (newChildTask != iteration.getMarkedTask()) {
+                            taskBuilder.setMarkedTask(iteration, newChildTask);
+                        }
+                        
+                        // check, if there is a harmonized iteration
+                        IIteration harmonizedIteration =
+                            harmonizedIterations.get(iteration.getMarkedTask());
+                        
+                        if ((harmonizedIteration != null) && (iteration != harmonizedIteration)) {
+                            // there is a harmonized iteration --> set it as new task
+                            /*System.out.println("harmonizing iteration of " +
+                                               iteration.getMarkedTask() + " from " + iteration +
+                                               " to " + harmonizedIteration);*/
+                            taskBuilder.setTask(iterationInstance, harmonizedIteration);
+                        }
+                        else if (harmonizedIteration == null) {
+                            // remember this iteration as the harmonized one
+                            harmonizedIterations.put(iteration.getMarkedTask(), iteration);
+                        }
+                    }
+                    
+                    @Override
+                    public void visit(IOptionalInstance optionalInstance) {
+                        // visit the children
+                        super.visit(optionalInstance);
+                        
+                        if (optionalInstance.getChild() == null) {
+                            return;
+                        }
+                        
+                        // there may have been a model update at the child. If so, set the
+                        // new marked task
+                        IOptional optional = optionalInstance.getOptional();
+                        ITask newChildTask = optionalInstance.getChild().getTask();
+                        
+                        if (newChildTask != optional.getMarkedTask()) {
+                            taskBuilder.setMarkedTask(optional, newChildTask);
+                        }
+                        
+                        // check, if there is a harmonized optional
+                        IOptional harmonizedOptional =
+                            harmonizedOptionals.get(optional.getMarkedTask());
+                        
+                        if ((harmonizedOptional != null) && (optional != harmonizedOptional)) {
+                            // there is a harmonized optional --> set it as new task
+                            /*System.out.println("harmonizing optional of " +
+                                               optional.getMarkedTask() + " from " + optional +
+                                               " to " + harmonizedOptional);*/
+                            taskBuilder.setTask(optionalInstance, harmonizedOptional);
+                        }
+                        else if (harmonizedOptional == null) {
+                            // remember this optional as the harmonized one
+                            harmonizedOptionals.put(optional.getMarkedTask(), optional);
+                        }
+                    }
+
+                    @Override
+                    public void visit(ISelectionInstance selectionInstance) {
+                        ITask childTaskBeforeUpdate = selectionInstance.getChild().getTask();
+                        
+                        super.visit(selectionInstance);
+                        
+                        ITask childTaskAfterUpdate = selectionInstance.getChild().getTask();
+                        
+                        if (childTaskBeforeUpdate != childTaskAfterUpdate) {
+                            // update the selection model if required.
+                            ISelection selection = selectionInstance.getSelection();
+                            
+                            boolean foundOtherInstanceWithOldChild = false;
+                            
+                            for (ITaskInstance instance : selection.getInstances()) {
+                                ITask child = ((ISelectionInstance) instance).getChild().getTask();
+                                
+                                if (child == childTaskBeforeUpdate) {
+                                    foundOtherInstanceWithOldChild = true;
+                                    break;
+                                }
+                            }
+                            
+                            if (!foundOtherInstanceWithOldChild) {
+                                taskBuilder.removeChild(selection, childTaskBeforeUpdate);
+                            }
+                            
+                            // remove and add the child to ensure to have it only once
+                            taskBuilder.removeChild(selection, childTaskAfterUpdate);
+                            taskBuilder.addChild(selection, childTaskAfterUpdate);
+                        }
+                    }
+
+                    @Override
+                    public void visit(ISequenceInstance sequenceInstance) {
+                        ISequence sequence = sequenceInstance.getSequence();
+                        int childIndex = 0;
+                        
+                        for (ITaskInstance child : sequenceInstance) {
+                            child.accept(this);
+                            
+                            ITask newChildTask = child.getTask();
+                            
+                            if (sequence.getChildren().get(childIndex) != newChildTask) {
+                                taskBuilder.setChild(sequenceInstance.getSequence(), childIndex,
+                                                     newChildTask);
+                            }
+                            
+                            childIndex++;
+                        }
+                    }
+                    
+                });
+
+            }
+            
+            // several subsequent instances, which had formerly different tasks, may now have
+            // the same. Hence, they need to be merged. But as everything else would be way too
+            // complex, we only perform the merge, if they occur next to each other on the
+            // same level
+            mergeSubsequentIdenticalMarkingTemporalRelationships(session);
+        }
     }
 
@@ -430,19 +573,7 @@
         // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< TEST IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 
-        // create also replacements for potential parent iterations or optionals
-        IIteration harmonizedIteration = taskFactory.createNewIteration();
-        taskBuilder.setMarkedTask(harmonizedIteration, replacementTask);
-        
-        IOptional harmonizedOptional = taskFactory.createNewOptional();
-        taskBuilder.setMarkedTask(harmonizedOptional, replacementTask);
-        
+
         for (IUserSession session : appData.getSessions()) {
-            replaceTaskInstances(session, replacements, similarTasks,
-                                 harmonizedIteration, harmonizedOptional);
-            
-            // several subsequent instances, which had formerly different tasks, may now have the
-            // same. Hence, they need to be merged. But as everything else would be way too complex,
-            // we only perform the merge, if they occur next to each other on the same level
-            mergeSubsequentIdenticalMarkingTemporalRelationships(session);
+            replaceTaskInstances(session, replacements, similarTasks);
         }
         
@@ -1115,7 +1246,5 @@
     private void replaceTaskInstances(ITaskInstanceList                 taskInstanceList,
                                       Map<ITaskInstance, ITaskInstance> replacements,
-                                      SimilarTasks                      similarTasks,
-                                      IIteration                        harmonizedIteration,
-                                      IOptional                         harmonizedOptional)
+                                      SimilarTasks                      similarTasks)
     {
         for (int i = 0; i < taskInstanceList.size(); i++) {
@@ -1129,4 +1258,8 @@
                     ISequence task = ((ISequenceInstance) taskInstanceList).getSequence();
                     taskBuilder.setChild(task, i, replacement.getTask());
+                }
+                else if (taskInstanceList instanceof IIterationInstance) {
+                    IIteration task = ((IIterationInstance) taskInstanceList).getIteration();
+                    taskBuilder.setMarkedTask(task, replacement.getTask());
                 }
                 
@@ -1138,13 +1271,5 @@
             }
             else {
-                ITask modelUpdate = replaceTaskInstances(childInstance, replacements, similarTasks,
-                                                         harmonizedIteration, harmonizedOptional);
-                
-                if (modelUpdate != null) {
-                    if (taskInstanceList instanceof ISequenceInstance) {
-                        taskBuilder.setChild
-                            (((ISequenceInstance) taskInstanceList).getSequence(), i, modelUpdate);
-                    }
-                }
+                replaceTaskInstances(childInstance, replacements, similarTasks);
             }
         }
@@ -1156,7 +1281,5 @@
     private void replaceTaskInstances(IOptionalInstance                 optionalInstance,
                                       Map<ITaskInstance, ITaskInstance> replacements,
-                                      SimilarTasks                      similarTasks,
-                                      IIteration                        harmonizedIteration,
-                                      IOptional                         harmonizedOptional)
+                                      SimilarTasks                      similarTasks)
     {
         ITaskInstance childInstance = optionalInstance.getChild();
@@ -1175,10 +1298,5 @@
             }
             else {
-                ITask modelUpdate = replaceTaskInstances(childInstance, replacements, similarTasks,
-                                                         harmonizedIteration, harmonizedOptional);
-                
-                if (modelUpdate != null) {
-                    taskBuilder.setMarkedTask(optionalInstance.getOptional(), modelUpdate);
-                }
+                replaceTaskInstances(childInstance, replacements, similarTasks);
             }
         }
@@ -1190,7 +1308,5 @@
     private void replaceTaskInstances(ISelectionInstance                selectionInstance,
                                       Map<ITaskInstance, ITaskInstance> replacements,
-                                      SimilarTasks                      similarTasks,
-                                      IIteration                        harmonizedIteration,
-                                      IOptional                         harmonizedOptional)
+                                      SimilarTasks                      similarTasks)
     {
         TaskComparator comparator = identTaskHandlStrat.getTaskComparator();
@@ -1237,23 +1353,5 @@
             }
             else {
-                ITask previousChildTask = childInstance.getTask();
-                ITask modelUpdate = replaceTaskInstances(childInstance, replacements, similarTasks,
-                                                         harmonizedIteration, harmonizedOptional);
-                
-                if (modelUpdate != null) {
-                    taskBuilder.removeChild(selectionInstance.getSelection(), previousChildTask);
-
-                    boolean found = false;
-                    for (ITask child : selectionInstance.getSelection().getChildren()) {
-                        if (comparator.equals(child, modelUpdate)) {
-                            found = true;
-                            break;
-                        }
-                    }
-                    
-                    if (!found) {
-                        taskBuilder.addChild(selectionInstance.getSelection(), modelUpdate);
-                    }
-                }
+                replaceTaskInstances(childInstance, replacements, similarTasks);
             }
         }
@@ -1263,48 +1361,20 @@
      *
      */
-    private ITask replaceTaskInstances(ITaskInstance                     childInstance,
-                                       Map<ITaskInstance, ITaskInstance> replacements,
-                                       SimilarTasks                      similarTasks,
-                                       IIteration                        harmonizedIteration,
-                                       IOptional                         harmonizedOptional)
+    private void replaceTaskInstances(ITaskInstance                     childInstance,
+                                      Map<ITaskInstance, ITaskInstance> replacements,
+                                      SimilarTasks                      similarTasks)
     {
-        ITask modelUpdate = null;
-        
         if (childInstance instanceof IIterationInstance) {
-            ITask markedTask = ((IIterationInstance) childInstance).getIteration().getMarkedTask();
-            
-            if ((markedTask == similarTasks.getLeftHandSide()) ||
-                (markedTask == similarTasks.getRightHandSide()))
-            {
-                taskBuilder.setTask(childInstance, harmonizedIteration);
-                modelUpdate = harmonizedIteration;
-            }
-
-            replaceTaskInstances((ITaskInstanceList) childInstance, replacements, similarTasks,
-                                 harmonizedIteration, harmonizedOptional);
+            replaceTaskInstances((ITaskInstanceList) childInstance, replacements, similarTasks);
         }
         else if (childInstance instanceof IOptionalInstance) {
-            ITask markedTask = ((IOptionalInstance) childInstance).getOptional().getMarkedTask();
-            
-            if ((markedTask == similarTasks.getLeftHandSide()) ||
-                (markedTask == similarTasks.getRightHandSide()))
-            {
-                taskBuilder.setTask(childInstance, harmonizedOptional);
-                modelUpdate = harmonizedOptional;
-            }
-            
-            replaceTaskInstances((IOptionalInstance) childInstance, replacements, similarTasks,
-                                 harmonizedIteration, harmonizedOptional);
+            replaceTaskInstances((IOptionalInstance) childInstance, replacements, similarTasks);
         }
         else if (childInstance instanceof ISelectionInstance) {
-            replaceTaskInstances((ISelectionInstance) childInstance, replacements, similarTasks,
-                                 harmonizedIteration, harmonizedOptional);
+            replaceTaskInstances((ISelectionInstance) childInstance, replacements, similarTasks);
         }
         else if (childInstance instanceof ISequenceInstance) {
-            replaceTaskInstances((ITaskInstanceList) childInstance, replacements, similarTasks,
-                                 harmonizedIteration, harmonizedOptional);
-        }
-        
-        return modelUpdate;
+            replaceTaskInstances((ITaskInstanceList) childInstance, replacements, similarTasks);
+        }
     }
 
