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 1123)
+++ trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeChecker.java	(revision 1146)
@@ -17,7 +17,4 @@
 import static org.junit.Assert.*;
 
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -33,7 +30,8 @@
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeInfo;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
 
 /**
@@ -56,6 +54,5 @@
 
     /**
-     * TODO: comment
-     * 
+     *
      */
     public TaskTreeChecker() {
@@ -64,6 +61,5 @@
 
     /**
-     * TODO: comment
-     * 
+     *
      */
     public TaskTreeChecker(boolean doTrace) {
@@ -74,45 +70,30 @@
      *
      */
-    public void assertTaskTree(String taskTreeSpec, ITaskTree taskTree) {
-        Map<ITaskTreeNode, Integer> taskMapCopy = new HashMap<ITaskTreeNode, Integer>();
-
-        for (Map.Entry<ITaskTreeNode, ITaskTreeNodeInfo> entry : taskTree.getTaskMap().entrySet()) {
-            if (entry.getValue().getNoOfOccurencesInTree() > 0) {
-                taskMapCopy.put(entry.getKey(), entry.getValue().getNoOfOccurencesInTree());
-            }
-            else {
-                taskMapCopy.put(entry.getKey(), 1);
-            }
-        }
-
+    public void assertTaskInstanceList(String userSessionSpec, ITaskInstanceList taskInstances) {
         if (doTrace) {
-            dumpTaskMap(taskMapCopy);
-        }
-
-        TaskSpec task = null;
-
-        Matcher taskMatcher = taskPattern.matcher(taskTreeSpec);
+            new TaskTreeEncoder().encode(taskInstances, System.err);
+        }
+
+        TaskSpec taskInstanceSpec = null;
+
+        Matcher taskMatcher = taskPattern.matcher(userSessionSpec);
+        
+        Map<String, ITask> tasks = new HashMap<String, ITask>();
 
         while (taskMatcher.find()) {
 
-            task = parseTask(taskMatcher);
-            
-            if (task != null) {
-                assertTaskAndChildrenInMapAndRemove(task, taskMapCopy);
-            }
-        }
-
-        assertTrue("more tasks in map, than expected", taskMapCopy.isEmpty());
-    }
-
-    /**
-     * <p>
-     * TODO: comment
-     * </p>
-     *
-     * @param oracle
-     * @param result
-     */
-    public void assertTaskNodesEqual(ITaskTreeNode expected, ITaskTreeNode checked) {
+            taskInstanceSpec = parseTaskInstance(taskMatcher);
+            
+            if (taskInstanceSpec != null) {
+                assertTaskInstanceList(taskInstanceSpec, taskInstances, tasks);
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    public void assertTaskInstanceListsEqual(ITaskInstanceList expected, ITaskInstanceList checked)
+    {
         if (expected == null) {
             assertNull("null", checked);
@@ -123,9 +104,56 @@
             assertEquals(expected.toString() + ": types do not match",
                          expected.getClass(), checked.getClass());
-            assertEquals(expected.toString() + ": names do not match",
-                         expected.getName(), checked.getName());
-            
-            List<ITaskTreeNode> expectedChildren = expected.getChildren();
-            List<ITaskTreeNode> checkedChildren = checked.getChildren();
+            
+            if ((expected != null) && (expected.size() > 0)) {
+                assertNotNull(expected.toString() + ": children not there", checked);
+                assertEquals(expected.toString() + ": different number of children",
+                             expected.size(), checked.size());
+                
+                Map<ITask, ITask> equalTasksMap = new HashMap<ITask, ITask>();
+                for (int i = 0; i < expected.size(); i++) {
+                    assertTaskInstancesEqual(expected.get(i), checked.get(i), equalTasksMap);
+                }
+            }
+            else {
+                assertTrue(expected.toString() + ": unexpected children",
+                           (checked == null) || (checked.size() == 0));
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    public void assertTaskInstancesEqual(ITaskInstance expected, ITaskInstance checked) {
+        Map<ITask, ITask> equalTasksMap = new HashMap<ITask, ITask>();
+        assertTaskInstancesEqual(expected, checked, equalTasksMap);
+    }
+
+    /**
+     *
+     */
+    private void assertTaskInstancesEqual(ITaskInstance     expected,
+                                          ITaskInstance     checked,
+                                          Map<ITask, ITask> equalTasksMap)
+    {
+        if (expected == null) {
+            assertNull("null", checked);
+        }
+        else {
+            assertNotNull(expected.toString(), checked);
+            
+            assertEquals(expected.toString() + ": types do not match",
+                         expected.getClass(), checked.getClass());
+            
+            if (equalTasksMap.containsKey(expected.getTask())) {
+                assertEquals(expected.toString() + ": tasks do not match",
+                             checked.getTask(), equalTasksMap.get(expected.getTask()));
+            }
+            else {
+                equalTasksMap.put(expected.getTask(), checked.getTask());
+            }
+            
+            List<ITaskInstance> expectedChildren = expected.getChildren();
+            List<ITaskInstance> checkedChildren = checked.getChildren();
             
             if ((expectedChildren != null) && (expectedChildren.size() > 0)) {
@@ -136,5 +164,5 @@
                 if (expected instanceof ISequence) {
                     for (int i = 0; i < expectedChildren.size(); i++) {
-                        assertTaskNodesEqual(expectedChildren.get(i), checkedChildren.get(i));
+                        assertTaskInstancesEqual(expectedChildren.get(i), checkedChildren.get(i));
                     }
                 }
@@ -144,5 +172,5 @@
                         for (int j = 0; j < checkedChildren.size(); j++) {
                             try {
-                                assertTaskNodesEqual
+                                assertTaskInstancesEqual
                                     (expectedChildren.get(i), checkedChildren.get(j));
                                 found = true;
@@ -166,146 +194,7 @@
 
     /**
-     * TODO: comment
      * 
-     * @param taskTree
-     */
-    public void dumpAsCheckString(ITaskTree taskTree) {
-        dumpNodeAsCheckString(taskTree.getRoot(), new int[4], "");
-    }
-
-    /**
-     * TODO: comment
-     * 
-     * @param root
-     * @param string
-     */
-    private void dumpNodeAsCheckString(ITaskTreeNode node, int[] typeCounters, String indent) {
-        System.out.print("       \"");
-        System.out.print(indent);
-
-        if (node instanceof ISequence) {
-            System.out.print("Sequence sequence");
-            System.out.print(typeCounters[0]++);
-            System.out.println(" {\" +");
-        }
-        else if (node instanceof IIteration) {
-            System.out.print("Iteration iteration");
-            System.out.print(typeCounters[1]++);
-            System.out.println(" {\" +");
-        }
-        else if (node instanceof ISelection) {
-            System.out.print("Selection selection");
-            System.out.print(typeCounters[2]++);
-            System.out.println(" {\" +");
-        }
-        else if (node instanceof IEventTask) {
-            if (((IEventTask) node).getEventType() instanceof TextInput) {
-                System.out.print("TextInputEvent textInput");
-                System.out.print(typeCounters[3]++);
-                System.out.print(" \"");
-                System.out.print(((TextInput) ((IEventTask) node).getEventType()).getEnteredText());
-                System.out.print("\"");
-            }
-            else {
-                System.out.print("Event ");
-                System.out.print(((IEventTask) node).getEventType().getName());
-            }
-            System.out.print(" {}\" +");
-        }
-        else {
-            fail("unknown type of node in task tree " + node);
-        }
-
-        for (ITaskTreeNode child : node.getChildren()) {
-            dumpNodeAsCheckString(child, typeCounters, indent + "  ");
-        }
-
-        if (!(node instanceof IEventTask)) {
-            System.out.print("       \"");
-            System.out.print(indent);
-            System.out.print("}\" +");
-        }
-
-        System.out.println();
-    }
-
-    /**
-     * TODO: comment
-     * 
-     * @param taskTree
-     */
-    public void dumpFullTaskTree(ITaskTree taskTree) throws FileNotFoundException {
-        PrintWriter out = null;
-        try {
-            out = new PrintWriter(new FileOutputStream("taskTree.txt"));
-            dumpFullNode(taskTree.getRoot(), out, "", 0);
-        }
-        finally {
-            if (out != null) {
-                out.close();
-            }
-        }
-
-    }
-
-    /**
-     *
-     */
-    private void dumpFullNode(ITaskTreeNode node, PrintWriter out, String indent, int index) {
-        if (node instanceof ISequence) {
-            if (index > 0) {
-                out.println();
-            }
-            out.print(indent);
-            out.print(node.toString());
-            out.println(" {");
-        }
-        else if (node instanceof IIteration) {
-            if (index > 0) {
-                out.println();
-            }
-            out.print(indent);
-            out.print(node.toString());
-            out.println(" {");
-        }
-        else if (node instanceof ISelection) {
-            if (index > 0) {
-                out.println();
-            }
-            out.print(indent);
-            out.print(node.toString());
-            out.println(" {");
-        }
-        else if (node instanceof IEventTask) {
-            out.print(indent);
-            out.print(((IEventTask) node).getEventType());
-            out.print(" ");
-            out.print(((IEventTask) node).getEventTarget().getStringIdentifier());
-//            if (((IEventTask) node).getEventTarget() instanceof IGUIElement) {
-//              out.print(" ");
-//              out.print(((IGUIElement) ((IEventTask) node).getEventTarget()).getSpecification());
-//            }
-        }
-        else {
-            fail("unknown type of node in task tree " + node);
-        }
-
-        int i = 0;
-        for (ITaskTreeNode child : node.getChildren()) {
-            dumpFullNode(child, out, indent + "  ", i++);
-        }
-
-        if (!(node instanceof IEventTask)) {
-            out.print(indent);
-            out.print("}");
-        }
-
-        out.println();
-    }
-
-    /**
-     * 
-     */
-    private TaskSpec parseTask(Matcher taskMatcher) {
+     */
+    private TaskSpec parseTaskInstance(Matcher taskMatcher) {
         if ("}".equals(taskMatcher.group(1))) {
             throw new IllegalArgumentException("invalid task specification");
@@ -338,5 +227,5 @@
         List<TaskSpec> children = new ArrayList<TaskSpec>();
         while (taskMatcher.find() && !"}".equals(taskMatcher.group(0))) {
-            children.add(parseTask(taskMatcher));
+            children.add(parseTaskInstance(taskMatcher));
         }
 
@@ -352,38 +241,45 @@
      * @param taskMapCopy
      */
-    private void assertTaskAndChildrenInMapAndRemove(TaskSpec                    task,
-                                                     Map<ITaskTreeNode, Integer> taskMap)
+    private void assertTaskInstanceList(TaskSpec           taskSpec,
+                                        ITaskInstanceList  taskInstances,
+                                        Map<String, ITask> tasks)
     {
-        for (Map.Entry<ITaskTreeNode, Integer> entry : taskMap.entrySet()) {
-            if (taskSpecEqualsTask(task, entry.getKey())) {
-                if (task.children != null) {
-                    for (TaskSpec child : task.children) {
-                        assertTaskAndChildrenInMapAndRemove(child, taskMap);
-                    }
-                }
-
-                int count = taskMap.get(entry.getKey());
-                if (count == 1) {
-                    taskMap.remove(entry.getKey());
-                }
-                else {
-                    taskMap.put(entry.getKey(), count - 1);
-                }
-                return;
-            }
-        }
-
-        fail("expected task " + task.type + " " + task.name + " not included in task map");
-    }
-
-    /**
-     *
-     */
-    private boolean taskSpecEqualsTask(TaskSpec taskSpec, ITaskTreeNode task) {
+        if (doTrace) {
+            System.err.println("\ncomparing " + taskSpec.type + " with " + taskInstances + "\n");
+        }
+
+        if ((taskInstances instanceof IUserSession) && (!"UserSession".equals(taskSpec.type))) {
+            fail("can not compare a task instance with a user session");
+        }
+        else if ((!(taskInstances instanceof IUserSession)) &&
+                 (!"TaskInstances".equals(taskSpec.type)))
+        {
+            fail("can not compare a task instance with a task instance list");
+        }
+        
+        if (taskSpec.children.length != taskInstances.size()) {
+            fail("number of task instances in task instance list does not match");
+        }
+        
+        for (int i = 0; i < taskInstances.size(); i++) {
+            TaskSpec childSpec = taskSpec.children[i];
+            assertTrue(taskSpecEqualsTaskInstance(childSpec, taskInstances.get(i), tasks));
+        }
+    }
+
+    /**
+     *
+     */
+    private boolean taskSpecEqualsTaskInstance(TaskSpec           taskSpec,
+                                               ITaskInstance      taskInstance,
+                                               Map<String, ITask> tasks)
+    {
         if (doTrace) {
             System.err.println("comparing " + taskSpec.name + " with");
-            dumpTask(task, 0, "");
-        }
-
+            new TaskTreeEncoder().encode(taskInstance, System.err);
+        }
+
+        ITask task = taskInstance.getTask();
+        
         if (("Event".equals(taskSpec.type) && (!(task instanceof IEventTask))) ||
             ("TextInputEvent".equals(taskSpec.type) &&
@@ -396,5 +292,5 @@
             if (doTrace) {
                 System.err.println("task types do not match: " + taskSpec.type + " != " +
-                    task.getClass().getSimpleName() + "\n");
+                                   task.getClass().getSimpleName() + "\n");
             }
             return false;
@@ -440,7 +336,29 @@
             }
         }
-
-        if (((taskSpec.children == null) && (task.getChildren().size() > 0)) ||
-            ((taskSpec.children != null) && (taskSpec.children.length != task.getChildren().size())))
+        
+        // check the task name against the map
+        if (tasks.containsKey(taskSpec.name)) {
+            if (!tasks.get(taskSpec.name).equals(task)) {
+                if (doTrace) {
+                    System.err.println("the task instance is not of the expected task: " +
+                                       taskSpec.name + " != " + task + "\n");
+                }
+                return false;
+            }
+        }
+        else if (tasks.containsValue(task)) {
+            if (doTrace) {
+                System.err.println("the task of the task instance " + taskSpec.name +
+                                   " should be different to another one but it isn't\n");
+            }
+            return false;
+        }
+        else {
+            tasks.put(taskSpec.name, task);
+        }
+
+        if (((taskSpec.children == null) && (taskInstance.getChildren().size() > 0)) ||
+            ((taskSpec.children != null) &&
+             (taskSpec.children.length != taskInstance.getChildren().size())))
         {
             if (doTrace) {
@@ -448,13 +366,14 @@
                     ("numbers of children do not match: " +
                      (taskSpec.children == null ? "0" : taskSpec.children.length) + " != " +
-                     (task.getChildren() == null ? "0" : task.getChildren().size()) + "\n");
+                     (taskInstance.getChildren() == null ? "0" :
+                          taskInstance.getChildren().size()) + "\n");
             }
             return false;
         }
 
-        Iterator<ITaskTreeNode> children = task.getChildren().iterator();
+        Iterator<ITaskInstance> children = taskInstance.getChildren().iterator();
         if (taskSpec.children != null) {
             for (TaskSpec child : taskSpec.children) {
-                if (!taskSpecEqualsTask(child, children.next())) {
+                if (!taskSpecEqualsTaskInstance(child, children.next(), tasks)) {
                     if (doTrace) {
                         System.err.println("one of the children does not match\n");
@@ -478,46 +397,7 @@
         }
     }
-
-    /**
-   *
-   */
-    private void dumpTaskMap(Map<ITaskTreeNode, Integer> taskMap) {
-        System.err.println();
-        for (Map.Entry<ITaskTreeNode, Integer> entry : taskMap.entrySet()) {
-            dumpTask(entry.getKey(), entry.getValue(), "");
-            System.err.println();
-        }
-    }
-
-    /**
-     *
-     */
-    private void dumpTask(ITaskTreeNode task, int count, String indent) {
-        System.err.print(indent);
-        System.err.print(task);
-        System.err.print(" ");
-        System.err.print(task.getDescription());
-        System.err.print(" ");
-
-        if (count > 0) {
-            System.err.print("(");
-            System.err.print(count);
-            System.err.print(" occurrences)");
-        }
-
-        System.err.println();
-
-        if ((task.getChildren() != null) && (task.getChildren().size() > 0)) {
-            for (ITaskTreeNode child : task.getChildren()) {
-                dumpTask(child, 0, indent + "  ");
-            }
-        }
-    }
     
     /**
-     * TODO comment
-     * 
-     * @version $Revision: $ $Date: $
-     * @author 2011, last modified by $Author: $
+     *
      */
     private class TaskSpec {
Index: trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeDecoder.java
===================================================================
--- trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeDecoder.java	(revision 1146)
+++ trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeDecoder.java	(revision 1146)
@@ -0,0 +1,227 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.tasktrees;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+import de.ugoe.cs.autoquest.eventcore.StringEventType;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
+import de.ugoe.cs.autoquest.test.DummyGUIElement;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 01.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class TaskTreeDecoder {
+    
+    /** */
+    private static Pattern taskInstancePattern = Pattern.compile("([^{}]+)\\{|\\}");
+    
+    /** */
+    private static Pattern taskInstanceDetailsPattern =
+        Pattern.compile("\\s*(\\w*)\\s*([\\w\\(\\)\"]*)\\s*((\\w*)|(\".*\"))?");
+    
+    /** */
+    private ITaskFactory taskFactory;
+    
+    /** */
+    private ITaskBuilder taskBuilder;
+    
+    /** */
+    Map<String, IEventTarget> targets = new HashMap<String, IEventTarget>();
+    
+    /** */
+    Map<String, ITask> tasks = new HashMap<String, ITask>();
+    
+    /**
+     *
+     */
+    public TaskTreeDecoder(ITaskFactory taskFactory, ITaskBuilder taskBuilder) {
+        super();
+        this.taskFactory = taskFactory;
+        this.taskBuilder = taskBuilder;
+    }
+
+    /**
+     *
+     */
+    public ITaskInstanceList decode(String taskTreeSpec) {
+        ITaskInstanceList taskInstanceList = null;
+
+        Matcher taskMatcher = taskInstancePattern.matcher(taskTreeSpec);
+
+        if (taskMatcher.find()) {
+            taskInstanceList = parseTaskInstanceList(taskMatcher);
+        }
+        
+        if (taskMatcher.find()) {
+            throw new IllegalArgumentException("too many tasks specified");
+        }
+        
+        return taskInstanceList;
+    }
+
+    /**
+     * 
+     */
+    private ITaskInstanceList parseTaskInstanceList(Matcher taskMatcher) {
+        if ("}".equals(taskMatcher.group(1))) {
+            throw new IllegalArgumentException("invalid task instance list specification");
+        }
+        
+        String taskDetails = taskMatcher.group(1);
+        
+        Matcher matcher = taskInstanceDetailsPattern.matcher(taskDetails);
+        
+        if (!matcher.find()) {
+            throw new IllegalArgumentException("could not parse task details");
+        }
+
+        String type = matcher.group(1);
+        
+        ITaskInstanceList list;
+        
+        if ("UserSession".equals(type)) {
+            list = taskFactory.createUserSession();
+        }
+        else if ("TaskInstances".equals(type)) {
+            list = taskFactory.createNewTaskInstance(taskFactory.createNewSequence());
+        }
+        else {
+            throw new IllegalArgumentException("unknown type of task instance list: " + type);
+        }
+        
+        while (taskMatcher.find() && !"}".equals(taskMatcher.group(0))) {
+            ITaskInstance childInstance = parseTaskInstance(taskMatcher);
+            
+            if (!(list instanceof IUserSession)) {
+                taskBuilder.addChild
+                    ((ISequence) ((ITaskInstance) list).getTask(), childInstance.getTask());
+            }
+
+            taskBuilder.addTaskInstance(list, childInstance);
+        }
+
+        return list;
+    }
+
+    /**
+     * 
+     */
+    private ITaskInstance parseTaskInstance(Matcher taskMatcher) {
+        if ("}".equals(taskMatcher.group(1))) {
+            throw new IllegalArgumentException("invalid task instance specification");
+        }
+        
+        String taskDetails = taskMatcher.group(1);
+        
+        Matcher matcher = taskInstanceDetailsPattern.matcher(taskDetails);
+        
+        if (!matcher.find()) {
+            throw new IllegalArgumentException("could not parse task details");
+        }
+
+        String type = matcher.group(1);
+        String id = matcher.group(2);
+        
+        ITask task = tasks.get(id);
+        
+        if (task == null) {
+            if ("Sequence".equals(type)) {
+                task = taskFactory.createNewSequence();
+            }
+            else if ("Selection".equals(type)) {
+                task = taskFactory.createNewSelection();
+            }
+            else if ("Iteration".equals(type)) {
+                task = taskFactory.createNewIteration();
+            }
+            else if ("Optional".equals(type)) {
+                task = taskFactory.createNewOptional();
+            }
+            else {
+                IEventTarget target = targets.get(id);
+            
+                if (target == null) {
+                    target = new DummyGUIElement(id);
+                    targets.put(id, target);
+                }
+            
+                task = taskFactory.createNewEventTask(new StringEventType(type), target);
+            }
+            
+            tasks.put(id, task);
+        }
+        
+        if ((matcher.group(5) != null) && (!"".equals(matcher.group(5).trim()))) {
+            taskBuilder.setDescription(task, matcher.group(5).trim());
+        }
+
+        ITaskInstance instance = taskFactory.createNewTaskInstance(task);
+        
+        while (taskMatcher.find() && !"}".equals(taskMatcher.group(0))) {
+            ITaskInstance childInstance = parseTaskInstance(taskMatcher);
+            
+            if (task instanceof ISequence) {
+                taskBuilder.addChild((ISequence) task, childInstance.getTask());
+            }
+            else if (task instanceof ISelection) {
+                taskBuilder.addChild((ISelection) task, childInstance.getTask());
+            }
+            else if (task instanceof IIteration) {
+                if (((IIteration) task).getMarkedTask() == null) {
+                    taskBuilder.setMarkedTask((IIteration) task, childInstance.getTask());
+                }
+                else if (!((IIteration) task).getMarkedTask().equals(childInstance.getTask())) {
+                    throw new IllegalArgumentException
+                        ("can not add more than one child to an iteration");
+                }
+            }
+            else if (task instanceof IOptional) {
+                if (((IOptional) task).getMarkedTask() == null) {
+                    taskBuilder.setMarkedTask((IOptional) task, childInstance.getTask());
+                }
+                else if (!((IOptional) task).getMarkedTask().equals(childInstance.getTask())) {
+                    throw new IllegalArgumentException
+                        ("can not add more than one child to an optional");
+                }
+            }
+            else {
+                throw new IllegalArgumentException("can not add children to something that is no " +
+                                                   "sequence, selection, iteration, or optional");
+            }
+            
+            taskBuilder.addChild(instance, childInstance);
+        }
+
+        return instance;
+    }
+
+}
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 1146)
+++ trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeEncoder.java	(revision 1146)
@@ -0,0 +1,265 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.tasktrees;
+
+import static org.junit.Assert.*;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import de.ugoe.cs.autoquest.eventcore.gui.TextInput;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITemporalRelationship;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
+
+/**
+ * TODO comment
+ * 
+ * @version $Revision: $ $Date: 01.04.2012$
+ * @author 2012, last modified by $Author: patrick$
+ */
+public class TaskTreeEncoder {
+    
+    /**
+     *
+     */
+    public void encode(List<IUserSession> userSessions)
+        throws FileNotFoundException
+    {
+        PrintStream out = null;
+        try {
+            out = new PrintStream(new FileOutputStream("userSessions.txt"));
+            for (IUserSession session : userSessions) {
+                encode(session, out);
+            }
+        }
+        finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+    
+    /**
+     *
+     */
+    public void encode(ITaskInstanceList taskInstanceList)
+        throws FileNotFoundException
+    {
+        PrintStream out = null;
+        try {
+            out = new PrintStream(new FileOutputStream("taskInstanceList.txt"));
+            encode(taskInstanceList, out);
+        }
+        finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    public void encode(ITaskInstanceList taskInstanceList, PrintStream out) {
+        if (taskInstanceList instanceof IUserSession) {
+            out.println("UserSession {");
+        }
+        else {
+            out.println("TaskInstances {");
+        }
+        
+        for (ITaskInstance taskInstance : taskInstanceList) {
+            encode(taskInstance, out, "  ", 0);
+        }
+        
+        out.println('}');
+    }
+
+    /**
+     *
+     */
+    public void encode(ITaskInstance taskInstance, PrintStream out) {
+        encode(taskInstance, out, "", 0);
+    }
+    
+    /**
+     *
+     */
+    private void encode(ITaskInstance taskInstance,
+                        PrintStream   out,
+                        String        indent,
+                        int           index)
+    {
+        ITask task = taskInstance.getTask();
+        
+        if (task instanceof ITemporalRelationship) {
+            if (index > 0) {
+                out.println();
+            }
+            out.print(indent);
+
+            if (task instanceof ISequence) {
+                out.print("Sequence ");
+            }
+            else if (task instanceof ISelection) {
+                out.print("Selection ");
+            }            
+            else if (task instanceof IIteration) {
+                out.print("Iteration ");
+            }            
+            else if (task instanceof IOptional) {
+                out.print("Optional ");
+            }
+            
+            out.print(task.getId());
+            out.println(" {");
+        }
+        else if (task instanceof IEventTask) {
+            out.print(indent);
+            out.print(((IEventTask) task).getEventType());
+            out.print(" ");
+            out.print(((IEventTask) task).getEventTarget().getStringIdentifier());
+//            if (((IEventTask) node).getEventTarget() instanceof IGUIElement) {
+//              out.print(" ");
+//              out.print(((IGUIElement) ((IEventTask) node).getEventTarget()).getSpecification());
+//            }
+        }
+        else {
+            fail("unknown type of task referred by task instance " + taskInstance);
+        }
+
+        int i = 0;
+        for (ITaskInstance child : taskInstance.getChildren()) {
+            encode(child, out, indent + "  ", i++);
+        }
+
+        if (task instanceof ITemporalRelationship) {
+            out.print(indent);
+            out.print("}");
+        }
+
+        out.println();
+    }
+    
+    /**
+     *
+     */
+    public void dumpAsCheckString(IUserSession userSession) {
+        int[] typeCounters = new int[4];
+        Map<ITask, String> taskIds = new HashMap<ITask, String>();
+        
+        for (ITaskInstance taskInstance : userSession) {
+            dumpTaskInstanceAsCheckString(taskInstance, typeCounters, taskIds, "");
+        }
+    }
+
+    /**
+     *
+     */
+    private void dumpTaskInstanceAsCheckString(ITaskInstance      taskInstance,
+                                               int[]              typeCounters,
+                                               Map<ITask, String> taskIds,
+                                               String             indent)
+    {
+        ITask task = taskInstance.getTask();
+        
+        System.out.print("       \"");
+        System.out.print(indent);
+
+        String id = taskIds.get(task);
+        
+        if (task instanceof ISequence) {
+            if (id == null) {
+                id = "sequence" + typeCounters[0]++;
+            }
+            
+            System.out.print("Sequence ");
+            System.out.print(id);
+            System.out.println(" {\" +");
+        }
+        else if (task instanceof IIteration) {
+            if (id == null) {
+                id = "iteration" + typeCounters[1]++;
+            }
+            
+            System.out.print("Iteration ");
+            System.out.print(id);
+            System.out.println(" {\" +");
+        }
+        else if (task instanceof ISelection) {
+            if (id == null) {
+                id = "selection" + typeCounters[2]++;
+            }
+            
+            System.out.print("Selection ");
+            System.out.print(id);
+            System.out.println(" {\" +");
+        }
+        else if (task instanceof IEventTask) {
+            if (((IEventTask) task).getEventType() instanceof TextInput) {
+                if (id == null) {
+                    id = "textInput" + typeCounters[3]++;
+                }
+                
+                System.out.print("TextInputEvent ");
+                System.out.print(id);
+                System.out.print(" \"");
+                System.out.print(((TextInput) ((IEventTask) task).getEventType()).getEnteredText());
+                System.out.print("\"");
+            }
+            else {
+                if (id == null) {
+                    id = "event" + typeCounters[3]++;
+                }
+                
+                System.out.print("Event ");
+                System.out.print(id);
+                System.out.print(' ');
+                System.out.print(((IEventTask) task).getEventType().getName());
+            }
+            System.out.print(" {}\" +");
+        }
+        else {
+            fail("unknown type of task referred by task instance " + taskInstance);
+        }
+
+        taskIds.put(task, id);
+        
+        for (ITaskInstance child : taskInstance.getChildren()) {
+            dumpTaskInstanceAsCheckString(child, typeCounters, taskIds, indent + "  ");
+        }
+
+        if (!(task instanceof IEventTask)) {
+            System.out.print("       \"");
+            System.out.print(indent);
+            System.out.print("}\" +");
+        }
+
+        System.out.println();
+    }
+
+}
Index: trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeInstantiator.java
===================================================================
--- trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeInstantiator.java	(revision 1123)
+++ 	(revision )
@@ -1,173 +1,0 @@
-//   Copyright 2012 Georg-August-Universität Göttingen, Germany
-//
-//   Licensed under the Apache License, Version 2.0 (the "License");
-//   you may not use this file except in compliance with the License.
-//   You may obtain a copy of the License at
-//
-//       http://www.apache.org/licenses/LICENSE-2.0
-//
-//   Unless required by applicable law or agreed to in writing, software
-//   distributed under the License is distributed on an "AS IS" BASIS,
-//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//   See the License for the specific language governing permissions and
-//   limitations under the License.
-
-package de.ugoe.cs.autoquest.tasktrees;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import de.ugoe.cs.autoquest.eventcore.IEventTarget;
-import de.ugoe.cs.autoquest.eventcore.StringEventType;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
-import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
-import de.ugoe.cs.autoquest.test.DummyGUIElement;
-
-/**
- * TODO comment
- * 
- * @version $Revision: $ $Date: 01.04.2012$
- * @author 2012, last modified by $Author: patrick$
- */
-public class TaskTreeInstantiator {
-    
-    /** */
-    private static Pattern taskPattern = Pattern.compile("([^{}]+)\\{|\\}");
-    
-    /** */
-    private static Pattern taskDetailsPattern =
-        Pattern.compile("\\s*(\\w*)\\s*([\\w\\(\\)\"]*)\\s*((\\w*)|(\".*\"))?");
-    
-    /** */
-    private ITaskTreeNodeFactory taskTreeNodeFactory;
-    
-    /** */
-    private ITaskTreeBuilder taskTreeBuilder;
-    
-    /** */
-    Map<String, IEventTarget> targets = new HashMap<String, IEventTarget>();
-    
-    /**
-     *
-     */
-    public TaskTreeInstantiator(ITaskTreeNodeFactory taskTreeNodeFactory,
-                                ITaskTreeBuilder taskTreeBuilder)
-    {
-        super();
-        this.taskTreeNodeFactory = taskTreeNodeFactory;
-        this.taskTreeBuilder = taskTreeBuilder;
-    }
-
-    /**
-     *
-     */
-    public ITaskTreeNode instantiateTaskTree(String taskTreeSpec) {
-        ITaskTreeNode task = null;
-
-        Matcher taskMatcher = taskPattern.matcher(taskTreeSpec);
-
-        if (taskMatcher.find()) {
-            task = parseTask(taskMatcher);
-        }
-        
-        if (taskMatcher.find()) {
-            throw new IllegalArgumentException("too many tasks specified");
-        }
-        
-        return task;
-    }
-
-    /**
-     * 
-     */
-    private ITaskTreeNode parseTask(Matcher taskMatcher) {
-        if ("}".equals(taskMatcher.group(1))) {
-            throw new IllegalArgumentException("invalid task specification");
-        }
-        
-        String taskDetails = taskMatcher.group(1);
-        
-        Matcher matcher = taskDetailsPattern.matcher(taskDetails);
-        
-        if (!matcher.find()) {
-            throw new IllegalArgumentException("could not parse task details");
-        }
-
-        ITaskTreeNode task;
-        
-        String type = matcher.group(1);
-        
-        String targetId = matcher.group(2);
-        if ((matcher.group(4) != null) && (!"".equals(matcher.group(4).trim()))) {
-            targetId += matcher.group(4).trim();
-        }
-        
-        IEventTarget target = targets.get(targetId);
-        
-        if (target == null) {
-            target = new DummyGUIElement(targetId);
-            targets.put(targetId, target);
-        }
-        
-        if ("Sequence".equals(type)) {
-            task = taskTreeNodeFactory.createNewSequence();
-        }
-        else if ("Selection".equals(type)) {
-            task = taskTreeNodeFactory.createNewSelection();
-        }
-        else if ("Iteration".equals(type)) {
-            task = taskTreeNodeFactory.createNewIteration();
-        }
-        else if ("Optional".equals(type)) {
-            task = taskTreeNodeFactory.createNewOptional();
-        }
-        else {
-            task = taskTreeNodeFactory.createNewEventTask(new StringEventType(type), target);
-        }
-        
-        if ((matcher.group(5) != null) && (!"".equals(matcher.group(5).trim()))) {
-            taskTreeBuilder.setDescription(task, matcher.group(5).trim());
-        }
-
-        while (taskMatcher.find() && !"}".equals(taskMatcher.group(0))) {
-            if (task instanceof ISequence) {
-                taskTreeBuilder.addChild((ISequence) task, parseTask(taskMatcher));
-            }
-            else if (task instanceof ISelection) {
-                taskTreeBuilder.addChild((ISelection) task, parseTask(taskMatcher));
-            }
-            else if (task instanceof IIteration) {
-                if ((task.getChildren() == null) || (task.getChildren().size() == 0)) {
-                    taskTreeBuilder.setChild((IIteration) task, parseTask(taskMatcher));
-                }
-                else {
-                    throw new IllegalArgumentException
-                        ("can not add more than one child to an iteration");
-                }
-            }
-            else if (task instanceof IOptional) {
-                if ((task.getChildren() == null) || (task.getChildren().size() == 0)) {
-                    taskTreeBuilder.setChild((IOptional) task, parseTask(taskMatcher));
-                }
-                else {
-                    throw new IllegalArgumentException
-                        ("can not add more than one child to an optional");
-                }
-            }
-            else {
-                throw new IllegalArgumentException("can not add children to something that is no " +
-                                                   "sequence, selection, or iteration");
-            }
-        }
-
-        return task;
-    }
-
-}
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 1146)
+++ trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeValidator.java	(revision 1146)
@@ -0,0 +1,144 @@
+//   Copyright 2012 Georg-August-Universität Göttingen, Germany
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+package de.ugoe.cs.autoquest.tasktrees;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public class TaskTreeValidator {
+
+    /**
+     * 
+     */
+    public void validate(List<IUserSession> userSessions) {
+        for (IUserSession userSession : userSessions) {
+            validate(userSession);
+        }
+    }
+
+    /**
+     * 
+     */
+    public void validate(ITaskInstanceList taskInstances) {
+        for (ITaskInstance taskInstance : taskInstances) {
+            validate(taskInstance);
+        }
+    }
+
+    /**
+     * 
+     */
+    public void validate(ITaskInstance taskInstance) {
+        assertNotNull("task model of task instance must not be null", taskInstance.getTask());
+        
+        if (taskInstance.getTask() instanceof ISequence) {
+            ISequence task = (ISequence) taskInstance.getTask();
+            
+            assertEquals("number of children of sequence instance must match sequence model",
+                         taskInstance.size(), task.getChildren().size());
+            
+            for (int i = 0; i < taskInstance.size(); i++) {
+                assertNotNull("sequence instance child " + i + " was null", taskInstance.get(i));
+                ITask childTask = taskInstance.get(i).getTask();
+                assertSame("task of sequence child " + i + " does not match sequence model",
+                           childTask, task.getChildren().get(i));
+            }
+        }
+        else if (taskInstance.getTask() instanceof ISelection) {
+            ISelection task = (ISelection) taskInstance.getTask();
+            
+            assertEquals
+                ("number of children of selection instance must be 1", 1, taskInstance.size());
+            assertTrue
+                ("number of children of selection must be larger 0", task.getChildren().size() > 0);
+            
+            boolean found = false;
+            for (ITask childTask : task.getChildren()) {
+                assertNotNull("child of selection model must not be null", childTask);
+                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);
+                if (childTask.equals(taskInstance.get(0).getTask())) {
+                    found = true;
+                    break;
+                }
+            }
+            
+            assertTrue("no child of the selection model matches the model of child of the " +
+                       "selection instance", found);
+        }
+        else if (taskInstance.getTask() instanceof IIteration) {
+            ITask childTask = ((IIteration) taskInstance.getTask()).getMarkedTask();
+            assertNotNull("child task of iteration model must not be null", childTask);
+            assertFalse("child of iteration model must not be an iteration",
+                        childTask instanceof IIteration);
+            assertFalse("child of iteration model must not be an optional",
+                        childTask instanceof IOptional);
+            
+            for (int i = 0; i < taskInstance.size(); i++) {
+                assertNotNull("iteration instance child " + i + " was null", taskInstance.get(i));
+                assertSame("task of iteration child " + i + " does not match iteration model",
+                           childTask, taskInstance.get(i).getTask());
+            }
+        }
+        else if (taskInstance.getTask() instanceof IOptional) {
+            ITask childTask = ((IOptional) taskInstance.getTask()).getMarkedTask();
+            assertNotNull("child task of optional model must not be null", childTask);
+            assertFalse("child of optional model must not be an optional",
+                        childTask instanceof IOptional);
+            
+            assertEquals
+                ("number of children of optional instance must be 1", 1, taskInstance.size());
+            
+            assertEquals("task of optional child does not match optional model",
+                         childTask, taskInstance.get(0).getTask());
+        }
+        else if (taskInstance.getTask() instanceof IEventTask) {
+            IEventTask task = (IEventTask) taskInstance.getTask();
+            assertNotNull("event task model must not be null", task);
+            assertNotNull("event type of event task model must not be null", task.getEventType());
+            assertNotNull
+                ("event target of event task model must not be null", task.getEventTarget());
+
+            assertEquals("event task instance must not have children", 0, taskInstance.size());
+        }
+        else {
+            fail("unknown task model: " + taskInstance.getTask());
+        }
+        
+        for (ITaskInstance child : taskInstance) {
+            validate(child);
+        }
+    }
+}
