Index: /trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/ShowTaskTreeDialog.java
===================================================================
--- /trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/ShowTaskTreeDialog.java	(revision 1423)
+++ /trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/ShowTaskTreeDialog.java	(revision 1424)
@@ -15,4 +15,6 @@
 package de.ugoe.cs.autoquest.ui.swt;
 
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
 import java.util.Collection;
 import java.util.Collections;
@@ -25,18 +27,30 @@
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.events.ShellListener;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Dialog;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
 import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
 import org.eclipse.swt.widgets.TreeItem;
 
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
@@ -45,6 +59,4 @@
 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
-
-import org.eclipse.swt.widgets.Label;
 
 /**
@@ -58,14 +70,40 @@
 
     /** the main shell */
-    protected Shell shell;
+    private Shell shell;
     
+    /** the listener for the main shell to prevent disposing required */
+    private ShellListener shellListener;
+    
+    /** the tab folder containing the instance tree as well as the model tree */
+    private TabFolder tabFolder;
+
     /** the tree of task instances on the left */
     private Tree instanceTree;
     
-    /** the tree of tasks (model) on the right*/
+    /** the tree of tasks on the left */
     private Tree modelTree;
+    
+    /** the tree of a specific task on the right */
+    private Tree taskDetailsTree;
+
+    /** the tree of execution variants of a specific task on the right */
+    private Tree executionVariantsTree;
+
+    /** the tree of involved GUI elements of a specific task on the right bottom */
+    private Tree involvedGUIElementsTree;
+
+    /** the table containing the parents tasks of a displayed task */
+    private Tree parentTasks;
 
     /** the displayed task model */
-    protected ITaskModel taskModel;
+    private ITaskModel taskModel;
+    
+    /** default expansion listener */
+    private Listener defaultExpansionListener = new Listener() {
+        public void handleEvent(final Event event) {
+            ensureChildren((TreeItem) event.item);
+            ((TreeItem) event.item).setExpanded(true);
+        }
+    };
 
     /**
@@ -80,14 +118,64 @@
     /**
      * displays the dialog
+     * @param task 
      */
     public void open() {
-        createContents();
-        shell.open();
-        shell.layout();
+        open(null);
+    }
+
+    /**
+     * displays the dialog with a specific task opened
+     * @param task 
+     */
+    public void open(ITask task) {
+        if (shell == null) {
+            createContents();
+            shell.open();
+            shell.layout();
+
+            VisualizationUtils.updateColumnWidths(taskDetailsTree);
+        }
+        else {
+            shell.setVisible(true);
+        }
+        
+        if (task != null) {
+            shellListener = new ShellAdapter() {
+                @Override
+                public void shellClosed(ShellEvent e) {
+                    e.doit = false;
+                    shell.setVisible(false);
+                }
+            };
+            
+            shell.addShellListener(shellListener);
+        }
+
+        if (task != null) {
+            navigateTo(task);
+        }
+        
         Display display = getParent().getDisplay();
-        while (!shell.isDisposed()) {
+        while (!shell.isDisposed() && shell.isVisible()) {
             if (!display.readAndDispatch()) {
                 display.sleep();
             }
+        }
+        
+        if (task == null) {
+            dispose();
+        }
+    }
+
+    /**
+     * disposes the dialog if it is not used anymore
+     */
+    public void dispose() {
+        if ((shell != null) && (!shell.isDisposed())) {
+            if (shellListener != null) {
+                shell.removeShellListener(shellListener);
+            }
+            
+            shell.dispose();
         }
     }
@@ -99,34 +187,21 @@
      */
     private void createContents() {
-        shell = new Shell(getParent(), SWT.SHELL_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
-        shell.setSize(750, 800);
+        shell = new Shell(getParent(), SWT.SHELL_TRIM | SWT.BORDER);
+
+        GraphicsDevice gd =
+            GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
+        
+        shell.setSize(gd.getDisplayMode().getWidth(), gd.getDisplayMode().getHeight());
         shell.setText(getText());
 
         shell.setLayout(new GridLayout(4, false));
         
-        SashForm sashForm = new SashForm(shell, SWT.HORIZONTAL);
-        sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1));
-        
-        instanceTree = new Tree(sashForm, SWT.BORDER | SWT.MULTI);
-        instanceTree.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                modelTree.removeAll();
-                TreeItem[] selectedItems = instanceTree.getSelection();
-                if (selectedItems.length == 1) {
-                    if (selectedItems[0].getData() instanceof ITaskInstance) {
-                        buildModelTree((ITaskInstance) selectedItems[0].getData());
-                    }
-                    else if (selectedItems[0].getData() instanceof ITaskModel) {
-                        buildModelTree((ITaskModel) selectedItems[0].getData());
-                    }
-                }
-            }
-        });
-
-        buildInstanceTree();
-
-        modelTree = new Tree(sashForm, SWT.BORDER | SWT.MULTI);
-        buildModelTree(taskModel);
+        SashForm mainSashForm = new SashForm(shell, SWT.HORIZONTAL);
+        mainSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1));
+        
+        createSessionsAndTasksTabFolder(mainSashForm);
+        createTaskDetailsView(mainSashForm);
+
+        mainSashForm.setWeights(new int[] { 1, 3 });
 
         Button btnExpandAll = new Button(shell, SWT.NONE);
@@ -134,5 +209,10 @@
             @Override
             public void widgetSelected(SelectionEvent e) {
-                expandAll(instanceTree, true);
+                if (tabFolder.getSelectionIndex() == 0) {
+                    VisualizationUtils.expandAll(instanceTree, true);
+                }
+                else {
+                    VisualizationUtils.expandAll(modelTree, true);
+                }
             }
         });
@@ -143,14 +223,149 @@
             @Override
             public void widgetSelected(SelectionEvent e) {
-                expandAll(instanceTree, false);
+                if (tabFolder.getSelectionIndex() == 0) {
+                    VisualizationUtils.expandAll(instanceTree, false);
+                }
+                else {
+                    VisualizationUtils.expandAll(modelTree, false);
+                }
             }
         });
         btnCollapseAll.setText("Collapse all");
         
-        //new Label(shell, SWT.NONE);
         new Label(shell, SWT.NONE);
         new Label(shell, SWT.NONE);
-        new Label(shell, SWT.NONE);
-
+    }
+
+    /**
+     *
+     */
+    private void createSessionsAndTasksTabFolder(SashForm mainSashForm) {
+        tabFolder = new TabFolder(mainSashForm, SWT.NONE);
+        tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+        tabFolder.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                VisualizationUtils.updateColumnWidths(modelTree);
+            }
+        });
+        
+        TabItem instanceTreeTab = new TabItem(tabFolder, SWT.NONE);
+        instanceTreeTab.setText("Task Instances");
+
+        instanceTree = new Tree(tabFolder, SWT.BORDER | SWT.SINGLE | SWT.VIRTUAL);
+        instanceTree.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                TreeItem[] selectedItems = instanceTree.getSelection();
+                if ((selectedItems.length == 1) &&
+                    (selectedItems[0].getData() instanceof ITaskInstance))
+                {
+                    displayTaskDetails(((ITaskInstance) selectedItems[0].getData()).getTask());
+                }
+                else {
+                    clearTaskDetails();
+                }
+            }
+        });
+
+        VisualizationUtils.addItemSpecificContextMenu
+            (instanceTree, ITaskInstance.class, "show in task list", new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                navigateTo(((ITaskInstance) instanceTree.getSelection()[0].getData()).getTask());
+            }
+        });
+
+        buildInstanceTree();
+        instanceTreeTab.setControl(instanceTree);
+
+        TabItem modelTreeTab = new TabItem(tabFolder, SWT.NONE);
+        modelTreeTab.setText("Tasks");
+        
+        modelTree =
+            VisualizationUtils.createTaskDetailsTree(tabFolder, "tasks in model", taskModel);
+       
+        // show task details if requested
+        modelTree.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                TreeItem[] selectedItems = modelTree.getSelection();
+                if ((selectedItems.length == 1) && (selectedItems[0].getData() instanceof ITask)) {
+                    displayTaskDetails((ITask) selectedItems[0].getData());
+                }
+                else {
+                    clearTaskDetails();
+                }
+            }
+        });
+        
+        buildModelTree(taskModel);
+        
+        modelTreeTab.setControl(modelTree);
+    }
+
+    /**
+     *
+     */
+    private void createTaskDetailsView(SashForm mainSashForm) {
+        Composite detailsComposite = new Composite(mainSashForm, SWT.NO_BACKGROUND);
+        detailsComposite.setLayout(new GridLayout(1, false));
+        detailsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+        
+        new Label(detailsComposite, SWT.NONE).setText("Task Details:");
+        
+        SashForm detailsSashForm = new SashForm(detailsComposite, SWT.VERTICAL);
+        detailsSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+        
+        SashForm detailsTopSashForm = new SashForm(detailsSashForm, SWT.HORIZONTAL);
+        detailsTopSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+        
+        taskDetailsTree =
+            VisualizationUtils.createTaskDetailsTree(detailsTopSashForm, "task details", taskModel);
+        
+        VisualizationUtils.addExpansionListener(taskDetailsTree, defaultExpansionListener);
+        
+        VisualizationUtils.addItemSpecificContextMenu(taskDetailsTree, ITask.class,
+                                                      "show in task list", new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                navigateTo((ITask) taskDetailsTree.getSelection()[0].getData());
+            }
+        });
+        
+        executionVariantsTree = new Tree(detailsTopSashForm, SWT.BORDER | SWT.SINGLE | SWT.WRAP);
+        executionVariantsTree.setHeaderVisible(true);
+        
+        TreeColumn taskColumn = new TreeColumn(executionVariantsTree, SWT.NONE);
+        taskColumn.setText("instance variants");
+        taskColumn.setAlignment(SWT.LEFT);
+
+        // load the correct children on expansion
+        VisualizationUtils.addExpansionListener(executionVariantsTree, defaultExpansionListener);
+        
+        detailsTopSashForm.setWeights(new int[] { 3, 2 });
+
+        SashForm detailsBottomSashForm = new SashForm(detailsSashForm, SWT.HORIZONTAL);
+        detailsBottomSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+        
+        parentTasks = VisualizationUtils.createTaskDetailsTree
+            (detailsBottomSashForm, "parent tasks", taskModel);
+        
+        VisualizationUtils.addItemSpecificContextMenu(parentTasks, ITask.class,
+                                                      "show in task list", new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                navigateTo((ITask) parentTasks.getSelection()[0].getData());
+            }
+        });
+        
+        involvedGUIElementsTree =
+            VisualizationUtils.createGUIElementsTree(detailsBottomSashForm, "involved GUI elements");
+        
+        detailsBottomSashForm.setWeights(new int[] { 2, 3 });
+        detailsSashForm.setWeights(new int[] { 1, 1 });
     }
 
@@ -160,5 +375,8 @@
     private void buildInstanceTree() {
         List<IUserSession> sessions = taskModel.getUserSessions();
-        
+
+        // load the correct children on expansion
+        VisualizationUtils.addExpansionListener(instanceTree, defaultExpansionListener);
+
         TreeItem root = new TreeItem(instanceTree, SWT.NULL);
         root.setText(sessions.size() + " sessions");
@@ -168,4 +386,6 @@
             buildInstanceTree(root, session);
         }
+        
+        root.setExpanded(true);
     }
 
@@ -174,32 +394,10 @@
      */
     private void buildInstanceTree(TreeItem currentParent, IUserSession session) {
-        TreeItem child = new TreeItem(currentParent, SWT.NULL);
-        child.setText(session.toString());
-        child.setData(session);
-        
-        for (ITaskInstance childInstance : session) {
-            buildInstanceTree(child, childInstance);
-        }
-    }
-
-    /**
-     * convenience method for creating the display of the instances
-     */
-    private void buildInstanceTree(TreeItem currentParent, ITaskInstance taskInstance) {
-        TreeItem child = new TreeItem(currentParent, SWT.NULL);
-        child.setText(taskInstance.toString());
-        child.setData(taskInstance);
-        
-        if (taskInstance instanceof ITaskInstanceList) {
-            for (ITaskInstance childInstance : (ITaskInstanceList) taskInstance) {
-                buildInstanceTree(child, childInstance);
-            }
-        }
-        else if (taskInstance instanceof ISelectionInstance) {
-            buildInstanceTree(child, ((ISelectionInstance) taskInstance).getChild());
-        }
-        else if (taskInstance instanceof IOptionalInstance) {
-            buildInstanceTree(child, ((IOptionalInstance) taskInstance).getChild());
-        }
+        TreeItem item = new TreeItem(currentParent, SWT.NULL);
+        item.setText(session.toString());
+        item.setData(session);
+        
+        // simulate a child
+        new TreeItem(item, SWT.NULL);
     }
 
@@ -208,27 +406,25 @@
      */
     private void buildModelTree(ITaskModel taskModel) {
-        modelTree.removeAll();
-        
-        // load the correct children on expansion
-        if (modelTree.getListeners(SWT.Expand).length == 0) {
-           modelTree.addListener(SWT.Expand, new Listener() {
-               public void handleEvent(final Event event) {
-                   ensureChildren((TreeItem) event.item);
-                   ((TreeItem) event.item).setExpanded(true);
-               }
-           });
-        }
-        
-        Collection<ITask> tasks = taskModel.getTasks();
+        Collection<ITask> allTasks = taskModel.getTasks();
+        
+        List<ITask> sequences = new LinkedList<ITask>();
+        List<ITask> iterations = new LinkedList<ITask>();
+        List<ITask> selections = new LinkedList<ITask>();
+        List<ITask> optionals = new LinkedList<ITask>();
+        List<ITask> others = new LinkedList<ITask>();
         
         TreeItem root = new TreeItem(modelTree, SWT.NULL);
-        root.setText(tasks.size() + " tasks in model (showing only root tasks)");
+        root.setText(allTasks.size() + " tasks in model");
         root.setData(taskModel);
 
-        tasks = createSortedTaskList(tasks);
-        
-        for (ITask task : tasks) {
-            createTreeItemFor(task, root);
-        }
+        createSortedTaskLists(allTasks, sequences, iterations, selections, optionals, others);
+        
+        //allTasks = createSortedTaskList(allTasks);
+        
+        createModelTreeItemFor(sequences, sequences.size() + " Sequences", root);
+        createModelTreeItemFor(iterations, iterations.size() + " Iterations", root);
+        createModelTreeItemFor(selections, selections.size() + " Selections", root);
+        createModelTreeItemFor(optionals, optionals.size() + " Optionals", root);
+        createModelTreeItemFor(others, others.size() + " other Tasks", root);
         
         root.setExpanded(true);
@@ -236,92 +432,158 @@
 
     /**
-     * convenience method for creating the display of the task model
-     */
-    private void buildModelTree(ITaskInstance taskInstance) {
-        modelTree.removeAll();
-        TreeItem root = new TreeItem(modelTree, SWT.NULL);
-        root.setText("model of instance " + taskInstance);
-        root.setData(taskInstance);
-
-        createTreeItemFor(taskInstance.getTask(), root);
-        
-        expandAll(root, true, 20);
-    }
-
-    /**
-     * sort the list of tasks so that it contain those occurring most often first
-     */
-    private List<ITask> createSortedTaskList(Collection<ITask> tasks) {
-        /*Set<ITask> resultSet = new HashSet<ITask>(tasks);
-        
-        for (ITask task : tasks) {
-            removeChildren(task, resultSet);
-        }*/
-        
-        List<ITask> result = new LinkedList<ITask>(tasks);
-        
-        Collections.sort(result, new Comparator<ITask>() {
-            @Override
-            public int compare(ITask task1, ITask task2) {
-                return taskModel.getTaskInfo(task2).getCount() -
-                    taskModel.getTaskInfo(task1).getCount();
-            }
-
-            /*private int depth(ITask task) {
-                int maxChildDepth = 0;
-                if (task instanceof IStructuringTemporalRelationship) {
-                    for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) {
-                        maxChildDepth = Math.max(maxChildDepth, depth(child));
+     *
+     */
+    private void createSortedTaskLists(Collection<ITask> allTasks,
+                                       List<ITask>       sequences,
+                                       List<ITask>       iterations,
+                                       List<ITask>       selections,
+                                       List<ITask>       optionals,
+                                       List<ITask>       others)
+    {
+        List<ITask> toAdd;
+        
+        for (ITask task : allTasks) {
+            if (task instanceof ISequence) {
+                toAdd = sequences;
+            }
+            else if (task instanceof IIteration) {
+                toAdd = iterations;
+            }
+            else if (task instanceof ISelection) {
+                toAdd = selections;
+            }
+            else if (task instanceof IOptional) {
+                toAdd = optionals;
+            }
+            else {
+                toAdd = others;
+            }
+            
+            int taskCount = task.getInstances().size();
+            int start = 0;
+            int end = toAdd.size();
+            int center = 0;
+            int centerCount;
+            
+            while (start != end) {
+                center = start + ((end - start) / 2);
+                
+                if ((center != start) || (center != end)) {
+                    centerCount = toAdd.get(center).getInstances().size();
+                
+                    if (centerCount > taskCount) {
+                        start = Math.max(center, start + 1);
                     }
-                }
-                else if (task instanceof IMarkingTemporalRelationship) {
-                    maxChildDepth = Math.max
-                        (maxChildDepth, depth(((IMarkingTemporalRelationship) task).getMarkedTask()));
-                }
-                return maxChildDepth + 1;
-            }*/
-        });
-        
-        return result;
-    }
-
-    /**
-     * convenience method for removed all non root tasks of the provided list
-     */
-    /*private void removeChildren(ITask task, Set<ITask> result) {
-        if (task instanceof IStructuringTemporalRelationship) {
-            for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) {
-                result.remove(child);
-            }
-        }
-        else if (task instanceof IMarkingTemporalRelationship) {
-            result.remove(((IMarkingTemporalRelationship) task).getMarkedTask());
-        }
-    }*/
-
-    /**
-     * expands all nodes in the tree
-     */
-    private void expandAll(Tree tree, boolean expanded) {
-        for (TreeItem item : tree.getItems()) {
-            expandAll(item, expanded, Integer.MAX_VALUE);
-        }
-    }
-
-    /**
-     * expands all nodes in the tree
-     */
-    private void expandAll(TreeItem item, boolean expanded, int maxChildrenToExpand) {
-        if (expanded) {
-            ensureChildren(item);
-        }
-        
-        if (item.getItems().length < maxChildrenToExpand) {
-            item.setExpanded(expanded);
-
-            for (TreeItem childItem : item.getItems()) {
-                expandAll(childItem, expanded, maxChildrenToExpand);
-            }
-        }
+                    else if (centerCount < taskCount) {
+                        end = Math.min(center, end - 1);
+                    }
+                    else {
+                        // add the event directly where the center is, as the count of the center
+                        // and the new task are equal
+                        end = center;
+                        start = end;
+                        break;
+                    }
+                }
+                else {
+                    // add the event to the position denoted by the add index
+                    break;
+                }
+            }
+            
+            toAdd.add(start, task);
+        }
+    }
+
+    /**
+     *
+     */
+    private void clearTaskDetails() {
+        taskDetailsTree.removeAll();
+        executionVariantsTree.removeAll();
+        involvedGUIElementsTree.removeAll();
+        parentTasks.removeAll();
+    }
+
+    /**
+     *
+     */
+    private void displayTaskDetails(ITask task) {
+        clearTaskDetails();
+        
+        VisualizationUtils.createTreeItemFor(task, taskDetailsTree, taskModel, true);
+        VisualizationUtils.expandAll(taskDetailsTree, true);
+        
+        // do it twice. Otherwise, it doesn't work
+        VisualizationUtils.updateColumnWidths(taskDetailsTree);
+        
+        Collection<Collection<ITaskInstance>> executionVariants = task.getExecutionVariants();
+        List<Collection<ITaskInstance>> sortedExecutionVariants =
+            new LinkedList<Collection<ITaskInstance>>(executionVariants);
+        
+        Collections.sort(sortedExecutionVariants, new Comparator<Collection<ITaskInstance>>() {
+            @Override
+            public int compare(Collection<ITaskInstance> list1, Collection<ITaskInstance> list2) {
+                return list2.size() - list1.size();
+            }
+        });
+        
+        int counter = 1;
+        for (Collection<ITaskInstance> variant : sortedExecutionVariants) {
+            TreeItem item = new TreeItem(executionVariantsTree, SWT.NULL);
+            if (variant.size() > 1) {
+                item.setText("variant " + counter++ + " (executed " + variant.size() + " times)");
+            }
+            else {
+                item.setText("variant " + counter++ + " (executed once)");
+            }
+            item.setData(variant);
+            
+            createTreeItemFor(variant.iterator().next(), item);
+        }
+
+        VisualizationUtils.expandAll(executionVariantsTree, true);
+        VisualizationUtils.updateColumnWidths(executionVariantsTree);
+        
+        addParentTasks(task);
+        VisualizationUtils.updateColumnWidths(parentTasks);
+        
+        VisualizationUtils.addInvolvedTargets(involvedGUIElementsTree, task);
+    }
+
+    /**
+     *
+     */
+    private void addParentTasks(ITask task) {
+        for (ITask candidate : taskModel.getTasks()) {
+            if (((candidate instanceof IStructuringTemporalRelationship) &&
+                 (((IStructuringTemporalRelationship) candidate).getChildren().contains(task))) ||
+                ((candidate instanceof IMarkingTemporalRelationship) &&
+                 (((IMarkingTemporalRelationship) candidate).getMarkedTask().equals(task))))
+            {
+                VisualizationUtils.createTreeItemFor(candidate, parentTasks, taskModel, false);
+            }
+        }
+    }
+
+    /**
+     * 
+     */
+    private void navigateTo(ITask task) {
+        tabFolder.setSelection(1);
+        
+        OUTER:
+        for (TreeItem sublist : modelTree.getItem(0).getItems()) {
+            for (TreeItem taskItem : sublist.getItems()) {
+                if (task.equals(taskItem.getData())) {
+                    modelTree.setSelection(taskItem);
+                    sublist.setExpanded(true);
+                    VisualizationUtils.updateColumnWidths(modelTree);
+                    break OUTER;
+                }
+            }
+        }
+        
+        displayTaskDetails(task);
     }
     
@@ -330,24 +592,67 @@
      */
     private void ensureChildren(TreeItem parent) {
-        if (parent.getData() instanceof ITask) {
-            TreeItem[] items = parent.getItems();
-            if ((items == null) || (items.length == 0) || (items[0].getData() == null)) {
-                if (items != null) {
-                    for (int i = 0; i < items.length; i++) {
-                        items[i].dispose();
-                    }
-                }
-
+        TreeItem[] items = parent.getItems();
+        if ((items == null) || (items.length == 0) || (items[0].getData() == null)) {
+            if (items != null) {
+                for (int i = 0; i < items.length; i++) {
+                    items[i].dispose();
+                }
+            }
+
+            if (parent.getData() instanceof ITask) {
                 ITask task = (ITask) parent.getData();
 
                 if (task instanceof IStructuringTemporalRelationship) {
                     for (ITask subTask : ((IStructuringTemporalRelationship) task).getChildren()) {
-                        createTreeItemFor(subTask, parent);
+                        VisualizationUtils.createTreeItemFor(subTask, parent, taskModel, true);
                     }
                 }
                 else if (task instanceof IMarkingTemporalRelationship) {
-                    createTreeItemFor
-                        (((IMarkingTemporalRelationship) task).getMarkedTask(), parent);
-                }
+                    VisualizationUtils.createTreeItemFor
+                        (((IMarkingTemporalRelationship) task).getMarkedTask(), parent,
+                         taskModel, true);
+                }
+            }
+            else if (parent.getData() instanceof List<?>) {
+                @SuppressWarnings("unchecked")
+                List<ITask> tasks = (List<ITask>) parent.getData();
+                for (ITask task : tasks) {
+                    VisualizationUtils.createTreeItemFor(task, parent, taskModel, false);
+                }
+            }
+            else if (parent.getData() instanceof ITaskInstanceList) {
+                for (ITaskInstance subInstance : (ITaskInstanceList) parent.getData()) {
+                    createTreeItemFor(subInstance, parent);
+                }
+            }
+            else if (parent.getData() instanceof ITaskInstance) {
+                ITaskInstance instance = (ITaskInstance) parent.getData();
+
+                if (instance instanceof ISelectionInstance) {
+                    if (((ISelectionInstance) instance).getChild() != null) {
+                        createTreeItemFor(((ISelectionInstance) instance).getChild(), parent);
+                    }
+                }
+                else if (instance instanceof IOptionalInstance) {
+                    if (((IOptionalInstance) instance).getChild() != null) {
+                        createTreeItemFor(((IOptionalInstance) instance).getChild(), parent);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    private void createModelTreeItemFor(List<ITask> taskList, String name, TreeItem parent) {
+        TreeItem item = new TreeItem(parent, SWT.NULL);
+        item.setText(name);
+        item.setData(taskList);
+        
+        // simulate a child
+        if (taskList.size() > 0) {
+            for (ITask task : taskList) {
+                VisualizationUtils.createTreeItemFor(task, item, taskModel, false);
             }
         }
@@ -357,16 +662,18 @@
      * convenience method to create a tree item for a task
      */
-    private void createTreeItemFor(ITask task, TreeItem parent) {
+    private void createTreeItemFor(ITaskInstance taskInstance,
+                                   TreeItem      parent)
+    {
         TreeItem item = new TreeItem(parent, SWT.NULL);
-        item.setText(task.toString() + " (" + taskModel.getTaskInfo(task).getCount() + ")");
-        item.setData(task);
+        item.setText(taskInstance.toString());
+        item.setData(taskInstance);
         
         // simulate a child
-        if ((task instanceof IStructuringTemporalRelationship) ||
-            (task instanceof IMarkingTemporalRelationship))
+        if ((taskInstance instanceof ITaskInstanceList) ||
+            (taskInstance instanceof ISelectionInstance) ||
+            (taskInstance instanceof IOptionalInstance))
         {
             new TreeItem(item, SWT.NULL);
         }
     }
-
 }
Index: /trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/VisualizationUtils.java
===================================================================
--- /trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/VisualizationUtils.java	(revision 1424)
+++ /trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/VisualizationUtils.java	(revision 1424)
@@ -0,0 +1,359 @@
+//   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.ui.swt;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MenuAdapter;
+import org.eclipse.swt.events.MenuEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.Widget;
+
+import de.ugoe.cs.autoquest.eventcore.IEventTarget;
+import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskMetric;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+class VisualizationUtils {
+    
+
+    /**
+     *
+     */
+    static Tree createTaskDetailsTree(Composite  parent,
+                                      String     firstColumnHeader,
+                                      ITaskModel taskModel)
+    {
+        final Tree tree = new Tree(parent, SWT.BORDER | SWT.SINGLE | SWT.VIRTUAL);
+        tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+        tree.setHeaderVisible(true);
+        
+        TreeColumn taskColumn = new TreeColumn(tree, SWT.NONE);
+        taskColumn.setText(firstColumnHeader);
+        taskColumn.setAlignment(SWT.LEFT);
+       
+        TaskMetric[] metrics = taskModel.getAllMetrics();
+        
+        for (TaskMetric metric : metrics) {
+            TreeColumn metricColumn = new TreeColumn(tree, SWT.WRAP);
+            metricColumn.setText(metric.getName().replace(' ', '\n'));
+            metricColumn.setToolTipText(metric.getDescription());
+            metricColumn.setAlignment(SWT.CENTER);
+        }
+
+        // update the columns widths on expansion and collapse
+        if (tree.getListeners(SWT.Expand).length == 0) {
+            tree.addListener(SWT.Expand, new Listener() {
+               public void handleEvent(final Event event) {
+                   ((TreeItem) event.item).setExpanded(true);
+                   updateColumnWidths(tree);
+               }
+           });
+        }
+
+        if (tree.getListeners(SWT.Collapse).length == 0) {
+            tree.addListener(SWT.Collapse, new Listener() {
+               public void handleEvent(final Event event) {
+                   ((TreeItem) event.item).setExpanded(false);
+                   updateColumnWidths(tree);
+               }
+           });
+        }
+
+        return tree;
+    }
+
+    /**
+     * convenience method to create a tree item for a task
+     */
+    static void createTreeItemFor(ITask      task,
+                                  Widget     parent,
+                                  ITaskModel taskModel,
+                                  boolean    createChildren)
+    {
+        ITaskInfo taskInfo = taskModel.getTaskInfo(task);
+        
+        TaskMetric[] metrics = taskModel.getAllMetrics();
+        String[] values = new String[metrics.length + 2];
+        
+        values[0] = task.toString();
+        
+        for (int i = 0; i < metrics.length; i++) {
+            int contextValue = Integer.MIN_VALUE;
+            
+            if (parent.getData() instanceof ITask) {
+                contextValue = taskInfo.getMeasureValue(metrics[i], (ITask) parent.getData());
+            }
+            
+            if (contextValue > Integer.MIN_VALUE) {
+                values[i + 1] = metrics[i].formatValue(contextValue) + "(" +
+                    metrics[i].formatValue(taskInfo.getMeasureValue(metrics[i])) + ")";
+            }
+            else {
+                values[i + 1] = metrics[i].formatValue(taskInfo.getMeasureValue(metrics[i]));
+            }
+        }
+        
+        values[values.length - 1] = Integer.toString(task.getId());
+        
+        TreeItem item;
+        if (parent instanceof TreeItem) {
+            item = new TreeItem((TreeItem) parent, SWT.NULL);
+        }
+        else {
+            item = new TreeItem((Tree) parent, SWT.NULL);
+        }
+        item.setText(values);
+        item.setData(task);
+        
+        if (createChildren) {
+            // simulate a child
+            if ((task instanceof IStructuringTemporalRelationship) ||
+                (task instanceof IMarkingTemporalRelationship))
+            {
+                new TreeItem(item, SWT.NULL);
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    static Tree createGUIElementsTree(Composite  parent, String name) {
+        Tree tree = new Tree(parent, SWT.BORDER | SWT.SINGLE);
+        tree.setHeaderVisible(true);
+        
+        TreeColumn guiElementColumn = new TreeColumn(tree, SWT.NONE);
+        guiElementColumn.setText(name);
+        guiElementColumn.setAlignment(SWT.LEFT);
+        
+        return tree;
+    }
+
+    /**
+     *
+     */
+    static void updateColumnWidths(Tree tree) {
+        TreeColumn firstColumn = tree.getColumn(0);
+        firstColumn.pack();
+        
+        if (tree.getColumnCount() > 1) {
+            int availableWidth = tree.getBounds().width - firstColumn.getWidth();
+            int effectiveWidth = 0;
+            for (int i = 1; i < tree.getColumnCount(); i++) {
+                TreeColumn column = tree.getColumn(i);
+                column.pack();
+                effectiveWidth += column.getWidth();
+            }
+            
+            if (effectiveWidth < availableWidth) {
+                firstColumn.setWidth(firstColumn.getWidth() + availableWidth - effectiveWidth - 20);
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    static void addItemSpecificContextMenu(final Tree             tree,
+                                           final Class<?>         selectedItemDataType,
+                                           final String           menuItemText,
+                                           final SelectionAdapter menuItemSelectionAdapter)
+    {
+        final Menu menu = new Menu(tree);
+        tree.setMenu(menu);
+        menu.addMenuListener(new MenuAdapter() {
+            public void menuShown(MenuEvent e) {
+                MenuItem[] items = menu.getItems();
+                for (int i = 0; i < items.length; i++) {
+                    items[i].dispose();
+                }
+                
+                if (selectedItemDataType.isInstance(tree.getSelection()[0].getData())) {
+                    MenuItem newItem = new MenuItem(menu, SWT.NONE);
+                    newItem.setText(menuItemText);
+                    newItem.addSelectionListener(menuItemSelectionAdapter);
+                }
+            }
+        });
+    }
+    
+    /**
+     *
+     */
+    static void addInvolvedTargets(Tree guiElementsTree, ITask task) {
+        List<IEventTarget> targets = new ArrayList<IEventTarget>();
+        getInvolvedTargets(task, targets);
+        addInvolvedTargets(guiElementsTree, targets);
+    }
+    
+    /**
+     *
+     */
+    static void getInvolvedTargets(ITask task, List<IEventTarget> involvedTargets) {
+        if (task instanceof IStructuringTemporalRelationship) {
+            for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) {
+                getInvolvedTargets(child, involvedTargets);
+            }
+        }
+        else if (task instanceof IMarkingTemporalRelationship) {
+            getInvolvedTargets
+                (((IMarkingTemporalRelationship) task).getMarkedTask(), involvedTargets);
+        }
+        else {
+            involvedTargets.add
+                (((IEventTaskInstance) task.getInstances().iterator().next()).getEvent().getTarget());
+        }
+    }
+
+    /**
+     *
+     */
+    static void addInvolvedTargets(Tree guiElementsTree, List<IEventTarget> targets) {
+        for (IEventTarget target : targets) {
+            List<IEventTarget> pathToIntegrate = new LinkedList<IEventTarget>();
+
+            while (target != null) {
+                pathToIntegrate.add(0, target);
+
+                if (target instanceof IGUIElement) {
+                    target = ((IGUIElement) target).getParent();
+                }
+                else {
+                    target = null;
+                }
+            }
+
+            TreeItem parent = null;
+
+            while (pathToIntegrate.size() > 0) {
+                TreeItem[] children;
+
+                if (parent == null) {
+                    children = guiElementsTree.getItems();
+                }
+                else {
+                    children = parent.getItems();
+                }
+
+                TreeItem childItem = null;
+
+                if (children != null) {
+                    for (TreeItem child : children) {
+                        if (pathToIntegrate.get(0).equals(child.getData())) {
+                            childItem = child;
+                        }
+                    }
+                }
+
+                if (childItem == null) {
+                    if (parent == null) {
+                        childItem = new TreeItem(guiElementsTree, SWT.NONE);
+                    }
+                    else {
+                        childItem = new TreeItem(parent, SWT.NONE);
+                    }
+
+                    childItem.setText(pathToIntegrate.get(0).toString());
+                    childItem.setData(pathToIntegrate.get(0));
+                }
+
+                pathToIntegrate.remove(0);
+                parent = childItem;
+            }
+        }
+        
+        expandAll(guiElementsTree, true);
+        updateColumnWidths(guiElementsTree);
+    }
+
+    /**
+     *
+     */
+    static void addExpansionListener(Tree tree, Listener listener) {
+        Listener[] listeners = tree.getListeners(SWT.Expand);
+        
+        for (Listener existingListener : listeners) {
+            if ((existingListener == listener) || (existingListener.equals(listener))) {
+                return;
+            }
+        }
+        
+        tree.addListener(SWT.Expand, listener);
+    }
+    
+    /**
+     * expands all nodes in a tree
+     */
+    static void expandAll(Tree tree, boolean expanded) {
+        for (TreeItem item : tree.getItems()) {
+            expandAll(item, expanded, Integer.MAX_VALUE);
+        }
+    }
+
+    /**
+     * expands all nodes in a tree up to a specific number of children
+     */
+    static void expandAll(TreeItem item, boolean expanded, int maxChildrenToExpand) {
+        if (item.getItems().length < maxChildrenToExpand) {
+            Listener[] listeners = item.getParent().getListeners(SWT.Expand);
+            if (listeners != null) {
+                for (Listener listener : listeners) {
+                    Event event = new Event();
+                    event.type = SWT.Expand;
+                    event.item = item;
+                    listener.handleEvent(event);
+                }
+            }
+            
+            item.setExpanded(expanded);
+
+            for (TreeItem childItem : item.getItems()) {
+                expandAll(childItem, expanded, maxChildrenToExpand);
+            }
+        }
+    }
+
+    /**
+     * 
+     */
+    private VisualizationUtils() {
+        // prevent instantiation
+    }
+}
