net.java.treaty.eclipse.views.ContractView.java Source code

Java tutorial

Introduction

Here is the source code for net.java.treaty.eclipse.views.ContractView.java

Source

/*
 * Copyright (C) 2009 Jens Dietrich
 * 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 net.java.treaty.eclipse.views;

import static net.java.treaty.eclipse.Constants.VERIFICATION_EXCEPTION;
import static net.java.treaty.eclipse.Constants.VERIFICATION_RESULT;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.java.treaty.Condition;
import net.java.treaty.Annotatable;
import net.java.treaty.ComplexCondition;
import net.java.treaty.Component;
import net.java.treaty.ConjunctiveCondition;
import net.java.treaty.Connector;
import net.java.treaty.ConnectorType;
import net.java.treaty.Contract;
import net.java.treaty.ContractTypeChecker;
import net.java.treaty.ExistsCondition;
import net.java.treaty.NegatedCondition;
import net.java.treaty.PropertyCondition;
import net.java.treaty.PropertySupport;
import net.java.treaty.RelationshipCondition;
import net.java.treaty.Resource;
import net.java.treaty.Role;
import net.java.treaty.TreatyException;
import net.java.treaty.VerificationPolicy;
import net.java.treaty.VerificationReport;
import net.java.treaty.VerificationResult;
import net.java.treaty.contractregistry.ContractRegistryListener;
import net.java.treaty.eclipse.Constants;
import net.java.treaty.eclipse.EclipseExtension;
import net.java.treaty.eclipse.EclipseExtensionPoint;
import net.java.treaty.eclipse.EclipsePlugin;
import net.java.treaty.eclipse.Logger;
import net.java.treaty.eclipse.action.EclipseActionRegistry;
import net.java.treaty.eclipse.contractregistry.EclipseContractRegistry;
import net.java.treaty.eclipse.exporter.Exporter;
import net.java.treaty.eclipse.exporter.ExporterRegistry;
import net.java.treaty.eclipse.exporter.ExporterRegistryListener;
import net.java.treaty.eclipse.trigger.EclipseTriggerRegistry;
import net.java.treaty.eclipse.ui.Activator;
import net.java.treaty.eclipse.ui.actions.UIActionVocabulary;
import net.java.treaty.eclipse.ui.triggers.ManualTriggerVocabulary;
import net.java.treaty.eclipse.verification.TriggeredEclipseVerifier;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.DrillDownAdapter;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;

/**
 * <p>
 * Contract viewer of Eclipse Treaty implementation.
 * </p>
 * 
 * @author Jens Dietrich
 */
public class ContractView extends ViewPart implements ContractRegistryListener, ExporterRegistryListener {

    /**
     * <p>
     * The {@link DummyViewContentProvider} is used during startup until the
     * {@link ContractView} has been initialized.
     * </p>
     * 
     * @author Jens Dietrich
     */
    private class DummyViewContentProvider implements IStructuredContentProvider, ITreeContentProvider {

        /** The root {@link Object}. */
        private Object ROOT = new Object();

        /** The initial message. */
        private String INITIALIZING = "Initializing, please wait ...";

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java
         * .lang.Object)
         */
        public Object[] getElements(Object inputElement) {

            if (inputElement.equals(getViewSite())) {
                return getChildren(ROOT);
            }
            // no else.

            return getChildren(inputElement);
        }

        /*
         * (non-Javadoc)
         * @see org.eclipse.jface.viewers.IContentProvider#dispose()
         */
        public void dispose() {

            /* Do nothing. */
        }

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface
         * .viewers.Viewer, java.lang.Object, java.lang.Object)
         */
        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {

            /* Do nothing. */
        }

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.
         * Object)
         */
        public Object[] getChildren(Object parent) {

            if (parent == ROOT) {
                return new String[] { INITIALIZING };
            }

            return new Object[] {};
        }

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object
         * )
         */
        public Object getParent(Object element) {

            if (element == INITIALIZING)
                return ROOT;

            return null;
        }

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.
         * Object)
         */
        public boolean hasChildren(Object element) {

            return element == ROOT;
        }
    }

    /**
     * <p>
     * Action to export {@link Contract}s and their results.
     * </p>
     * 
     * @author Jens Dietrich.
     */
    private class ExportAction extends Action {

        /** The {@link Exporter} of this {@link ExportAction}. */
        private Exporter myExporter = null;

        /**
         * <p>
         * Creates a new {@link ExportAction}.
         * </p>
         * 
         * @param exporter
         *          The {@link Exporter} of this {@link ExportAction}.
         */
        ExportAction(Exporter exporter) {

            super();

            this.myExporter = exporter;
        }

        /*
         * (non-Javadoc)
         * @see org.eclipse.jface.action.Action#run()
         */
        public void run() {

            actionExport(this.myExporter);
        }
    }

    /**
     * <p>
     * Represents nodes that consist of a key and a value.
     * </p>
     * 
     * @author Jens Dietrich
     */
    private class KeyValueNode {

        /** The key of this {@link KeyValueNode}. */
        private String key = null;

        /** The value of this {@link KeyValueNode}. */
        private String value = null;

        /**
         * <p>
         * Creates a new {@link KeyValueNode}.
         * </p>
         * 
         * @param key
         *          The key of this {@link KeyValueNode}.
         * @param value
         *          The value of this {@link KeyValueNode}.
         */
        public KeyValueNode(String key, String value) {

            super();

            this.key = key;
            this.value = value;
        }
    }

    /**
     * <p>
     * The content provider class is responsible for providing objects to the
     * view. It can wrap existing objects in adapters or simply return objects
     * as-is. These objects may be sensitive to the current input of the view, or
     * ignore it and always show the same content (like Task List, for example).
     * </p>
     * 
     * <p>
     * TreeObject implements such a wrapper.
     * </p>
     * 
     * @author Jens Dietrich
     */
    private class TreeObject implements IAdaptable {

        /** The wrapped object of this {@link TreeObject}. */
        private Object object;

        /** The {@link TreeParent} of this {@link TreeObject} (if any). */
        private TreeParent parent;

        /**
         * <p>
         * Creates a new {@link TreeObject} wrapper for a given {@link Object}.
         * </p>
         * 
         * @param object
         *          The {@link Object} that shall be wrapped.
         */
        public TreeObject(Object object) {

            this.object = object;
        }

        /*
         * (non-Javadoc)
         * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
         */
        @SuppressWarnings("unchecked")
        public Object getAdapter(Class key) {

            return null;
        }

        /**
         * <p>
         * Returns the wrapped Object of this {@link TreeObject}.
         * </p>
         * 
         * @return The wrapped Object of this {@link TreeObject}.
         */
        public Object getObject() {

            return this.object;
        }

        /**
         * <p>
         * Returns the {@link TreeParent} of this {@link TreeObject}.
         * </p>
         * 
         * @return The {@link TreeParent} of this {@link TreeObject}.
         */
        public TreeParent getParent() {

            return parent;
        }

        /**
         * <p>
         * Sets the {@link TreeParent} of this {@link TreeObject}.
         * </p>
         * 
         * @param parent
         *          The {@link TreeParent} of this {@link TreeObject}.
         */
        public void setParent(TreeParent parent) {

            this.parent = parent;
        }

        /*
         * (non-Javadoc)
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {

            return getObject().toString();
        }
    }

    /**
     * <p>
     * {@link TreeParent}s are {@link TreeObject}s that contain other
     * {@link TreeObject}s.
     * </p>
     * 
     * @author Jens Dietrich
     */
    private class TreeParent extends TreeObject {

        /** The children {@link TreeObject}s of this {@link TreeParent}. */
        private List<TreeObject> children = new ArrayList<TreeObject>();

        /**
         * <p>
         * Creates a new {@link TreeParent} for a given {@link Object}.
         * </p>
         * 
         * @param object
         *          The {@link Object} that shall be wrapped.
         */
        public TreeParent(Object object) {

            super(object);
        }

        /**
         * <p>
         * Adds a given {@link TreeObject} as child to this {@link TreeParent}.
         * </p>
         * 
         * @param child
         *          The {@link TreeObject} that shall be added.
         */
        public void addChild(TreeObject child) {

            this.children.add(child);
            child.setParent(this);
        }

        /**
         * <p>
         * Returns all children {@link TreeObject}s of this {@link TreeParent}.
         * </p>
         * 
         * @return All children {@link TreeObject}s of this {@link TreeParent}.
         */
        public TreeObject[] getChildren() {

            if (children == null)
                return new TreeObject[0];
            return (TreeObject[]) this.children.toArray(new TreeObject[this.children.size()]);
        }

        /**
         * <p>
         * Returns <code>true</code> if this {@link TreeParent} has children.
         * </p>
         * 
         * @return <code>true</code> if this {@link TreeParent} has children.
         */
        public boolean hasChildren() {

            return children.size() > 0;
        }
    }

    /**
     * <p>
     * The {@link ViewContentProvider} is used to provide the content of all
     * elements that shall be displayed in this {@link ContractView}.
     * </p>
     * 
     * @author Jens Dietrich
     */
    private class ViewContentProvider implements IStructuredContentProvider, ITreeContentProvider {

        /** The root {@link TreeParent} of the view. */
        private TreeParent invisibleRoot;

        /*
         * (non-Javadoc)
         * @see org.eclipse.jface.viewers.IContentProvider#dispose()
         */
        public void dispose() {

            /* Remains empty. */
        }

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.
         * Object)
         */
        public Object[] getChildren(Object parent) {

            Object[] result;

            /* Check if the given parent is a TreeParent. */
            if (parent instanceof TreeParent) {

                /* Delegate operation. */
                result = ((TreeParent) parent).getChildren();
            }

            /* Else return an empty array. */
            else {
                result = new Object[0];
            }
            // end else.

            return result;
        }

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java
         * .lang.Object)
         */
        public Object[] getElements(Object parent) {

            Object[] result;

            /* If the parent is the view, return the root object's children. */
            if (parent.equals(getViewSite())) {

                /* Probably initialize the root object. */
                if (this.invisibleRoot == null) {
                    initialize();
                }
                // no else.

                result = this.getChildren(invisibleRoot);
            }

            /* Else return the children of the given parent. */
            else {
                result = getChildren(parent);
            }

            return result;
        }

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object
         * )
         */
        public Object getParent(Object child) {

            Object result;
            result = null;

            /* For TreeObjects return their parents. */
            if (child instanceof TreeObject) {
                result = ((TreeObject) child).getParent();
            }
            // no else.

            return result;
        }

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.
         * Object)
         */
        public boolean hasChildren(Object parent) {

            boolean result;
            result = false;

            if (parent instanceof TreeParent) {
                result = ((TreeParent) parent).hasChildren();
            }
            // no else.

            return result;
        }

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface
         * .viewers.Viewer, java.lang.Object, java.lang.Object)
         */
        public void inputChanged(Viewer v, Object oldInput, Object newInput) {

            /* Remains empty. */
        }

        /**
         * <p>
         * Initializes this {@link ViewContentProvider}.
         * </p>
         */
        private void initialize() {

            /* Create an empty root object. */
            this.invisibleRoot = new TreeParent("");
            this.addPluginNodes(this.invisibleRoot);
        }

        /**
         * <p>
         * A helper method that adds nodes for all {@link EclipsePlugin}s (and
         * recursively for their children) to a given {@link TreeParent}.
         * </p>
         * 
         * @param parent
         *          The {@link TreeParent} to which the nodes shall be added.
         */
        private void addPluginNodes(TreeParent parent) {

            List<EclipsePlugin> eclipsePlugins;
            eclipsePlugins = new ArrayList<EclipsePlugin>(myContractedPlugins);
            Collections.sort(eclipsePlugins);

            for (EclipsePlugin plugin : eclipsePlugins) {
                TreeParent node;
                node = new TreeParent(plugin);

                parent.addChild(node);
                this.addExtensionPointNodes(node, plugin);
            }
            // end for.
        }

        /**
         * <p>
         * A helper method that adds nodes for all {@link EclipseExtensionPoint}s
         * (and recursively for their children) from a given {@link EclipsePlugin}
         * to a given {@link TreeParent}.
         * </p>
         * 
         * @param parent
         *          The {@link TreeParent} to which the nodes shall be added.
         * @param plugin
         *          The {@link EclipsePlugin} whose {@link EclipseExtensionPoint}s
         *          shall be added.
         */
        private void addExtensionPointNodes(TreeParent parent, EclipsePlugin plugin) {

            for (EclipseExtensionPoint eclipseExtensionPoint : plugin.getExtensionPoints()) {

                if (eclipseExtensionPoint.hasContracts()) {
                    TreeParent node;
                    node = new TreeParent(eclipseExtensionPoint);

                    parent.addChild(node);
                    this.addDefinedContractNodes(node, eclipseExtensionPoint);
                }
                // no else.
            }
            // end for.
        }

        /**
         * <p>
         * A helper method that adds nodes for all defined {@link Contracts}s (and
         * recursively for their children) from a given
         * {@link EclipseExtensionPoint} to a given {@link TreeParent}.
         * </p>
         * 
         * @param parent
         *          The {@link TreeParent} to which the nodes shall be added.
         * @param eclipseExtensionPoint
         *          The {@link EclipseExtensionPoint} whose {@link Contracts} s
         *          shall be added.
         */
        private void addDefinedContractNodes(TreeParent parent, EclipseExtensionPoint eclipseExtensionPoint) {

            List<Contract> contracts;
            contracts = new ArrayList<Contract>(eclipseExtensionPoint.getContracts());
            Collections.sort(contracts);

            /* Iterate through all contracts of the extension point. */
            for (Contract contract : contracts) {

                TreeParent node;
                node = new TreeParent(contract);

                /* Add the contract node. */
                parent.addChild(node);
                this.addContractContentNodes(node, contract);

                List<EclipseExtension> eclipseExtensions;
                eclipseExtensions = new ArrayList<EclipseExtension>(eclipseExtensionPoint.getExtensions());
                Collections.sort(eclipseExtensions);

                /* Add a node for instantiating extensions. */
                node = new TreeParent(eclipseExtensions.size() + " " + LABEL_INSTANCES);
                parent.addChild(node);

                /* Add children nodes for all extensions that instantiate the contract. */
                for (EclipseExtension eclipseExtension : eclipseExtensions) {
                    // TreeParent node2 = new TreeParent(x.getOwner());
                    // node.addChild(node2);
                    this.addContractedExtensionNodes(node, eclipseExtension);
                }
                // end for (extensions).
            }
            // end for (contracts).
        }

        /**
         * <p>
         * A helper method that adds nodes for all {@link Contract}s (and
         * recursively for their children) from a given {@link EclipseExtension} to
         * a given {@link TreeParent}.
         * </p>
         * 
         * @param parent
         *          The {@link TreeParent} to which the nodes shall be added.
         * @param eclipseExtension
         *          The {@link EclipseExtension} whose {@link Contracts} s shall be
         *          added.
         */
        private void addContractedExtensionNodes(TreeParent parent, EclipseExtension eclipseExtension) {

            TreeParent node;
            node = new TreeParent(eclipseExtension);

            parent.addChild(node);

            List<Contract> contracts;
            contracts = new ArrayList<Contract>(eclipseExtension.getContracts());
            Collections.sort(contracts);

            for (Contract contract : contracts) {
                // TreeParent node2;
                // node2 = new TreeParent(contract);
                //
                // node.addChild(node2);
                // this.addInstantiatedContractNodes(node2, contract);
                this.addInstantiatedContractNodes(node, contract);
            }
            // end for.
        }

        /**
         * <p>
         * A helper method that adds nodes for a {@link Contract}s instantiated by
         * an {@link EclipseExtension} to a given {@link TreeParent}.
         * </p>
         * 
         * @param parent
         *          The {@link TreeParent} to which the nodes shall be added.
         * @param contract
         *          The {@link Contracts} that shall be added.
         */
        private void addInstantiatedContractNodes(TreeParent parent, Contract contract) {

            TreeParent node;
            node = new TreeParent(contract);

            parent.addChild(node);
            this.addContractContentNodes(node, contract);
        }

        /**
         * <p>
         * A helper method that adds nodes for all content (and recursively for
         * their children) from a given {@link Contract} to a given
         * {@link TreeParent}.
         * </p>
         * 
         * @param parent
         *          The {@link TreeParent} to which the nodes shall be added.
         * @param contract
         *          The {@link Contracts} whose content shall be added.
         */
        private void addContractContentNodes(TreeParent parent, Contract contract) {

            Map<Resource, Role> ownerTypes;
            ownerTypes = new HashMap<Resource, Role>();

            for (Resource r : contract.getConsumerResources()) {
                ownerTypes.put(r, Role.CONSUMER);
            }

            for (Resource r : contract.getSupplierResources()) {
                ownerTypes.put(r, Role.SUPPLIER);
            }

            for (Resource r : contract.getExternalResources()) {
                ownerTypes.put(r, Role.LEGISLATOR);
            }

            TreeParent contractRootNode = null;

            /* Probably add extension point resources. */
            if (contract.getConsumerResources().size() > 0) {

                contractRootNode = new TreeParent(
                        getResourceLabel("extension point resources", contract.getConsumer()));
                parent.addChild(contractRootNode);

                for (Resource r : contract.getConsumerResources()) {
                    this.addResourceNode(contractRootNode, r, ownerTypes);
                }
            }
            // no else.

            /* Probably add extension resources. */
            if (contract.getSupplierResources().size() > 0) {
                contractRootNode = new TreeParent(getResourceLabel("extension resources", contract.getSupplier()));
                parent.addChild(contractRootNode);

                for (Resource r : contract.getSupplierResources()) {
                    this.addResourceNode(contractRootNode, r, ownerTypes);
                }
            }
            // no else.

            /* Probably add external resources. */
            if (contract.getExternalResources().size() > 0) {

                contractRootNode = new TreeParent(getResourceLabel("third party resources", contract.getOwner()));
                parent.addChild(contractRootNode);

                for (Resource r : contract.getExternalResources()) {
                    this.addResourceNode(contractRootNode, r, ownerTypes);
                }
            }
            // no else.

            /* Add nodes for the contracts conditions. */
            for (Condition c : contract.getConstraints()) {

                /* The top level conjunction is displayed as set. */
                if (c instanceof ConjunctiveCondition) {

                    for (Condition c2 : ((ConjunctiveCondition) c).getParts()) {
                        this.addConditionNodes(parent, c2, ownerTypes);
                    }
                }

                else {
                    this.addConditionNodes(parent, c, ownerTypes);
                }
                // end else.
            }
            // end for.

            /* Add nodes for triggers. */
            for (URI triggerType : contract.getTriggers()) {
                this.addTriggerNode(parent, triggerType);
            }
            // end for.

            /* Add nodes for on failure actions. */
            for (URI actionType : contract.getOnVerificationFailsActions()) {
                this.addActionNode(parent, actionType, KEY_ON_FAILURE_ACTION);
            }
            // end for.

            /* Add nodes for on success actions. */
            for (URI actionType : contract.getOnVerificationSucceedsActions()) {
                this.addActionNode(parent, actionType, KEY_ON_SUCCESS_ACTION);
            }
            // end for.
        }

        /**
         * <p>
         * A helper method that add a node for a given {@link Resource}.
         * </p>
         * 
         * @param parent
         *          The {@link TreeParent} to that the node shall be added.
         * @param resource
         *          The {@link Resource} for that a node shall be added.
         * @param ownerTypes
         *          A Map containing all {@link Resource}s belonging to this
         *          {@link Resource}.
         */
        private void addResourceNode(TreeParent parent, Resource resource, Map<Resource, Role> ownerTypes) {

            if (resource == null) {
                TreeObject node = new TreeObject(resource);
                parent.addChild(node);
            }

            else {
                TreeParent node = new TreeParent(resource);
                parent.addChild(node);

                this.addConditionPartNodes(node, resource, ownerTypes);
            }
        }

        /**
         * <p>
         * A helper method that adds nodes for a given {@link Map} of resources and
         * a given {@link AbstractCondition} to a given {@link TreeParent}.
         * </p>
         * 
         * @param parent
         *          The {@link TreeParent} to that the nodes shall be added.
         * @param condition
         *          The {@link AbstractCondition}.
         * @param ownerTypes
         *          The given {@link Resource}s and {@link OwnerType}s.
         */
        private void addConditionNodes(TreeParent parent, Condition condition, Map<Resource, Role> ownerTypes) {

            if (condition instanceof RelationshipCondition) {

                RelationshipCondition relationshipCondition;
                relationshipCondition = (RelationshipCondition) condition;

                TreeParent node;
                node = new TreeParent(relationshipCondition);

                parent.addChild(node);

                this.addResourceNode(node, relationshipCondition.getResource1(), ownerTypes);
                node.addChild(new TreeObject(
                        new KeyValueNode("relationship", relationshipCondition.getRelationship().toString())));

                this.addResourceNode(node, relationshipCondition.getResource2(), ownerTypes);
            }

            else if (condition instanceof PropertyCondition) {

                PropertyCondition propertyCondition;
                propertyCondition = (PropertyCondition) condition;

                TreeParent node;
                node = new TreeParent(propertyCondition);

                parent.addChild(node);
                this.addResourceNode(node, propertyCondition.getResource(), ownerTypes);

                Iterator<String> propertyNameIterator;
                propertyNameIterator = propertyCondition.getPropertyNames();

                while (propertyNameIterator.hasNext()) {
                    String propertyName;
                    propertyName = propertyNameIterator.next();

                    node.addChild(new TreeObject(new KeyValueNode("property", propertyName)));
                }
                // end while.

                node.addChild(new TreeObject(new KeyValueNode("op", propertyCondition.getOperator().toString())));
                node.addChild(new TreeObject(new KeyValueNode("value", "" + propertyCondition.getValue())));
            }

            else if (condition instanceof ExistsCondition) {

                ExistsCondition existsCondition;
                existsCondition = (ExistsCondition) condition;

                TreeParent node;
                node = new TreeParent(existsCondition);

                parent.addChild(node);
                this.addResourceNode(node, existsCondition.getResource(), ownerTypes);
            }

            else if (condition instanceof ComplexCondition) {

                ComplexCondition complexCondition;
                complexCondition = (ComplexCondition) condition;

                TreeParent node;
                node = new TreeParent(complexCondition);

                parent.addChild(node);

                for (Condition part : complexCondition.getParts()) {
                    this.addConditionNodes(node, part, ownerTypes);
                }
            }

            else if (condition instanceof NegatedCondition) {
                NegatedCondition negation;
                negation = (NegatedCondition) condition;

                TreeParent node;
                node = new TreeParent(negation);

                parent.addChild(node);
                this.addConditionNodes(node, negation.getNegatedCondition(), ownerTypes);
            }
        }

        /**
         * <p>
         * A helper method that adds nodes to a given {@link TreeParent} for a given
         * {@link Resource} which is part of an {@link AbstractCondition}.
         * 
         * @param parent
         *          The {@link TreeParent} to that the nodes shall be added.
         * @param resource
         *          The {@link Resource} that shall be added.
         * @param ownerTypes
         *          A {@link Map} of {@link Resource}s and {@link OwnerType}s.
         */
        private void addConditionPartNodes(TreeParent parent, Resource resource, Map<Resource, Role> ownerTypes) {

            parent.addChild(new TreeObject(new KeyValueNode("id", resource.getId())));
            parent.addChild(new TreeObject(new KeyValueNode("type", resource.getType().toString())));
            parent.addChild(new TreeObject(new KeyValueNode("name", resource.getName())));
            parent.addChild(new TreeObject(new KeyValueNode("reference", resource.getRef())));

            // parent.addChild(new TreeObject(new
            // KeyValueNode("value",""+r.getValue())));

            Role role;
            role = ownerTypes.get(resource);

            if (role != null) {
                parent.addChild(new TreeObject(new KeyValueNode("provided by", role.toString())));
            }

            // parent.addChild(new TreeObject(new
            // KeyValueNode("value",""+r.getValue())));
        }

        /**
         * <p>
         * A helper method that adds nodes to a given {@link TreeParent} for a given
         * trigger (as a {@link URI}).
         * 
         * @param parent
         *          The {@link TreeParent} to that the nodes shall be added.
         * @param triggerType
         *          The trigger that shall be added.
         */
        private void addTriggerNode(TreeParent parent, URI triggerType) {

            parent.addChild(new TreeObject(new KeyValueNode(KEY_TRIGGER, triggerType.toString())));
        }

        /**
         * <p>
         * A helper method that adds nodes to a given {@link TreeParent} for a given
         * action (as a {@link URI}).
         * </p>
         * 
         * @param parent
         *          The {@link TreeParent} to that the nodes shall be added.
         * @param actionType
         *          The action that shall be added.
         * @param kind
         *          Indentifies the type of action. Use either
         *          {@link ContractView#KEY_ON_FAILURE_ACTION} or
         *          {@link ContractView#KEY_ON_SUCCESS_ACTION}.
         */
        private void addActionNode(TreeParent parent, URI actionType, String kind) {

            parent.addChild(new TreeObject(new KeyValueNode(kind, actionType.toString())));
        }

        /**
         * <p>
         * Returns a new {@link String} that is append to a given {@link String} and
         * describes a given {@link Connector}.
         * </p>
         * 
         * @param string
         *          The {@link String} to that the result should be appended.
         * @param connector
         *          The {@link Connector} that shall be described.
         * @return The gerated descriptional {@link String}.
         */
        private String getResourceLabel(String string, Connector connector) {

            StringBuffer buffer;
            buffer = new StringBuffer(string);

            if (connector != null) {
                Component component;
                component = connector.getOwner();

                if (component != null) {
                    buffer.append(" (defined in ");
                    buffer.append(component.getId());
                    buffer.append(')');
                }
                // no else.
            }
            // no else.

            return buffer.toString();
        }
    }

    /**
     * <p>
     * Used to provide the labels for the {@link TreeViewer}.
     * </p>
     * 
     * @author Jens Dietrich
     */
    private class ViewLabelProvider implements ITableLabelProvider {

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.
         * jface.viewers.ILabelProviderListener)
         */
        public void addListener(ILabelProviderListener arg0) {

            /* Do nothing. */
        }

        /*
         * (non-Javadoc)
         * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
         */
        public void dispose() {

            /* Do nothing. */
        }

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang
         * .Object, int)
         */
        public Image getColumnImage(Object node, int column) {

            Image result;
            result = null;

            if (node instanceof TreeObject) {

                Object adaptedObject;
                adaptedObject = ((TreeObject) node).getObject();

                if (column == STATUS_COLUMN) {
                    result = this.getStatusIcon(adaptedObject);
                }

                else if (column == LABEL_COLUMN) {

                    if (adaptedObject instanceof Connector) {
                        Connector connector;
                        connector = (Connector) adaptedObject;

                        if (connector.getType() == ConnectorType.SUPPLIER) {
                            result = getIcon("extension.gif");
                        }

                        else if (connector.getType() == ConnectorType.CONSUMER) {
                            result = getIcon("extensionpoint.gif");
                        }
                        // no else.
                    }

                    else if (adaptedObject instanceof Component) {
                        result = getIcon("plugin.gif");
                    }

                    else if (adaptedObject instanceof Contract) {
                        result = getIcon("contract.gif");
                    }

                    else if (adaptedObject instanceof Condition && !(adaptedObject instanceof ComplexCondition)) {
                        result = getIcon("constraint.gif");
                    }

                    else if (adaptedObject instanceof Resource) {
                        boolean isVariable;
                        isVariable = ((Resource) adaptedObject).getName() == null;

                        Image icon;
                        icon = IconProvider.findIcon(((Resource) adaptedObject).getType(), isVariable);

                        if (icon != null) {
                            result = icon;
                        }

                        /* Probably use a default image. */
                        else {

                            if (isVariable) {
                                result = getIcon("variable.png");
                            }

                            else {
                                getIcon("constant.png");
                            }
                        }
                        // end else.
                    }

                    else if (adaptedObject instanceof KeyValueNode
                            && (((KeyValueNode) adaptedObject).key.equals("relationship"))) {

                        /* (Relationship). */
                        result = getIcon("link.gif");
                    }

                    else if (adaptedObject instanceof KeyValueNode
                            && ((((KeyValueNode) adaptedObject).key.equals(KEY_ON_SUCCESS_ACTION))
                                    || ((KeyValueNode) adaptedObject).key.equals(KEY_ON_FAILURE_ACTION))) {

                        /* (Action). */
                        result = getIcon("action.gif");
                    }

                    else if (adaptedObject instanceof KeyValueNode
                            && (((KeyValueNode) adaptedObject).key.equals(KEY_TRIGGER))) {

                        /* (Action). */
                        result = getIcon("trigger.gif");
                    }

                    else if (node instanceof TreeParent) {
                        return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
                    }
                    // no else.
                }
                // no else (unknown column).
            }
            // no else (node is no TreeObject, return null).

            return result;
        }

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang
         * .Object, int)
         */
        public String getColumnText(Object node, int column) {

            String result;

            if (!(node instanceof TreeObject)) {
                if (column == LABEL_COLUMN) {
                    result = node.toString();
                }

                else {
                    result = "";
                }
            }

            else {
                Object adaptedObject;
                adaptedObject = ((TreeObject) node).getObject();

                if (column == STATUS_COLUMN) {
                    return this.getStatus(adaptedObject);
                }

                else if (column == LABEL_COLUMN) {

                    if (adaptedObject instanceof EclipseExtensionPoint) {
                        result = ((Connector) adaptedObject).getId();
                    }

                    else if (adaptedObject instanceof EclipseExtension) {
                        EclipseExtension eclipseExtension;
                        eclipseExtension = (EclipseExtension) adaptedObject;

                        StringBuffer buffer;
                        buffer = new StringBuffer();
                        buffer.append(eclipseExtension.getOwner().getId()).append('/');

                        String id;
                        id = eclipseExtension.getId();

                        if (id == null) {
                            buffer.append("Anonymous Extension");
                        }

                        else {
                            buffer.append(eclipseExtension.getId());
                        }

                        result = buffer.toString();
                    }

                    else if (adaptedObject instanceof Component) {
                        result = ((Component) adaptedObject).getId();
                    }

                    else if (adaptedObject instanceof Contract) {
                        Contract contract;
                        contract = (Contract) adaptedObject;

                        URL contractUrl;
                        contractUrl = contract.getLocation();

                        if (contractUrl == null) {
                            return "A Contract";
                        }

                        else {
                            /*
                             * Check whether or not the contract has been provided by third
                             * party.
                             */
                            if (contract.getOwner() != null
                                    && !contract.getConsumer().equals(contract.getOwner())) {
                                Connector connector;
                                connector = contract.getOwner();

                                Component component;
                                component = connector.getOwner();

                                String componentID;
                                componentID = component.getId();

                                result = componentID + contractUrl.getPath();
                            }

                            /* Else the context is defined by parent node. */
                            else {
                                result = contractUrl.getPath();
                            }
                        }
                        // end else (contractURL != null).
                    }

                    else if (adaptedObject instanceof Resource) {
                        Resource resource;
                        resource = (Resource) adaptedObject;

                        result = this.toString(resource);
                    }

                    else if (adaptedObject instanceof KeyValueNode) {

                        KeyValueNode keyValueNode;
                        keyValueNode = (KeyValueNode) adaptedObject;

                        result = keyValueNode.key + ": " + keyValueNode.value;
                    }

                    else if (adaptedObject instanceof RelationshipCondition) {
                        result = this.toString((RelationshipCondition) adaptedObject);
                    }

                    else if (adaptedObject instanceof PropertyCondition) {
                        result = this.toString((PropertyCondition) adaptedObject);
                    }

                    else if (adaptedObject instanceof ExistsCondition) {
                        result = this.toString((ExistsCondition) adaptedObject);
                    }

                    else if (adaptedObject instanceof ComplexCondition) {
                        result = ((ComplexCondition) adaptedObject).getConnective();
                    }

                    else if (adaptedObject instanceof NegatedCondition) {
                        result = "not";
                    }

                    else {
                        return adaptedObject.toString();
                    }
                    // end else (instanceof check).
                }

                /* (unknown column). */
                else {
                    result = "";
                }
            }
            // end else (node is TreeObject).

            return result;
        }

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang
         * .Object, java.lang.String)
         */
        public boolean isLabelProperty(Object arg0, String arg1) {

            /* Do nothing. */
            return false;
        }

        /*
         * (non-Javadoc)
         * @see
         * org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse
         * .jface.viewers.ILabelProviderListener)
         */
        public void removeListener(ILabelProviderListener arg0) {

            /* Do nothing. */
        }

        /**
         * <p>
         * Returns the verification status of a given {@link Object} as a
         * {@link String}.
         * </p>
         * 
         * @param object
         *          The {@link Object} whose status shall be returned.
         * @return The verification status as a {@link String}.
         */
        private String getStatus(Object object) {

            String result;
            result = "";

            if (object instanceof Annotatable) {

                Annotatable annotatable;
                Object status;

                annotatable = (Annotatable) object;
                status = annotatable.getProperty(VERIFICATION_RESULT);

                if (status == VerificationResult.FAILURE) {
                    result = "failure";
                }

                else if (status == VerificationResult.SUCCESS) {
                    result = "success";
                }

                else if (status == VerificationResult.UNKNOWN) {
                    result = "unknown";
                }

                else {
                    result = "not verified";
                }
                // no else.
            }
            return result;
        }

        /**
         * <p>
         * Returns a {@link String} representation of a given
         * {@link ExistsCondition}.
         * </p>
         * 
         * @param condition
         *          The {@link ExistsCondition} whose {@link String} representation
         *          shall be returned.
         * @return A {@link String} representation of a given
         *         {@link ExistsCondition}.
         */
        private String toString(ExistsCondition condition) {

            StringBuffer buf = new StringBuffer();
            buf.append(toString(condition.getResource()));
            buf.append(" must exist");
            return buf.toString();
        }

        /**
         * <p>
         * Returns a {@link String} representation of a given
         * {@link PropertyCondition}.
         * </p>
         * 
         * @param condition
         *          The {@link PropertyCondition} whose {@link String}
         *          representation shall be returned.
         * @return A {@link String} representation of a given
         *         {@link PropertyCondition}.
         */
        private String toString(PropertyCondition condition) {

            StringBuffer buf = new StringBuffer();
            buf.append(toString(condition.getResource()));
            buf.append(' ');

            Iterator<String> propertyNameIterator;
            propertyNameIterator = condition.getPropertyNames();

            while (propertyNameIterator.hasNext()) {
                buf.append(condition.getProperty(propertyNameIterator.next()));
                buf.append(' ');
            }
            // end while

            buf.append(' ');
            buf.append(condition.getOperator().toString());
            buf.append(' ');
            buf.append(condition.getValue());
            return buf.toString();
        }

        /**
         * <p>
         * Returns a {@link String} representation of a given
         * {@link RelationshipCondition}.
         * </p>
         * 
         * @param condition
         *          The {@link RelationshipCondition} whose {@link String}
         *          representation shall be returned.
         * @return A {@link String} representation of a given
         *         {@link RelationshipCondition}.
         */
        private String toString(RelationshipCondition condition) {

            StringBuffer buf = new StringBuffer();
            buf.append(toString(condition.getResource1()));
            buf.append(' ');
            String p = condition.getRelationship().toString();
            p = p.substring(p.lastIndexOf('#') + 1); // last token
            buf.append(p);
            buf.append(' ');
            buf.append(toString(condition.getResource2()));
            return buf.toString();
        }

        /**
         * <p>
         * Returns a {@link String} representation of a given {@link Resource}.
         * </p>
         * 
         * @param resource
         *          The {@link Resource} whose {@link String} representation shall
         *          be returned.
         * @return A {@link String} representation of a given {@link Resource}.
         */
        private String toString(Resource resource) {

            if (resource.getName() != null) {
                boolean loadProblem = resource.getValue() == null
                        && resource.getProperty(VERIFICATION_EXCEPTION) != null;
                return loadProblem ? "!" + resource.getName() : resource.getName();
            } else {
                return resource.getId();
            }
        }

        /**
         * <p>
         * Returns the status icon (verification result) of a given node.
         * </p>
         * 
         * @param node
         *          The node whose {@link Image} shall be returned.
         * @return The status icon (verification result) of a given node.
         */
        private Image getStatusIcon(Object node) {

            Image result;
            result = null;

            if (node instanceof Annotatable) {
                Annotatable annotatable;
                annotatable = (Annotatable) node;

                Object status;
                status = annotatable.getProperty(VERIFICATION_RESULT);

                // if (c instanceof Constraint && !((Constraint)c).isInstantiated()) {
                // return getIcon("status_notinstantiated.gif"); }

                if (status == VerificationResult.FAILURE) {
                    result = getIcon("status_failure.gif");
                }

                else if (status == VerificationResult.SUCCESS) {
                    result = getIcon("status_success.gif");
                }

                else {
                    result = getIcon("status_open.gif");
                }
                // end else.
            }
            // no else.

            return result;
        }
    }

    /** Key used for {@link KeyValueNode}s representing actions. */
    private static final String KEY_ON_FAILURE_ACTION = "onFailure";

    /** Key used for {@link KeyValueNode}s representing actions. */
    private static final String KEY_ON_SUCCESS_ACTION = "onSuccess";

    /** Key used for {@link KeyValueNode}s representing triggers. */
    private static final String KEY_TRIGGER = "verification caused by";

    /** The number of the column used to display the {@link Contract}'s labels. */
    private static int LABEL_COLUMN = 0;

    /** Label used to display contract instances in the {@link ContractView}. */
    private static final String LABEL_INSTANCES = "Contract Instances";

    /**
     * The number of the column used to display the {@link Contract}'s
     * verification status.
     */
    private static int STATUS_COLUMN = 1;

    /**
     * Indicates which {@link VerificationPolicy} shall be used. If enabled,
     * {@link VerificationPolicy#FAST} is used. Else
     * {@link VerificationPolicy#DETAILED} is used.
     */
    private boolean isFastVerificationEnabled = false;

    /**
     * A boolean that specifies whether or not the {@link ContractView} has been
     * updated after the {@link EclipseContractRegistry} changed for the last
     * time.
     */
    private boolean isUpdated;

    /** {@link Action} to enable or disable fast verification. */
    private Action myActionEnableFastVerifaction;

    /** {@link Action} to print the current stack trace. */
    private Action myActionPrintStackTrace;

    /**
     * The {@link Action} that can be used to refresh the {@link ContractView}
     * manually.
     */
    private Action myActionRefresh;

    /** {@link Action} to display a {@link Contract}'s source code. */
    private Action myActionShowContractSource;

    /** {@link Action} to display a {@link Contract}'s vizualisation. */
    private Action myActionShowContractVizualisation;

    /** {@link Action} to check types of actions and triggers in {@link Contract}s. */
    private Action myActionTypeCheck;

    /**
     * {@link Action} to verify all {@link Contract}s provided by this
     * {@link ContractView}.
     */
    private Action myActionVerifyAllContracts;

    /** {@link Action} to verify currently selected {@link Contract}s. */
    private Action myActionVerifySelectedContracts;

    /** {@link Action}s to export {@link Contract}s from the {@link ContractView}. */
    private Map<Exporter, ExportAction> myActionsExport = new HashMap<Exporter, ExportAction>();

    /** The {@link MenuManager} of the context menu. */
    private MenuManager myContextMenuManager;

    /**
     * All {@link EclipsePlugin}s that have {@link EclipseExtensionPoint}s that
     * are contracted by {@link Contract}s.
     */
    private Collection<EclipsePlugin> myContractedPlugins = null;

    /** The {@link DrillDownAdapter} of this {@link ContractView}. */
    private DrillDownAdapter myDrillDownAdapter;

    /** The icons of this {@link ContractView} must be stored to be disposed. */
    private Map<String, Image> myIcons = new HashMap<String, Image>();

    /**
     * The {@link TreeViewer} used to display the {@link Contract}s and their
     * {@link EclipsePlugin}s.
     */
    private TreeViewer myViewer;

    /**
     * <p>
     * Creates a new {@link ContractView}.
     * </p>
     */
    public ContractView() {

    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.ui.part.WorkbenchPart#dispose()
     */
    @Override
    public void dispose() {

        /* Un-Register as contract view of the UIActions. */
        try {
            UIActionVocabulary actionVocabulary;
            actionVocabulary = (UIActionVocabulary) EclipseActionRegistry.INSTANCE
                    .getActionVocabulary(new URI(UIActionVocabulary.ACTION_TYPE_SHOW_VERIFICATION_RESULT));

            actionVocabulary.setContractView(null);
        }

        catch (URISyntaxException e1) {
            Logger.warn("ContractView could not be un-registered at the UIActionVocabulary. "
                    + "UI might not work as excepted.", e1);
        }

        catch (TreatyException e) {
            Logger.warn("ContractView could not be un-registered at the UIActionVocabulary. "
                    + "UI might not work as excepted.", e);
        }

        /* Disconnect from Contract Registry. */
        EclipseContractRegistry.getInstance().removeContractRegistryListener(this);

        /* Disconnect from ExporterRegistry. */
        ExporterRegistry.INSTANCE.removeExporterRegistryListener(this);

        /* Dispose all icons. */
        for (Image icon : myIcons.values()) {
            icon.dispose();
        }

        super.dispose();
    }

    /**
     * <p>
     * This is a call-back that will allow us to create the viewer and initialize
     * it.
     * </p>
     * 
     * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
     */
    @Override
    public void createPartControl(Composite parent) {

        this.myViewer = new TreeViewer(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);

        this.myViewer.getTree().setHeaderVisible(true);

        TreeColumn columnStatus;
        TreeColumn columnLabel;

        if (LABEL_COLUMN < STATUS_COLUMN) {
            columnLabel = new TreeColumn(myViewer.getTree(), SWT.LEFT);
            columnStatus = new TreeColumn(myViewer.getTree(), SWT.LEFT);
        }

        else {
            columnStatus = new TreeColumn(myViewer.getTree(), SWT.LEFT);
            columnLabel = new TreeColumn(myViewer.getTree(), SWT.LEFT);
        }

        Rectangle bounds;
        bounds = myViewer.getTree().getDisplay().getBounds();

        columnLabel.setText("Plug-in Contracts");
        columnLabel.setWidth(Math.min(600, bounds.width - 200));

        columnStatus.setText("Status");
        columnStatus.setWidth(150);

        this.myViewer.setLabelProvider(new ViewLabelProvider());

        this.myViewer.setContentProvider(new DummyViewContentProvider());
        this.myViewer.setInput(getViewSite());

        this.myViewer.addSelectionChangedListener(new ISelectionChangedListener() {

            /*
             * (non-Javadoc)
             * @see
             * org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged
             * (org.eclipse.jface.viewers.SelectionChangedEvent)
             */
            public void selectionChanged(SelectionChangedEvent e) {

                Object selectedObject;
                selectedObject = getSelectedObject();

                /*
                 * Probably enable actions to display source code and verification
                 * exception of selection.
                 */
                boolean isActionAvailable = selectedObject != null && selectedObject instanceof PropertySupport
                        && ((PropertySupport) selectedObject).getProperty(Constants.VERIFICATION_EXCEPTION) != null;

                myActionPrintStackTrace.setEnabled(isActionAvailable);
                myActionShowContractSource.setEnabled(getSelectedContract() != null);
                myActionShowContractVizualisation.setEnabled(getSelectedContract() != null);

                Set<Contract> selectedInstantiatedConstracts;
                selectedInstantiatedConstracts = getSelectedInstantiatedContracts();

                myActionVerifySelectedContracts.setEnabled(
                        selectedInstantiatedConstracts != null && !selectedInstantiatedConstracts.isEmpty());
            }
        });

        this.makeActions();
        this.hookContextMenu();
        this.contributeToActionBars();

        /* Background initialization. */
        this.actionReloadContracts();

        /* Register as listener of the contract registry. */
        EclipseContractRegistry.getInstance().addContractRegistryListener(this);

        /* Register as listener of the ExporterRegistry. */
        ExporterRegistry.INSTANCE.addExporterRegistryListener(this);

        /* Register as contract view of the UIActions. */
        try {
            UIActionVocabulary actionVocabulary;
            actionVocabulary = (UIActionVocabulary) EclipseActionRegistry.INSTANCE
                    .getActionVocabulary(new URI(UIActionVocabulary.ACTION_TYPE_SHOW_VERIFICATION_RESULT));

            actionVocabulary.setContractView(this);
        }

        catch (URISyntaxException e1) {
            Logger.warn("ContractView could not be registered at the UIActionVocabulary. "
                    + "UI might not work as excepted.", e1);
        }

        catch (TreatyException e) {
            Logger.warn("ContractView could not be registered at the UIActionVocabulary. "
                    + "UI might not work as excepted.", e);
        }
    }

    /*
     * (non-Javadoc)
     * @see
     * net.java.treaty.eclipse.exporter.ExporterRegistryListener#exporterAdded
     * (net.java.treaty.eclipse.exporter.Exporter)
     */
    public void exporterAdded(Exporter exporter) {

        if (!this.myActionsExport.containsKey(exporter)) {

            this.createExportAction(exporter);

            /* Update the menus. */
            PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {

                /*
                 * (non-Javadoc)
                 * @see java.lang.Runnable#run()
                 */
                public void run() {

                    hookContextMenu();
                    contributeToActionBars();
                }
            });
        }
        // no else (action already exists).
    }

    /*
     * (non-Javadoc)
     * @see
     * net.java.treaty.eclipse.exporter.ExporterRegistryListener#exporterRemoved
     * (net.java.treaty.eclipse.exporter.Exporter)
     */
    public void exporterRemoved(Exporter exporter) {

        if (this.myActionsExport.containsKey(exporter)) {

            this.myActionsExport.remove(exporter);

            /* Update the menus. */
            PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {

                /*
                 * (non-Javadoc)
                 * @see java.lang.Runnable#run()
                 */
                public void run() {

                    hookContextMenu();
                    contributeToActionBars();
                }
            });
        }
        // no else (action already removed).
    }

    /**
     * <p>
     * Passing the focus request to the viewer's control.
     * </p>
     */
    public void setFocus() {

        this.myViewer.getControl().setFocus();
    }

    /*
     * (non-Javadoc)
     * @see net.java.treaty.contractregistry.ContractRegistryListener#update()
     */
    public void update() {

        /* Set the flag before doing anything. */
        this.isUpdated = false;

        /*
         * Each update causes a thread. But each thread that is executed afterwards
         * the flag has been set to true again will not do anything.
         */
        PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {

            /*
             * (non-Javadoc)
             * @see java.lang.Runnable#run()
             */
            public void run() {

                actionReloadContracts();
            }
        });
    }

    /**
     * <p>
     * Returns the {@link ImageDescriptor} for a given path.
     * </p>
     * 
     * @param path
     *          The path whose {@link ImageDescriptor} shall be returned.
     * @return The {@link ImageDescriptor} for a given path.
     */
    public ImageDescriptor getImageDescriptor(String path) {

        return AbstractUIPlugin.imageDescriptorFromPlugin(Activator.PLUGIN_ID, path);
    }

    /**
     * <p>
     * Displays the verification result for a given {@link List} of verified
     * {@link Contract}s and a given {@link List} of violated {@link Contract}s.
     * </p>
     * 
     * @param verificationReports
     *          The {@link VerificationReport}s of all {@link Contract}s that have
     *          been verified.
     * @param triggerType
     *          The trigger that triggered the verification. Can be
     *          <code>null</code>.
     */
    public void reportVerificationResult(Collection<VerificationReport> verificationReports, URI triggerType) {

        int totalContractCount;
        totalContractCount = verificationReports.size();

        int failedContractCount;
        failedContractCount = 0;

        for (VerificationReport verificationReport : verificationReports) {

            if (verificationReport.getVerificationResult() != VerificationResult.SUCCESS) {
                failedContractCount++;
            }
            // no else.
        }
        // end for.

        StringBuffer buffer;
        buffer = new StringBuffer();

        if (failedContractCount == 0) {
            buffer.append(totalContractCount + " Contract instances have been verified successfully.");
        }

        else {
            buffer.append(totalContractCount + " Contract instances checked, verification has failed for "
                    + failedContractCount + " Contract instances. Verification status annotations have "
                    + "been added to the Contract View.");
        }
        // end else.

        if (triggerType != null) {
            buffer.append("\n\nThe verification was triggered by a " + triggerType + " event.");
        }
        // no else.

        final String msg;
        msg = buffer.toString();

        Runnable runnable;
        runnable = new Runnable() {

            public void run() {

                MessageDialog.openInformation(myViewer.getControl().getShell(), "Verification result", msg);
            }
        };

        myViewer.getControl().getDisplay().syncExec(runnable);
    }

    /**
     * <p>
     * Behavior of the {@link Action} to check the trigger and action types in all
     * {@link Contract}s.
     * </p>
     */
    private void actionContracTypeCheck() {

        ContractTypeChecker contractTypeChecker;
        contractTypeChecker = new ContractTypeChecker(EclipseActionRegistry.INSTANCE,
                EclipseTriggerRegistry.INSTANCE);

        Set<TreatyException> warnings;
        warnings = contractTypeChecker
                .checkContracts(EclipseContractRegistry.getInstance().getInstantiatedContracts());

        final String msg;

        if (warnings.size() == 0) {
            msg = "All Trigger and Action types are defined.";
        }

        else {
            StringBuffer msgBuffer;
            msgBuffer = new StringBuffer();

            msgBuffer.append("Some Trigger or Action types used in Contracts are not defined:\n");

            int index;
            index = 0;
            for (TreatyException treatyException : warnings) {
                msgBuffer.append("\n" + treatyException.getMessage());
                index++;

                if (index > 5) {
                    msgBuffer.append("\n" + (warnings.size() - 5) + " more...");
                    break;
                }
                // no else.
            }
            // end for.

            msg = msgBuffer.toString();
        }

        Runnable runnable;
        runnable = new Runnable() {

            public void run() {

                MessageDialog.openInformation(myViewer.getControl().getShell(), "Contract Type Check Result", msg);
            }
        };

        this.myViewer.getControl().getDisplay().syncExec(runnable);
    }

    /**
     * <p>
     * Behavior of the {@link Action} to export all instantiated {@link Contract}
     * s by using a given {@link Exporter}.
     * </p>
     * 
     * @param exporter
     *          The {@link Exporter} that shall be used for export.
     */
    private void actionExport(Exporter exporter) {

        Collection<Contract> contracts;
        contracts = EclipseContractRegistry.getInstance().getInstantiatedContracts();

        /* Try to export. */
        try {
            String fileName;
            fileName = null;

            /* Probably export to a folder. */
            if (exporter.exportToFolder()) {

                DirectoryDialog directoryDialog;

                directoryDialog = new DirectoryDialog(this.getViewSite().getShell(), SWT.OPEN);
                directoryDialog.setText("Select a target folder for export.");

                fileName = directoryDialog.open();
            }

            /* Else export to a file. */
            else {
                FileDialog fileDialog;

                fileDialog = new FileDialog(this.getViewSite().getShell(), SWT.OPEN);
                fileDialog.setFilterExtensions(exporter.getFilterExtensions());
                fileDialog.setFilterNames(exporter.getFilterNames());
                fileDialog.setText("Select a file for export.");

                fileName = fileDialog.open();
            }
            // no else.

            /* Probably export the contracts. */
            if (fileName != null) {
                exporter.export(contracts, new File(fileName));

                /* Show the result. */
                /* FIXME Claas: Probably Exporters should work as jobs as well. */
                Runnable runnable;
                runnable = new Runnable() {

                    public void run() {

                        MessageDialog.openInformation(myViewer.getControl().getShell(), "Contract Export",
                                "Contract export finished successfully.");
                    }
                };

                myViewer.getControl().getDisplay().syncExec(runnable);
            }
            // no else.
        }
        // end try.

        catch (IOException e) {
            Logger.error("Exception exporting contracts", e);

            /* Show the result. */
            final String msg;
            msg = e.getMessage();

            Runnable runnable;
            runnable = new Runnable() {

                public void run() {

                    MessageDialog.openInformation(myViewer.getControl().getShell(), "Contract Export",
                            "Contract export failed. Reason: " + msg);
                }
            };

            myViewer.getControl().getDisplay().syncExec(runnable);
        }
        // end catch.
    }

    /**
     * <p>
     * Prints the verification exception stack trace. For the selected object in
     * the {@link ContractView}.
     * </p>
     */
    private void actionPrintStackTrace() {

        Object selectedObject;
        selectedObject = this.getSelectedObject();

        if (selectedObject != null && selectedObject instanceof PropertySupport
                && ((PropertySupport) selectedObject).getProperty(Constants.VERIFICATION_EXCEPTION) != null) {

            Exception exception = (Exception) ((PropertySupport) selectedObject)
                    .getProperty(Constants.VERIFICATION_EXCEPTION);

            if (exception != null) {

                try {
                    new ViewExceptionStackTraceDialog(this.getViewSite().getShell(), exception).open();
                }

                catch (Exception e) {
                    Logger.error("Exception during display of VerificationException.", e);
                }
                // end catch.
            }
            // no else.
        }
        // no else.
    }

    /**
     * <p>
     * Updates the GUI by requesting the {@link EclipseContractRegistry} for a new
     * version of the current {@link Contract} model.
     * </p>
     */
    private synchronized void actionReloadContracts() {

        if (!this.isUpdated) {

            /*
             * It is very important that this flag is set before the contracts are
             * updated to avoid unwanted side effects.
             */
            this.isUpdated = true;

            /* Load the contracted plug-ins. */
            this.myContractedPlugins = EclipseContractRegistry.getInstance().getContractedEclipsePlugins();

            /* Update the viewer. */
            this.myViewer.setContentProvider(new ViewContentProvider());
            this.myViewer.setInput(getViewSite());

            this.switchActions(true);
        }
        // no else.
    }

    /**
     * <p>
     * Shows a dialog window to display the source code of a selected
     * {@link Contract}.
     * </p>
     */
    private void actionShowContractSource() {

        Contract contract;
        contract = this.getSelectedContract();

        if (contract != null) {
            try {
                URL contractURL;
                contractURL = contract.getLocation();

                new ViewContractSourceDialog(new Shell(), contractURL).open();
            }

            catch (Exception e) {
                Logger.error("Error occurred during display of contract source code", e);
            }
            // end catch.
        }
        // no else.
    }

    /**
     * <p>
     * Shows a dialog window to display the visualization of a selected
     * {@link Contract}.
     * </p>
     */
    private void actionShowContractVizualisation() {

        Contract contract;
        contract = this.getSelectedContract();

        if (contract != null) {

            try {
                ContractVizViewer4Swing.show(contract);
            }

            catch (Exception e) {
                Logger.error("Error occurred during display of contract vizualisation", e);
            }
            // end catch.
        }
        // no else.
    }

    /**
     * <p>
     * Runs the verification of all {@link Contract}s.
     * </p>
     */
    private void actionVerifyAllContracts() {

        try {
            URI triggerVerifyAll;
            triggerVerifyAll = new URI(ManualTriggerVocabulary.TRIGGER_TYPE_VERIFY_ALL);

            ManualTriggerVocabulary manualTriggerVocabulary;
            manualTriggerVocabulary = (ManualTriggerVocabulary) EclipseTriggerRegistry.INSTANCE
                    .getTriggerVocabulary(triggerVerifyAll);

            manualTriggerVocabulary.fireTriggerVerifyAll();
        }
        // end try.

        catch (URISyntaxException e) {
            Logger.error("Unexpected exception during verification of all Contracts.", e);
        }

        catch (TreatyException e) {
            Logger.error("Unexpected exception during verification of all Contracts.", e);
        }
        // end catch.
    }

    /**
     * <p>
     * Runs the verification for the currently selected {@link Contract}s.
     * </p>
     */
    private void actionVerifySelectedContracts() {

        Set<Contract> contracts;
        contracts = this.getSelectedInstantiatedContracts();

        if (contracts != null && !contracts.isEmpty()) {

            try {
                URI triggerVerifyAll;
                triggerVerifyAll = new URI(ManualTriggerVocabulary.TRIGGER_TYPE_VERIFY_SELECTED);

                ManualTriggerVocabulary manualTriggerVocabulary;
                manualTriggerVocabulary = (ManualTriggerVocabulary) EclipseTriggerRegistry.INSTANCE
                        .getTriggerVocabulary(triggerVerifyAll);

                manualTriggerVocabulary.fireTriggerVerifySelected(contracts);
            }
            // end try.

            catch (URISyntaxException e) {
                Logger.error("Unexpected exception during verification of selected Contracts.", e);
            }

            catch (TreatyException e) {
                Logger.error("Unexpected exception during verification of all Contracts.", e);
            }
            // end catch.
        }
        // no else.
    }

    /**
     * <p>
     * A helper method that collects all instantiated {@link Contract}s of a given
     * {@link EclipseExtensionPoint} and adds them to a given {@link Collection}.
     * </p>
     * 
     * @param eclipseExtensionPoint
     *          The extension point whose {@link Contract}s shall be added.
     * @param contractList
     *          The {@link Collection} to that the {@link Contract}s shall be
     *          added.
     */
    private void collectInstantiatedContracts(EclipseExtensionPoint eclipseExtensionPoint,
            Collection<Contract> contractList) {

        for (EclipseExtension eclipseExtension : eclipseExtensionPoint.getExtensions()) {
            this.collectInstantiatedContract(eclipseExtension, contractList);
        }
        // end for.
    }

    /**
     * <p>
     * A helper method that collects all instantiated {@link Contract}s of a given
     * {@link EclipseExtension} and adds them to a given {@link Collection}.
     * </p>
     * 
     * @param eclipseExtension
     *          The extension point whose {@link Contract}s shall be added.
     * @param contractList
     *          The {@link Collection} to that the {@link Contract}s shall be
     *          added.
     */
    private void collectInstantiatedContract(EclipseExtension eclipseExtension, Collection<Contract> contractList) {

        for (Contract contract : eclipseExtension.getContracts()) {

            if (contract != null && contract.isInstantiated()) {
                contractList.add(contract);
            }
            // no else.

            /* Probably set annotation here. */
        }
        // end for.
    }

    /**
     * <p>
     * Initializes the pull down menu and the tool bar according to the context
     * menu.
     * </p>
     */
    private void contributeToActionBars() {

        IActionBars bars = getViewSite().getActionBars();
        this.fillLocalPullDown(bars.getMenuManager());
        this.fillLocalToolBar(bars.getToolBarManager());
    }

    private void createExportAction(Exporter exporter) {

        /* Probably create the action. */
        if (!this.myActionsExport.containsKey(exporter)) {

            ExportAction exportAction;
            exportAction = new ExportAction(exporter);

            exportAction.setEnabled(true);
            exportAction.setText(exporter.getName());
            exportAction.setImageDescriptor(getImageDescriptor("icons/export.gif"));
            exportAction.setToolTipText(
                    "Export instantiated contracts and verification results (if available), exporter used: "
                            + exporter.getName());

            this.myActionsExport.put(exporter, exportAction);
        }
        // no else (action already exists).
    }

    /**
     * <p>
     * Initializes the context menu with its {@link Action}s.
     * </p>
     * 
     * @param manager
     *          The {@link IMenuManager} of the context menu.
     */
    private void fillContextMenu(IMenuManager manager) {

        manager.add(this.myActionRefresh);
        manager.add(this.myActionEnableFastVerifaction);
        manager.add(this.myActionVerifyAllContracts);
        manager.add(this.myActionVerifySelectedContracts);
        manager.add(this.myActionPrintStackTrace);
        manager.add(this.myActionShowContractSource);
        manager.add(this.myActionShowContractVizualisation);
        manager.add(this.myActionTypeCheck);

        manager.add(new Separator());

        for (Action actExport : this.myActionsExport.values()) {
            manager.add(actExport);
        }

        manager.add(new Separator());

        this.myDrillDownAdapter.addNavigationActions(manager);

        /* Other plug-ins can contribute there actions here. */
        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
    }

    /**
     * <p>
     * Initializes the pull down menu.
     * </p>
     * 
     * @param manager
     *          The {@link IMenuManager} used to initialize.
     */
    private void fillLocalPullDown(IMenuManager manager) {

        manager.removeAll();

        manager.add(this.myActionRefresh);

        manager.add(new Separator());

        manager.add(this.myActionEnableFastVerifaction);

        manager.add(new Separator());

        manager.add(this.myActionVerifyAllContracts);
        manager.add(this.myActionVerifySelectedContracts);

        manager.add(new Separator());

        for (Action actExport : this.myActionsExport.values()) {
            manager.add(actExport);
        }
        // end for.
    }

    /**
     * <p>
     * A helper method that fills the tool bar with icons for the {@link Action}s
     * of the {@link ContractView}.
     * </p>
     * 
     * @param toolBarManager
     *          The {@link IToolBarManager} to that the {@link Action}s shall be
     *          added.
     */
    private void fillLocalToolBar(IToolBarManager toolBarManager) {

        toolBarManager.removeAll();

        toolBarManager.add(this.myActionRefresh);
        toolBarManager.add(this.myActionVerifyAllContracts);
        toolBarManager.add(this.myActionVerifySelectedContracts);

        toolBarManager.add(new Separator());

        for (Action actExport : this.myActionsExport.values()) {
            toolBarManager.add(actExport);
        }
        // end for.

        toolBarManager.add(new Separator());

        this.myDrillDownAdapter = new DrillDownAdapter(this.myViewer);
        this.myDrillDownAdapter.addNavigationActions(toolBarManager);
    }

    /**
     * <p>
     * Returns the {@link Contract} for a given {@link TreeObject}.
     * </p>
     * 
     * @param treeObject
     *          The {@link TreeObject} whose {@link Contract} shall be returned.
     * @return The {@link Contract} for a given {@link TreeObject}.
     */
    private Contract findContract(TreeObject treeObject) {

        Object adaptedObject = treeObject.getObject();

        // check whether this is a contract
        if (adaptedObject instanceof Contract) {
            return (Contract) adaptedObject;
        }

        // check whether the first child and only this is a contract
        // this will pick contracts when parents (extensions and ext points)
        // are selected
        if (treeObject instanceof TreeParent) {
            TreeObject[] children = ((TreeParent) treeObject).getChildren();
            if (children != null && children.length > 0 && children[0].getObject() instanceof Contract) {
                Contract contract = (Contract) children[0].getObject();
                boolean isUniqueSelection = true;
                for (int i = 1; i < children.length; i++) {
                    isUniqueSelection = isUniqueSelection && !(children[i].getObject() instanceof Contract);
                }
                if (isUniqueSelection)
                    return contract;
            }
        }

        TreeObject parent = treeObject.getParent();
        if (parent != null) {
            return this.findContract(parent);
        }

        return null;
    }

    /**
     * <p>
     * Returns the {@link Image} for a given name. Probably the {@link Image} will
     * be initialized.
     * </p>
     * 
     * @param name
     *          The name whose {@link Image} shall be returned.
     * @return The {@link Image} to the given name.
     */
    private Image getIcon(String name) {

        Image result;

        String path;
        path = "icons/" + name;

        result = this.myIcons.get(path);

        if (result == null) {
            result = getImageDescriptor(path).createImage();
            this.myIcons.put(path, result);
        }
        // no else.

        return result;
    }

    /**
     * <p>
     * Returns the currently in this {@link ContractView} selected
     * {@link Contract}.
     * </p>
     * 
     * @return The currently selected {@link Contract}.
     */
    private Contract getSelectedContract() {

        Contract result;

        TreeItem[] selection;
        selection = myViewer.getTree().getSelection();

        if (selection == null || selection.length == 0) {
            result = null;
        }

        else {
            TreeObject treeObject;
            treeObject = (TreeObject) selection[0].getData();

            result = this.findContract(treeObject);
        }

        return result;
    }

    /**
     * <p>
     * Returns the instantiated {@link Contract}s that are part of the currently
     * selected items in this {@link ContractView}.
     * </p>
     * 
     * @return The instantiated {@link Contract}s that are part of the currently
     *         selected items in this {@link ContractView}.
     */
    private Set<Contract> getSelectedInstantiatedContracts() {

        Set<Contract> result;
        result = new HashSet<Contract>();

        Contract selectedContract;
        selectedContract = this.getSelectedContract();

        /* Probably use the selected contract. */
        if (selectedContract != null) {

            /* If the contract is instantiated, return it. */
            if (selectedContract.isInstantiated()) {
                result.add(selectedContract);
            }

            /* Else collect its instances. */
            else {

                EclipseExtensionPoint eclipseExtensionPoint;
                eclipseExtensionPoint = (EclipseExtensionPoint) selectedContract.getConsumer();

                this.collectInstantiatedContracts(eclipseExtensionPoint, result);
            }
            // end else.
        }

        /* Else try to find selected contracts. */
        else {

            TreeItem[] selection;
            selection = this.myViewer.getTree().getSelection();

            /* Check if the selection is empty. */
            if (selection != null && selection.length > 0) {

                Object selectedObject;
                selectedObject = ((TreeObject) selection[0].getData()).getObject();

                TreeItem parent;
                parent = selection[0].getParentItem();

                if (selectedObject instanceof EclipseExtension) {
                    this.collectInstantiatedContract((EclipseExtension) selectedObject, result);
                }

                else if (selectedObject instanceof EclipseExtensionPoint) {
                    this.collectInstantiatedContracts((EclipseExtensionPoint) selectedObject, result);
                }

                else if (selectedObject instanceof EclipsePlugin) {

                    EclipsePlugin eclipsePlugin;
                    eclipsePlugin = (EclipsePlugin) selectedObject;

                    if (parent != null && LABEL_INSTANCES.equals(parent.getData().toString())) {

                        /* Folder for instances selected. */
                        for (EclipseExtension eclipseExtension : eclipsePlugin.getExtensions()) {
                            this.collectInstantiatedContract(eclipseExtension, result);
                        }
                        // end for.
                    }

                    else {

                        /* parent of extension points. */
                        for (EclipseExtensionPoint eclipseExtensionPoint : eclipsePlugin.getExtensionPoints()) {
                            this.collectInstantiatedContracts(eclipseExtensionPoint, result);
                        }
                        // end for.
                    }
                    // end else.
                }
                // no else.
            }
            // no else (empty selection).
        }
        // end else.

        return result;
    }

    /**
     * <p>
     * Returns the currently in the {@link ContractView} selected {@link Object}.
     * Please note that this method already returns the adapted {@link Object},
     * and not the {@link TreeObject}.
     * </p>
     * 
     * @return The currently selected {@link Object}.
     */
    private Object getSelectedObject() {

        Object result;

        TreeItem[] selection;
        selection = myViewer.getTree().getSelection();

        if (selection == null || selection.length == 0) {
            result = null;
        }

        else if (selection[0].getData() instanceof TreeObject) {
            result = ((TreeObject) selection[0].getData()).getObject();
        }

        else {
            result = selection[0].getData();
        }

        return result;
    }

    /**
     * <p>
     * Initializes the context menu of this {@link ContractView}.
     * </p>
     */
    private void hookContextMenu() {

        this.myContextMenuManager = new MenuManager("#PopupMenu");
        this.myContextMenuManager.setRemoveAllWhenShown(true);

        this.myContextMenuManager.addMenuListener(new IMenuListener() {

            public void menuAboutToShow(IMenuManager manager) {

                ContractView.this.fillContextMenu(manager);
            }
        });

        Menu menu;
        menu = this.myContextMenuManager.createContextMenu(this.myViewer.getControl());

        this.myViewer.getControl().setMenu(menu);
        getSite().registerContextMenu(this.myContextMenuManager, this.myViewer);
    }

    /**
     * <p>
     * Creates all {@link Action}s of the {@link ContractView}.
     * </p>
     */
    private void makeActions() {

        /* Action to print the stack trace. */
        this.myActionPrintStackTrace = new Action() {

            public void run() {

                actionPrintStackTrace();
            }
        };

        this.myActionPrintStackTrace.setText("Display verification exception details.");
        this.myActionPrintStackTrace.setToolTipText("Displays the verification exception stack trace.");
        this.myActionPrintStackTrace.setEnabled(false);

        this.myActionRefresh = new Action() {

            public void run() {

                actionReloadContracts();
            }
        };

        this.myActionRefresh.setText("Reset");
        this.myActionRefresh.setImageDescriptor(getImageDescriptor("icons/refresh.gif"));
        this.myActionRefresh
                .setToolTipText("Reloads all contracts and resets verification status of all contracts.");

        /* Action to verify all contracts. */
        this.myActionVerifyAllContracts = new Action() {

            public void run() {

                actionVerifyAllContracts();
            }
        };

        this.myActionVerifyAllContracts.setText("Verify all contracts");
        this.myActionVerifyAllContracts.setImageDescriptor(getImageDescriptor("icons/verify_all.gif"));
        this.myActionVerifyAllContracts.setToolTipText("Run verification for all contracts.");

        /* Action to verify selected contracts. */
        this.myActionVerifySelectedContracts = new Action() {

            public void run() {

                actionVerifySelectedContracts();
            }
        };

        this.myActionVerifySelectedContracts.setText("Verify selected contracts");
        this.myActionVerifySelectedContracts.setImageDescriptor(getImageDescriptor("icons/verify_sel.gif"));
        this.myActionVerifySelectedContracts.setToolTipText("Runs verification for selected contracts.");
        this.myActionVerifySelectedContracts.setEnabled(false);

        /* Action to show a contracts source code. */
        this.myActionShowContractSource = new Action() {

            public void run() {

                actionShowContractSource();
            }
        };

        this.myActionShowContractSource.setEnabled(false);
        this.myActionShowContractSource.setText("Display contract source");
        this.myActionShowContractSource.setToolTipText("Displays the source code of the contract.");

        /* Action to show a contracts vizualisation. */
        this.myActionShowContractVizualisation = new Action() {

            public void run() {

                actionShowContractVizualisation();
            }
        };

        this.myActionShowContractVizualisation.setEnabled(false);
        this.myActionShowContractVizualisation.setText("Display contract vizualisation");
        this.myActionShowContractVizualisation.setToolTipText("Vizualises the selected contract.");

        /* Create an export action for each exporter. */
        for (Exporter exporter : ExporterRegistry.INSTANCE.getExporters()) {

            this.createExportAction(exporter);
        }
        // end for.

        this.myActionTypeCheck = new Action() {

            /*
             * (non-Javadoc)
             * @see org.eclipse.jface.action.Action#run()
             */
            public void run() {

                actionContracTypeCheck();
            }
        };

        this.myActionTypeCheck.setText("Check all Trigger and Action Types.");
        this.myActionTypeCheck.setToolTipText("Checks if all used Trigger and Actions Types are defined.");
        this.myActionTypeCheck.setEnabled(true);

        this.myActionEnableFastVerifaction = new Action() {

            /*
             * (non-Javadoc)
             * @see org.eclipse.jface.action.Action#run()
             */
            public void run() {

                /* Disable or enable. */
                isFastVerificationEnabled = !isFastVerificationEnabled;
                myActionEnableFastVerifaction.setChecked(isFastVerificationEnabled);

                if (isFastVerificationEnabled) {
                    TriggeredEclipseVerifier.INSTANCE.setVerificationPolicy(VerificationPolicy.FAST);
                }

                else {
                    TriggeredEclipseVerifier.INSTANCE.setVerificationPolicy(VerificationPolicy.DETAILED);
                }
            }
        };

        this.myActionEnableFastVerifaction.setEnabled(true);
        this.myActionEnableFastVerifaction.setChecked(isFastVerificationEnabled);
        this.myActionEnableFastVerifaction.setText("Use fast Verification");
        this.myActionEnableFastVerifaction
                .setToolTipText("If enabled fast verification is used for AND and OR conditions.");
    }

    /**
     * <p>
     * A helper method that verifies and refreshes all {@link Contract}s, if the
     * given flag is <code>true</code>.
     * </p>
     * 
     * @param on
     *          Indicates whether or not all {@link Contract}s shall be verified
     *          and refreshed.
     */
    private void switchActions(boolean on) {

        /* Probably verify and refresh. */
        this.myActionVerifyAllContracts.setEnabled(on);
        this.myActionRefresh.setEnabled(on);

        for (Action act : this.myActionsExport.values()) {
            act.setEnabled(on);
        }

        /* Probably verify selected, instantiated contracts. */
        Set<Contract> instantiatedConstracts;
        instantiatedConstracts = getSelectedInstantiatedContracts();

        this.myActionVerifySelectedContracts
                .setEnabled(on && instantiatedConstracts != null && !instantiatedConstracts.isEmpty());
    }
}