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 1921)
+++ trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/ShowTaskTreeDialog.java	(revision 2033)
@@ -15,6 +15,8 @@
 package de.ugoe.cs.autoquest.ui.swt;
 
+import java.awt.Frame;
 import java.awt.GraphicsDevice;
 import java.awt.GraphicsEnvironment;
+import java.lang.reflect.Method;
 import java.util.Collection;
 import java.util.Collections;
@@ -24,5 +26,7 @@
 
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.awt.SWT_AWT;
 import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.custom.StackLayout;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
@@ -30,13 +34,18 @@
 import org.eclipse.swt.events.ShellEvent;
 import org.eclipse.swt.events.ShellListener;
+import org.eclipse.swt.graphics.Color;
 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.Control;
 import org.eclipse.swt.widgets.Dialog;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.TabFolder;
@@ -45,4 +54,6 @@
 import org.eclipse.swt.widgets.TreeColumn;
 import org.eclipse.swt.widgets.TreeItem;
+import org.jfree.chart.ChartPanel;
+import org.jfree.chart.JFreeChart;
 
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
@@ -60,4 +71,5 @@
 import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
 import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskMetric;
+import de.ugoe.cs.util.console.Console;
 
 /**
@@ -76,5 +88,5 @@
     private ShellListener shellListener;
     
-    /** the tab folder containing the instance tree as well as the model tree */
+    /** the tab folder containing the instance tree, the model tree, and the visualizations list */
     private TabFolder tabFolder;
 
@@ -85,4 +97,16 @@
     private Tree modelTree;
     
+    /** the tree of possible visualizations on the left */
+    private Tree modelVisualizationTree;
+    
+    /** the right hand composite containing either task details or a visualization */
+    private Composite rightHandComposite;
+    
+    /** the stack layout displaying either the task details or a visualization */
+    private StackLayout rightHandLayout;
+    
+    /** the task details composite containing the task details tree, the execution variants, etc.*/
+    private Composite detailsComposite;
+    
     /** the tree of a specific task on the right */
     private Tree taskDetailsTree;
@@ -96,7 +120,13 @@
     /** the table containing the parents tasks of a displayed task */
     private Tree parentTasks;
+    
+    /** the visualization composite on the right hand side toggled with the details composite */
+    private Composite visualizationsComposite;
 
     /** the displayed task model */
     private ITaskModel taskModel;
+    
+    /** a boolean indicating if the CTTE export of a task is possible */
+    private boolean taskExportAvailable = false;
     
     /** default expansion listener */
@@ -122,4 +152,17 @@
      */
     public void open() {
+        // check, if export to CTTE is possible
+        try {
+            Class<?> exportClass = this.getClass().getClassLoader().loadClass
+                ("de.ugoe.cs.autoquest.plugin.exports.tasktree.CTTExportUtils");
+            
+            if (exportClass != null) {
+                taskExportAvailable = true;
+            }
+        }
+        catch (ClassNotFoundException e) {
+            // ignore. No export available
+        }
+        
         open(null);
     }
@@ -201,6 +244,6 @@
         mainSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1));
         
-        createSessionsAndTasksTabFolder(mainSashForm);
-        createTaskDetailsView(mainSashForm);
+        createLeftHandSideTabs(mainSashForm);
+        createRightHandSideView(mainSashForm);
 
         mainSashForm.setWeights(new int[] { 1, 3 });
@@ -241,5 +284,5 @@
      *
      */
-    private void createSessionsAndTasksTabFolder(SashForm mainSashForm) {
+    private void createLeftHandSideTabs(final SashForm mainSashForm) {
         tabFolder = new TabFolder(mainSashForm, SWT.NONE);
         tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
@@ -247,5 +290,20 @@
             @Override
             public void widgetSelected(SelectionEvent e) {
-                VisualizationUtils.updateColumnWidths(modelTree);
+                if (tabFolder.getSelectionIndex() == 0) {
+                    // task instances tab selected
+                    rightHandLayout.topControl = detailsComposite;
+                }
+                else if (tabFolder.getSelectionIndex() == 1) {
+                    // task model tab selected
+                    rightHandLayout.topControl = detailsComposite;
+                    VisualizationUtils.updateColumnWidths(modelTree);
+                }
+                else {
+                    rightHandLayout.topControl = visualizationsComposite;
+                }
+                
+                rightHandComposite.layout();
+                rightHandComposite.redraw();
+                rightHandComposite.update();
             }
         });
@@ -278,4 +336,15 @@
             }
         });
+        
+        if (taskExportAvailable) {
+            VisualizationUtils.addItemSpecificContextMenu
+                (instanceTree, ITask.class, "export to ConcurTaskTree", new SelectionAdapter()
+            {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    export((ITask) taskDetailsTree.getSelection()[0].getData());
+                }
+            });
+        }
 
         buildInstanceTree();
@@ -305,11 +374,71 @@
         
         modelTreeTab.setControl(modelTree);
-    }
-
+
+        TabItem modelVisualizationTab = new TabItem(tabFolder, SWT.NONE);
+        modelVisualizationTab.setText("Visualizations");
+        
+        modelVisualizationTree = new Tree(tabFolder, SWT.BORDER | SWT.SINGLE | SWT.VIRTUAL);
+        
+        TreeItem item1 = new TreeItem(modelVisualizationTree, SWT.NULL);
+        item1.setText(TaskTreePlotUtils.TASK_COUNT__EVENT_COVERAGE_PLOT);
+        
+        item1 = new TreeItem(modelVisualizationTree, SWT.NULL);
+        item1.setText(TaskTreePlotUtils.ORDERED_TASK_COUNT_PLOT);
+        
+        item1 = new TreeItem(modelVisualizationTree, SWT.NULL);
+        item1.setText(TaskTreePlotUtils.CUMULATIVE_TASK_COVERAGE_PLOT);
+        
+        Menu menu = modelVisualizationTree.getMenu();
+        
+        if (menu == null) {
+            menu = new Menu(modelVisualizationTree);
+            modelVisualizationTree.setMenu(menu);
+        }
+       
+        // show visualization if requested
+        modelVisualizationTree.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                clearVisualization();
+                TreeItem[] selectedItems = modelVisualizationTree.getSelection();
+                if (selectedItems.length == 1) {
+                    showVisualization(selectedItems[0].getText());
+                }
+            }
+        });
+        
+        modelVisualizationTab.setControl(modelVisualizationTree);
+        
+        // add a context menu for PDF export
+        final Menu finalMenu = menu;
+        MenuItem newItem = new MenuItem(finalMenu, SWT.NONE);
+        newItem.setText("save as PDF");
+        newItem.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                try {
+                    FileDialog dialog = new FileDialog(shell, SWT.SAVE);
+                    dialog.setFilterExtensions(new String [] {"*.pdf"});
+                    TaskTreePlotUtils.saveChartToPDF
+                        ((JFreeChart) modelVisualizationTree.getSelection()[0].getData(),
+                         dialog.open(), 500, 500);
+                }
+                catch (Exception e1) {
+                    // TODO Auto-generated catch block
+                    e1.printStackTrace();
+                }
+            }
+        });
+    }
+    
     /**
      *
      */
-    private void createTaskDetailsView(SashForm mainSashForm) {
-        Composite detailsComposite = new Composite(mainSashForm, SWT.NO_BACKGROUND);
+    private void createRightHandSideView(SashForm mainSashForm) {
+        rightHandComposite = new Composite(mainSashForm, SWT.NO_BACKGROUND);
+        rightHandLayout = new StackLayout();
+        rightHandComposite.setLayout(rightHandLayout);
+        
+        detailsComposite = new Composite(rightHandComposite, SWT.NO_BACKGROUND);
         detailsComposite.setLayout(new GridLayout(1, false));
         detailsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
@@ -328,6 +457,6 @@
         VisualizationUtils.addExpansionListener(taskDetailsTree, defaultExpansionListener);
         
-        VisualizationUtils.addItemSpecificContextMenu(taskDetailsTree, ITask.class,
-                                                      "show in task list", new SelectionAdapter()
+        VisualizationUtils.addItemSpecificContextMenu
+            (taskDetailsTree, ITask.class, "show in task list", new SelectionAdapter()
         {
             @Override
@@ -336,4 +465,15 @@
             }
         });
+        
+        if (taskExportAvailable) {
+            VisualizationUtils.addItemSpecificContextMenu
+                (taskDetailsTree, ITask.class, "export to ConcurTaskTree", new SelectionAdapter()
+            {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    export((ITask) taskDetailsTree.getSelection()[0].getData());
+                }
+            });
+        }
         
         executionVariantsTree = new Tree(detailsTopSashForm, SWT.BORDER | SWT.SINGLE | SWT.WRAP);
@@ -355,6 +495,6 @@
             (detailsBottomSashForm, "parent tasks", taskModel);
         
-        VisualizationUtils.addItemSpecificContextMenu(parentTasks, ITask.class,
-                                                      "show in task list", new SelectionAdapter()
+        VisualizationUtils.addItemSpecificContextMenu
+            (parentTasks, ITask.class, "show in task list", new SelectionAdapter()
         {
             @Override
@@ -364,6 +504,25 @@
         });
         
+        if (taskExportAvailable) {
+            VisualizationUtils.addItemSpecificContextMenu
+                (parentTasks, ITask.class, "export to ConcurTaskTree", new SelectionAdapter()
+            {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    export((ITask) taskDetailsTree.getSelection()[0].getData());
+                }
+            });
+        }
+        
         involvedTargetsTree =
             VisualizationUtils.createTargetsTree(detailsBottomSashForm, "involved GUI elements");
+        
+        visualizationsComposite = new Composite(rightHandComposite, SWT.NO_BACKGROUND);
+        visualizationsComposite.setLayout(new GridLayout(1, false));
+        visualizationsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+        
+        new Label(visualizationsComposite, SWT.NONE).setText("Visualization:");
+        
+        rightHandLayout.topControl = detailsComposite;
         
         detailsBottomSashForm.setWeights(new int[] { 2, 3 });
@@ -590,4 +749,21 @@
         displayTaskDetails(task);
     }
+
+    /**
+     * 
+     */
+    private void export(ITask task) {
+        try {
+            Class<?> exportClass = this.getClass().getClassLoader().loadClass
+                ("de.ugoe.cs.autoquest.plugin.exports.tasktree.CTTExportUtils");
+            
+            Method method = exportClass.getDeclaredMethod("exportToCTT", ITask.class, String.class);
+            
+            method.invoke(null, task, task.getId() + "_ctte.xml");
+        }
+        catch (Exception e) {
+            Console.logException(e);
+        }
+    }
     
     /**
@@ -680,3 +856,49 @@
         }
     }
+
+    /**
+     *
+     */
+    private void showVisualization(String name) {
+        Color backgroundColor = visualizationsComposite.getBackground();
+        Composite parent = new Composite(visualizationsComposite, SWT.EMBEDDED);
+        parent.setLayout(new GridLayout(1, false));
+        parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+        
+        Frame chartFrame = SWT_AWT.new_Frame(parent);
+        chartFrame.setBackground(new java.awt.Color(backgroundColor.getRed(),
+                                                    backgroundColor.getGreen(),
+                                                    backgroundColor.getBlue()));
+        
+        chartFrame.setLayout(new java.awt.GridLayout());
+        
+        List<ITaskModel> models = new LinkedList<>();
+        models.add(taskModel);
+        
+        List<String> names = new LinkedList<>();
+        names.add(name);
+        
+        List<Integer> groups = new LinkedList<>();
+        groups.add(0);
+
+        JFreeChart chart = TaskTreePlotUtils.createPlot(name, models, names, groups);
+        chartFrame.add(new ChartPanel(chart));
+        
+        modelVisualizationTree.getSelection()[0].setData(chart);
+        
+        rightHandComposite.layout();
+        rightHandComposite.redraw();
+        rightHandComposite.update();
+    }
+
+    /**
+     *
+     */
+    private void clearVisualization() {
+        for (Control child : visualizationsComposite.getChildren()) {
+            child.dispose();
+        }
+        
+        visualizationsComposite.pack();
+    }
 }
Index: trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/TaskTreePlotUtils.java
===================================================================
--- trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/TaskTreePlotUtils.java	(revision 2033)
+++ trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/TaskTreePlotUtils.java	(revision 2033)
@@ -0,0 +1,484 @@
+//   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.awt.BasicStroke;
+import java.awt.Graphics2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Rectangle2D;
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.text.DecimalFormat;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.AxisLocation;
+import org.jfree.chart.axis.LogarithmicAxis;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.ValueMarker;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.chart.title.TextTitle;
+import org.jfree.data.xy.DefaultTableXYDataset;
+import org.jfree.data.xy.XYDataset;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.ui.RectangleAnchor;
+import org.jfree.ui.RectangleInsets;
+
+import com.lowagie.text.Rectangle;
+import com.lowagie.text.pdf.DefaultFontMapper;
+import com.lowagie.text.pdf.PdfContentByte;
+import com.lowagie.text.pdf.PdfTemplate;
+import com.lowagie.text.pdf.PdfWriter;
+
+import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskMetric;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskTreeUtils;
+
+/**
+ * <p>
+ * TODO comment
+ * </p>
+ * 
+ * @author Patrick Harms
+ */
+public class TaskTreePlotUtils {
+    
+    /** name for visualizing a task count to event coverage plot */
+    public static final String TASK_COUNT__EVENT_COVERAGE_PLOT = "event coverage plot";
+    
+    /** name for visualizing the instance counts of tasks ordered by the event coverage */
+    public static final String ORDERED_TASK_COUNT_PLOT = "task instance count - coverage plot";
+    
+    /** name for visualizing a cumulative coverage of events by the tasks orded by their event
+     *  coverage */
+    public static final String CUMULATIVE_TASK_COVERAGE_PLOT = "cumulative task coverage plot";
+    
+    /** colors */
+    public static final java.awt.Color[] colors = new java.awt.Color[] {
+        java.awt.Color.BLACK, java.awt.Color.GRAY, java.awt.Color.RED, java.awt.Color.CYAN,
+        java.awt.Color.ORANGE, java.awt.Color.GREEN, java.awt.Color.MAGENTA, java.awt.Color.BLUE,
+        java.awt.Color.PINK, java.awt.Color.DARK_GRAY, java.awt.Color.LIGHT_GRAY,
+        java.awt.Color.YELLOW
+    };
+    
+    /**
+     *
+     */
+    public static JFreeChart createPlot(String           name,
+                                        List<ITaskModel> models,
+                                        List<String>     modelNames,
+                                        List<Integer>    groups)
+    {
+        JFreeChart chart = null;
+        
+        if (TASK_COUNT__EVENT_COVERAGE_PLOT.equals(name)) {
+            XYDataset dataset1 = createTaskCountEventCoveragePlotDataSet(models.get(0));
+            
+            chart = ChartFactory.createXYLineChart
+                (TASK_COUNT__EVENT_COVERAGE_PLOT, "task counts", "event coverage",
+                 dataset1, PlotOrientation.VERTICAL, models.size() > 1, false, false);
+            
+            for (int i = 1; i < models.size(); i++) {
+                chart.getXYPlot().setDataset
+                    (i, createTaskCountEventCoveragePlotDataSet(models.get(i)));
+            }
+            
+            XYPlot plot = chart.getXYPlot();
+            NumberAxis domainAxis = new LogarithmicAxis("task counts");
+            NumberAxis rangeAxis = new LogarithmicAxis("event coverage");
+            plot.setDomainAxis(domainAxis);
+            plot.setRangeAxis(rangeAxis);
+        }
+        else if (CUMULATIVE_TASK_COVERAGE_PLOT.equals(name)) {
+            Set<ISequence> mostProminent =
+                TaskTreeUtils.getMostProminentTasks(models.get(0), models.get(0).getTasks());
+            
+            XYDataset dataset = createCumulativeTaskCoveragePlotDataSet(models.get(0),
+                                                                        modelNames.get(0));
+            chart = ChartFactory.createXYLineChart
+                (CUMULATIVE_TASK_COVERAGE_PLOT, "tasks ordered by coverage",
+                 "cumulative action instance coverage", dataset,
+                 PlotOrientation.VERTICAL, models.size() > 1, false, false);
+            
+            final XYPlot plot = chart.getXYPlot();
+            plot.setBackgroundPaint(java.awt.Color.WHITE);
+            plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
+            
+            double mpMarker = (double) 100 * mostProminent.size() / dataset.getItemCount(0);
+            ValueMarker marker = new ValueMarker(mpMarker);
+            marker.setLabel(new DecimalFormat("#0.0").format(mpMarker));
+            marker.setLabelAnchor(RectangleAnchor.BOTTOM);
+            marker.setLabelOffset(new RectangleInsets(0, -12, 10, 15));
+            plot.addDomainMarker(marker);
+            
+            double xLow = 0;
+            double yLow = 0;
+            double xHigh = 100;
+            double yHigh = 100;
+            double maxY = 0;
+            for (int i = 0; i < dataset.getItemCount(0); i++) {
+                double xValue = dataset.getXValue(0, i);
+                double yValue = dataset.getYValue(0, i);
+                
+                if ((xLow < xValue) && (xValue < mpMarker)) {
+                    xLow = xValue;
+                    yLow = yValue;
+                }
+                else if ((xHigh > xValue) && (xValue > mpMarker)) {
+                    xHigh = xValue;
+                    yHigh = yValue;
+                }
+                
+                maxY = Math.max(maxY, yValue);
+            }
+            
+            marker = new ValueMarker((yHigh + yLow) / 2);
+            marker.setLabel(new DecimalFormat("#0.0").format((yHigh + yLow) / 2));
+            marker.setLabelOffset(new RectangleInsets(5, 15, 0, 10));
+            plot.addRangeMarker(marker);
+            marker = new ValueMarker(maxY);
+            marker.setLabel(new DecimalFormat("#0.0").format(maxY));
+            marker.setLabelOffset(new RectangleInsets(5, 15, 0, 10));
+            plot.addRangeMarker(marker);
+            
+            plot.getRenderer(0).setSeriesPaint(0, colors[0]);
+            plot.getRenderer(0).setSeriesStroke(0, new BasicStroke(3.0f, BasicStroke.CAP_ROUND,
+                                                                   BasicStroke.JOIN_ROUND));
+            
+            for (int i = 1; i < models.size(); i++) {
+                plot.setDataset(i, createCumulativeTaskCoveragePlotDataSet(models.get(i),
+                                                                           modelNames.get(i)));
+                
+                plot.setRenderer(i, new XYLineAndShapeRenderer(true, false));
+                plot.getRenderer(i).setSeriesPaint(0, colors[groups.get(i)]);
+                plot.getRenderer(i).setSeriesStroke(0, new BasicStroke(1.0f, BasicStroke.CAP_ROUND,
+                                                                       BasicStroke.JOIN_ROUND));
+            }
+
+            NumberAxis domainAxis = new NumberAxis("sequences ordered by coverage");
+            domainAxis.setUpperBound(100);
+            plot.setDomainAxis(domainAxis);
+            
+            NumberAxis rangeAxis = new NumberAxis("cumulative action instance coverage");
+            rangeAxis.setUpperBound(100);
+            plot.setRangeAxis(rangeAxis);
+        }
+        else if (ORDERED_TASK_COUNT_PLOT.equals(name)) {
+            XYDataset dataset = createOrderedTaskCountPlotDataSet(models.get(0), modelNames.get(0));
+            
+            chart = ChartFactory.createXYLineChart
+                (ORDERED_TASK_COUNT_PLOT, "tasks ordered by coverage",
+                 "number of instances", dataset, PlotOrientation.VERTICAL, models.size() > 1,
+                 false, false);
+            
+            final XYPlot plot = chart.getXYPlot();
+            plot.setBackgroundPaint(java.awt.Color.WHITE);
+            plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
+
+            XYLineAndShapeRenderer scatterRenderer = new XYLineAndShapeRenderer(false, true);
+            scatterRenderer.setSeriesShapesFilled(0, false);
+            scatterRenderer.setSeriesShape(0, new Ellipse2D.Float(-3.0f, -3.0f, 6.0f, 6.0f));
+            scatterRenderer.setSeriesPaint(0, colors[0]);
+            plot.setRenderer(0, scatterRenderer);
+
+            for (int i = 1; i < models.size(); i++) {
+                chart.getXYPlot().setDataset
+                    (i, createOrderedTaskCountPlotDataSet(models.get(i), modelNames.get(i)));
+                
+                scatterRenderer = new XYLineAndShapeRenderer(false, true);
+                scatterRenderer.setSeriesShapesFilled(0, false);
+                scatterRenderer.setSeriesShape(0, new Ellipse2D.Float(-3.0f, -3.0f, 6.0f, 6.0f));
+                scatterRenderer.setSeriesPaint(0, colors[i]);
+                plot.setRenderer(i, scatterRenderer);
+            }
+
+            NumberAxis domainAxis = new NumberAxis("sequences ordered by coverage");
+            domainAxis.setUpperBound(100);
+            plot.setDomainAxis(domainAxis);
+            
+            NumberAxis rangeAxis = new LogarithmicAxis("number of instances");
+            plot.setRangeAxis(rangeAxis);
+        }
+
+        return chart;
+    }
+    
+    /**
+     * 
+     */
+    public static void saveChartToPDF(JFreeChart chart, String fileName, int width, int height)
+        throws Exception
+    {
+        if (chart != null) {
+            BufferedOutputStream out = null;
+            try {
+                out = new BufferedOutputStream(new FileOutputStream(fileName)); 
+                    
+                //convert chart to PDF with iText:
+                Rectangle pagesize = new Rectangle(width, height); 
+                com.lowagie.text.Document document =
+                    new com.lowagie.text.Document(pagesize, 50, 50, 50, 50);
+                
+                try { 
+                    PdfWriter writer = PdfWriter.getInstance(document, out); 
+                    document.addAuthor("JFreeChart"); 
+                    document.open(); 
+            
+                    PdfContentByte cb = writer.getDirectContent(); 
+                    PdfTemplate tp = cb.createTemplate(width, height); 
+                    Graphics2D g2 = tp.createGraphics(width, height, new DefaultFontMapper()); 
+            
+                    Rectangle2D r2D = new Rectangle2D.Double(0, 0, width, height);
+                    TextTitle title = chart.getTitle();
+                    chart.setTitle((TextTitle) null);
+                    chart.draw(g2, r2D, null);
+                    chart.setTitle(title);
+                    g2.dispose(); 
+                    cb.addTemplate(tp, 0, 0); 
+                }
+                finally {
+                    document.close(); 
+                }
+            }
+            finally {
+                if (out != null) {
+                    out.close();
+                }
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    private static XYDataset createTaskCountEventCoveragePlotDataSet(ITaskModel taskModel) {
+        // tree maps required to have sorted maps
+        TreeMap<Integer, Integer> minValues = new TreeMap<>();
+        TreeMap<Integer, List<Integer>> allValues = new TreeMap<>();
+        TreeMap<Integer, Integer> maxValues = new TreeMap<>();
+        
+        for (ITask task : taskModel.getTasks()) {
+            if (task instanceof ISequence) {
+                ITaskInfo info = taskModel.getTaskInfo(task);
+                int count = task.getInstances().size();
+                int eventCoverage = info.getMeasureValue(TaskMetric.EVENT_COVERAGE);
+
+                Integer minValue = minValues.get(count);
+
+                if ((minValue == null) || (minValue > eventCoverage)) {
+                    minValues.put(count, eventCoverage);
+                }
+
+                Integer maxValue = maxValues.get(count);
+
+                if ((maxValue == null) || (maxValue < eventCoverage)) {
+                    maxValues.put(count, eventCoverage);
+                }
+
+                List<Integer> values = allValues.get(count);
+
+                if (values == null) {
+                    values = new LinkedList<Integer>();
+                    allValues.put(count, values);
+                }
+
+                values.add(eventCoverage);
+            }
+        }
+        
+        DefaultTableXYDataset dataset = new DefaultTableXYDataset();
+        XYSeries minSeries = new XYSeries("min values", true, false);
+        XYSeries avgSeries = new XYSeries("avg values", true, false);
+        XYSeries maxSeries = new XYSeries("max values", true, false);
+        
+        // entries are correctly sorted due to the map
+        for (Map.Entry<Integer, List<Integer>> entry : allValues.entrySet()) {
+            int count = entry.getKey();
+
+            minSeries.add(count, minValues.get(count));
+            maxSeries.add(count, maxValues.get(count));
+            
+            avgSeries.add(count, getAverage(entry.getValue()));
+        }
+        
+        dataset.addSeries(minSeries);
+        dataset.addSeries(avgSeries);
+        dataset.addSeries(maxSeries);
+        return dataset;
+    }
+
+    /**
+     *
+     */
+    private static XYDataset createCumulativeTaskCoveragePlotDataSet(ITaskModel     taskModel,
+                                                                     String         taskModelName)
+    {
+        Map<Integer, List<ISequence>> coverageCounts = new HashMap<>();
+        Map<ISequence, Set<IEventTaskInstance>> coverages = new HashMap<>();
+        Set<IEventTaskInstance> allEvents = new HashSet<>();
+        int maxCoverage = 0;
+        
+        for (ITask task : taskModel.getTasks()) {
+            if (task instanceof ISequence) {
+                final Set<IEventTaskInstance> coveredEvents = new HashSet<>();
+                
+                for (ITaskInstance instance : task.getInstances()) {
+                    instance.accept(new DefaultTaskInstanceTraversingVisitor() {
+                        @Override
+                        public void visit(IEventTaskInstance eventTaskInstance) {
+                            coveredEvents.add(eventTaskInstance);
+                        }
+                    });
+                }
+                
+                coverages.put((ISequence) task, coveredEvents);
+                
+                List<ISequence> tasksWithSameCoverage = coverageCounts.get(coveredEvents.size());
+
+                if (tasksWithSameCoverage == null) {
+                    tasksWithSameCoverage = new LinkedList<>();
+                    coverageCounts.put(coveredEvents.size(), tasksWithSameCoverage);
+                }
+
+                tasksWithSameCoverage.add((ISequence) task);
+                
+                maxCoverage = Math.max(maxCoverage, coveredEvents.size());
+            }
+            else if (task instanceof IEventTask) {
+                for (ITaskInstance instance : task.getInstances()) {
+                    allEvents.add((IEventTaskInstance) instance);
+                }
+            }
+        }
+        
+        XYSeries cumulativeSeries = new XYSeries(taskModelName, true, false);
+        Set<IEventTaskInstance> cumulativeCoverage = new HashSet<>();
+        
+        // entries are correctly sorted due to the map
+        int sequenceIndex = 1;
+        
+        for (int i = maxCoverage; i > 0; i--) {
+            List<ISequence> sequencesWithSameCoverage = coverageCounts.get(i);
+
+            if (sequencesWithSameCoverage == null) {
+                continue;
+            }
+            
+            for (ISequence sequence : sequencesWithSameCoverage) {
+                cumulativeCoverage.addAll(coverages.get(sequence));
+                double xvalue = (double) 100 * sequenceIndex / coverages.size();
+                double yvalue = (double) 100 * cumulativeCoverage.size() / allEvents.size();
+                cumulativeSeries.add(xvalue, yvalue);
+                sequenceIndex++;
+            }
+        }
+        
+        DefaultTableXYDataset dataset = new DefaultTableXYDataset();
+        dataset.addSeries(cumulativeSeries);
+        return dataset;
+    }
+
+    /**
+     *
+     */
+    private static XYDataset createOrderedTaskCountPlotDataSet(ITaskModel taskModel,
+                                                               String     taskModelName)
+    {
+        Map<Integer, List<ISequence>> coverageCounts = new HashMap<>();
+        Map<ISequence, Set<IEventTaskInstance>> coverages = new HashMap<>();
+        int maxCoverage = 0;
+        
+        for (ITask task : taskModel.getTasks()) {
+            if (task instanceof ISequence) {
+                final Set<IEventTaskInstance> coveredEvents = new HashSet<>();
+                
+                for (ITaskInstance instance : task.getInstances()) {
+                    instance.accept(new DefaultTaskInstanceTraversingVisitor() {
+                        @Override
+                        public void visit(IEventTaskInstance eventTaskInstance) {
+                            coveredEvents.add(eventTaskInstance);
+                        }
+                    });
+                }
+                
+                coverages.put((ISequence) task, coveredEvents);
+                
+                List<ISequence> tasksWithSameCoverage = coverageCounts.get(coveredEvents.size());
+
+                if (tasksWithSameCoverage == null) {
+                    tasksWithSameCoverage = new LinkedList<>();
+                    coverageCounts.put(coveredEvents.size(), tasksWithSameCoverage);
+                }
+
+                tasksWithSameCoverage.add((ISequence) task);
+                
+                maxCoverage = Math.max(maxCoverage, coveredEvents.size());
+            }
+        }
+        
+        XYSeries counts = new XYSeries(taskModelName, true, false);
+        
+        // entries are correctly sorted due to the map
+        int sequenceIndex = 1;
+        
+        for (int i = maxCoverage; i > 0; i--) {
+            List<ISequence> sequencesWithSameCoverage = coverageCounts.get(i);
+
+            if (sequencesWithSameCoverage == null) {
+                continue;
+            }
+            
+            for (ISequence sequence : sequencesWithSameCoverage) {
+                double xvalue = (double) 100 * sequenceIndex / coverages.size();
+                counts.add(xvalue, sequence.getInstances().size());
+                sequenceIndex++;
+            }
+        }
+        
+        DefaultTableXYDataset dataset = new DefaultTableXYDataset();
+        dataset.addSeries(counts);
+        return dataset;
+    }
+
+
+    /**
+     *
+     */
+    private static double getAverage(List<Integer> values) {
+        int all = 0;
+        
+        for (Integer value : values) {
+            all += value;
+        }
+
+        return ((double) all) / values.size();
+    }
+}
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 1921)
+++ trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/VisualizationUtils.java	(revision 2033)
@@ -116,17 +116,5 @@
         
         for (int i = 0; i < metrics.length; i++) {
-            int contextValue = Integer.MIN_VALUE;
-            
-            if (parent.getData() instanceof ITask) {
-                contextValue = taskInfo.getMeasureValue(metrics[i]);
-            }
-            
-            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[i + 1] = metrics[i].formatValue(taskInfo.getMeasureValue(metrics[i]));
         }
         
Index: trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/commands/CMDplotTaskTreeCoverage.java
===================================================================
--- trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/commands/CMDplotTaskTreeCoverage.java	(revision 2033)
+++ trunk/autoquest-ui-swt/src/main/java/de/ugoe/cs/autoquest/ui/swt/commands/CMDplotTaskTreeCoverage.java	(revision 2033)
@@ -0,0 +1,169 @@
+//   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.commands;
+
+import java.awt.Frame;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.awt.SWT_AWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.jfree.chart.ChartPanel;
+import org.jfree.chart.JFreeChart;
+import org.jfree.ui.RectangleEdge;
+
+import de.ugoe.cs.autoquest.CommandHelpers;
+import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
+import de.ugoe.cs.autoquest.ui.swt.TaskTreePlotUtils;
+import de.ugoe.cs.util.console.Command;
+import de.ugoe.cs.util.console.GlobalDataContainer;
+
+/**
+ * <p>
+ * Command to show sequences.
+ * </p>
+ * 
+ * @author Jeffrey Hall, Steffen Herbold
+ */
+public class CMDplotTaskTreeCoverage implements Command {
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.util.console.Command#help()
+     */
+    @Override
+    public String help() {
+        return "plotTaskTreeCoverage <taskTreeNames>";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see de.ugoe.cs.util.console.Command#run(java.util.List)
+     */
+    @Override
+    public void run(List<Object> parameters) {
+        List<Integer> taskTreeGroups = new LinkedList<>();
+        int group = 0;
+        
+        List<String> taskTreeNames = new LinkedList<>();
+        try {
+            for (Object param : parameters) {
+                if ("#".equals(param)) {
+                    group++;
+                }
+                else {
+                    taskTreeNames.add((String) param);
+                    taskTreeGroups.add(group);
+                }
+            }
+        }
+        catch (Exception e) {
+            throw new IllegalArgumentException();
+        }
+
+        List<ITaskModel> taskModels = new LinkedList<>();
+        
+        for (String taskTreeName : taskTreeNames) {
+            Object dataObject = GlobalDataContainer.getInstance().getData(taskTreeName);
+            if (dataObject == null) {
+                CommandHelpers.objectNotFoundMessage(taskTreeName);
+                return;
+            }
+            if (!(dataObject instanceof ITaskModel)) {
+                CommandHelpers.objectNotType(taskTreeName, "ITaskModel");
+                return;
+            }
+            
+            taskModels.add((ITaskModel) dataObject);
+        }
+
+        // create the chart
+        final JFreeChart chart = TaskTreePlotUtils.createPlot
+            (TaskTreePlotUtils.CUMULATIVE_TASK_COVERAGE_PLOT, taskModels, taskTreeNames,
+             taskTreeGroups);
+        
+        final int width;
+        if (chart.getLegend() != null) {
+            width = 700;
+            chart.getLegend().setPosition(RectangleEdge.RIGHT);
+        }
+        else {
+            width = 500;
+        }
+        
+        final Shell shell = new Shell(SWT.SHELL_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
+        shell.layout();
+        shell.setSize(width, 500);
+        shell.setLayout(new GridLayout(2, false));
+        
+        Composite parent = new Composite(shell, SWT.EMBEDDED);
+        parent.setLayout(new GridLayout(1, false));
+        parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
+        
+        Frame chartFrame = SWT_AWT.new_Frame(parent);
+        chartFrame.setLayout(new java.awt.GridLayout());
+        
+        chartFrame.add(new ChartPanel(chart));
+
+        Button btnExport = new Button(shell, SWT.NONE);
+        btnExport.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                try {
+                    FileDialog dialog = new FileDialog(shell, SWT.SAVE);
+                    dialog.setFilterExtensions(new String [] {"*.pdf"});
+                    
+                    TaskTreePlotUtils.saveChartToPDF(chart, dialog.open(), width, 500);
+                }
+                catch (Exception e1) {
+                    // TODO Auto-generated catch block
+                    e1.printStackTrace();
+                }
+            }
+        });
+        btnExport.setText("export to PDF");
+
+        Button btnClose = new Button(shell, SWT.NONE);
+        btnClose.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                shell.dispose();
+            }
+        });
+        btnClose.setText("close");
+
+        shell.open();
+        shell.layout();
+        Display display = shell.getDisplay();
+        while (!shell.isDisposed()) {
+            if (!display.readAndDispatch()) {
+                display.sleep();
+            }
+        }
+        
+        shell.dispose();
+    }
+}
