Index: trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeChecker.java
===================================================================
--- trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeChecker.java	(revision 1561)
+++ trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeChecker.java	(revision 1638)
@@ -27,4 +27,5 @@
 
 import de.ugoe.cs.autoquest.eventcore.gui.TextInput;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
@@ -161,4 +162,43 @@
      *
      */
+    public void assertEventTaskInstancesEqual(ITaskInstanceList expected,
+                                              ITaskInstanceList checked)
+    {
+        final List<IEventTaskInstance> expectedEventTaskInstances =
+            new ArrayList<IEventTaskInstance>();
+        
+        final List<IEventTaskInstance> checkedEventTaskInstances =
+                new ArrayList<IEventTaskInstance>();
+            
+        for (ITaskInstance instance : expected) {
+            instance.accept(new DefaultTaskInstanceTraversingVisitor() {
+                @Override
+                public void visit(IEventTaskInstance eventTaskInstance) {
+                    expectedEventTaskInstances.add(eventTaskInstance);
+                }
+            });
+        }
+        
+        for (ITaskInstance instance : checked) {
+            instance.accept(new DefaultTaskInstanceTraversingVisitor() {
+                @Override
+                public void visit(IEventTaskInstance eventTaskInstance) {
+                    checkedEventTaskInstances.add(eventTaskInstance);
+                }
+            });
+        }
+        
+        assertEquals("task instance lists differ in the number of event task instances",
+                     expectedEventTaskInstances.size(), checkedEventTaskInstances.size());
+        
+        for (int i = 0; i < expectedEventTaskInstances.size(); i++) {
+            assertTaskInstancesEqual
+                (expectedEventTaskInstances.get(i), checkedEventTaskInstances.get(i));
+        }
+    }
+
+    /**
+     *
+     */
     private void assertTaskInstancesEqual(ITaskInstance     expected,
                                           ITaskInstance     checked,
Index: trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeEncoder.java
===================================================================
--- trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeEncoder.java	(revision 1561)
+++ trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeEncoder.java	(revision 1638)
@@ -189,5 +189,7 @@
         }
         else if (taskInstance instanceof IOptionalInstance) {
-            encode(((IOptionalInstance) taskInstance).getChild(), out, indent + "  ", i++);
+            if (((IOptionalInstance) taskInstance).getChild() != null) {
+                encode(((IOptionalInstance) taskInstance).getChild(), out, indent + "  ", i++);
+            }
         }
 
Index: trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeValidator.java
===================================================================
--- trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeValidator.java	(revision 1561)
+++ trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeValidator.java	(revision 1638)
@@ -17,6 +17,10 @@
 import static org.junit.Assert.*;
 
+import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
-
+import java.util.Map;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
@@ -46,4 +50,43 @@
      * 
      */
+    public void validate(List<IUserSession> userSessions, boolean checkInstances) {
+        validate(userSessions);
+        
+        if (!checkInstances) {
+            return;
+        }
+        
+        Map<ITask, List<ITaskInstance>> allTasks = new HashMap<ITask, List<ITaskInstance>>();
+        
+        for (IUserSession userSession : userSessions) {
+            getAllTasksAndInstances(userSession, allTasks);
+        }
+        
+        for (Map.Entry<ITask, List<ITaskInstance>> entry : allTasks.entrySet()) {
+            assertEquals("number of task instances of task " + entry.getKey() + " in the " +
+                         "sessions is not equal to those referenced by the model",
+                         entry.getValue().size(), entry.getKey().getInstances().size());
+            
+            for (ITaskInstance candidate : entry.getValue()) {
+                boolean found = false;
+                for (ITaskInstance instance : entry.getKey().getInstances()) {
+                    if (candidate.equals(instance)) {
+                        if (!found) {
+                            found = true;
+                        }
+                        else {
+                            fail("the same instance is referred twice by the task");
+                        }
+                    }
+                }
+                
+                assertTrue("instance " + candidate + " is not referred by task", found);
+            }
+        }
+    }
+
+    /**
+     * 
+     */
     public void validate(List<IUserSession> userSessions) {
         for (IUserSession userSession : userSessions) {
@@ -94,6 +137,6 @@
                 assertFalse("child of selection model must not be a selection",
                             childTask instanceof ISelection);
-                assertFalse("child of selection model must not be an optional",
-                            childTask instanceof IOptional);
+                /*assertFalse("child of selection model must not be an optional",
+                            childTask instanceof IOptional);*/
                 if (childTask.equals(((ISelectionInstance) taskInstance).getChild().getTask())) {
                     found = true;
@@ -155,3 +198,85 @@
         }
     }
+
+
+    /**
+     * 
+     */
+    private void getAllTasksAndInstances(ITaskInstanceList                     taskInstances,
+                                         final Map<ITask, List<ITaskInstance>> allTasks)
+    {
+        for (ITaskInstance taskInstance : taskInstances) {
+            
+            taskInstance.accept(new DefaultTaskInstanceTraversingVisitor() {
+
+                /* (non-Javadoc)
+                 * @see DefaultTaskInstanceTraversingVisitor#visit(IOptionalInstance)
+                 */
+                @Override
+                public void visit(IOptionalInstance optionalInstance) {
+                    addToInstanceList(optionalInstance);
+                    super.visit(optionalInstance);
+                }
+
+                /* (non-Javadoc)
+                 * @see DefaultTaskInstanceTraversingVisitor#visit(ISelectionInstance)
+                 */
+                @Override
+                public void visit(ISelectionInstance selectionInstance) {
+                    addToInstanceList(selectionInstance);
+                    super.visit(selectionInstance);
+                }
+
+                /* (non-Javadoc)
+                 * @see DefaultTaskInstanceTraversingVisitor#visit(IEventTaskInstance)
+                 */
+                @Override
+                public void visit(IEventTaskInstance eventTaskInstance) {
+                    addToInstanceList(eventTaskInstance);
+                    super.visit(eventTaskInstance);
+                }
+
+                /* (non-Javadoc)
+                 * @see DefaultTaskInstanceTraversingVisitor#visit(IIterationInstance)
+                 */
+                @Override
+                public void visit(IIterationInstance iterationInstance) {
+                    addToInstanceList(iterationInstance);
+                    super.visit(iterationInstance);
+                }
+
+                /* (non-Javadoc)
+                 * @see DefaultTaskInstanceTraversingVisitor#visit(ISequenceInstance)
+                 */
+                @Override
+                public void visit(ISequenceInstance sequenceInstance) {
+                    addToInstanceList(sequenceInstance);
+                    super.visit(sequenceInstance);
+                }
+
+                private void addToInstanceList(ITaskInstance taskInstance) {
+                    List<ITaskInstance> instances = allTasks.get(taskInstance.getTask());
+                    
+                    if (instances == null) {
+                        instances = new LinkedList<ITaskInstance>();
+                        allTasks.put(taskInstance.getTask(), instances);
+                    }
+                    
+                    boolean found = false;
+                    
+                    for (ITaskInstance candidate : instances) {
+                        if (candidate.equals(taskInstance)) {
+                            found = true;
+                            break;
+                        }
+                    }
+                    
+                    assertFalse("instance " + taskInstance + " occurred twice", found);
+                    
+                    instances.add(taskInstance);
+                }
+                
+            });
+        }
+    }
 }
