Merge remote-tracking branch 'apache/master'
diff --git a/apache-taverna-activity-gis-activity-ui/pom.xml b/apache-taverna-activity-gis-activity-ui/pom.xml
new file mode 100644
index 0000000..45a1e11
--- /dev/null
+++ b/apache-taverna-activity-gis-activity-ui/pom.xml
@@ -0,0 +1,105 @@
+<?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>org.apache.taverna.gis</groupId>
+		<artifactId>apache-taverna-activity-gis</artifactId>
+		<version>0.0.1-incubating.SNAPSHOT</version>
+	</parent>
+	<artifactId>apache-taverna-activity-gis-activity-ui</artifactId>
+	<packaging>bundle</packaging>
+	<name>Gis Taverna activity UI</name>
+
+	<dependencies>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-gis-client</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+
+								<dependency>
+			<groupId>org.apache.taverna.engine</groupId>
+			<artifactId>taverna-workflowmodel-api</artifactId>
+			<version>${taverna.engine.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.engine</groupId>
+			<artifactId>taverna-reference-api</artifactId>
+			<version>${taverna.engine.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-databind</artifactId>
+			<version>2.3.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.4</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.engine</groupId>
+			<artifactId>taverna-workflowmodel-impl</artifactId>
+			<version>${taverna.engine.version}</version>
+			<scope>test</scope>
+		</dependency>
+		
+
+        <dependency>
+            <groupId>org.apache.taverna.workbench</groupId>
+            <artifactId>taverna-activity-palette-api</artifactId>
+            <version>${taverna.workbench.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.taverna.workbench</groupId>
+            <artifactId>taverna-edits-api</artifactId>
+            <version>${taverna.workbench.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.taverna.workbench</groupId>
+            <artifactId>taverna-selection-api</artifactId>
+            <version>${taverna.workbench.version}</version>
+        </dependency>
+        
+        <dependency>
+            <groupId>org.apache.taverna.workbench</groupId>
+            <artifactId>taverna-menu-api</artifactId>
+            <version>${taverna.workbench.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.taverna.workbench</groupId>
+            <artifactId>taverna-activity-icons-api</artifactId>
+            <version>${taverna.workbench.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.taverna.workbench</groupId>
+            <artifactId>taverna-helper-api</artifactId>
+            <version>${taverna.workbench.version}</version>
+        </dependency>        
+        <dependency>
+            <groupId>org.apache.taverna.workbench</groupId>
+            <artifactId>taverna-ui</artifactId>
+            <version>${taverna.workbench.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.taverna.workbench</groupId>
+            <artifactId>taverna-configuration-ui-api</artifactId>
+            <version>${taverna.workbench.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.taverna.workbench</groupId>
+            <artifactId>taverna-contextual-views-api</artifactId>
+            <version>${taverna.workbench.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.taverna.workbench</groupId>
+            <artifactId>taverna-activity-tools</artifactId>
+            <version>${taverna.workbench.version}</version>
+        </dependency>		
+
+	</dependencies>
+</project>
diff --git a/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/config/GisConfigurationPanel.java b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/config/GisConfigurationPanel.java
new file mode 100644
index 0000000..160adce
--- /dev/null
+++ b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/config/GisConfigurationPanel.java
@@ -0,0 +1,84 @@
+package org.apache.taverna.gis.ui.config;
+
+import java.awt.GridLayout;
+import java.net.URI;
+
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JTextField;
+
+import org.apache.taverna.workbench.ui.views.contextualviews.activity.ActivityConfigurationPanel;
+
+import org.apache.taverna.services.ServiceRegistry;
+import org.apache.taverna.scufl2.api.activity.Activity;
+
+@SuppressWarnings("serial")
+public class GisConfigurationPanel extends ActivityConfigurationPanel {
+
+	private final ServiceRegistry serviceRegistry;
+
+	private JTextField fieldString;
+	private JTextField fieldURI;
+
+	public GisConfigurationPanel(Activity activity, ServiceRegistry serviceRegistry) {
+		super(activity);
+		this.serviceRegistry = serviceRegistry;
+		initialise();
+	}
+
+	protected void initialise() {
+		// call super.initialise() to initialise the configuration
+		super.initialise();
+
+		removeAll();
+		setLayout(new GridLayout(0, 2));
+
+		// FIXME: Create GUI depending on activity configuration bean
+		JLabel labelString = new JLabel("Example string:");
+		add(labelString);
+		fieldString = new JTextField(20);
+		add(fieldString);
+		labelString.setLabelFor(fieldString);
+
+		JLabel labelURI = new JLabel("Example URI:");
+		add(labelURI);
+		fieldURI = new JTextField(25);
+		add(fieldURI);
+		labelURI.setLabelFor(fieldURI);
+
+		// Populate fields from activity configuration
+		fieldString.setText(getProperty("exampleString"));
+		fieldURI.setText(getProperty("exampleUri"));
+	}
+
+	/**
+	 * Check that user values in UI are valid
+	 */
+	@Override
+	public boolean checkValues() {
+		try {
+			URI.create(fieldURI.getText());
+		} catch (IllegalArgumentException ex) {
+			JOptionPane.showMessageDialog(this, ex.getCause().getMessage(),
+					"Invalid URI", JOptionPane.ERROR_MESSAGE);
+			// Not valid, return false
+			return false;
+		}
+		// All valid, return true
+		return true;
+	}
+
+	/**
+	 * Set the configuration properties from the UI
+	 */
+	@Override
+	public void noteConfiguration() {
+		// FIXME: Update bean fields from your UI elements
+		setProperty("exampleString", fieldString.getText());
+		setProperty("exampleUri", fieldURI.getText());
+
+		configureInputPorts(serviceRegistry);
+		configureOutputPorts(serviceRegistry);
+	}
+
+}
diff --git a/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/config/GisConfigureAction.java b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/config/GisConfigureAction.java
new file mode 100644
index 0000000..32ea030
--- /dev/null
+++ b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/config/GisConfigureAction.java
@@ -0,0 +1,46 @@
+package org.apache.taverna.gis.ui.config;
+
+import java.awt.event.ActionEvent;
+
+import org.apache.taverna.services.ServiceRegistry;
+import org.apache.taverna.scufl2.api.activity.Activity;
+
+import org.apache.taverna.servicedescriptions.ServiceDescriptionRegistry;
+import org.apache.taverna.workbench.activityicons.ActivityIconManager;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.ui.actions.activity.ActivityConfigurationAction;
+import org.apache.taverna.workbench.ui.views.contextualviews.activity.ActivityConfigurationDialog;
+
+@SuppressWarnings("serial")
+public class GisConfigureAction extends ActivityConfigurationAction {
+
+	private final EditManager editManager;
+	private final FileManager fileManager;
+	private final ServiceRegistry serviceRegistry;
+
+	public GisConfigureAction(Activity activity,
+			EditManager editManager, FileManager fileManager,
+			ActivityIconManager activityIconManager,
+			ServiceDescriptionRegistry serviceDescriptionRegistry,
+			ServiceRegistry serviceRegistry) {
+		super(activity, activityIconManager, serviceDescriptionRegistry);
+		this.editManager = editManager;
+		this.fileManager = fileManager;
+		this.serviceRegistry = serviceRegistry;
+	}
+
+	public void actionPerformed(ActionEvent e) {
+		ActivityConfigurationDialog currentDialog = getDialog(getActivity());
+		if (currentDialog != null) {
+			currentDialog.toFront();
+			return;
+		}
+
+		GisConfigurationPanel panel = new GisConfigurationPanel(getActivity(), serviceRegistry);
+		ActivityConfigurationDialog dialog = new ActivityConfigurationDialog(getActivity(), panel, editManager);
+
+		setDialog(getActivity(), dialog, fileManager);
+	}
+
+}
diff --git a/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/menu/GisConfigureMenuAction.java b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/menu/GisConfigureMenuAction.java
new file mode 100644
index 0000000..cdf45dc
--- /dev/null
+++ b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/menu/GisConfigureMenuAction.java
@@ -0,0 +1,64 @@
+package org.apache.taverna.gis.ui.menu;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.services.ServiceRegistry;
+
+import org.apache.taverna.servicedescriptions.ServiceDescriptionRegistry;
+import org.apache.taverna.ui.menu.ContextualMenuComponent;
+import org.apache.taverna.ui.menu.MenuComponent;
+import org.apache.taverna.workbench.activityicons.ActivityIconManager;
+import org.apache.taverna.workbench.activitytools.AbstractConfigureActivityMenuAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.file.FileManager;
+
+import org.apache.taverna.gis.ui.config.GisConfigureAction;
+
+public class GisConfigureMenuAction extends AbstractConfigureActivityMenuAction implements
+		MenuComponent, ContextualMenuComponent {
+
+	private static final URI ACTIVITY_TYPE = URI
+			.create("http://example.com/2013/activity/apache-taverna-activity-gis");
+
+	private EditManager editManager;
+	private FileManager fileManager;
+	private ActivityIconManager activityIconManager;
+	private ServiceDescriptionRegistry serviceDescriptionRegistry;
+	private ServiceRegistry serviceRegistry;
+
+	public GisConfigureMenuAction() {
+		super(ACTIVITY_TYPE);
+	}
+
+	@Override
+	protected Action createAction() {
+		Action result = new GisConfigureAction(findActivity(), editManager, fileManager,
+				activityIconManager, serviceDescriptionRegistry, serviceRegistry);
+		result.putValue(Action.NAME, "Configure example service");
+		addMenuDots(result);
+		return result;
+	}
+
+	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 setServiceDescriptionRegistry(ServiceDescriptionRegistry serviceDescriptionRegistry) {
+		this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+	}
+
+	public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+		this.serviceRegistry = serviceRegistry;
+	}
+
+}
diff --git a/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/serviceprovider/GisServiceDesc.java b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/serviceprovider/GisServiceDesc.java
new file mode 100644
index 0000000..5361629
--- /dev/null
+++ b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/serviceprovider/GisServiceDesc.java
@@ -0,0 +1,95 @@
+package org.apache.taverna.gis.ui.serviceprovider;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.Icon;
+
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.servicedescriptions.ServiceDescription;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class GisServiceDesc extends ServiceDescription {
+	public static final URI ACTIVITY_TYPE = URI
+			.create("http://ns.taverna.org.uk/2016/activity/gis");
+
+	
+	/**
+	 * The type of Activity which should be instantiated when adding a service
+	 * for this description
+	 */
+	@Override
+	public URI getActivityType() {
+		return ACTIVITY_TYPE;
+	}
+
+	@Override
+	public Configuration getActivityConfiguration() {
+		Configuration configuration = new Configuration();
+		configuration.setType(ACTIVITY_TYPE.resolve("#Config"));
+		ObjectNode json = configuration.getJsonAsObjectNode();
+		json.put("ogcServiceUri", ogcServiceUri.toASCIIString());
+		json.put("processIdentifier", processIdentifier);
+		return configuration;
+	}
+	
+	/**
+	 * An icon to represent this service description in the service palette.
+	 */
+	@Override
+	public Icon getIcon() {
+		return GisServiceIcon.getIcon();
+	}
+
+	/**
+	 * The display name that will be shown in service palette and will
+	 * be used as a template for processor name when added to workflow.
+	 */
+	@Override
+	public String getName() {
+		return processIdentifier;
+	}
+
+	/**
+	 * The path to this service description in the service palette. Folders
+	 * will be created for each element of the returned path.
+	 */
+	@Override
+	public List<String> getPath() {
+		// For deeper paths you may return several strings
+		return Arrays.asList("GIS", "WPS " + getOgcServiceUri());
+	}
+
+	/**
+	 * Return a list of data values uniquely identifying this service
+	 * description (to avoid duplicates). Include only primary key like fields,
+	 * ie. ignore descriptions, icons, etc.
+	 */
+	@Override
+	protected List<? extends Object> getIdentifyingData() {
+		// FIXME: Use your fields instead of example fields
+		return Arrays.<Object>asList(ogcServiceUri, processIdentifier);
+	}
+
+	
+	// All fields are searchable in the Service palette,
+	// for instance try a search for exampleString:3
+	private URI ogcServiceUri;
+	private String processIdentifier;
+	
+	public URI getOgcServiceUri() {
+		return ogcServiceUri;
+	}
+	public void setOgcServiceUri(URI ogcServiceUri) {
+		this.ogcServiceUri = ogcServiceUri;
+	}
+	public String getProcessIdentifier() {
+		return processIdentifier;
+	}
+	public void setProcessIdentifier(String processIdentifier) {
+		this.processIdentifier = processIdentifier;
+	}
+
+}
diff --git a/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/serviceprovider/GisServiceIcon.java b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/serviceprovider/GisServiceIcon.java
new file mode 100644
index 0000000..5f56537
--- /dev/null
+++ b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/serviceprovider/GisServiceIcon.java
@@ -0,0 +1,37 @@
+package org.apache.taverna.gis.ui.serviceprovider;
+
+import java.net.URI;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+
+import org.apache.taverna.workbench.activityicons.ActivityIconSPI;
+
+public class GisServiceIcon implements ActivityIconSPI {
+
+	private static final URI ACTIVITY_TYPE = URI
+			.create("http://example.com/2013/activity/apache-taverna-activity-gis");
+
+	private static Icon icon;
+
+	@Override
+	public int canProvideIconScore(URI activityType) {
+		if (ACTIVITY_TYPE.equals(activityType)) {
+			return DEFAULT_ICON + 1;
+		}
+		return NO_ICON;
+	}
+
+	@Override
+	public Icon getIcon(URI activityType) {
+		return getIcon();
+	}
+
+	public static Icon getIcon() {
+		if (icon == null) {
+			icon = new ImageIcon(GisServiceIcon.class.getResource("/exampleIcon.png"));
+		}
+		return icon;
+	}
+
+}
diff --git a/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/serviceprovider/GisServiceProvider.java b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/serviceprovider/GisServiceProvider.java
new file mode 100644
index 0000000..13ad4b2
--- /dev/null
+++ b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/serviceprovider/GisServiceProvider.java
@@ -0,0 +1,184 @@
+package org.apache.taverna.gis.ui.serviceprovider;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.Icon;
+
+import org.apache.taverna.scufl2.api.common.Visitor;
+import org.apache.taverna.scufl2.api.common.WorkflowBean;
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.servicedescriptions.AbstractConfigurableServiceProvider;
+import org.apache.taverna.servicedescriptions.ConfigurableServiceProvider;
+import org.apache.taverna.servicedescriptions.ServiceDescription;
+import org.apache.taverna.servicedescriptions.ServiceDescriptionProvider;
+import org.apache.taverna.servicedescriptions.ServiceDescriptionProvider.FindServiceDescriptionsCallBack;
+import org.apache.taverna.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean;
+import org.apache.taverna.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean;
+import org.n52.wps.client.WPSClientSession;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import net.opengis.wps.x100.InputDescriptionType;
+import net.opengis.wps.x100.OutputDescriptionType;
+import net.opengis.wps.x100.ProcessDescriptionType;
+
+public class GisServiceProvider extends AbstractConfigurableServiceProvider
+		implements ConfigurableServiceProvider {
+
+
+	public GisServiceProvider() {
+		super(defaultConfig());
+		
+	}
+
+	private static Configuration defaultConfig() {
+		Configuration c = new Configuration();
+		ObjectNode conf = c.getJsonAsObjectNode();
+		conf.put("osgiServiceUri", "http://localhost:8080/geoserver/ows");
+		conf.put("processIdentifier", "gs:StringConcatWPS");
+		return c;
+	}
+
+	private static final URI providerId = GisServiceDesc.ACTIVITY_TYPE.resolve("#provider");
+
+	/**
+	 * Do the actual search for services. Return using the callBack parameter.
+	 */
+	@SuppressWarnings("unchecked")
+	public void findServiceDescriptionsAsync(FindServiceDescriptionsCallBack callBack) {
+		// Use callback.status() for long-running searches
+		callBack.status("Resolving GIS services");
+
+		List<ServiceDescription> results = new ArrayList<ServiceDescription>();
+
+		// FIXME: Implement the actual service search/lookup instead
+		// of dummy for-loop
+
+		GisServiceDesc service = new GisServiceDesc();
+		// Populate the service description bean
+		ObjectNode conf = getConfiguration().getJsonAsObjectNode();
+		String serviceUri = conf.get("osgiServiceUri").asText();
+		service.setOgcServiceUri(URI.create(serviceUri));
+		String processIdentifier = conf.get("processIdentifier").asText();
+		service.setProcessIdentifier(processIdentifier);
+
+		// TODO: Optional: set description (Set a better description
+		service.setDescription(processIdentifier);
+
+		// TODO: Exctract in a separate method 
+		// Get input ports
+		
+		WPSClientSession wpsClient = WPSClientSession.getInstance();
+
+        ProcessDescriptionType processDescription;
+		try {
+			processDescription = wpsClient
+			        .getProcessDescription(serviceUri, processIdentifier);
+		
+			InputDescriptionType[] inputList = processDescription.getDataInputs()
+	                .getInputArray();
+
+	        List<ActivityInputPortDefinitionBean> inputPortDefinitions = new ArrayList<ActivityInputPortDefinitionBean>();
+
+	        for (InputDescriptionType input : inputList) {
+	    		ActivityInputPortDefinitionBean newInputPort = new ActivityInputPortDefinitionBean();
+	    		newInputPort.setName(input.getIdentifier().getStringValue());
+	    		newInputPort.setDepth(0);
+	    		newInputPort.setAllowsLiteralValues(true);
+	    		newInputPort.setHandledReferenceSchemes(null);
+	    		newInputPort.setTranslatedElementType(String.class);
+	    		
+	    		inputPortDefinitions.add(newInputPort);
+	    		
+	        }
+	        
+	       // service.setInputPortDefinitions(inputPortDefinitions);
+			
+	        
+	        // Get output ports
+	        
+	        OutputDescriptionType[] outputList = processDescription.getProcessOutputs().getOutputArray();
+	        List<ActivityOutputPortDefinitionBean> outputPortDefinitions = new ArrayList<ActivityOutputPortDefinitionBean>();
+	        
+	        for( OutputDescriptionType output : outputList )
+	        {
+	        	ActivityOutputPortDefinitionBean newOutputPort = new ActivityOutputPortDefinitionBean();
+	        	newOutputPort.setName(output.getIdentifier().getStringValue());
+	        	newOutputPort.setDepth(0);
+	        	
+	        	outputPortDefinitions.add(newOutputPort);
+	        	
+	        }
+		
+	        //service.setOutputPortDefinitions(outputPortDefinitions);
+	        
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        
+		results.add(service);
+
+		// partialResults() can also be called several times from inside
+		// for-loop if the full search takes a long time
+		callBack.partialResults(results);
+
+		// No more results will be coming
+		callBack.finished();
+	}
+	
+	/**
+	 * Icon for service provider
+	 */
+	public Icon getIcon() {
+		return GisServiceIcon.getIcon();
+	}
+
+	/**
+	 * Name of service provider, appears in right click for 'Remove service
+	 * provider'
+	 */
+	public String getName() {
+		return "Geospatial Web Services";
+	}
+
+	@Override
+	public String toString() {
+		return "Geospatial Web Services " + getConfiguration().getJson().get("osgiServiceUri");
+	}
+
+	public String getId() {
+		return providerId.toASCIIString();
+	}
+
+	@Override
+	protected List<? extends Object> getIdentifyingData() {
+		return Arrays.asList(getConfiguration().getJson().get("osgiServiceUri"), 
+				getConfiguration().getJson().get("processIdentifier"));
+	}
+
+	@Override
+	public ServiceDescriptionProvider newInstance() {
+		return new GisServiceProvider();
+	}
+
+	@Override
+	public URI getType() {
+		return providerId;
+	}
+
+	@Override
+	public void setType(URI type) {
+	}
+
+	@Override
+	public boolean accept(Visitor visitor) {
+		return false;
+	}
+
+	
+}
diff --git a/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/view/GisActivityContextViewFactory.java b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/view/GisActivityContextViewFactory.java
new file mode 100644
index 0000000..1a0dc13
--- /dev/null
+++ b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/view/GisActivityContextViewFactory.java
@@ -0,0 +1,59 @@
+package org.apache.taverna.gis.ui.view;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.taverna.services.ServiceRegistry;
+import org.apache.taverna.scufl2.api.activity.Activity;
+
+import org.apache.taverna.servicedescriptions.ServiceDescriptionRegistry;
+import org.apache.taverna.workbench.activityicons.ActivityIconManager;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.ui.views.contextualviews.ContextualView;
+import org.apache.taverna.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+
+public class GisActivityContextViewFactory implements ContextualViewFactory<Activity> {
+
+	private static final URI ACTIVITY_TYPE = URI
+			.create("http://example.com/2013/activity/apache-taverna-activity-gis");
+
+	private EditManager editManager;
+	private FileManager fileManager;
+	private ActivityIconManager activityIconManager;
+	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 selection) {
+		return Arrays.<ContextualView>asList(new GisContextualView(selection, editManager,
+				fileManager, activityIconManager, 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 setServiceDescriptionRegistry(ServiceDescriptionRegistry serviceDescriptionRegistry) {
+		this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+	}
+
+	public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+		this.serviceRegistry = serviceRegistry;
+	}
+
+}
diff --git a/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/view/GisContextualView.java b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/view/GisContextualView.java
new file mode 100644
index 0000000..08fff1f
--- /dev/null
+++ b/apache-taverna-activity-gis-activity-ui/src/main/java/org/apache/taverna/gis/ui/view/GisContextualView.java
@@ -0,0 +1,88 @@
+package org.apache.taverna.gis.ui.view;
+
+import java.awt.Frame;
+
+import javax.swing.Action;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import org.apache.taverna.services.ServiceRegistry;
+
+import org.apache.taverna.servicedescriptions.ServiceDescriptionRegistry;
+import org.apache.taverna.workbench.activityicons.ActivityIconManager;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.ui.actions.activity.ActivityContextualView;
+
+import org.apache.taverna.scufl2.api.activity.Activity;
+
+import org.apache.taverna.gis.ui.config.GisConfigureAction;
+
+@SuppressWarnings("serial")
+public class GisContextualView extends ActivityContextualView {
+
+	private final EditManager editManager;
+	private final FileManager fileManager;
+	private final ActivityIconManager activityIconManager;
+	private final ServiceDescriptionRegistry serviceDescriptionRegistry;
+	private final ServiceRegistry serviceRegistry;
+
+	private JLabel description = new JLabel("ads");
+
+	public GisContextualView(Activity activity, EditManager editManager,
+			FileManager fileManager, ActivityIconManager activityIconManager,
+			ServiceDescriptionRegistry serviceDescriptionRegistry, ServiceRegistry serviceRegistry) {
+		super(activity);
+		this.editManager = editManager;
+		this.fileManager = fileManager;
+		this.activityIconManager = activityIconManager;
+		this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+		this.serviceRegistry = serviceRegistry;
+		initView();
+	}
+
+	@Override
+	public JComponent getMainFrame() {
+		JPanel jPanel = new JPanel();
+		jPanel.add(description);
+		refreshView();
+		return jPanel;
+	}
+
+	@Override
+	public String getViewTitle() {
+		JsonNode configuration = getConfigBean().getJson();
+		return "Gis service " + configuration.get("exampleString").asText();
+	}
+
+	/**
+	 * Typically called when the activity configuration has changed.
+	 */
+	@Override
+	public void refreshView() {
+		JsonNode configuration = getConfigBean().getJson();
+		description.setText("Gis service " + configuration.get("exampleUri").asText()
+				+ " - " + configuration.get("exampleString").asText());
+		// TODO: Might also show extra service information looked
+		// up dynamically from endpoint/registry
+	}
+
+	/**
+	 * View position hint
+	 */
+	@Override
+	public int getPreferredPosition() {
+		// We want to be on top
+		return 100;
+	}
+
+	@Override
+	public Action getConfigureAction(final Frame owner) {
+		return new GisConfigureAction(getActivity(), editManager, fileManager,
+				activityIconManager, serviceDescriptionRegistry, serviceRegistry);
+	}
+
+}
diff --git a/apache-taverna-activity-gis-activity-ui/src/main/resources/META-INF/spring/context-osgi.xml b/apache-taverna-activity-gis-activity-ui/src/main/resources/META-INF/spring/context-osgi.xml
new file mode 100644
index 0000000..4987ea3
--- /dev/null
+++ b/apache-taverna-activity-gis-activity-ui/src/main/resources/META-INF/spring/context-osgi.xml
@@ -0,0 +1,26 @@
+<?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="GisServiceIcon" interface="org.apache.taverna.workbench.activityicons.ActivityIconSPI" />
+
+	<service ref="GisServiceProvider" interface="org.apache.taverna.servicedescriptions.ServiceDescriptionProvider" />
+
+	<service ref="GisConfigureMenuAction" auto-export="interfaces" />
+
+	<service ref="GisActivityContextViewFactory" interface="org.apache.taverna.workbench.ui.views.contextualviews.activity.ContextualViewFactory" />
+
+	<reference id="editManager" interface="org.apache.taverna.workbench.edits.EditManager" />
+	<reference id="fileManager" interface="org.apache.taverna.workbench.file.FileManager" />
+	<reference id="menuManager" interface="org.apache.taverna.ui.menu.MenuManager" />
+	<reference id="selectionManager" interface="org.apache.taverna.workbench.selection.SelectionManager" />
+	<reference id="activityIconManager" interface="org.apache.taverna.workbench.activityicons.ActivityIconManager" />
+	<reference id="colourManager" interface="org.apache.taverna.workbench.configuration.colour.ColourManager" />
+	<reference id="serviceDescriptionRegistry" interface="org.apache.taverna.servicedescriptions.ServiceDescriptionRegistry" />
+	<reference id="serviceRegistry" interface="org.apache.taverna.services.ServiceRegistry" />
+
+</beans:beans>
diff --git a/apache-taverna-activity-gis-activity-ui/src/main/resources/META-INF/spring/context.xml b/apache-taverna-activity-gis-activity-ui/src/main/resources/META-INF/spring/context.xml
new file mode 100644
index 0000000..f0c1255
--- /dev/null
+++ b/apache-taverna-activity-gis-activity-ui/src/main/resources/META-INF/spring/context.xml
@@ -0,0 +1,31 @@
+<?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="GisServiceIcon"
+		class="org.apache.taverna.gis.ui.serviceprovider.GisServiceIcon" />
+
+	<bean id="GisServiceProvider"
+		class="org.apache.taverna.gis.ui.serviceprovider.GisServiceProvider" />
+
+	<bean id="GisConfigureMenuAction"
+		class="org.apache.taverna.gis.ui.menu.GisConfigureMenuAction">
+		<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="GisActivityContextViewFactory"
+		class="org.apache.taverna.gis.ui.view.GisActivityContextViewFactory">
+		<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>
+
+</beans>
diff --git a/apache-taverna-activity-gis-activity-ui/src/main/resources/exampleIcon.png b/apache-taverna-activity-gis-activity-ui/src/main/resources/exampleIcon.png
new file mode 100644
index 0000000..8bb31c3
--- /dev/null
+++ b/apache-taverna-activity-gis-activity-ui/src/main/resources/exampleIcon.png
Binary files differ
diff --git a/apache-taverna-activity-gis-activity/pom.xml b/apache-taverna-activity-gis-activity/pom.xml
new file mode 100644
index 0000000..a118bb5
--- /dev/null
+++ b/apache-taverna-activity-gis-activity/pom.xml
@@ -0,0 +1,57 @@
+<?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>org.apache.taverna.gis</groupId>
+		<artifactId>apache-taverna-activity-gis</artifactId>
+		<version>0.0.1-incubating.SNAPSHOT</version>
+	</parent>
+	<artifactId>apache-taverna-activity-gis-activity</artifactId>
+	<packaging>bundle</packaging>
+	<name>Gis Taverna activity</name>
+
+	<dependencies>
+								<dependency>
+			<groupId>org.apache.taverna.engine</groupId>
+			<artifactId>taverna-workflowmodel-api</artifactId>
+			<version>${taverna.engine.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.engine</groupId>
+			<artifactId>taverna-reference-api</artifactId>
+			<version>${taverna.engine.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-databind</artifactId>
+			<version>2.3.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.4</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.engine</groupId>
+			<artifactId>taverna-workflowmodel-impl</artifactId>
+			<version>${taverna.engine.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.engine</groupId>
+			<artifactId>taverna-activity-test-utils</artifactId>
+			<version>${taverna.engine.version}</version>
+			<scope>test</scope>
+		</dependency>
+		
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-gis-client</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+	</dependencies>
+</project>
diff --git a/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivity.java b/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivity.java
new file mode 100644
index 0000000..aa5c952
--- /dev/null
+++ b/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivity.java
@@ -0,0 +1,157 @@
+package org.apache.taverna.gis;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.ows.ServiceException;
+import org.n52.wps.client.ExecuteRequestBuilder;
+import org.n52.wps.client.ExecuteResponseAnalyser;
+import org.n52.wps.client.WPSClientException;
+import org.n52.wps.client.WPSClientSession;
+import org.n52.wps.io.data.IData;
+import org.n52.wps.io.data.binding.complex.GTVectorDataBinding;
+
+import net.opengis.wps.x100.DataType;
+import net.opengis.wps.x100.ExecuteDocument;
+import net.opengis.wps.x100.ExecuteResponseDocument;
+import net.opengis.wps.x100.OutputDataType;
+import net.opengis.wps.x100.ProcessDescriptionType;
+import org.apache.taverna.invocation.InvocationContext;
+import org.apache.taverna.reference.ReferenceService;
+import org.apache.taverna.reference.T2Reference;
+import org.apache.taverna.workflowmodel.processor.activity.AbstractAsynchronousActivity;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityConfigurationException;
+import org.apache.taverna.workflowmodel.processor.activity.AsynchronousActivity;
+import org.apache.taverna.workflowmodel.processor.activity.AsynchronousActivityCallback;
+import org.apache.taverna.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean;
+import org.apache.taverna.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean;
+
+public class GisActivity extends AbstractAsynchronousActivity<GisActivityConfigurationBean>
+		implements AsynchronousActivity<GisActivityConfigurationBean> {
+	
+	private GisActivityConfigurationBean configBean;
+
+	@Override
+	public void configure(GisActivityConfigurationBean configBean) throws ActivityConfigurationException {
+
+		// TODO: Should I call HealthChecker here??
+		// Any pre-config sanity checks
+		if (configBean.getOgcServiceUri().equals("")) {
+			throw new ActivityConfigurationException("Geospatial web service URI can't be empty");
+		}
+		// Store for getConfiguration()
+		this.configBean = configBean;
+
+		// REQUIRED: (Re)create input/output ports depending on configuration
+		configurePorts();
+	}
+
+	protected void configurePorts() {
+		// In case we are being reconfigured - remove existing ports first
+		// to avoid duplicates
+		removeInputs();
+		removeOutputs();
+
+		// Add input ports
+		for(ActivityInputPortDefinitionBean inputPort : configBean.getInputPortDefinitions())
+		{
+			addInput(inputPort.getName(),inputPort.getDepth(),inputPort.getAllowsLiteralValues(),inputPort.getHandledReferenceSchemes(), inputPort.getTranslatedElementType());
+		}
+		
+		// Add output ports
+		for(ActivityOutputPortDefinitionBean outputPort : configBean.getOutputPortDefinitions())
+		{
+			addOutput(outputPort.getName(),outputPort.getDepth());
+		}
+		
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public void executeAsynch(final Map<String, T2Reference> inputs, final AsynchronousActivityCallback callback) {
+		// Execute service asynchronously
+		callback.requestRun(new Runnable() {
+
+			public void run() {
+				InvocationContext context = callback.getContext();
+				ReferenceService referenceService = context.getReferenceService();
+
+				// Declare outputs variable
+				Map<String, T2Reference> outputs = null;
+				
+				try {
+					
+					// prepare the execute object
+					WPSClientSession wpsClient = WPSClientSession.getInstance();
+
+					ProcessDescriptionType processDescription = wpsClient.getProcessDescription(configBean.getOgcServiceUri().toString(), configBean.getProcessIdentifier());
+					
+					ExecuteRequestBuilder executeBuilder = new ExecuteRequestBuilder(processDescription);
+
+					for (ActivityInputPortDefinitionBean activityInputPort : configBean.getInputPortDefinitions()) {
+						String portValue = (String) referenceService.renderIdentifier(inputs.get(activityInputPort.getName()), String.class, context);
+						executeBuilder.addLiteralData(activityInputPort.getName(), portValue);
+					}
+				
+					ExecuteDocument execute = executeBuilder.getExecute();
+			
+					execute.getExecute().setService("WPS");
+					
+					Object responseObject = null;
+					
+					try {
+						// execute service
+						responseObject = wpsClient.execute(configBean.getOgcServiceUri().toString(), execute);
+					} catch (WPSClientException e) {
+						// if the an error return from service
+						callback.fail(e.getServerException().xmlText());
+					}
+
+					// Register outputs
+					outputs = new HashMap<String, T2Reference>();
+					T2Reference simpleRef = null;
+					
+					if (responseObject instanceof ExecuteResponseDocument) {
+			            ExecuteResponseDocument response = (ExecuteResponseDocument) responseObject;
+			            
+			            // analyser is used to get complex data
+			            ExecuteResponseAnalyser analyser = new ExecuteResponseAnalyser(
+			                    execute, response, processDescription);
+			            
+			            for(OutputDataType output : response.getExecuteResponse().getProcessOutputs().getOutputArray())
+						{
+			            	DataType data = output.getData();
+			            	
+			            	if (data.isSetLiteralData())
+							{
+			            		simpleRef = referenceService.register(data.getLiteralData().getStringValue(), 0, true, context);
+
+								outputs.put(output.getIdentifier().getStringValue(), simpleRef);
+							}
+			            	
+						}
+			            
+			        }
+					
+					
+				} catch (WPSClientException e) {
+					callback.fail(e.getMessage());
+				} catch (IOException e) {
+					callback.fail(e.getMessage());
+				}
+
+				callback.receiveResult(outputs, new int[0]);
+			}
+		});
+	}
+
+	@Override
+	public GisActivityConfigurationBean getConfiguration() {
+		return this.configBean;
+	}
+
+}
diff --git a/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivityConfigurationBean.java b/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivityConfigurationBean.java
new file mode 100644
index 0000000..31d193b
--- /dev/null
+++ b/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivityConfigurationBean.java
@@ -0,0 +1,52 @@
+package org.apache.taverna.gis;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.List;
+
+import net.opengis.wps.x100.InputDescriptionType;
+import net.opengis.wps.x100.OutputDescriptionType;
+import org.apache.taverna.workflowmodel.processor.activity.config.ActivityPortsDefinitionBean;
+
+/**
+ * Gis activity configuration bean.
+ * 
+ */
+public class GisActivityConfigurationBean extends ActivityPortsDefinitionBean implements Serializable {
+
+	/*
+	 * TODO: Remove this comment. Should the jackson ojbect be managed in this class?
+	 * 
+	 * The configuration specifies the variable options and configurations for
+	 * an activity that has been added to a workflow. For instance for a WSDL
+	 * activity, the configuration contains the URL for the WSDL together with
+	 * the method name. String constant configurations contain the string that
+	 * is to be returned, while Beanshell script configurations contain both the
+	 * scripts and the input/output ports (by subclassing
+	 * ActivityPortsDefinitionBean).
+	 * 
+	 * Configuration beans are serialised as XML (currently by using XMLBeans)
+	 * when Taverna is saving the workflow definitions. Therefore the
+	 * configuration beans need to follow the JavaBeans style and only have
+	 * fields of 'simple' types such as Strings, integers, etc. Other beans can
+	 * be referenced as well, as long as they are part of the same plugin.
+	 */
+	
+
+	private URI ogcServiceUri;
+	private String processIdentifier;
+	
+	public URI getOgcServiceUri() {	
+		return ogcServiceUri;
+	}
+	public void setOgcServiceUri(URI ogcServiceUri) {
+		this.ogcServiceUri = ogcServiceUri;
+	}
+	public String getProcessIdentifier() {
+		return processIdentifier;
+	}
+	public void setProcessIdentifier(String processIdentifier) {
+		this.processIdentifier = processIdentifier;
+	}
+
+}
diff --git a/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivityExample.java b/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivityExample.java
new file mode 100644
index 0000000..e533b43
--- /dev/null
+++ b/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivityExample.java
@@ -0,0 +1,132 @@
+package org.apache.taverna.gis;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import org.apache.taverna.invocation.InvocationContext;
+import org.apache.taverna.reference.ReferenceService;
+import org.apache.taverna.reference.T2Reference;
+import org.apache.taverna.workflowmodel.processor.activity.AbstractAsynchronousActivity;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityConfigurationException;
+import org.apache.taverna.workflowmodel.processor.activity.AsynchronousActivity;
+import org.apache.taverna.workflowmodel.processor.activity.AsynchronousActivityCallback;
+
+/**
+ * Gis <code>Activity<code>.
+ */
+public class GisActivityExample extends AbstractAsynchronousActivity<JsonNode>
+		implements AsynchronousActivity<JsonNode> {
+
+	public static final String ACTIVITY_TYPE = "http://example.com/2013/activity/apache-taverna-activity-gis";
+
+	/*
+	 * Best practice: Keep port names as constants to avoid misspelling. This
+	 * would not apply if port names are looked up dynamically from the service
+	 * operation, like done for WSDL services.
+	 */
+	public static final String IN_FIRST_INPUT = "firstInput";
+	public static final String IN_EXTRA_DATA = "extraData";
+	public static final String OUT_MORE_OUTPUTS = "moreOutputs";
+	public static final String OUT_SIMPLE_OUTPUT = "simpleOutput";
+	public static final String OUT_REPORT = "report";
+
+	private JsonNode configuration;
+
+	@Override
+	public void configure(JsonNode configuration) throws ActivityConfigurationException {
+
+		// Any pre-config sanity checks
+		if (configuration.get("exampleString").asText().equals("invalidExample")) {
+			throw new ActivityConfigurationException(
+					"Example string can't be 'invalidExample'");
+		}
+		// Store for getConfiguration(), but you could also make
+		// getConfiguration() return a new bean from other sources
+		this.configuration = configuration;
+
+		// OPTIONAL:
+		// Do any server-side lookups and configuration, like resolving WSDLs
+
+		// myClient = new MyClient(configuration.get("exampleUri").asText());
+		// this.service = myClient.getService(configuration.get("exampleString").asText());
+
+	}
+
+	@Override
+	public JsonNode getConfiguration() {
+		return configuration;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public void executeAsynch(final Map<String, T2Reference> inputs,
+			final AsynchronousActivityCallback callback) {
+		// Don't execute service directly now, request to be run ask to be run
+		// from thread pool and return asynchronously
+		callback.requestRun(new Runnable() {
+
+			public void run() {
+				InvocationContext context = callback
+						.getContext();
+				ReferenceService referenceService = context
+						.getReferenceService();
+				// Resolve inputs
+				String firstInput = (String) referenceService.renderIdentifier(inputs.get(IN_FIRST_INPUT),
+						String.class, context);
+
+				// Support our configuration-dependendent input
+				boolean optionalPorts = configuration.get("exampleString").asText().equals("specialCase");
+
+				List<byte[]> special = null;
+				// We'll also allow IN_EXTRA_DATA to be optionally not provided
+				if (optionalPorts && inputs.containsKey(IN_EXTRA_DATA)) {
+					// Resolve as a list of byte[]
+					special = (List<byte[]>) referenceService.renderIdentifier(
+							inputs.get(IN_EXTRA_DATA), byte[].class, context);
+				}
+
+
+				// TODO: Do the actual service invocation
+//				try {
+//					results = this.service.invoke(firstInput, special)
+//				} catch (ServiceException ex) {
+//					callback.fail("Could not invoke Gis service " + configBean.getExampleUri(),
+//							ex);
+//					// Make sure we don't call callback.receiveResult later
+//					return;
+//				}
+
+				// Register outputs
+				Map<String, T2Reference> outputs = new HashMap<>();
+				String simpleValue = "simple";
+				T2Reference simpleRef = referenceService.register(simpleValue, 0, true, context);
+				outputs.put(OUT_SIMPLE_OUTPUT, simpleRef);
+
+				// For list outputs, only need to register the top level list
+				List<String> moreValues = new ArrayList<>();
+				moreValues.add("Value 1");
+				moreValues.add("Value 2");
+				T2Reference moreRef = referenceService.register(moreValues, 1, true, context);
+				outputs.put(OUT_MORE_OUTPUTS, moreRef);
+
+				if (optionalPorts) {
+					// Populate our optional output port
+					// NOTE: Need to return output values for all defined output ports
+					String report = "Everything OK";
+					outputs.put(OUT_REPORT, referenceService.register(report,
+							0, true, context));
+				}
+
+				// return map of output data, with empty index array as this is
+				// the only and final result (this index parameter is used if
+				// pipelining output)
+				callback.receiveResult(outputs, new int[0]);
+			}
+		});
+	}
+
+}
diff --git a/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivityFactory.java b/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivityFactory.java
new file mode 100644
index 0000000..540dd3d
--- /dev/null
+++ b/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivityFactory.java
@@ -0,0 +1,94 @@
+package org.apache.taverna.gis;
+
+import static org.apache.taverna.gis.GisActivity.*;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.apache.taverna.workflowmodel.Edits;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityFactory;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityInputPort;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityOutputPort;
+
+/**
+ * Gis <code>ActivityFactory<code>.
+ */
+public class GisActivityFactory implements ActivityFactory {
+
+	private Edits edits;
+
+	@Override
+	public GisActivity createActivity() {
+		return new GisActivity();
+	}
+
+	@Override
+	public URI getActivityType() {
+		return URI.create(GisActivity.ACTIVITY_TYPE);
+	}
+
+	@Override
+	public JsonNode getActivityConfigurationSchema() {
+		ObjectMapper objectMapper = new ObjectMapper();
+		try {
+			return objectMapper.readTree(getClass().getResource("/schema.json"));
+		} catch (IOException e) {
+			return objectMapper.createObjectNode();
+		}
+	}
+
+	@Override
+	public Set<ActivityInputPort> getInputPorts(JsonNode configuration) {
+		Set<ActivityInputPort> inputPorts = new HashSet<>();
+
+		// FIXME: Replace with your input port definitions
+
+		// Hard coded input port, expecting a single String
+		inputPorts.add(edits.createActivityInputPort(IN_FIRST_INPUT, 0, true, null, String.class));
+
+		// Optional ports depending on configuration
+		if (configuration.get("exampleString").asText().equals("specialCase")) {
+			// depth 1, ie. list of binary byte[] arrays
+			inputPorts.add(edits.createActivityInputPort(IN_EXTRA_DATA, 1, true, null, byte[].class));
+		}
+
+		return inputPorts;
+	}
+
+	@Override
+	public Set<ActivityOutputPort> getOutputPorts(JsonNode configuration) {
+		Set<ActivityOutputPort> outputPorts = new HashSet<>();
+
+		// FIXME: Replace with your output port definitions
+
+		// Optional ports depending on configuration
+		if (configuration.get("exampleString").asText().equals("specialCase")) {
+			outputPorts.add(edits.createActivityOutputPort(OUT_REPORT, 0, 0));
+		}
+
+		// Single value output port (depth 0)
+		outputPorts.add(edits.createActivityOutputPort(OUT_SIMPLE_OUTPUT, 0, 0));
+		// Output port with list of values (depth 1)
+		outputPorts.add(edits.createActivityOutputPort(OUT_MORE_OUTPUTS, 1, 1));
+
+		return outputPorts;
+	}
+
+	/**
+	 * Sets the edits property.
+	 * <p>
+	 * This method is used by Spring. The property name must match the property specified
+	 * in the Spring context file.
+	 *
+	 * @param edits the <code>Edits</code> used to create input/output ports
+	 */
+	public void setEdits(Edits edits) {
+		this.edits = edits;
+	}
+
+}
diff --git a/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivityHealthChecker.java b/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivityHealthChecker.java
new file mode 100644
index 0000000..9e143b5
--- /dev/null
+++ b/apache-taverna-activity-gis-activity/src/main/java/org/apache/taverna/gis/GisActivityHealthChecker.java
@@ -0,0 +1,63 @@
+package org.apache.taverna.gis;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import org.apache.taverna.visit.VisitReport;
+import org.apache.taverna.visit.VisitReport.Status;
+import org.apache.taverna.workflowmodel.health.HealthCheck;
+import org.apache.taverna.workflowmodel.health.HealthChecker;
+
+/**
+ * Gis <code>HealthChecker</code>.
+ */
+public class GisActivityHealthChecker implements
+		HealthChecker<GisActivity> {
+
+	public boolean canVisit(Object o) {
+		// Return True if we can visit the object. We could do
+		// deeper (but not time consuming) checks here, for instance
+		// if the health checker only deals with GisActivity where
+		// a certain configuration option is enabled.
+		return o instanceof GisActivity;
+	}
+
+	public boolean isTimeConsuming() {
+		// Return true if the health checker does a network lookup
+		// or similar time consuming checks, in which case
+		// it would only be performed when using File->Validate workflow
+		// or File->Run.
+		return false;
+	}
+
+	public VisitReport visit(GisActivity activity, List<Object> ancestry) {
+		JsonNode config = activity.getConfiguration();
+
+		// We'll build a list of subreports
+		List<VisitReport> subReports = new ArrayList<>();
+
+		if (!URI.create(config.get("exampleUri").asText()).isAbsolute()) {
+			// Report Severe problems we know won't work
+			VisitReport report = new VisitReport(HealthCheck.getInstance(),
+					activity, "Example URI must be absolute", HealthCheck.INVALID_URL,
+					Status.SEVERE);
+			subReports.add(report);
+		}
+
+		if (config.get("exampleString").asText().equals("")) {
+			// Warning on possible problems
+			subReports.add(new VisitReport(HealthCheck.getInstance(), activity,
+					"Example string empty", HealthCheck.NO_CONFIGURATION,
+					Status.WARNING));
+		}
+
+		// The default explanation here will be used if the subreports list is
+		// empty
+		return new VisitReport(HealthCheck.getInstance(), activity,
+				"Gis service OK", HealthCheck.NO_PROBLEM, subReports);
+	}
+
+}
diff --git a/apache-taverna-activity-gis-activity/src/main/resources/schema.json b/apache-taverna-activity-gis-activity/src/main/resources/schema.json
new file mode 100644
index 0000000..1e396b3
--- /dev/null
+++ b/apache-taverna-activity-gis-activity/src/main/resources/schema.json
@@ -0,0 +1,25 @@
+{
+    "$schema": "http://json-schema.org/draft-03/schema#",
+    "id": "http://example.com/2013/activity/apache-taverna-activity-gis.schema.json",
+    "title": "Gis activity configuration",
+    "type": "object",
+    "properties": {
+        "@context": {
+            "description": "JSON-LD context for interpreting the configuration as RDF",
+            "required": true,
+            "enum": ["http://example.com/2013/activity/apache-taverna-activity-gis.context.json"]
+        },
+        "exampleString": {
+            "title": "Example String",
+            "description": "An example string property",
+            "type": "string",
+            "required": true
+        },
+        "exampleUri": {
+            "title": "Example URI",
+            "description": "An example uri property",
+            "type": "string",
+            "required": true
+        }
+    }
+}
diff --git a/apache-taverna-activity-gis-activity/src/main/resources/spring/context-osgi.xml b/apache-taverna-activity-gis-activity/src/main/resources/spring/context-osgi.xml
new file mode 100644
index 0000000..1b2a8c3
--- /dev/null
+++ b/apache-taverna-activity-gis-activity/src/main/resources/spring/context-osgi.xml
@@ -0,0 +1,17 @@
+<?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">
+
+	<!-- Services to be registered with the OSGi service register -->
+	<service ref="GisActivityHealthChecker" interface="org.apache.taverna.workflowmodel.health.HealthChecker" />
+
+	<service ref="GisActivityFactory" interface="org.apache.taverna.workflowmodel.processor.activity.ActivityFactory" />
+
+	<!-- References to services required from the OSGi service register -->
+	<reference id="edits" interface="org.apache.taverna.workflowmodel.Edits" />
+
+</beans:beans>
diff --git a/apache-taverna-activity-gis-activity/src/main/resources/spring/context.xml b/apache-taverna-activity-gis-activity/src/main/resources/spring/context.xml
new file mode 100644
index 0000000..e2b290e
--- /dev/null
+++ b/apache-taverna-activity-gis-activity/src/main/resources/spring/context.xml
@@ -0,0 +1,12 @@
+<?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="GisActivityHealthChecker" class="org.apache.taverna.gis.GisActivityHealthChecker" />
+
+	<bean id="GisActivityFactory" class="org.apache.taverna.gis.GisActivityFactory">
+		<property name="edits" ref="edits" />
+	</bean>
+
+</beans>
diff --git a/apache-taverna-activity-gis-activity/src/main/resources/wps_config.xml b/apache-taverna-activity-gis-activity/src/main/resources/wps_config.xml
new file mode 100644
index 0000000..cd73904
--- /dev/null
+++ b/apache-taverna-activity-gis-activity/src/main/resources/wps_config.xml
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<WPSConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://n52.org/wps https://raw.githubusercontent.com/52North/wps-config/52n-wps-config-1.2.1/src/main/xsd/schema_v2.xsd" xmlns="http://n52.org/wps">
+	<Datahandlers>
+		<ParserList>
+			<Parser name="WCPSQueryParser"
+				className="org.n52.wps.io.datahandler.parser.WCPSQueryParser"
+				active="true">
+				<Format mimetype="text/plain"
+					schema="http://schemas.opengis.net/wcps/1.0/wcpsAll.xsd" />
+			</Parser>
+			<Parser name="WKTParser"
+				className="org.n52.wps.io.datahandler.parser.WKTParser"
+				active="true">
+				<Format mimetype="application/wkt"/>
+			</Parser>
+			<Parser name="GenericXMLDataParser"
+				className="org.n52.wps.io.datahandler.parser.GenericXMLDataParser"
+				active="true">
+				<Format mimetype="text/xml" />
+				<Format mimetype="text/xml; subtype=gml/2.1.2"
+					schema="http://schemas.opengis.net/gml/2.1.2/feature.xsd" />
+			</Parser>
+			<Parser name="GenericFileParser"
+				className="org.n52.wps.io.datahandler.parser.GenericFileParser"
+				active="true">
+				<Format mimetype="application/x-zipped-shp" />
+				<Format mimetype="application/img" />
+				<Format mimetype="image/tiff" />
+				<Format mimetype="image/geotiff" />
+				<Format mimetype="application/geotiff" />
+				<Format mimetype="application/dbase" />
+				<Format mimetype="application/remap" />
+				<Format mimetype="application/x-erdas-hfa" />
+				<Format mimetype="application/x-netcdf" />
+				<Format mimetype="application/dgn" />
+				<Format mimetype="image/jpeg" />
+				<Format mimetype="image/png" />
+				<Format mimetype="application/x-geotiff" />
+				<Format mimetype="application/hdf4-eos" />
+				<Format mimetype="text/plain" />
+				<Format mimetype="application/rData" />
+				<Format mimetype="application/rData+Spatial" />
+				<Format mimetype="application/rData+SpatialPoints" />
+				<Format mimetype="application/rData+SpatialPolygons" />
+				<Format mimetype="text/html" />
+
+				<Format mimetype="application/rData" encoding="base64" />
+				<Format mimetype="application/rData+Spatial" encoding="base64" />
+				<Format mimetype="application/rData+SpatialPoints" encoding="base64" />
+				<Format mimetype="application/rData+SpatialPolygons" encoding="base64" />
+				<Format mimetype="application/x-zipped-shp" encoding="base64" />
+				<Format mimetype="application/img" encoding="base64" />
+				<Format mimetype="image/tiff" encoding="base64" />
+				<Format mimetype="application/geotiff" encoding="base64" />
+				<Format mimetype="application/dbase" encoding="base64" />
+				<Format mimetype="application/remap" encoding="base64" />
+				<Format mimetype="application/x-erdas-hfa" encoding="base64" />
+				<Format mimetype="application/x-netcdf" encoding="base64" />
+				<Format mimetype="application/dgn" encoding="base64" />
+				<Format mimetype="image/jpeg" encoding="base64" />
+				<Format mimetype="image/png" encoding="base64" />
+				<Format mimetype="application/x-geotiff" encoding="base64" />
+				<Format mimetype="application/hdf4-eos" encoding="base64" />
+				<Format mimetype="text/plain" encoding="base64" />
+			</Parser>
+		</ParserList>
+		<GeneratorList>			
+			<Generator name="WKTGenerator"
+				className="org.n52.wps.io.datahandler.generator.WKTGenerator"
+				active="true">
+				<Format mimetype="application/wkt"/>
+			</Generator>
+			<Generator name="GenericXMLDataGenerator"
+				className="org.n52.wps.io.datahandler.generator.GenericXMLDataGenerator"
+				active="true">
+				<Format mimetype="text/xml" />
+				<Format mimetype="text/xml; subtype=gml/2.1.2"
+					schema="http://schemas.opengis.net/gml/2.1.2/feature.xsd" />
+			</Generator>
+			<Generator name="GenericFileGenerator"
+				className="org.n52.wps.io.datahandler.generator.GenericFileGenerator"
+				active="true">
+				<Format mimetype="application/x-zipped-shp" encoding="base64" />
+				<Format mimetype="application/shp" encoding="base64" />
+				<Format mimetype="application/img" encoding="base64" />
+				<Format mimetype="image/tiff" encoding="base64" />
+				<Format mimetype="image/geotiff" encoding="base64" />
+				<Format mimetype="application/geotiff" encoding="base64" />
+				<Format mimetype="application/dbase" encoding="base64" />
+				<Format mimetype="application/remap" encoding="base64" />
+				<Format mimetype="application/x-erdas-hfa" encoding="base64" />
+				<Format mimetype="application/x-netcdf" encoding="base64" />
+				<Format mimetype="application/netcdf" encoding="base64" />
+				<Format mimetype="application/dgn" encoding="base64" />
+				<Format mimetype="image/jpeg" encoding="base64" />
+				<Format mimetype="image/png" encoding="base64" />
+				<Format mimetype="application/x-geotiff" encoding="base64" />
+				<Format mimetype="text/plain" encoding="base64" />
+				<Format mimetype="application/x-zipped-shp" encoding="base64" />
+				<Format mimetype="application/rData" encoding="base64" />
+				<Format mimetype="application/rData+Spatial" encoding="base64" />
+				<Format mimetype="application/rData+SpatialPoints" encoding="base64" />
+				<Format mimetype="application/rData+SpatialPolygons" encoding="base64" />
+				
+				<Format mimetype="application/rData" />
+				<Format mimetype="application/rData+Spatial" />
+				<Format mimetype="application/rData+SpatialPoints" />
+				<Format mimetype="application/rData+SpatialPolygons" />
+				<Format mimetype="application/x-zipped-shp" />
+				<Format mimetype="application/shp" />
+				<Format mimetype="application/img" />
+				<Format mimetype="image/tiff" />
+				<Format mimetype="image/geotiff" />
+				<Format mimetype="application/geotiff" />
+				<Format mimetype="application/dbase" />
+				<Format mimetype="application/remap" />
+				<Format mimetype="application/x-erdas-hfa" />
+				<Format mimetype="application/x-netcdf" />
+				<Format mimetype="application/netcdf" />
+				<Format mimetype="application/dgn" />
+				<Format mimetype="image/jpeg" />
+				<Format mimetype="image/png" />
+				<Format mimetype="application/x-geotiff" />
+				<Format mimetype="text/plain" />
+				<Format mimetype="application/pdf" />
+				<Format mimetype="application/zip" />
+				<Format mimetype="text/html" />
+			</Generator>
+		</GeneratorList>
+	</Datahandlers>
+	<AlgorithmRepositoryList>
+		<Repository name="LocalAlgorithmRepository"
+			className="org.n52.wps.server.LocalAlgorithmRepository" active="true">
+			<Property name="Algorithm" active="true">org.n52.wps.server.algorithm.JTSConvexHullAlgorithm</Property>
+			<Property name="Algorithm" active="true">org.n52.wps.server.algorithm.test.DummyTestClass</Property>
+			<Property name="Algorithm" active="true">org.n52.wps.server.algorithm.test.LongRunningDummyTestClass</Property>
+			<Property name="Algorithm" active="true">org.n52.wps.server.algorithm.test.MultipleComplexInAndOutputsDummyTestClass</Property>
+			<Property name="Algorithm" active="true">org.n52.wps.server.algorithm.test.MultiReferenceInputAlgorithm</Property>
+			<Property name="Algorithm" active="true">org.n52.wps.server.algorithm.test.MultiReferenceBinaryInputAlgorithm</Property>
+			<Property name="Algorithm" active="true">org.n52.wps.server.algorithm.test.EchoProcess</Property>
+		</Repository>
+		<Repository name="UploadedAlgorithmRepository"
+			className="org.n52.wps.server.UploadedAlgorithmRepository" active="false">
+		</Repository>
+		<Repository name="ServiceLoaderAlgorithmRepository"
+			className="org.n52.wps.server.ServiceLoaderAlgorithmRepository" active="true">
+		</Repository>
+		<!--
+		<Repository name="MCProcessRepository" className="org.n52.wps.mc.MCProcessRepository" active="true">
+			<Property name="REMOTE_REPOSITORY" active="false">http://141.30.100.178/gpfeed2/gpfeed.xml</Property>
+			<Property name="LOCAL_REPOSITORY" active="true">D:\MCpackages</Property>
+		</Repository>
+		-->
+  </AlgorithmRepositoryList>
+	<RemoteRepositoryList />
+
+	<Server protocol="http" hostname="localhost" hostport="8080"
+		includeDataInputsInResponse="false" computationTimeoutMilliSeconds="5"
+		cacheCapabilites="false" webappPath="wps" repoReloadInterval="0" maxPoolSize="20" keepAliveSeconds="1000" maxQueuedTasks="100" minPoolSize="10" >
+		<!-- Setting to 'true' will enable filtering of responses documents.  Any server URL in
+             the response document will be replaced with the server URL used in the HTTP request. -->
+        <Property name="responseURLFilterEnabled" active="true">false</Property>
+		<Database>
+			<!-- NOTE: database wipe is only implemented for the FlatFileDatabase (the default) -->
+			<!-- enable database wiping base on values below -->
+			<Property name="wipe.enabled" active="true">true</Property>
+			<!-- scans database every 1 hour -->
+			<Property name="wipe.period" active="true">PT1H</Property>
+			<!-- deletes files older than 7 days -->
+			<Property name="wipe.threshold" active="true">P7D</Property>
+		</Database>
+
+        <!--
+            POSTGRES Connector
+            ==================
+            Ensure that the postgres driver is available to the server during
+            launch. The server will fail to start if Postgres is active but the
+            driver is missing. However, if the driver exists and the database
+            cannot be connected to (unavailable, username/pass issue, etc), the
+            framework will fail-over to the Flatfile Database
+            jndiName or username/password: If jndiName exists, username
+            and password are not used.
+            saveResultsToDb: Setting to false will save results output to file
+            and put the URI link to the file in the database. Setting to true
+            stores the actual result output in the database (You probably don't
+            want this if you have large results).
+            JNDI Configuration:
+            <Database>
+                <Property active="true" name="databaseClass">org.n52.wps.server.database.PostgresDatabase</Property>
+                <Property active="true" name="jndiName">jndiname</Property>
+                <Property active="true" name="saveResultsToDb">false</Property>
+                <Property name="wipe.enabled" active="true">true</Property>
+                <Property name="wipe.period" active="true">PT1H</Property>
+                <Property name="wipe.threshold" active="true">P7D</Property>
+            </Database>
+            Direct connection configuration:
+            <Database>
+                Alternative connection method
+                <Property active="true" name="databaseName">postgres</Property>
+                <Property active="true" name="databasePath">//localhost:5432</Property>
+                <Property active="true" name="username">username</Property>
+                <Property active="true" name="password">password</Property>
+                <Property active="true" name="saveResultsToDb">false</Property>
+                <Property name="wipe.enabled" active="true">true</Property>
+                <Property name="wipe.period" active="true">PT1H</Property>
+                <Property name="wipe.threshold" active="true">P7D</Property>
+            </Database>
+-->
+
+	</Server>
+</WPSConfiguration>
\ No newline at end of file
diff --git a/apache-taverna-activity-gis-activity/src/test/java/org/apache/taverna/gis/GisActivityFactoryTest.java b/apache-taverna-activity-gis-activity/src/test/java/org/apache/taverna/gis/GisActivityFactoryTest.java
new file mode 100644
index 0000000..4b137c6
--- /dev/null
+++ b/apache-taverna-activity-gis-activity/src/test/java/org/apache/taverna/gis/GisActivityFactoryTest.java
@@ -0,0 +1,100 @@
+package org.apache.taverna.gis;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import org.apache.taverna.workflowmodel.impl.EditsImpl;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityInputPort;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityOutputPort;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class GisActivityFactoryTest {
+
+	private ObjectNode configuration;
+
+	private GisActivityFactory activityFactory;
+
+	@Before
+	public void setUp() throws Exception {
+		configuration = JsonNodeFactory.instance.objectNode();
+		configuration.put("exampleString", "something");
+		configuration.put("exampleUri", "http://localhost:8080/myEndPoint");
+
+		activityFactory = new GisActivityFactory();
+		activityFactory.setEdits(new EditsImpl());
+	}
+
+	@Test
+	public void testCreateActivity() {
+		GisActivity activity = activityFactory.createActivity();
+		assertNotNull(activity);
+		assertNotSame(activity, activityFactory.createActivity());
+	}
+
+	@Test
+	public void testGetActivityURI() {
+		assertEquals(URI.create(GisActivity.ACTIVITY_TYPE), activityFactory.getActivityType());
+	}
+
+	@Test
+	public void testGetActivityConfigurationSchema() {
+		JsonNode configurationSchema = activityFactory.getActivityConfigurationSchema();
+		assertNotNull(configurationSchema);
+		assertTrue(configurationSchema.has("properties"));
+		JsonNode propertiesNode = configurationSchema.get("properties");
+		assertTrue(propertiesNode.has("exampleString"));
+		assertTrue(propertiesNode.has("exampleUri"));
+	}
+
+	@Test
+	public void testGetInputPorts() {
+		Set<String> expectedInputs = new HashSet<String>();
+		expectedInputs.add("firstInput");
+
+		Set<ActivityInputPort> inputPorts = activityFactory.getInputPorts(configuration);
+		assertEquals("Unexpected inputs", expectedInputs.size(), inputPorts.size());
+		for (ActivityInputPort inputPort : inputPorts) {
+			assertTrue("Wrong input : " + inputPort.getName(), expectedInputs
+					.remove(inputPort.getName()));
+		}
+
+		ObjectNode specialConfiguration = JsonNodeFactory.instance.objectNode();
+		specialConfiguration.put("exampleString", "specialCase");
+		specialConfiguration.put("exampleUri", "http://localhost:8080/myEndPoint");
+
+		assertEquals("Unexpected inputs", 2, activityFactory.getInputPorts(specialConfiguration).size());
+	}
+
+	@Test
+	public void testGetOutputPorts() {
+		Set<String> expectedOutputs = new HashSet<String>();
+		expectedOutputs.add("simpleOutput");
+		expectedOutputs.add("moreOutputs");
+
+		Set<ActivityOutputPort> outputPorts = activityFactory.getOutputPorts(configuration);
+		assertEquals("Unexpected outputs", expectedOutputs.size(), outputPorts.size());
+		for (ActivityOutputPort outputPort : outputPorts) {
+			assertTrue("Wrong output : " + outputPort.getName(),
+					expectedOutputs.remove(outputPort.getName()));
+		}
+
+		ObjectNode specialConfiguration = JsonNodeFactory.instance.objectNode();
+		specialConfiguration.put("exampleString", "specialCase");
+		specialConfiguration.put("exampleUri", "http://localhost:8080/myEndPoint");
+
+		assertEquals("Unexpected outputs", 3, activityFactory.getOutputPorts(specialConfiguration).size());
+	}
+
+}
diff --git a/apache-taverna-activity-gis-activity/src/test/java/org/apache/taverna/gis/GisActivityTest.java b/apache-taverna-activity-gis-activity/src/test/java/org/apache/taverna/gis/GisActivityTest.java
new file mode 100644
index 0000000..1134774
--- /dev/null
+++ b/apache-taverna-activity-gis-activity/src/test/java/org/apache/taverna/gis/GisActivityTest.java
@@ -0,0 +1,73 @@
+package org.apache.taverna.gis;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import org.apache.taverna.activities.testutils.ActivityInvoker;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityConfigurationException;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityInputPort;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityOutputPort;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class GisActivityTest {
+
+	private ObjectNode configuration;
+
+	private GisActivity activity = new GisActivity();
+
+	@Before
+	public void makeConfiguration() throws Exception {
+		configuration = JsonNodeFactory.instance.objectNode();
+		configuration.put("exampleString", "something");
+		configuration.put("exampleUri", "http://localhost:8080/myEndPoint");
+	}
+
+	@Test
+	public void configureActivity() throws Exception {
+		activity.configure(configuration);
+		assertTrue(configuration.equals(activity.getConfiguration()));
+	}
+
+	@Test(expected = ActivityConfigurationException.class)
+	public void invalidConfiguration() throws ActivityConfigurationException {
+		ObjectNode invalidBean = JsonNodeFactory.instance.objectNode();
+		invalidBean.put("exampleString", "invalidExample");
+		// Should throw ActivityConfigurationException
+		activity.configure(invalidBean);
+	}
+
+	@Test
+	public void executeAsynch() throws Exception {
+		activity.configure(configuration);
+
+		Map<String, Object> inputs = new HashMap<String, Object>();
+		inputs.put("firstInput", "hello");
+
+		Map<String, Class<?>> expectedOutputTypes = new HashMap<String, Class<?>>();
+		expectedOutputTypes.put("simpleOutput", String.class);
+		expectedOutputTypes.put("moreOutputs", String.class);
+
+		Map<String, Object> outputs = ActivityInvoker.invokeAsyncActivity(
+				activity, inputs, expectedOutputTypes);
+
+		assertEquals("Unexpected outputs", 2, outputs.size());
+		assertEquals("simple", outputs.get("simpleOutput"));
+		assertEquals(Arrays.asList("Value 1", "Value 2"), outputs
+				.get("moreOutputs"));
+
+	}
+
+}
diff --git a/apache-taverna-activity-gis-plugin/pom.xml b/apache-taverna-activity-gis-plugin/pom.xml
new file mode 100644
index 0000000..ebc2cd5
--- /dev/null
+++ b/apache-taverna-activity-gis-plugin/pom.xml
@@ -0,0 +1,28 @@
+<?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>org.apache.taverna.gis</groupId>
+		<artifactId>apache-taverna-activity-gis</artifactId>
+		<version>0.0.1-incubating.SNAPSHOT</version>
+	</parent>
+	<artifactId>apache-taverna-activity-gis-plugin</artifactId>
+	<packaging>taverna-plugin</packaging>
+	<name>Gis Taverna plugin</name>
+	<description>Description of Example Taverna plugin</description>
+	<dependencies>
+		<dependency>
+			<groupId>${project.groupId}</groupId>
+			<artifactId>apache-taverna-activity-gis-activity</artifactId>
+			<version>0.0.1-incubating.SNAPSHOT</version>
+		</dependency>
+		<!-- Enable for Workbench integration
+		<dependency>
+			<groupId>${project.groupId}</groupId>
+			<artifactId>apache-taverna-activity-gis-activity-ui</artifactId>
+			<version>0.0.1-incubating.SNAPSHOT</version>
+		</dependency>
+		-->
+	</dependencies>
+</project>
diff --git a/pom.xml b/pom.xml
index 733c43a..149bd40 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,63 +1,75 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+	license agreements. See the NOTICE file distributed with this work for additional 
+	information regarding copyright ownership. The ASF licenses this file to 
+	You under the Apache License, Version 2.0 (the "License"); you may not use 
+	this file except in compliance with the License. You may obtain a copy of 
+	the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
+	by applicable law or agreed to in writing, software distributed under the 
+	License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
+	OF ANY KIND, either express or implied. See the License for the specific 
+	language governing permissions and limitations under the License. -->
+<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>org.apache.taverna</groupId>
+		<artifactId>apache-taverna-parent</artifactId>
+		<version>2-incubating</version>
+	</parent>
+	<groupId>org.apache.taverna.gis</groupId>
+	<artifactId>apache-taverna-plugin-gis</artifactId>
+	<version>0.0.1-incubating-SNAPSHOT</version>
+	<packaging>pom</packaging>
 
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-<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>org.apache.taverna</groupId>
-    <artifactId>apache-taverna-parent</artifactId>
-    <version>2-incubating</version>
-  </parent>
-  <groupId>org.apache.taverna.gis</groupId>
-  <artifactId>apache-taverna-plugin-gis</artifactId>
-  <version>0.0.1-incubating-SNAPSHOT</version>
-  <packaging>pom</packaging>
-
-  <name>Apache Taverna Plugin GIS</name>
-  <description>
+	<name>Apache Taverna Plugin GIS</name>
+	<description>
 	Taverna support for Geographical Information Systems, in particular
 	the OGC activity.
   </description>
-  <properties>
-    <taverna.language.version>0.15.0-incubating</taverna.language.version>
-    <taverna.osgi.version>0.2.1-incubating</taverna.osgi.version>
-    <taverna.engine.version>3.1.0-incubating</taverna.engine.version>
-  </properties>
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<taverna.language.version>0.15.1-incubating</taverna.language.version>
+		<taverna.osgi.version>0.2.1-incubating</taverna.osgi.version>
+		<taverna.engine.version>3.1.0-incubating</taverna.engine.version>
+		<taverna.workbench.version>3.1.0-incubating-SNAPSHOT</taverna.workbench.version>
+	</properties>
 
-  <scm>
-    <connection>scm:git:https://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-gis.git</connection>
-    <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-gis.git</developerConnection>
-    <url>https://github.com/apache/incubator-taverna-plugin-gis</url>
-    <tag>HEAD</tag>
-  </scm>
+	<scm>
+		<connection>scm:git:https://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-gis.git</connection>
+		<developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-gis.git</developerConnection>
+		<url>https://github.com/apache/incubator-taverna-plugin-gis</url>
+		<tag>HEAD</tag>
+	</scm>
 
-  <repositories>
-    <repository>
-      <id>apache.snapshots</id>
-      <name>Apache Snapshot Repository</name>
-      <url>http://repository.apache.org/snapshots</url>
-      <releases>
-        <enabled>false</enabled>
-      </releases>
-    </repository>
-  </repositories>
 
-  <modules>
-    <module>taverna-ogc-activity</module>
-    <module>taverna-ogc-activity-ui</module>
-  </modules>
+	<repositories>
+		<repository>
+			<id>apache.snapshots</id>
+			<name>Apache Snapshot Repository</name>
+			<url>http://repository.apache.org/snapshots</url>
+			<releases>
+				<enabled>false</enabled>
+			</releases>
+		</repository>
+		<repository>
+			<id>n52-releases</id>
+			<name>52n Releases</name>
+			<url>http://52north.org/maven/repo/releases</url>
+			<releases>
+				<enabled>true</enabled>
+			</releases>
+			<snapshots>
+				<enabled>true</enabled>
+			</snapshots>
+		</repository>
+	</repositories>
+
+	<modules>
+		<module>apache-taverna-activity-gis-plugin</module>
+		<module>apache-taverna-activity-gis-activity</module>
+		<module>apache-taverna-activity-gis-activity-ui</module>
+		<module>taverna-gis-client</module>
+	</modules>
+
 </project>
diff --git a/taverna-gis-client/pom.xml b/taverna-gis-client/pom.xml
new file mode 100644
index 0000000..909a17e
--- /dev/null
+++ b/taverna-gis-client/pom.xml
@@ -0,0 +1,17 @@
+<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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.taverna.gis</groupId>
+    <artifactId>apache-taverna-activity-gis</artifactId>
+    <version>0.0.1-incubating.SNAPSHOT</version>
+  </parent>
+  <artifactId>taverna-gis-client</artifactId>
+  
+  <dependencies>
+  		<dependency>
+			<groupId>org.n52.wps</groupId>
+			<artifactId>52n-wps-client-lib</artifactId>
+			<version>3.3.1</version>
+		</dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/taverna-ogc-activity-ui/.gitignore b/taverna-ogc-activity-ui/.gitignore
deleted file mode 100644
index 8b13789..0000000
--- a/taverna-ogc-activity-ui/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/taverna-ogc-activity-ui/pom.xml b/taverna-ogc-activity-ui/pom.xml
deleted file mode 100644
index 5149a81..0000000
--- a/taverna-ogc-activity-ui/pom.xml
+++ /dev/null
@@ -1,135 +0,0 @@
-<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/xsd/maven-4.0.0.xsd">

-    <modelVersion>4.0.0</modelVersion>

-    <parent>

-      <groupId>org.apache.taverna.gis</groupId>

-      <artifactId>apache-taverna-plugin-gis</artifactId>

-      <version>0.0.1-incubating-SNAPSHOT</version>

-    </parent>

-    <artifactId>taverna-ogc-activity-ui</artifactId>

-    <packaging>bundle</packaging>

-    <name>Apache Taverna OGC Activity UI</name>

-

-    <properties>

-<!-- Temporary Taverna 2.5 dependencies -->

-	<t2.lang.version>1.5</t2.lang.version>

-	<t2.ui.api.version>1.5</t2.ui.api.version>

-	<t2.ui.impl.version>1.5</t2.ui.impl.version>

-    </properties>

-    <dependencies>

-<!-- START CWL dependencies -->

-<!--

-        <dependency>

-            <groupId>?</groupId>

-            <artifactId>?</artifactId>

-            <version>?</version>

-        </dependency>

-        <dependency>

-            <groupId>${project.parent.groupId}</groupId>

-            <artifactId>taverna-ogc-activity</artifactId>

-            <version>${project.parent.version}</version>

-        </dependency>

--->

-<!-- END CWL dependencies -->

-

-<!-- START Taverna 3 dependencies -->

-        <dependency>

-            <groupId>org.apache.taverna.language</groupId>

-            <artifactId>taverna-scufl2-api</artifactId>

-            <version>${taverna.language.version}</version>

-        </dependency>

-        <dependency>

-            <groupId>org.apache.taverna.engine</groupId>

-            <artifactId>taverna-services-api</artifactId>

-            <version>${taverna.engine.version}</version>

-        </dependency>

-<!-- Temporarily disabled to avoid confusion with Taverna 2 deps below

-        <dependency>

-            <groupId>org.apache.taverna.workbench</groupId>

-            <artifactId>taverna-workbench-api</artifactId>

-            <version>${taverna.workbench.version}</version>

-        </dependency>

-        <dependency>

-            <groupId>org.apache.taverna.workbench</groupId>

-            <artifactId>taverna-contextual-views-api</artifactId>

-            <version>${taverna.workbench.version}</version>

-        </dependency>

-        <dependency>

-            <groupId>org.apache.taverna.workbench</groupId>

-            <artifactId>taverna-menu-api</artifactId>

-              <version>${taverna.workbench.version}</version>

-        </dependency>

-        <dependency>

-            <groupId>org.apache.taverna.workbench</groupId>

-            <artifactId>taverna-workflow-view</artifactId>

-            <version>${taverna.workbench.version}</version>

-        </dependency>

-        <dependency>

-            <groupId>org.apache.taverna.workbench</groupId>

-            <artifactId>taverna-activity-tools</artifactId>

-            <version>${taverna.workbench.version}</version>

-        </dependency>

--->

-<!-- END Taverna 3 dependencies -->

-

-<!-- START Taverna 2 dependencies -->

-

-        <dependency>

-            <groupId>net.sf.taverna.t2.ui-api</groupId>

-            <artifactId>activity-palette-api</artifactId>

-            <version>${t2.ui.api.version}</version>

-        </dependency>

-        <dependency>

-            <groupId>net.sf.taverna.t2.ui-api</groupId>

-            <artifactId>activity-icons-api</artifactId>

-            <version>${t2.ui.api.version}</version>

-        </dependency>

-        <dependency>

-            <groupId>net.sf.taverna.t2.ui-api</groupId>

-            <artifactId>menu-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>

-        <dependency>

-            <groupId>net.sf.taverna.t2.ui-impl</groupId>

-            <artifactId>activity-tools</artifactId>

-            <version>${t2.ui.impl.version}</version>

-        </dependency>

-        <dependency>

-            <groupId>net.sf.taverna.t2.lang</groupId>

-            <artifactId>ui</artifactId>

-            <version>${t2.lang.version}</version>

-        </dependency>

-<!-- END Taverna 2 dependencies -->

-

-    </dependencies>

-

-    <repositories>

-        <!-- these needed only for Taverna 2 dependencies -->

-        <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>

diff --git a/taverna-ogc-activity/pom.xml b/taverna-ogc-activity/pom.xml
deleted file mode 100644
index aca7cf3..0000000
--- a/taverna-ogc-activity/pom.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
-<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>org.apache.taverna.gis</groupId>
-    <artifactId>apache-taverna-plugin-gis</artifactId>
-    <version>0.0.1-incubating-SNAPSHOT</version>
-  </parent>
-  <artifactId>taverna-ogc-activity</artifactId>
-  <packaging>bundle</packaging>
-  <name>Apache Taverna OGC Activity</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.taverna.language</groupId>
-      <artifactId>taverna-scufl2-api</artifactId>
-      <version>${taverna.language.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.taverna.engine</groupId>
-      <artifactId>taverna-reference-api</artifactId>
-      <version>${taverna.engine.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.taverna.engine</groupId>
-      <artifactId>taverna-workflowmodel-api</artifactId>
-      <version>${taverna.engine.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.taverna.osgi</groupId>
-      <artifactId>taverna-app-configuration-api</artifactId>
-      <version>${taverna.osgi.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>${junit.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.taverna.engine</groupId>
-      <artifactId>taverna-activity-test-utils</artifactId>
-      <version>${taverna.engine.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.taverna.engine</groupId>
-      <artifactId>taverna-workflowmodel-impl</artifactId>
-      <version>${taverna.engine.version}</version>
-      <scope>test</scope>
-    </dependency>
-
-  </dependencies>
-
-
-</project>