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 1975)
+++ trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/CondenseSimilarTasksRule.java	(revision 1976)
@@ -188,7 +188,16 @@
         
         RuleApplicationData appData = new RuleApplicationData(sessions);
+        //int mergecount = 0;
         
         do {
             appData.setTaskModel(taskFactory.createTaskModel(sessions));
+            
+            /*mergecount++;
+            if ((mergecount > 140) && ((mergecount % 20) == 0)) {
+                System.out.println("performing validation " + mergecount);
+                new TaskTreeValidator().validate(appData.getTaskModel().getUserSessions(), true);
+            }*/
+            
+            
             appData.setMostSimilarTasks(null);
             
@@ -319,21 +328,20 @@
                         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);
-                        }
-                        
+
+                        if (optionalInstance.getChild() != null) {
+                            // there may have been a model update at the child. If so, set the
+                            // new marked task
+                            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
@@ -869,5 +877,7 @@
         for (TaskPath path : leftHandSideTraversal.getTraversalPaths()) {
             for (FlattenInstruction instruction : result) {
-                if (instruction.matches(path)) {
+                if ((instruction.getInstruction() != FlattenInstruction.Instruction.INTEGRATE_OPTIONAL) &&
+                    (instruction.matches(path)))
+                {
                     continue OUTER;
                 }
@@ -880,5 +890,7 @@
         for (TaskPath path : rightHandSideTraversal.getTraversalPaths()) {
             for (FlattenInstruction instruction : result) {
-                if (instruction.matches(path)) {
+                if ((instruction.getInstruction() != FlattenInstruction.Instruction.INTEGRATE_OPTIONAL) &&
+                    (instruction.matches(path)))
+                {
                     continue OUTER;
                 }
@@ -982,14 +994,36 @@
                                  List<TaskPath>           previousPaths)
     {
-        boolean instructionApplied = false;
         
         TaskComparator comp = identTaskHandlStrat.getTaskComparator();
         
-        //System.out.println("applying instructions on " + taskPath);
+        // System.out.println("applying integrate optional instructions on " + taskPath);
+        
+        for (FlattenInstruction instruction : flattenInstructions) {
+            if ((instruction.getInstruction() == FlattenInstruction.Instruction.INTEGRATE_OPTIONAL) &&
+                (instruction.matches(taskPath)))
+            {
+                // System.out.print("found instruction ");
+                // instruction.dump(System.out);
+                TaskPath previousPath = previousPaths.size() > 0 ?
+                    previousPaths.get(previousPaths.size() - 1) : null;
+                
+                if (pathsMatch(instruction.getPrecedingPath(), previousPath)) {
+                    IOptional optional = instruction.getOptional();
+                    IOptionalInstance optionalInstance =
+                            taskFactory.createNewTaskInstance(optional);
+                    taskBuilder.addTaskInstance(session, optionalInstance);
+                }
+                
+                break;
+            }
+        }
+        
+        boolean instanceHandled = false;
+        // System.out.println("applying other instructions on " + taskPath);
         
         for (FlattenInstruction instruction : flattenInstructions) {
             if (instruction.matches(taskPath)) {
-                //System.out.print("found instruction ");
-                //instruction.dump(System.out);
+                // System.out.print("found instruction ");
+                // instruction.dump(System.out);
                 
                 switch (instruction.getInstruction()) {
@@ -998,10 +1032,10 @@
                             taskBuilder.addTaskInstance(session, instance);
                         }
-                        instructionApplied = true;
+                        instanceHandled = true;
                         break;
                     }
                     case MAKE_OPTIONAL: {
-                        instructionApplied = true;
-
+                        instanceHandled = true;
+                        
                         if (instance == null) {
                             break;
@@ -1030,5 +1064,5 @@
                     }
                     case MAKE_SELECTION: {
-                        instructionApplied = true;
+                        instanceHandled = true;
 
                         if (instance == null) {
@@ -1072,19 +1106,5 @@
                     }
                     case INTEGRATE_OPTIONAL: {
-                        TaskPath previousPath = previousPaths.size() > 0 ?
-                            previousPaths.get(previousPaths.size() - 1) : null;
-                        
-                        if (pathsMatch(instruction.getPrecedingPath(), previousPath)) {
-                            IOptional optional = instruction.getOptional();
-                            IOptionalInstance optionalInstance =
-                                    taskFactory.createNewTaskInstance(optional);
-                            taskBuilder.addTaskInstance(session, optionalInstance);
-                        }
-                        
-                        if (instance != null) {
-                            taskBuilder.addTaskInstance(session, instance);
-                        }
-                        
-                        instructionApplied = true;
+                        // have been applied beforehand
                         break;
                     }
@@ -1095,10 +1115,10 @@
             }
             
-            if (instructionApplied) {
+            if (instanceHandled) {
                 break;
             }
         }
         
-        if (!instructionApplied) {
+        if (!instanceHandled) {
             ITask task = taskPath.getLast();
             if (task instanceof IIteration) {
