You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/02/17 12:45:38 UTC

[14/52] [abbrv] incubator-taverna-workbench git commit: taverna-ui-impl/

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/WorkbenchConfigurationPanel.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/WorkbenchConfigurationPanel.java b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/WorkbenchConfigurationPanel.java
new file mode 100644
index 0000000..ecddc35
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/WorkbenchConfigurationPanel.java
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.impl.configuration;
+
+import static java.awt.GridBagConstraints.*;
+import static javax.swing.JFileChooser.APPROVE_OPTION;
+import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
+import static javax.swing.JOptionPane.WARNING_MESSAGE;
+import static javax.swing.JOptionPane.showMessageDialog;
+import static net.sf.taverna.t2.workbench.helper.Helper.showHelp;
+import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.openIcon;
+
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
+
+import net.sf.taverna.t2.workbench.configuration.workbench.WorkbenchConfiguration;
+
+import org.apache.log4j.Logger;
+
+@SuppressWarnings("serial")
+public class WorkbenchConfigurationPanel extends JPanel {
+	private static final String RESTART_MSG = "For the new configuration to be fully applied, it is advised to restart Taverna.";
+	private static final String DOT_PATH_MSG = "Path to Graphviz executable <code>dot</code>:";
+	private static final String CONTEXT_MENU_SIZE_MSG = "Maximum number of services/ports in right-click menu:";
+	private static Logger logger = Logger
+			.getLogger(WorkbenchConfigurationUIFactory.class);
+
+	private JTextField dotLocation = new JTextField(25);
+	private JTextField menuItems = new JTextField(10);
+	private JCheckBox warnInternal = new JCheckBox("Warn on internal errors");
+	private JCheckBox captureConsole = new JCheckBox(
+			"Capture output on stdout/stderr to log file");
+
+	private final WorkbenchConfiguration workbenchConfiguration;
+
+	public WorkbenchConfigurationPanel(
+			WorkbenchConfiguration workbenchConfiguration) {
+		super();
+		this.workbenchConfiguration = workbenchConfiguration;
+		initComponents();
+	}
+
+	private static JLabel htmlLabel(String html) {
+		return new JLabel("<html><body>" + html + "</body></html>");
+	}
+
+	private void initComponents() {
+		this.setLayout(new GridBagLayout());
+		GridBagConstraints gbc = new GridBagConstraints();
+
+		// Title describing what kind of settings we are configuring here
+		JTextArea descriptionText = new JTextArea(
+				"General Workbench configuration");
+		descriptionText.setLineWrap(true);
+		descriptionText.setWrapStyleWord(true);
+		descriptionText.setEditable(false);
+		descriptionText.setFocusable(false);
+		descriptionText.setBorder(new EmptyBorder(10, 10, 10, 10));
+		gbc.anchor = WEST;
+		gbc.gridx = 0;
+		gbc.gridy = 0;
+		gbc.gridwidth = 2;
+		gbc.weightx = 1.0;
+		gbc.weighty = 0.0;
+		gbc.fill = HORIZONTAL;
+		this.add(descriptionText, gbc);
+
+		gbc.gridx = 0;
+		gbc.gridy = 1;
+		gbc.gridwidth = 2;
+		gbc.weightx = 0.0;
+		gbc.weighty = 0.0;
+		gbc.insets = new Insets(10, 5, 0, 0);
+		gbc.fill = NONE;
+		this.add(htmlLabel(DOT_PATH_MSG), gbc);
+
+		dotLocation.setText(workbenchConfiguration.getDotLocation());
+		gbc.gridy++;
+		gbc.gridwidth = 1;
+		gbc.weightx = 1.0;
+		gbc.insets = new Insets(0, 0, 0, 0);
+		gbc.fill = HORIZONTAL;
+		this.add(dotLocation, gbc);
+
+		JButton browseButton = new JButton();
+		gbc.gridx = 1;
+		gbc.weightx = 0.0;
+		gbc.fill = NONE;
+		this.add(browseButton, gbc);
+		browseButton.setAction(new AbstractAction() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				System.setProperty("com.apple.macos.use-file-dialog-packages",
+						"false");
+				JFileChooser fileChooser = new JFileChooser();
+				fileChooser.putClientProperty(
+						"JFileChooser.appBundleIsTraversable", "always");
+				fileChooser.putClientProperty(
+						"JFileChooser.packageIsTraversable", "always");
+
+				fileChooser.setDialogTitle("Browse for dot");
+
+				fileChooser.resetChoosableFileFilters();
+				fileChooser.setAcceptAllFileFilterUsed(false);
+
+				fileChooser.setMultiSelectionEnabled(false);
+
+				int returnVal = fileChooser
+						.showOpenDialog(WorkbenchConfigurationPanel.this);
+				if (returnVal == APPROVE_OPTION)
+					dotLocation.setText(fileChooser.getSelectedFile()
+							.getAbsolutePath());
+			}
+		});
+		browseButton.setIcon(openIcon);
+
+		gbc.gridx = 0;
+		gbc.gridy++;
+		gbc.gridwidth = 2;
+		gbc.weightx = 0.0;
+		gbc.weighty = 0.0;
+		gbc.insets = new Insets(10, 5, 0, 0);
+		gbc.fill = HORIZONTAL;
+		this.add(htmlLabel(CONTEXT_MENU_SIZE_MSG), gbc);
+
+		menuItems.setText(Integer.toString(workbenchConfiguration
+				.getMaxMenuItems()));
+		gbc.gridy++;
+		gbc.weightx = 1.0;
+		gbc.gridwidth = 1;
+		gbc.insets = new Insets(0, 0, 0, 0);
+		gbc.fill = HORIZONTAL;
+		this.add(menuItems, gbc);
+
+		gbc.gridx = 0;
+		gbc.gridy++;
+		gbc.gridwidth = 2;
+		gbc.weightx = 1.0;
+		gbc.fill = HORIZONTAL;
+		gbc.insets = new Insets(10, 0, 0, 0);
+		warnInternal
+				.setSelected(workbenchConfiguration.getWarnInternalErrors());
+		this.add(warnInternal, gbc);
+
+		gbc.gridy++;
+		gbc.insets = new Insets(0, 0, 10, 0);
+		captureConsole.setSelected(workbenchConfiguration.getCaptureConsole());
+		this.add(captureConsole, gbc);
+
+		// Add the buttons panel
+		gbc.gridx = 0;
+		gbc.gridy++;
+		gbc.gridwidth = 3;
+		gbc.weightx = 1.0;
+		gbc.weighty = 1.0;
+		gbc.fill = BOTH;
+		gbc.anchor = SOUTH;
+		this.add(getButtonsPanel(), gbc);
+	}
+
+	private Component getButtonsPanel() {
+		final JPanel panel = new JPanel();
+		panel.setLayout(new FlowLayout(FlowLayout.CENTER));
+
+		/**
+		 * The helpButton shows help about the current component
+		 */
+		JButton helpButton = new JButton(new AbstractAction("Help") {
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				showHelp(panel);
+			}
+		});
+		panel.add(helpButton);
+
+		/**
+		 * The resetButton changes the property values shown to those
+		 * corresponding to the configuration currently applied.
+		 */
+		JButton resetButton = new JButton(new AbstractAction("Reset") {
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				resetFields();
+			}
+		});
+		panel.add(resetButton);
+
+		JButton applyButton = new JButton(new AbstractAction("Apply") {
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				String menus = menuItems.getText();
+				try {
+					workbenchConfiguration.setMaxMenuItems(Integer
+							.valueOf(menus));
+				} catch (IllegalArgumentException e) {
+					String message = "Invalid menu items number " + menus
+							+ ":\n" + e.getLocalizedMessage();
+					showMessageDialog(panel, message, "Invalid menu items",
+							WARNING_MESSAGE);
+					return;
+				}
+
+				workbenchConfiguration.setCaptureConsole(captureConsole
+						.isSelected());
+				workbenchConfiguration.setWarnInternalErrors(warnInternal
+						.isSelected());
+				workbenchConfiguration.setDotLocation(dotLocation.getText());
+				try {
+					showMessageDialog(panel, RESTART_MSG, "Restart adviced",
+							INFORMATION_MESSAGE);
+				} catch (Exception e) {
+					logger.error("Error storing updated configuration", e);
+				}
+			}
+		});
+		panel.add(applyButton);
+		return panel;
+	}
+
+	/**
+	 * Resets the shown field values to those currently set (last saved) in the
+	 * configuration.
+	 * 
+	 * @param configurable
+	 */
+	private void resetFields() {
+		menuItems.setText(Integer.toString(workbenchConfiguration
+				.getMaxMenuItems()));
+		dotLocation.setText(workbenchConfiguration.getDotLocation());
+		warnInternal
+				.setSelected(workbenchConfiguration.getWarnInternalErrors());
+		captureConsole.setSelected(workbenchConfiguration.getCaptureConsole());
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/WorkbenchConfigurationUIFactory.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/WorkbenchConfigurationUIFactory.java b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/WorkbenchConfigurationUIFactory.java
new file mode 100644
index 0000000..263233f
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/WorkbenchConfigurationUIFactory.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.impl.configuration;
+
+import javax.swing.JPanel;
+
+import uk.org.taverna.configuration.Configurable;
+import uk.org.taverna.configuration.ConfigurationUIFactory;
+
+import net.sf.taverna.t2.workbench.configuration.workbench.WorkbenchConfiguration;
+
+public class WorkbenchConfigurationUIFactory implements ConfigurationUIFactory {
+	private WorkbenchConfiguration workbenchConfiguration;
+
+	@Override
+	public boolean canHandle(String uuid) {
+		return uuid.equals(workbenchConfiguration.getUUID());
+	}
+
+	@Override
+	public JPanel getConfigurationPanel() {
+		return new WorkbenchConfigurationPanel(workbenchConfiguration);
+	}
+
+	@Override
+	public Configurable getConfigurable() {
+		return workbenchConfiguration;
+	}
+
+	public void setWorkbenchConfiguration(
+			WorkbenchConfiguration workbenchConfiguration) {
+		this.workbenchConfiguration = workbenchConfiguration;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/colour/ColourManagerImpl.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/colour/ColourManagerImpl.java b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/colour/ColourManagerImpl.java
new file mode 100644
index 0000000..4c03dbe
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/colour/ColourManagerImpl.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.impl.configuration.colour;
+
+import static java.awt.Color.WHITE;
+import static java.awt.Color.decode;
+
+import java.awt.Color;
+import java.util.HashMap;
+import java.util.Map;
+
+import uk.org.taverna.configuration.AbstractConfigurable;
+import uk.org.taverna.configuration.ConfigurationManager;
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+
+/**
+ * A factory class that determines the colour that a Colourable UI component
+ * should be displayed as, according to a schema configured by the user.
+ * 
+ * @author Stuart Owen
+ * @author Ian Dunlop
+ * @see Colourable
+ */
+public class ColourManagerImpl extends AbstractConfigurable implements
+		ColourManager {
+	// Names of things that may be coloured
+	private static final String WORKFLOW_PORT_OBJECT = "uk.org.taverna.scufl2.api.port.WorkflowPort";
+	private static final String PROCESSOR_PORT_OBJECT = "uk.org.taverna.scufl2.api.port.ProcessorPort";
+	private static final String PROCESSOR_OBJECT = "uk.org.taverna.scufl2.api.core.Processor";
+	private static final String MERGE_OBJECT = "net.sf.taverna.t2.workflowmodel.Merge";
+	private static final String NONEXECUTABLE_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/nonExecutable";
+	private static final String XML_SPLITTER_OUT_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/xml-splitter/out";
+	private static final String XML_SPLITTER_IN_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/xml-splitter/in";
+	private static final String LOCALWORKER_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/localworker";
+	private static final String WSDL_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/wsdl";
+	private static final String CONSTANT_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/constant";
+	private static final String SOAPLAB_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/soaplab";
+	private static final String RSHELL_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/rshell";
+	private static final String NESTED_WORKFLOW = "http://ns.taverna.org.uk/2010/activity/nested-workflow";
+	private static final String MOBY_PARSER_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/biomoby/parser";
+	private static final String MOBY_OBJECT_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/biomoby/object";
+	private static final String MOBY_SERVICE_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/biomoby/service";
+	private static final String BIOMART_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/biomart";
+	private static final String BEANSHELL_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/beanshell";
+	private static final String APICONSUMER_ACTIVITY = "http://ns.taverna.org.uk/2010/activity/apiconsumer";
+
+	// Names of colours used
+	private static final String burlywood2 = "#deb887";
+	private static final String darkgoldenrod1 = "#ffb90f";
+	private static final String darkolivegreen3 = "#a2cd5a";
+	private static final String gold = "#ffd700";
+	private static final String grey = "#777777";
+	private static final String lightcyan2 = "#d1eeee";
+	private static final String lightgoldenrodyellow = "#fafad2";
+	// light purple non standard
+	private static final String lightpurple = "#ab92ea";
+	private static final String lightsteelblue = "#b0c4de";
+	private static final String mediumorchid2 = "#d15fee";
+	private static final String palegreen = "#98fb98";
+	private static final String pink = "#ffc0cb";
+	private static final String purplish = "#8070ff";
+	// ShadedLabel.Orange
+	private static final String shadedorange = "#eece8f";
+	// ShadedLabel.Green
+	private static final String shadedgreen = "#a1c69d";
+	// slightly lighter than the real steelblue4
+	private static final String steelblue4 = "#648faa";
+	private static final String turquoise = "#77aadd";
+	private static final String white = "#ffffff";
+
+	private Map<String, String> defaultPropertyMap;
+	private Map<Object, Color> cachedColours;
+
+	public ColourManagerImpl(ConfigurationManager configurationManager) {
+		super(configurationManager);
+		initialiseDefaults();
+	}
+
+	@Override
+	public String getCategory() {
+		return "colour";
+	}
+
+	@Override
+	public Map<String, String> getDefaultPropertyMap() {
+		if (defaultPropertyMap == null)
+			initialiseDefaults();
+		return defaultPropertyMap;
+	}
+
+	@Override
+	public String getDisplayName() {
+		return "Colour Management";
+	}
+
+	@Override
+	public String getFilePrefix() {
+		return "ColourManagement";
+	}
+
+	/**
+	 * Unique identifier for this ColourManager
+	 */
+	@Override
+	public String getUUID() {
+		return "a2148420-5967-11dd-ae16-0800200c9a66";
+	}
+
+	private void initialiseDefaults() {
+		defaultPropertyMap = new HashMap<>();
+		cachedColours = new HashMap<>();
+
+		defaultPropertyMap.put(APICONSUMER_ACTIVITY, palegreen);
+		defaultPropertyMap.put(BEANSHELL_ACTIVITY, burlywood2);
+		defaultPropertyMap.put(BIOMART_ACTIVITY, lightcyan2);
+		defaultPropertyMap.put(CONSTANT_ACTIVITY, lightsteelblue);
+		defaultPropertyMap.put(LOCALWORKER_ACTIVITY, mediumorchid2);
+		defaultPropertyMap.put(MOBY_SERVICE_ACTIVITY, darkgoldenrod1);
+		defaultPropertyMap.put(MOBY_OBJECT_ACTIVITY, gold);
+		defaultPropertyMap.put(MOBY_PARSER_ACTIVITY, white);
+		defaultPropertyMap.put(NESTED_WORKFLOW, pink);
+		defaultPropertyMap.put(RSHELL_ACTIVITY, steelblue4);
+		defaultPropertyMap.put(SOAPLAB_ACTIVITY, lightgoldenrodyellow);
+		defaultPropertyMap.put(WSDL_ACTIVITY, darkolivegreen3);
+		defaultPropertyMap.put(XML_SPLITTER_IN_ACTIVITY, lightpurple);
+		defaultPropertyMap.put(XML_SPLITTER_OUT_ACTIVITY, lightpurple);
+
+		defaultPropertyMap.put(NONEXECUTABLE_ACTIVITY, grey);
+
+		defaultPropertyMap.put(MERGE_OBJECT, turquoise);
+		defaultPropertyMap.put(PROCESSOR_OBJECT, shadedgreen);
+		defaultPropertyMap.put(PROCESSOR_PORT_OBJECT, purplish);
+		defaultPropertyMap.put(WORKFLOW_PORT_OBJECT, shadedorange);
+	}
+
+	@Override
+	public Color getPreferredColour(String itemKey) {
+		Color colour = cachedColours.get(itemKey);
+		if (colour == null) {
+			String colourString = (String) getProperty(itemKey);
+			colour = colourString == null ? WHITE : decode(colourString);
+			cachedColours.put(itemKey, colour);
+		}
+		return colour;
+	}
+
+	@Override
+	public void setPreferredColour(String itemKey, Color colour) {
+		cachedColours.put(itemKey, colour);
+	}
+
+	@Override
+	public void restoreDefaults() {
+		super.restoreDefaults();
+		if (cachedColours == null)
+			cachedColours = new HashMap<>();
+		else
+			cachedColours.clear();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/mimetype/MimeTypeManagerImpl.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/mimetype/MimeTypeManagerImpl.java b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/mimetype/MimeTypeManagerImpl.java
new file mode 100644
index 0000000..0ff6c65
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/mimetype/MimeTypeManagerImpl.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.impl.configuration.mimetype;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.taverna.t2.workbench.configuration.mimetype.MimeTypeManager;
+import uk.org.taverna.configuration.AbstractConfigurable;
+import uk.org.taverna.configuration.ConfigurationManager;
+
+public class MimeTypeManagerImpl extends AbstractConfigurable implements
+		MimeTypeManager {
+	/**
+	 * Constructs a new <code>MimeTypeManagerImpl</code>.
+	 * 
+	 * @param configurationManager
+	 */
+	public MimeTypeManagerImpl(ConfigurationManager configurationManager) {
+		super(configurationManager);
+	}
+
+	@Override
+	public String getCategory() {
+		return "Mime Type";
+	}
+
+	@Override
+	public Map<String, String> getDefaultPropertyMap() {
+		HashMap<String, String> map = new HashMap<>();
+		map.put("text/plain", "Plain Text");
+		map.put("text/xml", "XML Text");
+		map.put("text/html", "HTML Text");
+		map.put("text/rtf", "Rich Text Format");
+		map.put("text/x-graphviz", "Graphviz Dot File");
+		map.put("image/png", "PNG Image");
+		map.put("image/jpeg", "JPEG Image");
+		map.put("image/gif", "GIF Image");
+		map.put("application/octet-stream", "Binary Data");
+		map.put("application/zip", "Zip File");
+		map.put("chemical/x-swissprot", "SWISSPROT Flat File");
+		map.put("chemical/x-embl-dl-nucleotide", "EMBL Flat File");
+		map.put("chemical/x-ppd", "PPD File");
+		map.put("chemical/seq-aa-genpept", "Genpept Protein");
+		map.put("chemical/seq-na-genbank", "Genbank Nucleotide");
+		map.put("chemical/x-pdb", "PDB 3D Structure File");
+		return map;
+	}
+
+	@Override
+	public String getUUID() {
+		return "b9277fa0-5967-11dd-ae16-0800200c9a66";
+	}
+
+	@Override
+	public String getDisplayName() {
+		return "Mime Type Manager";
+	}
+
+	@Override
+	public String getFilePrefix() {
+		return "MimeTypeManagerImpl";
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ui/T2ConfigurationFrameImpl.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ui/T2ConfigurationFrameImpl.java b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ui/T2ConfigurationFrameImpl.java
new file mode 100644
index 0000000..4910f78
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ui/T2ConfigurationFrameImpl.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.impl.configuration.ui;
+
+import static javax.swing.JSplitPane.HORIZONTAL_SPLIT;
+import static net.sf.taverna.t2.workbench.helper.HelpCollator.registerComponent;
+import static net.sf.taverna.t2.workbench.helper.Helper.setKeyCatcher;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JFrame;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.ListModel;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import net.sf.taverna.t2.workbench.configuration.workbench.ui.T2ConfigurationFrame;
+
+import org.apache.log4j.Logger;
+
+import uk.org.taverna.configuration.ConfigurationUIFactory;
+
+public class T2ConfigurationFrameImpl implements T2ConfigurationFrame {
+	private static Logger logger = Logger.getLogger(T2ConfigurationFrameImpl.class);
+	private static final int FRAME_WIDTH = 700;
+	private static final int FRAME_HEIGHT = 450;
+
+	private List<ConfigurationUIFactory> configurationUIFactories = new ArrayList<>();
+
+	private JFrame frame;
+	private JSplitPane splitPane;
+	private JList<ConfigurableItem> list;
+
+	public T2ConfigurationFrameImpl() {
+	}
+
+	@Override
+	public void showFrame() {
+		getFrame().setVisible(true);
+	}
+
+	@Override
+	public void showConfiguration(String name) {
+		showFrame();
+		ListModel<ConfigurableItem> lm = list.getModel();
+		for (int i = 0; i < lm.getSize(); i++)
+			if (lm.getElementAt(i).toString().equals(name)) {
+				list.setSelectedIndex(i);
+				break;
+			}
+	}
+
+	private JFrame getFrame() {
+		if (frame != null)
+			return frame;
+
+		frame = new JFrame();
+		setKeyCatcher(frame);
+		registerComponent(frame);
+		frame.setLayout(new BorderLayout());
+
+		/*
+		 * Split pane to hold list of properties (on the left) and their
+		 * configurable options (on the right)
+		 */
+		splitPane = new JSplitPane(HORIZONTAL_SPLIT);
+		splitPane.setBorder(null);
+
+		list = getConfigurationList();
+		JScrollPane jspList = new JScrollPane(list);
+		jspList.setBorder(new EmptyBorder(5, 5, 5, 5));
+		jspList.setMinimumSize(new Dimension(150,
+				jspList.getPreferredSize().height));
+
+		splitPane.setLeftComponent(jspList);
+		splitPane.setRightComponent(new JPanel());
+		splitPane.setDividerSize(1);
+
+		// select first item if one exists
+		if (list.getModel().getSize() > 0)
+			list.setSelectedValue(list.getModel().getElementAt(0), true);
+
+		frame.add(splitPane);
+		frame.setSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
+		return frame;
+	}
+
+	private JList<ConfigurableItem> getConfigurationList() {
+		if (list != null)
+			return list;
+
+		list = new JList<>();
+		list.addListSelectionListener(new ListSelectionListener() {
+			@Override
+			public void valueChanged(ListSelectionEvent e) {
+				if (list.getSelectedValue() instanceof ConfigurableItem) {
+					ConfigurableItem item = (ConfigurableItem) list
+							.getSelectedValue();
+					setMainPanel(item.getPanel());
+				}
+
+				/*
+				 * Keep the split pane's divider at its current position - but
+				 * looks ugly. The problem with divider moving from its current
+				 * position after selecting an item from the list on the left is
+				 * that the right hand side panels are loaded dynamically and it
+				 * seems there is nothing we can do about it - it's just the
+				 * JSplitPane's behaviour
+				 */
+				// splitPane.setDividerLocation(splitPane.getLastDividerLocation());
+			}
+		});
+		list.setListData(getListItems());
+		return list;
+	}
+
+	private void setMainPanel(JPanel panel) {
+		panel.setBorder(new EmptyBorder(15, 15, 15, 15));
+		splitPane.setRightComponent(panel);
+	}
+
+	public void setConfigurationUIFactories(
+			List<ConfigurationUIFactory> configurationUIFactories) {
+		this.configurationUIFactories = configurationUIFactories;
+	}
+
+	private ConfigurableItem[] getListItems() {
+		List<ConfigurableItem> arrayList = new ArrayList<>();
+		for (ConfigurationUIFactory fac : configurationUIFactories) {
+			String name = fac.getConfigurable().getDisplayName();
+			if (name != null) {
+				logger.info("Adding configurable for name: " + name);
+				arrayList.add(new ConfigurableItem(fac));
+			} else {
+				logger.warn("The configurable " + fac.getConfigurable().getClass()
+						+ " has a null name");
+			}
+		}
+		// Sort the list alphabetically
+		ConfigurableItem[] array = arrayList.toArray(new ConfigurableItem[0]);
+		Arrays.sort(array, new Comparator<ConfigurableItem>() {
+			@Override
+			public int compare(ConfigurableItem item1, ConfigurableItem item2) {
+				return item1.toString().compareToIgnoreCase(item2.toString());
+			}
+		});
+		return array;
+	}
+
+	public void update(Object service, Map<?, ?> properties) {
+		getConfigurationList().setListData(getListItems());
+		if (frame != null) {
+			frame.revalidate();
+			frame.repaint();
+			// select first item if one exists
+			if (list.getModel().getSize() > 0)
+				list.setSelectedValue(list.getModel().getElementAt(0), true);
+		}
+	}
+
+	class ConfigurableItem {
+		private final ConfigurationUIFactory factory;
+
+		public ConfigurableItem(ConfigurationUIFactory factory) {
+			this.factory = factory;
+		}
+
+		public JPanel getPanel() {
+			return factory.getConfigurationPanel();
+		}
+
+		@Override
+		public String toString() {
+			return factory.getConfigurable().getDisplayName();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ui/WorkbenchConfigurationMenu.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ui/WorkbenchConfigurationMenu.java b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ui/WorkbenchConfigurationMenu.java
new file mode 100644
index 0000000..453f0c0
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ui/WorkbenchConfigurationMenu.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.impl.configuration.ui;
+
+import java.awt.event.ActionEvent;
+import java.net.URI;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+
+import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
+import net.sf.taverna.t2.workbench.configuration.workbench.ui.T2ConfigurationFrame;
+
+public class WorkbenchConfigurationMenu extends AbstractMenuAction {
+	private static final String MAC_OS_X = "Mac OS X";
+
+	private T2ConfigurationFrame t2ConfigurationFrame;
+
+	public WorkbenchConfigurationMenu() {
+		super(URI.create("http://taverna.sf.net/2008/t2workbench/menu#preferences"),
+				100);
+	}
+
+	@SuppressWarnings("serial")
+	@Override
+	protected Action createAction() {
+		return new AbstractAction("Preferences") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				t2ConfigurationFrame.showFrame();
+			}
+		};
+	}
+
+	@Override
+	public boolean isEnabled() {
+		return !MAC_OS_X.equalsIgnoreCase(System.getProperty("os.name"));
+	}
+
+	public void setT2ConfigurationFrame(T2ConfigurationFrame t2ConfigurationFrame) {
+		this.t2ConfigurationFrame = t2ConfigurationFrame;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ui/WorkbenchPreferencesSection.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ui/WorkbenchPreferencesSection.java b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ui/WorkbenchPreferencesSection.java
new file mode 100644
index 0000000..d131ac3
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ui/WorkbenchPreferencesSection.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester   
+ * 
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ * 
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *    
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *    
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.impl.configuration.ui;
+
+import java.net.URI;
+
+import net.sf.taverna.t2.ui.menu.AbstractMenuSection;
+
+public class WorkbenchPreferencesSection extends AbstractMenuSection {
+	private static final URI FILE_MENU = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#file");
+	private static final URI PREFERENCES_MENU_ITEM = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#preferences");
+
+	public WorkbenchPreferencesSection() {
+		super(FILE_MENU, 100, PREFERENCES_MENU_ITEM);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent b/taverna-workbench-configuration-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
new file mode 100644
index 0000000..3b51dd4
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
@@ -0,0 +1,2 @@
+net.sf.taverna.t2.workbench.ui.impl.configuration.ui.WorkbenchPreferencesSection
+net.sf.taverna.t2.workbench.ui.impl.configuration.ui.WorkbenchConfigurationMenu

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory b/taverna-workbench-configuration-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory
new file mode 100644
index 0000000..4af55ec
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory
@@ -0,0 +1 @@
+net.sf.taverna.t2.workbench.ui.impl.configuration.WorkbenchConfigurationUIFactory
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/main/resources/META-INF/spring/configuration-impl-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/main/resources/META-INF/spring/configuration-impl-context-osgi.xml b/taverna-workbench-configuration-impl/src/main/resources/META-INF/spring/configuration-impl-context-osgi.xml
new file mode 100644
index 0000000..29aea44
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/main/resources/META-INF/spring/configuration-impl-context-osgi.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans:beans xmlns="http://www.springframework.org/schema/osgi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:beans="http://www.springframework.org/schema/beans"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans.xsd
+                      http://www.springframework.org/schema/osgi
+                      http://www.springframework.org/schema/osgi/spring-osgi.xsd">
+
+	<service ref="t2ConfigurationFrame" interface="net.sf.taverna.t2.workbench.configuration.workbench.ui.T2ConfigurationFrame" />
+
+	<service ref="WorkbenchConfigurationUIFactory" interface="uk.org.taverna.configuration.ConfigurationUIFactory" />
+
+	<service ref="WorkbenchPreferencesSection" auto-export="interfaces" />
+	<service ref="WorkbenchConfigurationMenu" auto-export="interfaces" />
+
+	<service ref="ColourManager" interface="net.sf.taverna.t2.workbench.configuration.colour.ColourManager" />
+	<service ref="WorkbenchConfiguration" interface="net.sf.taverna.t2.workbench.configuration.workbench.WorkbenchConfiguration" />
+	<service ref="MimeTypeManager" interface="net.sf.taverna.t2.workbench.configuration.mimetype.MimeTypeManager" />
+
+	<reference id="configurationManager" interface="uk.org.taverna.configuration.ConfigurationManager" />
+	<reference id="applicationConfiguration" interface="uk.org.taverna.configuration.app.ApplicationConfiguration" />
+
+	<list id="configurationUIFactories" interface="uk.org.taverna.configuration.ConfigurationUIFactory" cardinality="0..N">
+		<listener ref="t2ConfigurationFrame" bind-method="update" unbind-method="update"/>
+	</list>
+
+</beans:beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/main/resources/META-INF/spring/configuration-impl-context.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/main/resources/META-INF/spring/configuration-impl-context.xml b/taverna-workbench-configuration-impl/src/main/resources/META-INF/spring/configuration-impl-context.xml
new file mode 100644
index 0000000..40da7fd
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/main/resources/META-INF/spring/configuration-impl-context.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<bean id="t2ConfigurationFrame" class="net.sf.taverna.t2.workbench.ui.impl.configuration.ui.T2ConfigurationFrameImpl">
+		<property name="configurationUIFactories" ref="configurationUIFactories" />
+	</bean>
+
+	<bean id="WorkbenchConfigurationUIFactory" class="net.sf.taverna.t2.workbench.ui.impl.configuration.WorkbenchConfigurationUIFactory">
+		<property name="workbenchConfiguration">
+			<ref local="WorkbenchConfiguration"/>
+		</property>
+	</bean>
+
+	<bean id="WorkbenchPreferencesSection" class="net.sf.taverna.t2.workbench.ui.impl.configuration.ui.WorkbenchPreferencesSection" />
+	<bean id="WorkbenchConfigurationMenu" class="net.sf.taverna.t2.workbench.ui.impl.configuration.ui.WorkbenchConfigurationMenu">
+		<property name="t2ConfigurationFrame">
+			<ref local="t2ConfigurationFrame"/>
+		</property>
+	</bean>
+
+	<bean id="ColourManager" class="net.sf.taverna.t2.workbench.ui.impl.configuration.colour.ColourManagerImpl">
+		<constructor-arg ref="configurationManager"/>
+	</bean>
+	<bean id="WorkbenchConfiguration" class="net.sf.taverna.t2.workbench.ui.impl.configuration.WorkbenchConfigurationImpl">
+		<constructor-arg ref="configurationManager"/>
+		<property name="applicationConfiguration" ref="applicationConfiguration" />
+	</bean>
+	<bean id="MimeTypeManager" class="net.sf.taverna.t2.workbench.ui.impl.configuration.mimetype.MimeTypeManagerImpl">
+		<constructor-arg ref="configurationManager"/>
+	</bean>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/test/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ConfigurationManagerTest.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/test/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ConfigurationManagerTest.java b/taverna-workbench-configuration-impl/src/test/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ConfigurationManagerTest.java
new file mode 100644
index 0000000..1202c11
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/test/java/net/sf/taverna/t2/workbench/ui/impl/configuration/ConfigurationManagerTest.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.impl.configuration;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.util.UUID;
+
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+import net.sf.taverna.t2.workbench.ui.impl.configuration.colour.ColourManagerImpl;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import uk.org.taverna.configuration.app.impl.ApplicationConfigurationImpl;
+import uk.org.taverna.configuration.impl.ConfigurationManagerImpl;
+
+public class ConfigurationManagerTest {
+
+	ConfigurationManagerImpl configurationManager;
+
+	@Before
+	public void setup() {
+		configurationManager = new ConfigurationManagerImpl(new ApplicationConfigurationImpl());
+	}
+
+	@Test
+	public void createConfigManager() {
+		assertNotNull("Config Manager should not be null", configurationManager);
+	}
+
+	@Ignore("Hardcoded /Users/Ian") //FIXME: update test to work using File.createTempFile(...)
+	@Test
+	public void populateConfigOfColourmanager() {
+		ColourManager manager= new ColourManagerImpl(null);
+
+		manager.setProperty("colour.first", "25");
+		manager.setProperty("colour.second", "223");
+
+		configurationManager.setBaseConfigLocation(new File("/Users/Ian/scratch"));
+		try {
+			configurationManager.store(manager);
+		} catch (Exception e1) {
+			e1.printStackTrace();
+		}
+
+		ColourManager manager2 = new ColourManagerImpl(configurationManager);
+
+		try {
+			configurationManager.populate(manager2);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+
+		assertEquals("Properties do not match", manager2.getProperty("colour.first"), manager.getProperty("colour.first"));
+		assertEquals("Properties do not match", manager2.getProperty("colour.second"), manager.getProperty("colour.second"));
+
+
+	}
+
+	@Test
+	public void saveColoursForDummyColourable() {
+		String dummy = "";
+		ColourManager manager=new ColourManagerImpl(configurationManager);
+		manager.setProperty(dummy.getClass().getCanonicalName(), "#000000");
+
+		File f = new File(System.getProperty("java.io.tmpdir"));
+		File d = new File(f, UUID.randomUUID().toString());
+		d.mkdir();
+		configurationManager.setBaseConfigLocation(d);
+		try {
+			configurationManager.store(manager);
+		} catch (Exception e1) {
+			e1.printStackTrace();
+		}
+
+		try {
+			configurationManager.populate(manager);
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-configuration-impl/src/test/java/net/sf/taverna/t2/workbench/ui/impl/configuration/colour/ColourManagerTest.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-configuration-impl/src/test/java/net/sf/taverna/t2/workbench/ui/impl/configuration/colour/ColourManagerTest.java b/taverna-workbench-configuration-impl/src/test/java/net/sf/taverna/t2/workbench/ui/impl/configuration/colour/ColourManagerTest.java
new file mode 100644
index 0000000..0239ea8
--- /dev/null
+++ b/taverna-workbench-configuration-impl/src/test/java/net/sf/taverna/t2/workbench/ui/impl/configuration/colour/ColourManagerTest.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.impl.configuration.colour;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.awt.Color;
+import java.io.File;
+import java.util.UUID;
+
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import uk.org.taverna.configuration.Configurable;
+import uk.org.taverna.configuration.app.impl.ApplicationConfigurationImpl;
+import uk.org.taverna.configuration.impl.ConfigurationManagerImpl;
+
+public class ColourManagerTest {
+
+	private ConfigurationManagerImpl configurationManager;
+
+	@Before
+	public void setup() {
+		configurationManager = new ConfigurationManagerImpl(new ApplicationConfigurationImpl());
+
+		File f = new File(System.getProperty("java.io.tmpdir"));
+		File d = new File(f, UUID.randomUUID().toString());
+		d.mkdir();
+		configurationManager.setBaseConfigLocation(d);
+	}
+
+	@Test
+	public void testGetPreferredColourEqualsWhite() throws Exception {
+		String dummy = new String();
+
+		Color c = new ColourManagerImpl(configurationManager).getPreferredColour(dummy);
+		assertEquals("The default colour should be WHITE", Color.WHITE, c);
+	}
+
+	@Test
+	public void testConfigurableness() throws Exception {
+		ColourManager manager = new ColourManagerImpl(configurationManager);
+		assertTrue(manager instanceof Configurable);
+
+		assertEquals("wrong category", "colour", manager.getCategory());
+		assertEquals("wrong name", "Colour Management", manager.getDisplayName());
+		assertEquals("wrong UUID", "a2148420-5967-11dd-ae16-0800200c9a66",
+				manager.getUUID());
+		assertNotNull("there is no default property map", manager
+				.getDefaultPropertyMap());
+	}
+
+	@Test
+	public void saveAsWrongArrayType() throws Exception {
+		String dummy = "";
+		ColourManager manager = new ColourManagerImpl(configurationManager);
+		manager.setProperty(dummy.getClass().getCanonicalName(), "#ffffff");
+
+		File baseLoc = File.createTempFile("test", "scratch");
+		baseLoc.delete();
+		assertTrue("Could not make directory " + baseLoc, baseLoc.mkdir());
+		configurationManager.setBaseConfigLocation(baseLoc);
+		configurationManager.store(manager);
+		configurationManager.populate(manager);
+		manager.getPreferredColour(dummy);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-contextual-views-impl/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-contextual-views-impl/pom.xml b/taverna-workbench-contextual-views-impl/pom.xml
new file mode 100644
index 0000000..1cafa80
--- /dev/null
+++ b/taverna-workbench-contextual-views-impl/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>net.sf.taverna.t2</groupId>
+		<artifactId>ui-impl</artifactId>
+		<version>2.0-SNAPSHOT</version>
+	</parent>
+	<groupId>net.sf.taverna.t2.ui-impl</groupId>
+	<artifactId>contextual-views-impl</artifactId>
+	<packaging>bundle</packaging>
+	<name>Contextual Views Implementation</name>
+	<description>Contextual views for the activities</description>
+	<dependencies>
+		<dependency>
+			<groupId>net.sf.taverna.t2.ui-api</groupId>
+			<artifactId>contextual-views-api</artifactId>
+			<version>${t2.ui.api.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.taverna.t2.ui-api</groupId>
+			<artifactId>selection-api</artifactId>
+			<version>${t2.ui.api.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>uk.org.taverna.scufl2</groupId>
+			<artifactId>scufl2-api</artifactId>
+			<version>${scufl2.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>javax.help</groupId>
+			<artifactId>javahelp</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/impl/ContextualViewFactoryRegistryImpl.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/impl/ContextualViewFactoryRegistryImpl.java b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/impl/ContextualViewFactoryRegistryImpl.java
new file mode 100644
index 0000000..8bac354
--- /dev/null
+++ b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/impl/ContextualViewFactoryRegistryImpl.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+
+/**
+ * @author Alan R Williams
+ */
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactoryRegistry;
+
+/**
+ * An SPI registry for discovering ActivityViewFactories for a given object,
+ * like an {@link net.sf.taverna.t2.workflowmodel.processor.activity.Activity}.
+ * <p>
+ * For {@link ContextualViewFactory factories} to be found, its full qualified
+ * name needs to be defined as a resource file
+ * <code>/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualViewFactory</code>
+ * 
+ * @author Stuart Owen
+ * @author Ian Dunlop
+ * @author Stian Soiland-Reyes
+ * 
+ * @see ContextualViewFactory
+ */
+public class ContextualViewFactoryRegistryImpl implements
+		ContextualViewFactoryRegistry {
+	private List<ContextualViewFactory<?>> contextualViewFactories;
+
+	/**
+	 * Discover and return the ContextualViewFactory associated to the provided
+	 * object. This is accomplished by returning the discovered
+	 * {@link ContextualViewFactory#canHandle(Object)} that returns true for
+	 * that Object.
+	 * 
+	 * @param object
+	 * @return
+	 * @see ContextualViewFactory#canHandle(Object)
+	 */
+	@Override
+	public List<ContextualViewFactory<?>> getViewFactoriesForObject(
+			Object object) {
+		List<ContextualViewFactory<?>> result = new ArrayList<>();
+		for (ContextualViewFactory<?> factory : contextualViewFactories)
+			if (factory.canHandle(object))
+				result.add(factory);
+		return result;
+	}
+
+	public void setContextualViewFactories(
+			List<ContextualViewFactory<?>> contextualViewFactories) {
+		this.contextualViewFactories = contextualViewFactories;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualView.java b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualView.java
new file mode 100644
index 0000000..018a121
--- /dev/null
+++ b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualView.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.annotated;
+
+import static javax.swing.BoxLayout.Y_AXIS;
+
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+import java.util.regex.Pattern;
+
+import javax.swing.BoxLayout;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.TitledBorder;
+
+import net.sf.taverna.t2.annotation.Annotated;
+import net.sf.taverna.t2.annotation.AnnotationBeanSPI;
+import net.sf.taverna.t2.lang.ui.DialogTextArea;
+import net.sf.taverna.t2.workbench.edits.CompoundEdit;
+import net.sf.taverna.t2.workbench.edits.Edit;
+import net.sf.taverna.t2.workbench.edits.EditException;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.impl.ContextualViewComponent;
+
+import org.apache.log4j.Logger;
+
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+
+/**
+ * This is a ContextualView that should be able to display and allow editing of
+ * Annotation information for any Annotated. At the moment it is only used for
+ * Dataflow.
+ * 
+ * @author Alan R Williams
+ */
+@SuppressWarnings("serial")
+class AnnotatedContextualView extends ContextualView {
+	private static final int WORKFLOW_NAME_LENGTH = 20;
+	public static final String VIEW_TITLE = "Annotations";
+	private final static String MISSING_VALUE = "Type here to give details";
+	private final static int DEFAULT_AREA_WIDTH = 60;
+	private final static int DEFAULT_AREA_ROWS = 8;
+
+	private static Logger logger = Logger
+			.getLogger(AnnotatedContextualView.class);
+	private static PropertyResourceBundle prb = (PropertyResourceBundle) ResourceBundle
+			.getBundle("annotatedcontextualview");
+
+	// TODO convert to scufl2
+	// private static AnnotationTools annotationTools = new AnnotationTools();
+
+	/**
+	 * The object to which the Annotations apply
+	 */
+	private Annotated<?> annotated;
+	private SelectionManager selectionManager;
+	private EditManager editManager;
+	private boolean isStandalone = false;
+	private JPanel panel;
+	@SuppressWarnings("unused")
+	private final List<AnnotationBeanSPI> annotationBeans;
+
+	public AnnotatedContextualView(Annotated<?> annotated,
+			EditManager editManager, SelectionManager selectionManager,
+			List<AnnotationBeanSPI> annotationBeans) {
+		super();
+		this.editManager = editManager;
+		this.selectionManager = selectionManager;
+		this.annotationBeans = annotationBeans;
+		this.annotated = annotated;
+
+		initialise();
+		initView();
+	}
+
+	@Override
+	public void refreshView() {
+		initialise();
+	}
+
+	private void initialise() {
+		if (panel == null) {
+			panel = new JPanel();
+			panel.setLayout(new BoxLayout(panel, Y_AXIS));
+		} else
+			panel.removeAll();
+		populatePanel();
+		revalidate();
+	}
+
+	@Override
+	public JComponent getMainFrame() {
+		return panel;
+	}
+
+	@Override
+	public String getViewTitle() {
+		return VIEW_TITLE;
+	}
+
+	private Map<String,String> getAnnotations() {
+		// TODO convert to scufl2
+		Map<String, String> result = new HashMap<>();
+		//for (Class<?> c : annotationTools.getAnnotatingClasses(annotated)) {
+		// String name = "";
+		// try {
+		// name = prb.getString(c.getCanonicalName());
+		// } catch (MissingResourceException e) {
+		// name = c.getCanonicalName();
+		// }
+		// String value = annotationTools.getAnnotationString(annotated, c,
+		// MISSING_VALUE);
+		// result.put(name,value);
+		//}
+		return result;
+	}
+	public void populatePanel() {
+		JPanel scrollPanel = new JPanel();
+		scrollPanel.setLayout(new BoxLayout(scrollPanel, Y_AXIS));
+		panel.setBorder(new EmptyBorder(5, 5, 5, 5));
+		Map<String,String>annotations = getAnnotations();
+		for (String name : annotations.keySet()) {
+			JPanel subPanel = new JPanel();
+			subPanel.setBorder(new TitledBorder(name));
+			subPanel.add(createTextArea(String.class, annotations.get(name)));
+			scrollPanel.add(subPanel);
+		}
+		JScrollPane scrollPane = new JScrollPane(scrollPanel);
+		panel.add(scrollPane);
+	}
+
+	private JScrollPane createTextArea(Class<?> c, String value) {
+		DialogTextArea area = new DialogTextArea(value);
+		area.setFocusable(true);
+		area.addFocusListener(new TextAreaFocusListener(area, c));
+		area.setColumns(DEFAULT_AREA_WIDTH);
+		area.setRows(DEFAULT_AREA_ROWS);
+		area.setLineWrap(true);
+		area.setWrapStyleWord(true);
+
+		return new JScrollPane(area);
+	}
+
+	private class TextAreaFocusListener implements FocusListener {
+		String oldValue = null;
+		Class<?> annotationClass;
+		DialogTextArea area = null;
+
+		public TextAreaFocusListener(DialogTextArea area, Class<?> c) {
+			annotationClass = c;
+			oldValue = area.getText();
+			this.area = area;
+		}
+
+		@Override
+		public void focusGained(FocusEvent e) {
+			if (area.getText().equals(MISSING_VALUE))
+				area.setText("");
+		}
+
+		@Override
+		public void focusLost(FocusEvent e) {
+			String currentValue = area.getText();
+			if (currentValue.isEmpty() || currentValue.equals(MISSING_VALUE)) {
+				currentValue = MISSING_VALUE;
+				area.setText(currentValue);
+			}
+			if (!currentValue.equals(oldValue)) {
+				if (currentValue == MISSING_VALUE)
+					currentValue = "";
+				try {
+					WorkflowBundle currentDataflow = selectionManager
+							.getSelectedWorkflowBundle();
+					List<Edit<?>> editList = new ArrayList<>();
+					addWorkflowNameEdits(currentValue, currentDataflow,
+							editList);
+					if (!isStandalone)
+						ContextualViewComponent.selfGenerated = true;
+					editManager.doDataflowEdit(currentDataflow,
+							new CompoundEdit(editList));
+					ContextualViewComponent.selfGenerated = false;
+				} catch (EditException e1) {
+					logger.warn("Can't set annotation", e1);
+				}
+				oldValue = area.getText();
+			}
+		}
+
+		private boolean isTitleAnnotation() {
+			// TODO convert to scufl2
+			return prb.getString(annotationClass.getCanonicalName()).equals(
+					"Title");
+		}
+
+		// TODO convert to scufl2
+		private void addWorkflowNameEdits(String currentValue,
+				WorkflowBundle currentDataflow, List<Edit<?>> editList) {
+			//editList.add(annotationTools.setAnnotationString(annotated,
+			//		annotationClass, currentValue, edits));
+			if (annotated == currentDataflow && isTitleAnnotation()
+					&& !currentValue.isEmpty()) {
+				@SuppressWarnings("unused")
+				String sanitised = sanitiseName(currentValue);
+				//editList.add(edits.getUpdateDataflowNameEdit(currentDataflow,
+				//		sanitised));
+			}
+		}
+	}
+
+	/**
+	 * Checks that the name does not have any characters that are invalid for a
+	 * processor name.
+	 * <p>
+	 * The resulting name must contain only the chars [A-Za-z_0-9].
+	 * 
+	 * @param name
+	 *            the original name
+	 * @return the sanitised name
+	 */
+	private static String sanitiseName(String name) {
+		if (name.length() > WORKFLOW_NAME_LENGTH)
+			name = name.substring(0, WORKFLOW_NAME_LENGTH);
+		if (Pattern.matches("\\w++", name))
+			return name;
+		StringBuilder temp = new StringBuilder();
+		for (char c : name.toCharArray())
+			temp.append(Character.isLetterOrDigit(c) || c == '_' ? c : '_');
+		return temp.toString();
+	}
+
+	@Override
+	public int getPreferredPosition() {
+		return 500;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualViewFactory.java b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualViewFactory.java
new file mode 100644
index 0000000..eb18803
--- /dev/null
+++ b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualViewFactory.java
@@ -0,0 +1,43 @@
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.annotated;
+
+import static java.util.Collections.singletonList;
+
+import java.util.List;
+
+import net.sf.taverna.t2.annotation.Annotated;
+import net.sf.taverna.t2.annotation.AnnotationBeanSPI;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+
+public class AnnotatedContextualViewFactory implements
+		ContextualViewFactory<Annotated<?>> {
+	private EditManager editManager;
+	private List<AnnotationBeanSPI> annotationBeans;
+	private SelectionManager selectionManager;
+
+	@Override
+	public boolean canHandle(Object selection) {
+		return ((selection instanceof Annotated) && !(selection instanceof Activity));
+	}
+
+	@Override
+	public List<ContextualView> getViews(Annotated<?> selection) {
+		return singletonList((ContextualView) new AnnotatedContextualView(
+				selection, editManager, selectionManager, annotationBeans));
+	}
+
+	public void setEditManager(EditManager editManager) {
+		this.editManager = editManager;
+	}
+
+	public void setSelectionManager(SelectionManager selectionManager) {
+		this.selectionManager = selectionManager;
+	}
+
+	public void setAnnotationBeans(List<AnnotationBeanSPI> annotationBeans) {
+		this.annotationBeans = annotationBeans;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualView.java b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualView.java
new file mode 100644
index 0000000..f9308b5
--- /dev/null
+++ b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualView.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.condition;
+
+import java.awt.FlowLayout;
+
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.EmptyBorder;
+
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import uk.org.taverna.scufl2.api.core.BlockingControlLink;
+
+/**
+ * Contextual view for dataflow's control (condition) links.
+ * 
+ * @author David Withers
+ */
+class ConditionContextualView extends ContextualView {
+	private static final long serialVersionUID = -894521200616176439L;
+
+	private final BlockingControlLink condition;
+	private JPanel contitionView;
+
+	public ConditionContextualView(BlockingControlLink condition) {
+		this.condition = condition;
+		initView();
+	}
+
+	@Override
+	public JComponent getMainFrame() {
+		refreshView();
+		return contitionView;
+	}
+
+	@Override
+	public String getViewTitle() {
+		return "Control link: " + condition.getBlock().getName()
+				+ " runs after " + condition.getUntilFinished().getName();
+	}
+
+	@Override
+	public void refreshView() {
+		contitionView = new JPanel(new FlowLayout(FlowLayout.LEFT));
+		contitionView.setBorder(new EmptyBorder(5, 5, 5, 5));
+		JLabel label = new JLabel(
+				"<html><body><i>No details available.</i></body><html>");
+		contitionView.add(label);
+	}
+
+	@Override
+	public int getPreferredPosition() {
+		return 100;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualViewFactory.java b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualViewFactory.java
new file mode 100644
index 0000000..ea69f1a
--- /dev/null
+++ b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualViewFactory.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.condition;
+
+import static java.util.Arrays.asList;
+
+import java.util.List;
+
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+import net.sf.taverna.t2.workflowmodel.Condition;
+import uk.org.taverna.scufl2.api.core.BlockingControlLink;
+
+/**
+ * A factory of contextual views for dataflow's condition links.
+ * 
+ * @author David Withers
+ * 
+ */
+public class ConditionContextualViewFactory implements
+		ContextualViewFactory<BlockingControlLink> {
+	@Override
+	public boolean canHandle(Object object) {
+		return object instanceof Condition;
+	}
+
+	@Override
+	public List<ContextualView> getViews(BlockingControlLink condition) {
+		return asList(new ContextualView[] { new ConditionContextualView(
+				condition) });
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualView.java b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualView.java
new file mode 100644
index 0000000..4a63868
--- /dev/null
+++ b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualView.java
@@ -0,0 +1,108 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.dataflow;
+
+import static net.sf.taverna.t2.lang.ui.HtmlUtils.buildTableOpeningTag;
+import static net.sf.taverna.t2.lang.ui.HtmlUtils.createEditorPane;
+import static net.sf.taverna.t2.lang.ui.HtmlUtils.getHtmlHead;
+import static net.sf.taverna.t2.lang.ui.HtmlUtils.panelForHtml;
+
+import javax.swing.JComponent;
+import javax.swing.JEditorPane;
+
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workflowmodel.Dataflow;
+import uk.org.taverna.scufl2.api.core.Workflow;
+import uk.org.taverna.scufl2.api.port.InputWorkflowPort;
+import uk.org.taverna.scufl2.api.port.OutputWorkflowPort;
+
+/**
+ * @author alanrw
+ */
+@SuppressWarnings("serial")
+class DataflowContextualView extends ContextualView {
+	private static int MAX_LENGTH = 50;
+	private static final String ELLIPSIS = "...";
+
+	private Workflow dataflow;
+	private JEditorPane editorPane;
+	private final FileManager fileManager;
+	private final ColourManager colourManager;
+
+	public DataflowContextualView(Workflow dataflow, FileManager fileManager,
+			ColourManager colourManager) {
+		this.dataflow = dataflow;
+		this.fileManager = fileManager;
+		this.colourManager = colourManager;
+		initView();
+	}
+
+	@Override
+	public JComponent getMainFrame() {
+		editorPane = createEditorPane(buildHtml());
+		return panelForHtml(editorPane);
+	}
+
+	private String buildHtml() {
+		StringBuilder html = new StringBuilder(getHtmlHead(getBackgroundColour()));
+		html.append(buildTableOpeningTag());
+
+		html.append("<tr><td colspan=\"2\" align=\"center\"><b>Source</b></td></tr>");
+		String source = "Newly created";
+		if (fileManager.getDataflowSource(dataflow.getParent()) != null)
+			source = fileManager.getDataflowName(dataflow.getParent());
+
+		html.append("<tr><td colspan=\"2\" align=\"center\">").append(source)
+				.append("</td></tr>");
+		if (!dataflow.getInputPorts().isEmpty()) {
+			html.append("<tr><th>Input Port Name</th><th>Depth</th></tr>");
+			for (InputWorkflowPort dip : dataflow.getInputPorts())
+				html.append("<tr><td>")
+						.append(dip.getName())
+						.append("</td><td>")
+						.append(dip.getDepth() < 0 ? "invalid/unpredicted"
+								: dip.getDepth()).append("</td></tr>");
+		}
+		if (!dataflow.getOutputPorts().isEmpty()) {
+			html.append("<tr><th>Output Port Name</th><th>Depth</th></tr>");
+			for (OutputWorkflowPort dop : dataflow.getOutputPorts())
+				html.append("<tr><td>")
+						.append(dop.getName())
+						.append("</td><td>")
+						.append(/*(dop.getDepth() < 0 ?*/ "invalid/unpredicted" /*: dop.getDepth())*/)
+						.append("</td>" + "</tr>");
+		}
+
+		return html.append("</table>").append("</body></html>").toString();
+	}
+
+	public String getBackgroundColour() {
+		return colourManager.getDefaultPropertyMap().get(
+				Dataflow.class.toString());
+	}
+
+	@Override
+	public int getPreferredPosition() {
+		return 100;
+	}
+
+	private String limitName(String fullName) {
+		if (fullName.length() <= MAX_LENGTH)
+			return fullName;
+		return fullName.substring(0, MAX_LENGTH - ELLIPSIS.length()) + ELLIPSIS;
+	}
+
+	@Override
+	public String getViewTitle() {
+		return "Workflow " + limitName(dataflow.getName());
+	}
+
+	@Override
+	public void refreshView() {
+		editorPane.setText(buildHtml());
+		repaint();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualViewFactory.java b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualViewFactory.java
new file mode 100644
index 0000000..0d7f3c0
--- /dev/null
+++ b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualViewFactory.java
@@ -0,0 +1,41 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.dataflow;
+
+import java.util.Arrays;
+import java.util.List;
+
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+import uk.org.taverna.scufl2.api.core.Workflow;
+
+/**
+ * @author alanrw
+ */
+public class DataflowContextualViewFactory implements
+		ContextualViewFactory<Workflow> {
+	private FileManager fileManager;
+	private ColourManager colourManager;
+
+	@Override
+	public boolean canHandle(Object selection) {
+		return selection instanceof Workflow;
+	}
+
+	@Override
+	public List<ContextualView> getViews(Workflow selection) {
+		return Arrays.asList(new ContextualView[] {
+				new DataflowContextualView(selection, fileManager, colourManager)});
+	}
+
+	public void setFileManager(FileManager fileManager) {
+		this.fileManager = fileManager;
+	}
+
+	public void setColourManager(ColourManager colourManager) {
+		this.colourManager = colourManager;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflowinputport/DataflowInputPortContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflowinputport/DataflowInputPortContextualView.java b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflowinputport/DataflowInputPortContextualView.java
new file mode 100644
index 0000000..3f17a65
--- /dev/null
+++ b/taverna-workbench-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflowinputport/DataflowInputPortContextualView.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.dataflowinputport;
+
+import static java.awt.FlowLayout.LEFT;
+
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.EmptyBorder;
+
+import uk.org.taverna.scufl2.api.port.InputWorkflowPort;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+
+/**
+ * Contextual view for dataflow's input ports.
+ *
+ * @author Alex Nenadic
+ */
+class DataflowInputPortContextualView extends ContextualView{
+	private static final long serialVersionUID = -8746856072335775933L;
+
+	private InputWorkflowPort dataflowInputPort;
+	private JPanel dataflowInputPortView;
+	@SuppressWarnings("unused")
+	private FileManager fileManager;
+
+	public DataflowInputPortContextualView(InputWorkflowPort inputport,
+			FileManager fileManager) {
+		this.dataflowInputPort = inputport;
+		this.fileManager = fileManager;
+		initView();
+	}
+
+	@Override
+	public JComponent getMainFrame() {
+		refreshView();
+		return dataflowInputPortView;
+	}
+
+	@Override
+	public String getViewTitle() {
+		return "Workflow input port: " + dataflowInputPort.getName();
+	}
+
+	@Override
+	public void refreshView() {
+		dataflowInputPortView = new JPanel(new FlowLayout(LEFT));
+		dataflowInputPortView.setBorder(new EmptyBorder(5, 5, 5, 5));
+		JLabel label = new JLabel(getTextFromDepth("port",
+				dataflowInputPort.getDepth()));
+		dataflowInputPortView.add(label);
+	}
+
+	@SuppressWarnings("serial")
+	@Override
+	public Action getConfigureAction(Frame owner) {
+		return new AbstractAction("Update prediction") {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				// fileManager.getCurrentDataflow().checkValidity();
+				refreshView();
+			}
+		};
+	}
+
+	@Override
+	public int getPreferredPosition() {
+		return 100;
+	}
+}