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/23 11:23:10 UTC

[47/51] [partial] incubator-taverna-workbench git commit: Revert "temporarily empty repository"

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/servicedescriptions/StringConstantTemplateService.java
----------------------------------------------------------------------
diff --git a/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/servicedescriptions/StringConstantTemplateService.java b/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/servicedescriptions/StringConstantTemplateService.java
new file mode 100644
index 0000000..157f3b6
--- /dev/null
+++ b/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/servicedescriptions/StringConstantTemplateService.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * 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.activities.stringconstant.servicedescriptions;
+
+import java.net.URI;
+
+import javax.swing.Icon;
+
+import net.sf.taverna.t2.servicedescriptions.AbstractTemplateService;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescription;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
+import uk.org.taverna.scufl2.api.configurations.Configuration;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class StringConstantTemplateService extends AbstractTemplateService {
+	private static final URI ACTIVITY_TYPE = URI
+			.create("http://ns.taverna.org.uk/2010/activity/constant");
+	private static final URI providerId = URI
+			.create("http://taverna.sf.net/2010/service-provider/stringconstant");
+	public static final String DEFAULT_VALUE = "Add your own value here";
+	private static final String STRINGCONSTANT = "Text constant";
+
+	@Override
+	public URI getActivityType() {
+		return ACTIVITY_TYPE;
+	}
+
+	@Override
+	public Configuration getActivityConfiguration() {
+		Configuration configuration = new Configuration();
+		configuration.setType(ACTIVITY_TYPE.resolve("#Config"));
+		((ObjectNode) configuration.getJson()).put("string", DEFAULT_VALUE);
+		return configuration;
+	}
+
+	@Override
+	public Icon getIcon() {
+		return StringConstantActivityIcon.getStringConstantIcon();
+	}
+
+	@Override
+	public String getName() {
+		return STRINGCONSTANT;
+	}
+
+	@Override
+	public String getDescription() {
+		return "A string value that you can set";
+	}
+
+	public static ServiceDescription getServiceDescription() {
+		StringConstantTemplateService scts = new StringConstantTemplateService();
+		return scts.templateService;
+	}
+
+	@Override
+	public String getId() {
+		return providerId.toString();
+	}
+
+	@Override
+	public ServiceDescriptionProvider newInstance() {
+		return new StringConstantTemplateService();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/views/StringConstantActivityContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/views/StringConstantActivityContextualView.java b/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/views/StringConstantActivityContextualView.java
new file mode 100644
index 0000000..803692d
--- /dev/null
+++ b/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/views/StringConstantActivityContextualView.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * 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.activities.stringconstant.views;
+
+import static org.apache.commons.lang.StringEscapeUtils.escapeHtml;
+import static org.apache.commons.lang.StringUtils.abbreviate;
+
+import java.awt.Frame;
+
+import javax.swing.Action;
+
+import net.sf.taverna.t2.activities.stringconstant.actions.StringConstantActivityConfigurationAction;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.ui.actions.activity.HTMLBasedActivityContextualView;
+import uk.org.taverna.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.activity.Activity;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class StringConstantActivityContextualView extends
+		HTMLBasedActivityContextualView {
+	private static final long serialVersionUID = -553974544001808511L;
+	private static final int MAX_LENGTH = 100;
+
+	private final EditManager editManager;
+	private final FileManager fileManager;
+	private final ActivityIconManager activityIconManager;
+	private final ServiceDescriptionRegistry serviceDescriptionRegistry;
+	private final ServiceRegistry serviceRegistry;
+
+	public StringConstantActivityContextualView(Activity activity,
+			EditManager editManager, FileManager fileManager,
+			ActivityIconManager activityIconManager,
+			ColourManager colourManager,
+			ServiceDescriptionRegistry serviceDescriptionRegistry,
+			ServiceRegistry serviceRegistry) {
+		super(activity, colourManager);
+		this.editManager = editManager;
+		this.fileManager = fileManager;
+		this.activityIconManager = activityIconManager;
+		this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+		this.serviceRegistry = serviceRegistry;
+	}
+
+	@Override
+	public String getViewTitle() {
+		return "Text constant";
+	}
+
+	@Override
+	protected String getRawTableRowsHtml() {
+		JsonNode json = getConfigBean().getJson();
+		String value = json.get("string").textValue();
+		value = abbreviate(value, MAX_LENGTH);
+		value = escapeHtml(value);
+		String html = "<tr><td>Value</td><td>" + value + "</td></tr>";
+		return html;
+	}
+
+	@Override
+	public Action getConfigureAction(Frame owner) {
+		return new StringConstantActivityConfigurationAction(getActivity(),
+				owner, editManager, fileManager, activityIconManager,
+				serviceDescriptionRegistry, serviceRegistry);
+	}
+
+	@Override
+	public int getPreferredPosition() {
+		return 100;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/views/StringConstantActivityViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/views/StringConstantActivityViewFactory.java b/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/views/StringConstantActivityViewFactory.java
new file mode 100644
index 0000000..3f1e480
--- /dev/null
+++ b/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/views/StringConstantActivityViewFactory.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * 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.activities.stringconstant.views;
+
+import static java.util.Arrays.asList;
+
+import java.net.URI;
+import java.util.List;
+
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+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.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.activity.Activity;
+
+public class StringConstantActivityViewFactory implements
+		ContextualViewFactory<Activity> {
+	private static final URI ACTIVITY_TYPE = URI
+			.create("http://ns.taverna.org.uk/2010/activity/constant");
+
+	private EditManager editManager;
+	private FileManager fileManager;
+	private ActivityIconManager activityIconManager;
+	private ColourManager colourManager;
+	private ServiceDescriptionRegistry serviceDescriptionRegistry;
+	private ServiceRegistry serviceRegistry;
+
+	@Override
+	public boolean canHandle(Object object) {
+		return object instanceof Activity
+				&& ((Activity) object).getType().equals(ACTIVITY_TYPE);
+	}
+
+	@Override
+	public List<ContextualView> getViews(Activity activity) {
+		return asList(new ContextualView[] { new StringConstantActivityContextualView(
+				activity, editManager, fileManager, activityIconManager,
+				colourManager, serviceDescriptionRegistry, serviceRegistry) });
+	}
+
+	public void setEditManager(EditManager editManager) {
+		this.editManager = editManager;
+	}
+
+	public void setFileManager(FileManager fileManager) {
+		this.fileManager = fileManager;
+	}
+
+	public void setActivityIconManager(ActivityIconManager activityIconManager) {
+		this.activityIconManager = activityIconManager;
+	}
+
+	public void setColourManager(ColourManager colourManager) {
+		this.colourManager = colourManager;
+	}
+
+	public void setServiceDescriptionRegistry(
+			ServiceDescriptionRegistry serviceDescriptionRegistry) {
+		this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+	}
+
+	public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+		this.serviceRegistry = serviceRegistry;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/views/StringConstantConfigView.java
----------------------------------------------------------------------
diff --git a/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/views/StringConstantConfigView.java b/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/views/StringConstantConfigView.java
new file mode 100644
index 0000000..b371adb
--- /dev/null
+++ b/taverna-stringconstant-activity-ui/src/main/java/net/sf/taverna/t2/activities/stringconstant/views/StringConstantConfigView.java
@@ -0,0 +1,243 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.stringconstant.views;
+
+import static java.awt.BorderLayout.CENTER;
+import static java.awt.BorderLayout.SOUTH;
+import static java.awt.Color.WHITE;
+import static java.awt.Font.PLAIN;
+import static java.awt.GridBagConstraints.BOTH;
+import static java.awt.GridBagConstraints.FIRST_LINE_START;
+import static java.lang.String.format;
+import static javax.swing.BorderFactory.createTitledBorder;
+import static javax.swing.JOptionPane.YES_NO_OPTION;
+import static javax.swing.JOptionPane.YES_OPTION;
+import static javax.swing.JOptionPane.showConfirmDialog;
+import static javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION;
+import static javax.swing.border.TitledBorder.DEFAULT_POSITION;
+import static net.sf.taverna.t2.activities.stringconstant.servicedescriptions.StringConstantTemplateService.DEFAULT_VALUE;
+import static net.sf.taverna.t2.lang.ui.FileTools.readStringFromFile;
+import static net.sf.taverna.t2.lang.ui.FileTools.saveStringToFile;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JEditorPane;
+import javax.swing.JPanel;
+import javax.swing.JTextPane;
+import javax.swing.event.AncestorEvent;
+import javax.swing.event.AncestorListener;
+
+import net.sf.taverna.t2.lang.ui.LineEnabledTextPanel;
+import net.sf.taverna.t2.lang.ui.LinePainter;
+import net.sf.taverna.t2.lang.ui.NoWrapEditorKit;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ActivityConfigurationPanel;
+
+import org.apache.log4j.Logger;
+
+import uk.org.taverna.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.activity.Activity;
+import uk.org.taverna.scufl2.api.configurations.Configuration;
+
+/**
+ * @author alanrw
+ * @author David Withers
+ */
+@SuppressWarnings("serial")
+public class StringConstantConfigView extends ActivityConfigurationPanel {
+	private static final String CONTENT_PROPERTY = "string";
+	private static final String TEXT_FILE_EXTENSION = ".txt";
+	public static Logger logger = Logger.getLogger(StringConstantConfigView.class);
+	private static final Color LINE_COLOR = WHITE;
+	@SuppressWarnings("unused")
+	private static final String HELP_TOKEN = "net.sf.taverna.t2.activities.stringconstant.views.StringConstantConfigView";
+
+	/** The text */
+	private JEditorPane scriptTextArea;
+	private final ServiceRegistry serviceRegistry;
+
+	public StringConstantConfigView(Activity activity,
+			Configuration configuration, ServiceRegistry serviceRegistry) {
+		super(activity, configuration);
+		this.serviceRegistry = serviceRegistry;
+		setLayout(new GridBagLayout());
+		initialise();
+		addAncestorListener(new AncestorListener() {
+			@Override
+			public void ancestorAdded(AncestorEvent event) {
+				whenOpened();
+			}
+
+			@Override
+			public void ancestorMoved(AncestorEvent event) {
+			}
+
+			@Override
+			public void ancestorRemoved(AncestorEvent event) {
+			}
+		});
+	}
+
+	public StringConstantConfigView(Activity activity,
+			ServiceRegistry serviceRegistry) {
+		super(activity);
+		this.serviceRegistry = serviceRegistry;
+		setLayout(new GridBagLayout());
+		initialise();
+		addAncestorListener(new AncestorListener() {
+			@Override
+			public void ancestorAdded(AncestorEvent event) {
+				whenOpened();
+			}
+
+			@Override
+			public void ancestorMoved(AncestorEvent event) {
+			}
+
+			@Override
+			public void ancestorRemoved(AncestorEvent event) {
+			}
+		});
+	}
+
+	@Override
+	public void whenOpened() {
+		scriptTextArea.requestFocus();
+		if (scriptTextArea.getText().equals(DEFAULT_VALUE))
+			scriptTextArea.selectAll();
+	}
+
+	/** The name of the thing we are working with. */
+	protected String entityName() {
+		return "text";
+	}
+
+	@Override
+	protected void initialise() {
+		super.initialise();
+		// CSH.setHelpIDString(this, HELP_TOKEN);
+
+		setBorder(createTitledBorder(null, null, DEFAULT_JUSTIFICATION,
+				DEFAULT_POSITION, new Font("Lucida Grande", 1, 12)));
+
+		JPanel scriptEditPanel = new JPanel(new BorderLayout());
+
+		scriptTextArea = new JTextPane();
+		new LinePainter(scriptTextArea, LINE_COLOR);
+
+		// NOTE: Due to T2-1145 - always set editor kit BEFORE setDocument
+		scriptTextArea.setEditorKit(new NoWrapEditorKit());
+		scriptTextArea.setFont(new Font("Monospaced", PLAIN, 14));
+		scriptTextArea.setText(getProperty(CONTENT_PROPERTY));
+		scriptTextArea.setCaretPosition(0);
+		scriptTextArea.setPreferredSize(new Dimension(200, 100));
+
+		scriptEditPanel.add(new LineEnabledTextPanel(scriptTextArea), CENTER);
+
+		GridBagConstraints outerConstraint = new GridBagConstraints();
+		outerConstraint.anchor = FIRST_LINE_START;
+		outerConstraint.gridx = 0;
+		outerConstraint.gridy = 0;
+
+		outerConstraint.fill = BOTH;
+		outerConstraint.weighty = 0.1;
+		outerConstraint.weightx = 0.1;
+		add(scriptEditPanel, outerConstraint);
+
+		JButton loadScriptButton = new JButton("Load " + entityName());
+		loadScriptButton.setToolTipText(format("Load %s from a file",
+				entityName()));
+		loadScriptButton.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				loadText();
+			}
+		});
+
+		JButton saveRScriptButton = new JButton("Save " + entityName());
+		saveRScriptButton.setToolTipText(format("Save the %s to a file",
+				entityName()));
+		saveRScriptButton.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				saveText();
+			}
+		});
+
+		JButton clearScriptButton = new JButton("Clear " + entityName());
+		clearScriptButton.setToolTipText(format(
+				"Clear current %s from the edit area", entityName()));
+		clearScriptButton.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				clearText();
+			}
+		});
+
+		JPanel buttonPanel = new JPanel();
+		buttonPanel.setLayout(new FlowLayout());
+		buttonPanel.add(loadScriptButton);
+		buttonPanel.add(saveRScriptButton);
+		buttonPanel.add(clearScriptButton);
+
+		scriptEditPanel.add(buttonPanel, SOUTH);
+		setPreferredSize(new Dimension(600, 500));
+		this.validate();
+	}
+
+	/**
+	 * Method for loading the value
+	 */
+	private void loadText() {
+		String newScript = readStringFromFile(this, "Load " + entityName(),
+				TEXT_FILE_EXTENSION);
+		if (newScript != null) {
+			scriptTextArea.setText(newScript);
+			scriptTextArea.setCaretPosition(0);
+		}
+	}
+
+	/**
+	 * Method for saving the value
+	 */
+	private void saveText() {
+		saveStringToFile(this, "Save " + entityName(), TEXT_FILE_EXTENSION,
+				scriptTextArea.getText());
+	}
+
+	/**
+	 * Method for clearing the value
+	 */
+	private void clearText() {
+		if (showConfirmDialog(this,
+				format("Do you really want to clear the %s?", entityName()),
+				"Clearing the " + entityName(), YES_NO_OPTION) == YES_OPTION)
+			scriptTextArea.setText("");
+	}
+
+	@Override
+	public boolean checkValues() {
+		return true;
+	}
+
+	@Override
+	public boolean isConfigurationChanged() {
+		return !scriptTextArea.getText().equals(getProperty(CONTENT_PROPERTY));
+	}
+
+	@Override
+	public void noteConfiguration() {
+		setProperty(CONTENT_PROPERTY, scriptTextArea.getText());
+		configureInputPorts(serviceRegistry);
+		configureOutputPorts(serviceRegistry);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider
----------------------------------------------------------------------
diff --git a/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider b/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider
new file mode 100644
index 0000000..7a14b56
--- /dev/null
+++ b/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider
@@ -0,0 +1 @@
+net.sf.taverna.t2.activities.stringconstant.servicedescriptions.StringConstantTemplateService

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
----------------------------------------------------------------------
diff --git a/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent b/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
new file mode 100644
index 0000000..22938a2
--- /dev/null
+++ b/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
@@ -0,0 +1,3 @@
+net.sf.taverna.t2.activities.stringconstant.menu.AddStringConstantTemplateAction
+net.sf.taverna.t2.activities.stringconstant.menu.AddStringConstantTemplateMenuAction
+net.sf.taverna.t2.activities.stringconstant.menu.ConfigureStringConstantMenuAction
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI
----------------------------------------------------------------------
diff --git a/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI b/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI
new file mode 100644
index 0000000..58228ef
--- /dev/null
+++ b/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI
@@ -0,0 +1 @@
+net.sf.taverna.t2.activities.stringconstant.servicedescriptions.StringConstantActivityIcon
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
----------------------------------------------------------------------
diff --git a/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory b/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
new file mode 100644
index 0000000..73ca2a1
--- /dev/null
+++ b/taverna-stringconstant-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
@@ -0,0 +1 @@
+net.sf.taverna.t2.activities.stringconstant.views.StringConstantActivityViewFactory
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-stringconstant-activity-ui/src/main/resources/META-INF/spring/stringconstant-activity-ui-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-stringconstant-activity-ui/src/main/resources/META-INF/spring/stringconstant-activity-ui-context-osgi.xml b/taverna-stringconstant-activity-ui/src/main/resources/META-INF/spring/stringconstant-activity-ui-context-osgi.xml
new file mode 100644
index 0000000..359a72d
--- /dev/null
+++ b/taverna-stringconstant-activity-ui/src/main/resources/META-INF/spring/stringconstant-activity-ui-context-osgi.xml
@@ -0,0 +1,25 @@
+<?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="StringConstantActivityIcon" interface="net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI" />
+	<service ref="StringConstantTemplateService" interface="net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider" />
+	<service ref="StringConstantActivityViewFactory" interface="net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory" />
+
+	<service ref="AddStringConstantTemplateAction" auto-export="interfaces" />
+	<service ref="AddStringConstantTemplateMenuAction" auto-export="interfaces" />
+	<service ref="ConfigureStringConstantMenuAction" auto-export="interfaces" />
+
+	<reference id="editManager" interface="net.sf.taverna.t2.workbench.edits.EditManager" />
+	<reference id="fileManager" interface="net.sf.taverna.t2.workbench.file.FileManager" />
+	<reference id="menuManager" interface="net.sf.taverna.t2.ui.menu.MenuManager" />
+	<reference id="selectionManager" interface="net.sf.taverna.t2.workbench.selection.SelectionManager" />
+	<reference id="activityIconManager" interface="net.sf.taverna.t2.workbench.activityicons.ActivityIconManager" />
+	<reference id="colourManager" interface="net.sf.taverna.t2.workbench.configuration.colour.ColourManager" />
+	<reference id="serviceDescriptionRegistry" interface="net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry" />
+	<reference id="serviceRegistry" interface="uk.org.taverna.commons.services.ServiceRegistry" />
+</beans:beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-stringconstant-activity-ui/src/main/resources/META-INF/spring/stringconstant-activity-ui-context.xml
----------------------------------------------------------------------
diff --git a/taverna-stringconstant-activity-ui/src/main/resources/META-INF/spring/stringconstant-activity-ui-context.xml b/taverna-stringconstant-activity-ui/src/main/resources/META-INF/spring/stringconstant-activity-ui-context.xml
new file mode 100644
index 0000000..19bb6fd
--- /dev/null
+++ b/taverna-stringconstant-activity-ui/src/main/resources/META-INF/spring/stringconstant-activity-ui-context.xml
@@ -0,0 +1,49 @@
+<?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="StringConstantActivityIcon"
+		class="net.sf.taverna.t2.activities.stringconstant.servicedescriptions.StringConstantActivityIcon" />
+
+	<bean id="StringConstantTemplateService"
+		class="net.sf.taverna.t2.activities.stringconstant.servicedescriptions.StringConstantTemplateService" />
+
+	<bean id="AddStringConstantTemplateAction"
+		class="net.sf.taverna.t2.activities.stringconstant.menu.AddStringConstantTemplateAction">
+		<property name="editManager" ref="editManager" />
+		<property name="menuManager" ref="menuManager" />
+		<property name="selectionManager" ref="selectionManager" />
+		<property name="activityIconManager" ref="activityIconManager" />
+		<property name="serviceDescriptionRegistry" ref="serviceDescriptionRegistry" />
+		<property name="serviceRegistry" ref="serviceRegistry" />
+	</bean>
+	<bean id="AddStringConstantTemplateMenuAction"
+		class="net.sf.taverna.t2.activities.stringconstant.menu.AddStringConstantTemplateMenuAction">
+		<property name="editManager" ref="editManager" />
+		<property name="menuManager" ref="menuManager" />
+		<property name="selectionManager" ref="selectionManager" />
+		<property name="activityIconManager" ref="activityIconManager" />
+		<property name="serviceDescriptionRegistry" ref="serviceDescriptionRegistry" />
+		<property name="serviceRegistry" ref="serviceRegistry" />
+	</bean>
+	<bean id="ConfigureStringConstantMenuAction"
+		class="net.sf.taverna.t2.activities.stringconstant.menu.ConfigureStringConstantMenuAction">
+		<property name="editManager" ref="editManager" />
+		<property name="fileManager" ref="fileManager" />
+		<property name="activityIconManager" ref="activityIconManager" />
+		<property name="serviceDescriptionRegistry" ref="serviceDescriptionRegistry" />
+		<property name="serviceRegistry" ref="serviceRegistry" />
+	</bean>
+
+	<bean id="StringConstantActivityViewFactory"
+		class="net.sf.taverna.t2.activities.stringconstant.views.StringConstantActivityViewFactory">
+		<property name="editManager" ref="editManager" />
+		<property name="fileManager" ref="fileManager" />
+		<property name="activityIconManager" ref="activityIconManager" />
+		<property name="colourManager" ref="colourManager" />
+		<property name="serviceDescriptionRegistry" ref="serviceDescriptionRegistry" />
+		<property name="serviceRegistry" ref="serviceRegistry" />
+	</bean>
+</beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-stringconstant-activity-ui/src/main/resources/stringconstant.png
----------------------------------------------------------------------
diff --git a/taverna-stringconstant-activity-ui/src/main/resources/stringconstant.png b/taverna-stringconstant-activity-ui/src/main/resources/stringconstant.png
new file mode 100644
index 0000000..0810c97
Binary files /dev/null and b/taverna-stringconstant-activity-ui/src/main/resources/stringconstant.png differ

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-stringconstant-activity-ui/src/test/java/net/sf/taverna/t2/activities/stringconstant/views/TestStringConstantContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-stringconstant-activity-ui/src/test/java/net/sf/taverna/t2/activities/stringconstant/views/TestStringConstantContextualView.java b/taverna-stringconstant-activity-ui/src/test/java/net/sf/taverna/t2/activities/stringconstant/views/TestStringConstantContextualView.java
new file mode 100644
index 0000000..4555d0c
--- /dev/null
+++ b/taverna-stringconstant-activity-ui/src/test/java/net/sf/taverna/t2/activities/stringconstant/views/TestStringConstantContextualView.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * 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.activities.stringconstant.views;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import net.sf.taverna.t2.activities.stringconstant.actions.StringConstantActivityConfigurationAction;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import uk.org.taverna.scufl2.api.activity.Activity;
+
+public class TestStringConstantContextualView {
+	Activity activity;
+
+	@Before
+	public void setup() {
+		activity = new Activity();
+	}
+
+	@Test
+	@Ignore
+	public void testGetConfigureAction() throws Exception {
+		ContextualView view = new StringConstantActivityContextualView(
+				activity, null, null, null, null, null, null);
+		assertNotNull("The action should not be null",
+				view.getConfigureAction(null));
+		assertTrue(
+				"Should be a StringConstantActivityConfigurationAction",
+				view.getConfigureAction(null) instanceof StringConstantActivityConfigurationAction);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-unrecognized-activity-ui/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-unrecognized-activity-ui/pom.xml b/taverna-unrecognized-activity-ui/pom.xml
new file mode 100644
index 0000000..eb7a7c6
--- /dev/null
+++ b/taverna-unrecognized-activity-ui/pom.xml
@@ -0,0 +1,48 @@
+<?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</groupId>
+		<artifactId>taverna-parent</artifactId>
+		<version>3.0.1-SNAPSHOT</version>
+	</parent>
+	<groupId>net.sf.taverna.t2.ui-activities</groupId>
+	<artifactId>unrecognized-activity-ui</artifactId>
+	<version>2.0-SNAPSHOT</version>
+	<packaging>bundle</packaging>
+	<name>Taverna 2 Unrecognized Activity UI</name>
+	<dependencies>
+		<dependency>
+			<groupId>net.sf.taverna.t2.ui-api</groupId>
+			<artifactId>configuration-api</artifactId>
+			<version>${t2.ui.api.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.taverna.t2.ui-impl</groupId>
+			<artifactId>contextual-views-impl</artifactId>
+			<version>${t2.ui.impl.version}</version>
+		</dependency>
+	</dependencies>
+	<repositories>
+		<repository>
+			<releases />
+			<snapshots>
+				<enabled>false</enabled>
+			</snapshots>
+			<id>mygrid-repository</id>
+			<name>myGrid Repository</name>
+			<url>http://www.mygrid.org.uk/maven/repository
+			</url>
+		</repository>
+		<repository>
+			<releases>
+				<enabled>false</enabled>
+			</releases>
+			<snapshots />
+			<id>mygrid-snapshot-repository</id>
+			<name>myGrid Snapshot Repository</name>
+			<url>http://www.mygrid.org.uk/maven/snapshot-repository</url>
+		</repository>
+	</repositories>
+</project>
+

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-unrecognized-activity-ui/src/main/java/net/sf/taverna/t2/activities/unrecognized/views/UnrecognizedActivityViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-unrecognized-activity-ui/src/main/java/net/sf/taverna/t2/activities/unrecognized/views/UnrecognizedActivityViewFactory.java b/taverna-unrecognized-activity-ui/src/main/java/net/sf/taverna/t2/activities/unrecognized/views/UnrecognizedActivityViewFactory.java
new file mode 100644
index 0000000..9388016
--- /dev/null
+++ b/taverna-unrecognized-activity-ui/src/main/java/net/sf/taverna/t2/activities/unrecognized/views/UnrecognizedActivityViewFactory.java
@@ -0,0 +1,48 @@
+package net.sf.taverna.t2.activities.unrecognized.views;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+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.activity.Activity;
+
+/**
+ * This class generates a contextual view for a UnrecognizedActivity
+ *
+ * @author alanrw
+ */
+public class UnrecognizedActivityViewFactory implements ContextualViewFactory<Activity> {
+
+	public static final URI ACTIVITY_TYPE = URI.create("http://ns.taverna.org.uk/2010/activity/unrecognized");
+
+	private ColourManager colourManager;
+
+	/**
+	 * The factory can handle a UnrecognizedActivity
+	 *
+	 * @param object
+	 * @return
+	 */
+	public boolean canHandle(Object object) {
+		return object instanceof Activity && ((Activity) object).getType().equals(ACTIVITY_TYPE);
+	}
+
+	/**
+	 * Return a contextual view that can display information about a UnrecognizedActivity
+	 *
+	 * @param activity
+	 * @return
+	 */
+	public List<ContextualView> getViews(Activity activity) {
+		return Arrays.asList(new ContextualView[] { new UnrecognizedContextualView(activity,
+				colourManager) });
+	}
+
+	public void setColourManager(ColourManager colourManager) {
+		this.colourManager = colourManager;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-unrecognized-activity-ui/src/main/java/net/sf/taverna/t2/activities/unrecognized/views/UnrecognizedContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-unrecognized-activity-ui/src/main/java/net/sf/taverna/t2/activities/unrecognized/views/UnrecognizedContextualView.java b/taverna-unrecognized-activity-ui/src/main/java/net/sf/taverna/t2/activities/unrecognized/views/UnrecognizedContextualView.java
new file mode 100644
index 0000000..783704c
--- /dev/null
+++ b/taverna-unrecognized-activity-ui/src/main/java/net/sf/taverna/t2/activities/unrecognized/views/UnrecognizedContextualView.java
@@ -0,0 +1,56 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.unrecognized.views;
+
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+import net.sf.taverna.t2.workbench.ui.actions.activity.HTMLBasedActivityContextualView;
+import uk.org.taverna.scufl2.api.activity.Activity;
+import uk.org.taverna.scufl2.api.port.InputActivityPort;
+import uk.org.taverna.scufl2.api.port.OutputActivityPort;
+
+/**
+ * A UnrecognizedContextualView displays information about a UnrecognizedActivity
+ *
+ * @author alanrw
+ * @author David Withers
+ */
+@SuppressWarnings("serial")
+public class UnrecognizedContextualView extends HTMLBasedActivityContextualView {
+
+	public UnrecognizedContextualView(Activity activity, ColourManager colourManager) {
+		super(activity, colourManager);
+	}
+
+	/**
+	 * The table for the UnrecognizedActivity shows its ports.
+	 *
+	 * @return
+	 */
+	@Override
+	protected String getRawTableRowsHtml() {
+		StringBuilder html = new StringBuilder();
+		html.append("<tr><th>Input Port Name</th><th>Depth</th></tr>");
+		for (InputActivityPort inputActivityPort : getActivity().getInputPorts()) {
+			html.append("<tr><td>" + inputActivityPort.getName() + "</td><td>");
+			html.append(inputActivityPort.getDepth() + "</td></tr>");
+		}
+		html.append("<tr><th>Output Port Name</th><th>Depth</th></tr>");
+		for (OutputActivityPort outputActivityPort : getActivity().getOutputPorts()) {
+			html.append("<tr><td>" + outputActivityPort.getName() + "</td><td>");
+			html.append(outputActivityPort.getDepth() + "</td></tr>");
+		}
+		return html.toString();
+	}
+
+	@Override
+	public String getViewTitle() {
+		return "Unrecognized service";
+	}
+
+	@Override
+	public int getPreferredPosition() {
+		return 100;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-unrecognized-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
----------------------------------------------------------------------
diff --git a/taverna-unrecognized-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory b/taverna-unrecognized-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
new file mode 100644
index 0000000..0ec5cf1
--- /dev/null
+++ b/taverna-unrecognized-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
@@ -0,0 +1 @@
+net.sf.taverna.t2.activities.unrecognized.views.UnrecognizedActivityViewFactory

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-unrecognized-activity-ui/src/main/resources/META-INF/spring/unrecognized-activity-ui-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-unrecognized-activity-ui/src/main/resources/META-INF/spring/unrecognized-activity-ui-context-osgi.xml b/taverna-unrecognized-activity-ui/src/main/resources/META-INF/spring/unrecognized-activity-ui-context-osgi.xml
new file mode 100644
index 0000000..e5ec9ac
--- /dev/null
+++ b/taverna-unrecognized-activity-ui/src/main/resources/META-INF/spring/unrecognized-activity-ui-context-osgi.xml
@@ -0,0 +1,13 @@
+<?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="UnrecognizedActivityViewFactory" interface="net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory" />
+
+	<reference id="colourManager" interface="net.sf.taverna.t2.workbench.configuration.colour.ColourManager" />
+
+</beans:beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-unrecognized-activity-ui/src/main/resources/META-INF/spring/unrecognized-activity-ui-context.xml
----------------------------------------------------------------------
diff --git a/taverna-unrecognized-activity-ui/src/main/resources/META-INF/spring/unrecognized-activity-ui-context.xml b/taverna-unrecognized-activity-ui/src/main/resources/META-INF/spring/unrecognized-activity-ui-context.xml
new file mode 100644
index 0000000..940693e
--- /dev/null
+++ b/taverna-unrecognized-activity-ui/src/main/resources/META-INF/spring/unrecognized-activity-ui-context.xml
@@ -0,0 +1,10 @@
+<?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="UnrecognizedActivityViewFactory" class="net.sf.taverna.t2.activities.unrecognized.views.UnrecognizedActivityViewFactory">
+			<property name="colourManager" ref="colourManager" />
+	</bean>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-icons-api/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-icons-api/pom.xml b/taverna-workbench-activity-icons-api/pom.xml
new file mode 100644
index 0000000..0024571
--- /dev/null
+++ b/taverna-workbench-activity-icons-api/pom.xml
@@ -0,0 +1,20 @@
+<?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-api</artifactId>
+		<version>2.0-SNAPSHOT</version>
+	</parent>
+	<groupId>net.sf.taverna.t2.ui-api</groupId>
+	<artifactId>activity-icons-api</artifactId>
+	<packaging>bundle</packaging>
+	<name>Activity icon manager API</name>
+
+	<dependencies>
+		<dependency>
+			<groupId>uk.org.taverna.scufl2</groupId>
+			<artifactId>scufl2-api</artifactId>
+		</dependency>
+	</dependencies>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/ActivityIconManager.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/ActivityIconManager.java b/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/ActivityIconManager.java
new file mode 100644
index 0000000..d2c8fff
--- /dev/null
+++ b/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/ActivityIconManager.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (C) 2011 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.activityicons;
+
+import java.net.URI;
+
+import javax.swing.Icon;
+
+import uk.org.taverna.scufl2.api.activity.Activity;
+
+/**
+ * Manager for activities' icons.
+ * 
+ * @author David Withers
+ */
+public interface ActivityIconManager {
+	/** Returns an icon for the Activity. */
+	Icon iconForActivity(URI activityType);
+
+	Icon iconForActivity(Activity activity);
+
+	void resetIcon(URI activityType);
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/ActivityIconSPI.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/ActivityIconSPI.java b/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/ActivityIconSPI.java
new file mode 100644
index 0000000..7270dfc
--- /dev/null
+++ b/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/ActivityIconSPI.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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.activityicons;
+
+import java.net.URI;
+
+import javax.swing.Icon;
+
+/**
+ * Defines an interface for getting an icon for an Activity.
+ * 
+ * @author Alex Nenadic
+ */
+public interface ActivityIconSPI {
+	/**
+	 * A return value for {@link canProvideIconScore()} indicating an SPI cannot
+	 * provide an icon for a given activity.
+	 */
+	int NO_ICON = 0;
+
+	/**
+	 * {@link DefaultActivityIcon} returns this value that will be used when an
+	 * activity that has no other SPI providing an icon for. Any SPI shour
+	 * return value of at least DEFAULT_ICON + 1 if they want to 'override' the
+	 * default icon.
+	 */
+	int DEFAULT_ICON = 10;
+
+	/**
+	 * Returns a positive number if the class can provide an icon for the given
+	 * activity or {@link NO_ICON} otherwise. Out of two SPIs capable of
+	 * providing an icon for the same activity, the one returning a higher score
+	 * will be used.
+	 */
+	int canProvideIconScore(URI activityType);
+
+	/** Returns an icon for the Activity. */
+	Icon getIcon(URI activityType);
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/DefaultActivityIcon.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/DefaultActivityIcon.java b/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/DefaultActivityIcon.java
new file mode 100644
index 0000000..c474e69
--- /dev/null
+++ b/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/DefaultActivityIcon.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.activityicons;
+
+import java.net.URI;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+
+public class DefaultActivityIcon implements ActivityIconSPI {
+	private static final String ICON_RESOURCE = "/default-activity-icon.png";
+
+	@Override
+	public int canProvideIconScore(URI activityType) {
+		// For any activity we can provide a default icon
+		return DEFAULT_ICON;
+	}
+
+	@Override
+	public Icon getIcon(URI activityType) {
+		return getDefaultIcon();
+	}
+	
+	public static Icon getDefaultIcon() {
+		return IconLoader.icon;
+	}
+
+	private static class IconLoader {
+		static final Icon icon = loadDefaultIcon();
+
+		private static Icon loadDefaultIcon() {
+			return new ImageIcon(
+					DefaultActivityIcon.class.getResource(ICON_RESOURCE));
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/impl/ActivityIconManagerImpl.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/impl/ActivityIconManagerImpl.java b/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/impl/ActivityIconManagerImpl.java
new file mode 100644
index 0000000..f8294fc
--- /dev/null
+++ b/taverna-workbench-activity-icons-api/src/main/java/net/sf/taverna/t2/workbench/activityicons/impl/ActivityIconManagerImpl.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * 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.activityicons.impl;
+
+import static net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI.NO_ICON;
+
+import java.net.URI;
+import java.util.List;
+import java.util.WeakHashMap;
+
+import javax.swing.Icon;
+
+import uk.org.taverna.scufl2.api.activity.Activity;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI;
+
+/**
+ * Manager for activities' icons.
+ *
+ * @author Alex Nenadic
+ * @author Alan R Williams
+ */
+public class ActivityIconManagerImpl implements ActivityIconManager {
+	/** Cache of already obtained icons; maps activities to their icons*/
+	private WeakHashMap<URI, Icon> iconsMap = new WeakHashMap<>();
+
+	private List<ActivityIconSPI> activityIcons;
+
+	/** Returns an icon for the Activity. */
+	@Override
+	public Icon iconForActivity(URI activityType) {
+		Icon icon = iconsMap.get(activityType);
+		if (icon != null)
+			return icon;
+		int bestScore = NO_ICON;
+		ActivityIconSPI bestSPI = null;
+		for (ActivityIconSPI spi : activityIcons) {
+			int spiScore = spi.canProvideIconScore(activityType);
+			if (spiScore > bestScore) {
+				bestSPI = spi;
+				bestScore = spiScore;
+			}
+		}
+		if (bestSPI == null)
+			return null;
+		icon = bestSPI.getIcon(activityType);
+		iconsMap.put(activityType, icon);
+		return icon;
+	}
+
+	@Override
+	public Icon iconForActivity(Activity activity) {
+		return iconForActivity(activity.getType());
+	}
+
+	@Override
+	public void resetIcon(URI activityType) {
+		Icon icon = iconsMap.get(activityType);
+		if (icon != null)
+			iconsMap.remove(activityType);
+		iconForActivity(activityType);
+	}
+
+	public void setActivityIcons(List<ActivityIconSPI> activityIcons) {
+		this.activityIcons = activityIcons;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-icons-api/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-icons-api/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI b/taverna-workbench-activity-icons-api/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI
new file mode 100644
index 0000000..d268c81
--- /dev/null
+++ b/taverna-workbench-activity-icons-api/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI
@@ -0,0 +1 @@
+net.sf.taverna.t2.workbench.activityicons.DefaultActivityIcon
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-icons-api/src/main/resources/META-INF/spring/activity-icons-api-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-icons-api/src/main/resources/META-INF/spring/activity-icons-api-context-osgi.xml b/taverna-workbench-activity-icons-api/src/main/resources/META-INF/spring/activity-icons-api-context-osgi.xml
new file mode 100644
index 0000000..5c67640
--- /dev/null
+++ b/taverna-workbench-activity-icons-api/src/main/resources/META-INF/spring/activity-icons-api-context-osgi.xml
@@ -0,0 +1,15 @@
+<?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="DefaultActivityIcon" interface="net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI" />
+
+	<service ref="ActivityIconManager" interface="net.sf.taverna.t2.workbench.activityicons.ActivityIconManager" />
+
+	<list id="activityIcons" interface="net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI" cardinality="0..N" />
+
+</beans:beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-icons-api/src/main/resources/META-INF/spring/activity-icons-api-context.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-icons-api/src/main/resources/META-INF/spring/activity-icons-api-context.xml b/taverna-workbench-activity-icons-api/src/main/resources/META-INF/spring/activity-icons-api-context.xml
new file mode 100644
index 0000000..93c98c4
--- /dev/null
+++ b/taverna-workbench-activity-icons-api/src/main/resources/META-INF/spring/activity-icons-api-context.xml
@@ -0,0 +1,13 @@
+<?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="DefaultActivityIcon" class="net.sf.taverna.t2.workbench.activityicons.DefaultActivityIcon" />
+
+	<bean id="ActivityIconManager" class="net.sf.taverna.t2.workbench.activityicons.impl.ActivityIconManagerImpl">
+		<property name="activityIcons" ref="activityIcons" />
+	</bean>
+
+
+</beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-icons-api/src/main/resources/default-activity-icon.png
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-icons-api/src/main/resources/default-activity-icon.png b/taverna-workbench-activity-icons-api/src/main/resources/default-activity-icon.png
new file mode 100644
index 0000000..b7ed3e9
Binary files /dev/null and b/taverna-workbench-activity-icons-api/src/main/resources/default-activity-icon.png differ

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-palette-api/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/pom.xml b/taverna-workbench-activity-palette-api/pom.xml
new file mode 100644
index 0000000..1c9ab8c
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/pom.xml
@@ -0,0 +1,61 @@
+<?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-api</artifactId>
+		<version>2.0-SNAPSHOT</version>
+	</parent>
+	<groupId>net.sf.taverna.t2.ui-api</groupId>
+	<artifactId>activity-palette-api</artifactId>
+	<packaging>bundle</packaging>
+	<name>Activity Palette API</name>
+	<description>Activity Palette API</description>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<configuration>
+					<systemProperties>
+						<property>
+							<name>java.awt.headless</name>
+							<value>false</value>
+						</property>
+					</systemProperties>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+	<dependencies>
+		<dependency>
+			<groupId>net.sf.taverna.t2.ui-api</groupId>
+			<artifactId>workbench-api</artifactId>
+			<version>${t2.ui.api.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.taverna.t2.ui-api</groupId>
+			<artifactId>edits-api</artifactId>
+			<version>${t2.ui.api.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.taverna.t2.lang</groupId>
+			<artifactId>beans</artifactId>
+			<version>${t2.lang.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>uk.org.taverna.configuration</groupId>
+			<artifactId>taverna-configuration-api</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>uk.org.taverna.scufl2</groupId>
+			<artifactId>scufl2-api</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/8c4b365e/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/AbstractConfigurableServiceProvider.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/AbstractConfigurableServiceProvider.java b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/AbstractConfigurableServiceProvider.java
new file mode 100644
index 0000000..18cb176
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/AbstractConfigurableServiceProvider.java
@@ -0,0 +1,53 @@
+package net.sf.taverna.t2.servicedescriptions;
+
+import uk.org.taverna.scufl2.api.configurations.Configuration;
+
+public abstract class AbstractConfigurableServiceProvider extends
+		IdentifiedObject implements ConfigurableServiceProvider {
+	protected Configuration serviceProviderConfig;
+
+	/**
+	 * Construct configurable service provider.
+	 * 
+	 * @param configTemplate
+	 *            Template configuration
+	 */
+	public AbstractConfigurableServiceProvider(Configuration configTemplate) {
+		if (configTemplate == null)
+			throw new NullPointerException("Default config can't be null");
+		serviceProviderConfig = configTemplate;
+	}
+
+	/**
+	 * Package access constructor - only used with {@link #clone()} - otherwise
+	 * use {@link #AbstractConfigurableServiceProvider(Object)}
+	 */
+	AbstractConfigurableServiceProvider() {
+	}
+
+	@Override
+	public AbstractConfigurableServiceProvider clone() {
+		AbstractConfigurableServiceProvider provider = (AbstractConfigurableServiceProvider) newInstance();
+		Configuration configuration = getConfiguration();
+		if (configuration != null)
+			provider.configure(configuration);
+		return provider;
+	}
+
+	@Override
+	public synchronized void configure(Configuration conf) {
+		if (conf == null)
+			throw new IllegalArgumentException("Config can't be null");
+		this.serviceProviderConfig = conf;
+	}
+
+	@Override
+	public Configuration getConfiguration() {
+		return serviceProviderConfig;
+	}
+
+	@Override
+	public String toString() {
+		return getName() + " " + getConfiguration();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/AbstractTemplateService.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/AbstractTemplateService.java b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/AbstractTemplateService.java
new file mode 100644
index 0000000..d4909b1
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/AbstractTemplateService.java
@@ -0,0 +1,85 @@
+package net.sf.taverna.t2.servicedescriptions;
+
+import static java.util.Collections.singleton;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.Icon;
+
+import uk.org.taverna.scufl2.api.configurations.Configuration;
+
+public abstract class AbstractTemplateService implements
+		ServiceDescriptionProvider {
+	protected TemplateServiceDescription templateService = new TemplateServiceDescription();
+
+	@Override
+	public void findServiceDescriptionsAsync(
+			FindServiceDescriptionsCallBack callBack) {
+		callBack.partialResults(singleton(templateService));
+		callBack.finished();
+	}
+
+	@Override
+	public abstract Icon getIcon();
+
+	public URI getActivityType() {
+		return null;
+	}
+
+	public abstract Configuration getActivityConfiguration();
+
+	public class TemplateServiceDescription extends ServiceDescription {
+		@Override
+		public Icon getIcon() {
+			return AbstractTemplateService.this.getIcon();
+		}
+
+		@Override
+		public String getName() {
+			return AbstractTemplateService.this.getName();
+		}
+
+		@Override
+		public List<String> getPath() {
+			return Arrays.asList(SERVICE_TEMPLATES);
+		}
+
+		@Override
+		public boolean isTemplateService() {
+			return true;
+		}
+
+		@Override
+		protected List<Object> getIdentifyingData() {
+			// Do it by object identity
+			return null;
+		}
+
+		@Override
+		public URI getActivityType() {
+			return AbstractTemplateService.this.getActivityType();
+		}
+
+		@Override
+		public Configuration getActivityConfiguration() {
+			return AbstractTemplateService.this.getActivityConfiguration();
+		}
+
+		@Override
+		public String getDescription() {
+			return AbstractTemplateService.this.getDescription();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return "Template service " + getName();
+	}
+
+	public String getDescription() {
+		// Default to an empty string
+		return "";
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ConfigurableServiceProvider.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ConfigurableServiceProvider.java b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ConfigurableServiceProvider.java
new file mode 100644
index 0000000..0bf01bd
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ConfigurableServiceProvider.java
@@ -0,0 +1,10 @@
+package net.sf.taverna.t2.servicedescriptions;
+
+import uk.org.taverna.scufl2.api.common.Configurable;
+import uk.org.taverna.scufl2.api.configurations.Configuration;
+
+public interface ConfigurableServiceProvider extends
+		ServiceDescriptionProvider, Configurable, Cloneable {
+	void configure(Configuration configuration) throws Exception;
+	Configuration getConfiguration();
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/CustomizedConfigurePanelProvider.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/CustomizedConfigurePanelProvider.java b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/CustomizedConfigurePanelProvider.java
new file mode 100644
index 0000000..8bb5331
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/CustomizedConfigurePanelProvider.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.servicedescriptions;
+
+import uk.org.taverna.scufl2.api.configurations.Configuration;
+
+public interface CustomizedConfigurePanelProvider extends
+		ConfigurableServiceProvider {
+	void createCustomizedConfigurePanel(CustomizedConfigureCallBack callBack);
+
+	interface CustomizedConfigureCallBack {
+		void newProviderConfiguration(Configuration providerConfig);
+
+		Configuration getTemplateConfig();
+
+		ServiceDescriptionRegistry getServiceDescriptionRegistry();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/IdentifiedObject.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/IdentifiedObject.java b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/IdentifiedObject.java
new file mode 100644
index 0000000..596f502
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/IdentifiedObject.java
@@ -0,0 +1,30 @@
+package net.sf.taverna.t2.servicedescriptions;
+
+import java.util.List;
+
+import net.sf.taverna.t2.lang.beans.PropertyAnnotated;
+
+public abstract class IdentifiedObject extends PropertyAnnotated {
+	@Override
+	public boolean equals(Object obj) {
+		if (!(obj instanceof IdentifiedObject))
+			return false;
+		List<? extends Object> myIdentifyingData = getIdentifyingData();
+		if (myIdentifyingData == null)
+			return super.equals(obj);
+		if (!getClass().isInstance(obj) && obj.getClass().isInstance(this))
+			return false;
+		IdentifiedObject id = (IdentifiedObject) obj;
+		return myIdentifyingData.equals(id.getIdentifyingData());
+	}
+
+	@Override
+	public int hashCode() {
+		List<? extends Object> identifyingData = getIdentifyingData();
+		if (identifyingData == null)
+			return super.hashCode();
+		return identifyingData.hashCode();
+	}
+
+	protected abstract List<? extends Object> getIdentifyingData();
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescription.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescription.java b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescription.java
new file mode 100644
index 0000000..8551934
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescription.java
@@ -0,0 +1,80 @@
+package net.sf.taverna.t2.servicedescriptions;
+
+import java.net.URI;
+import java.util.List;
+
+import javax.swing.Icon;
+
+import net.sf.taverna.t2.lang.beans.PropertyAnnotation;
+import net.sf.taverna.t2.workbench.edits.Edit;
+import uk.org.taverna.scufl2.api.activity.Activity;
+import uk.org.taverna.scufl2.api.configurations.Configuration;
+import uk.org.taverna.scufl2.api.core.Processor;
+import uk.org.taverna.scufl2.api.core.Workflow;
+
+public abstract class ServiceDescription extends IdentifiedObject {
+	public static final String SERVICE_TEMPLATES = "Service templates";
+	private static final String NAME = "Name";
+	private static final String SERVICE_CONFIGURATION = "Service configuration";
+	private static final String SERVICE_IMPLEMENTATION_URI = "Service implementation URI";
+	private static final String DESCRIPTION = "Description";
+	public static final String LOCAL_SERVICES = "Local services";
+
+	private String description = "";
+
+	@PropertyAnnotation(expert = true, displayName = SERVICE_IMPLEMENTATION_URI)
+	public abstract URI getActivityType();
+
+	@PropertyAnnotation(expert = true, displayName = SERVICE_CONFIGURATION)
+	public Configuration getActivityConfiguration() {
+		Configuration configuration = new Configuration();
+		configuration.setType(getActivityType().resolve("#Config"));
+		return configuration;
+	}
+
+	@PropertyAnnotation(displayName = DESCRIPTION)
+	public String getDescription() {
+		return this.description;
+	}
+
+	@PropertyAnnotation(expert = true)
+	public abstract Icon getIcon();
+
+	@PropertyAnnotation(displayName = NAME)
+	public abstract String getName();
+
+	@PropertyAnnotation(expert = true)
+	public abstract List<? extends Comparable<?>> getPath();
+
+	@PropertyAnnotation(hidden = true)
+	public boolean isTemplateService() {
+		return false;
+	}
+
+	/**
+	 * @param description
+	 *            the description to set
+	 */
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	@Override
+	public String toString() {
+		return "Service description " + getName();
+	}
+
+	/**
+	 * Any additional edit that needs to be performed upon insertion of an
+	 * instance of the ServiceDescription into the {@link Workflow} within the
+	 * specified {@link Processor}
+	 * 
+	 * @param dataflow
+	 * @param p
+	 * @param a
+	 * @return
+	 */
+	public Edit<?> getInsertionEdit(Workflow dataflow, Processor p, Activity a) {
+		return null;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescriptionProvider.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescriptionProvider.java b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescriptionProvider.java
new file mode 100644
index 0000000..8170819
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescriptionProvider.java
@@ -0,0 +1,61 @@
+package net.sf.taverna.t2.servicedescriptions;
+
+import java.util.Collection;
+
+import javax.swing.Icon;
+
+import net.sf.taverna.t2.lang.beans.PropertyAnnotation;
+
+/**
+ * A provider of service descriptions
+ * 
+ * @author Stian Soiland-Reyes
+ */
+public interface ServiceDescriptionProvider {
+	/**
+	 * Get all service descriptions.
+	 * 
+	 * @param callBack
+	 */
+	void findServiceDescriptionsAsync(FindServiceDescriptionsCallBack callBack);
+
+	/**
+	 * @author stain
+	 */
+	interface FindServiceDescriptionsCallBack {
+		void partialResults(
+				Collection<? extends ServiceDescription> serviceDescriptions);
+
+		void status(String message);
+
+		void warning(String message);
+
+		void finished();
+
+		void fail(String message, Throwable ex);
+	}
+
+	/**
+	 * Name of this service description provider, for instance "BioCatalogue" or
+	 * "WSDL". This name is typically used in a "Add service..." menu.
+	 * 
+	 * @return Name of provider
+	 */
+	String getName();
+
+	@PropertyAnnotation(expert = true)
+	abstract Icon getIcon();
+
+	/**
+	 * @return unique id of this provider.
+	 */
+	String getId();
+
+	/**
+	 * Create a new copy of this service provider. It <i>need not be
+	 * configured</i> at the point where it is returned.
+	 * 
+	 * @return The copy.
+	 */
+	ServiceDescriptionProvider newInstance();
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescriptionRegistry.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescriptionRegistry.java b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescriptionRegistry.java
new file mode 100644
index 0000000..e9b6c04
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescriptionRegistry.java
@@ -0,0 +1,50 @@
+package net.sf.taverna.t2.servicedescriptions;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URL;
+import java.util.List;
+import java.util.Set;
+
+import net.sf.taverna.t2.lang.observer.Observable;
+import net.sf.taverna.t2.servicedescriptions.events.ServiceDescriptionRegistryEvent;
+
+public interface ServiceDescriptionRegistry extends
+		Observable<ServiceDescriptionRegistryEvent> {
+	void addServiceDescriptionProvider(ServiceDescriptionProvider provider);
+
+	Set<ServiceDescriptionProvider> getDefaultServiceDescriptionProviders();
+
+	Set<ServiceDescriptionProvider> getServiceDescriptionProviders();
+
+	Set<ServiceDescriptionProvider> getServiceDescriptionProviders(
+			ServiceDescription sd);
+
+	Set<ServiceDescription> getServiceDescriptions();
+
+	ServiceDescription getServiceDescription(URI activityType);
+
+	List<ConfigurableServiceProvider> getUnconfiguredServiceProviders();
+
+	Set<ServiceDescriptionProvider> getUserAddedServiceProviders();
+
+	Set<ServiceDescriptionProvider> getUserRemovedServiceProviders();
+
+	void loadServiceProviders();
+
+	void loadServiceProviders(File serviceProvidersURL);
+
+	void loadServiceProviders(URL serviceProvidersURL);
+
+	void refresh();
+
+	void removeServiceDescriptionProvider(ServiceDescriptionProvider provider);
+
+	void saveServiceDescriptions();
+
+	void saveServiceDescriptions(File serviceDescriptionsFile);
+
+	void exportCurrentServiceDescriptions(File serviceDescriptionsFile);
+
+	boolean isDefaultSystemConfigurableProvidersLoaded();
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescriptionsConfiguration.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescriptionsConfiguration.java b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescriptionsConfiguration.java
new file mode 100644
index 0000000..7fbcbfc
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/ServiceDescriptionsConfiguration.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) 2012 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.servicedescriptions;
+
+import uk.org.taverna.configuration.Configurable;
+
+/**
+ * @author David Withers
+ */
+public interface ServiceDescriptionsConfiguration extends Configurable {
+	public boolean isIncludeDefaults();
+
+	public void setIncludeDefaults(boolean includeDefaults);
+
+	public boolean isRemovePermanently();
+
+	public void setRemovePermanently(boolean removePermanently);
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/AbstractProviderEvent.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/AbstractProviderEvent.java b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/AbstractProviderEvent.java
new file mode 100644
index 0000000..1fd224e
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/AbstractProviderEvent.java
@@ -0,0 +1,16 @@
+package net.sf.taverna.t2.servicedescriptions.events;
+
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
+
+public abstract class AbstractProviderEvent extends
+		ServiceDescriptionRegistryEvent {
+	private final ServiceDescriptionProvider provider;
+
+	public AbstractProviderEvent(ServiceDescriptionProvider provider) {
+		this.provider = provider;
+	}
+
+	public ServiceDescriptionProvider getProvider() {
+		return provider;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/AbstractProviderNotification.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/AbstractProviderNotification.java b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/AbstractProviderNotification.java
new file mode 100644
index 0000000..2cabf90
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/AbstractProviderNotification.java
@@ -0,0 +1,18 @@
+package net.sf.taverna.t2.servicedescriptions.events;
+
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
+
+public class AbstractProviderNotification extends AbstractProviderEvent {
+
+	private final String message;
+
+	public AbstractProviderNotification(ServiceDescriptionProvider provider, String message) {
+		super(provider);
+		this.message = message;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/AddedProviderEvent.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/AddedProviderEvent.java b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/AddedProviderEvent.java
new file mode 100644
index 0000000..6e003d7
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/AddedProviderEvent.java
@@ -0,0 +1,10 @@
+package net.sf.taverna.t2.servicedescriptions.events;
+
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
+
+public class AddedProviderEvent extends AbstractProviderEvent {
+
+	public AddedProviderEvent(ServiceDescriptionProvider provider) {
+		super(provider);
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/PartialServiceDescriptionsNotification.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/PartialServiceDescriptionsNotification.java b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/PartialServiceDescriptionsNotification.java
new file mode 100644
index 0000000..3bd8c7f
--- /dev/null
+++ b/taverna-workbench-activity-palette-api/src/main/java/net/sf/taverna/t2/servicedescriptions/events/PartialServiceDescriptionsNotification.java
@@ -0,0 +1,22 @@
+package net.sf.taverna.t2.servicedescriptions.events;
+
+import java.util.Collection;
+
+import net.sf.taverna.t2.servicedescriptions.ServiceDescription;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
+
+public class PartialServiceDescriptionsNotification extends
+		AbstractProviderNotification {
+	private final Collection<? extends ServiceDescription> serviceDescriptions;
+
+	public PartialServiceDescriptionsNotification(
+			ServiceDescriptionProvider provider,
+			Collection<? extends ServiceDescription> serviceDescriptions) {
+		super(provider, "Found " + serviceDescriptions.size() + " services");
+		this.serviceDescriptions = serviceDescriptions;
+	}
+
+	public Collection<? extends ServiceDescription> getServiceDescriptions() {
+		return serviceDescriptions;
+	}
+}