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

[44/54] [partial] incubator-taverna-engine git commit: Revert "temporarily empty repository"

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-database-configuration-impl/src/main/java/uk/org/taverna/configuration/database/impl/DatabaseConfigurationImpl.java
----------------------------------------------------------------------
diff --git a/taverna-database-configuration-impl/src/main/java/uk/org/taverna/configuration/database/impl/DatabaseConfigurationImpl.java b/taverna-database-configuration-impl/src/main/java/uk/org/taverna/configuration/database/impl/DatabaseConfigurationImpl.java
new file mode 100644
index 0000000..de73269
--- /dev/null
+++ b/taverna-database-configuration-impl/src/main/java/uk/org/taverna/configuration/database/impl/DatabaseConfigurationImpl.java
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package uk.org.taverna.configuration.database.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import uk.org.taverna.configuration.database.DatabaseConfiguration;
+import uk.org.taverna.configuration.AbstractConfigurable;
+import uk.org.taverna.configuration.ConfigurationManager;
+
+/**
+ * Configuration for the reference service and provenance.
+ *
+ * @author David Withers
+ * @author Stuart Owen
+ */
+
+public class DatabaseConfigurationImpl extends AbstractConfigurable implements DatabaseConfiguration {
+
+	private Map<String, String> defaultPropertyMap;
+
+	private boolean autoSave = true;
+
+	public DatabaseConfigurationImpl(ConfigurationManager configurationManager) {
+		super(configurationManager);
+	}
+
+	@Override
+	public boolean isAutoSave() {
+		return autoSave;
+	}
+
+	@Override
+	public void enableAutoSave() {
+		autoSave = true;
+	}
+
+	@Override
+	public void disableAutoSave() {
+		autoSave = false;
+	}
+
+	@Override
+	protected void store() {
+		if (autoSave) {
+			super.store();
+		}
+	}
+
+	@Override
+	public boolean isInMemory() {
+		return getProperty(IN_MEMORY).equalsIgnoreCase("true");
+	}
+
+	@Override
+	public void setInMemory(boolean value) {
+		setProperty(IN_MEMORY, String.valueOf(value));
+	}
+
+	@Override
+	public boolean isExposeDatanature() {
+		return getProperty(EXPOSE_DATANATURE).equalsIgnoreCase("true");
+	}
+
+	@Override
+	public void setExposeDatanature(boolean exposeDatanature) {
+		setProperty(EXPOSE_DATANATURE, String.valueOf(exposeDatanature));
+	}
+
+	@Override
+	public String getDatabaseContext() {
+		if (getProperty(IN_MEMORY).equalsIgnoreCase("true")) {
+			return IN_MEMORY_CONTEXT;
+		} else {
+			return HIBERNATE_CONTEXT;
+		}
+	}
+
+	@Override
+	public void setPort(int port) {
+		setPort(String.valueOf(port));
+	}
+
+	@Override
+	public void setPort(String port) {
+		setProperty(PORT, port);
+	}
+
+	@Override
+	public void setDriverClassName(String driverClassName) {
+		setProperty(DRIVER_CLASS_NAME, driverClassName);
+	}
+
+	@Override
+	public String getDriverClassName() {
+		return getProperty(DRIVER_CLASS_NAME);
+	}
+
+	@Override
+	public boolean isProvenanceEnabled() {
+		return getProperty(ENABLE_PROVENANCE).equalsIgnoreCase("true");
+	}
+
+	@Override
+	public void setProvenanceEnabled(boolean value) {
+		setProperty(ENABLE_PROVENANCE, String.valueOf(value));
+	}
+
+	@Override
+	public void setStartInternalDerbyServer(boolean value) {
+		setProperty(START_INTERNAL_DERBY, String.valueOf(value));
+	}
+
+	@Override
+	public boolean getStartInternalDerbyServer() {
+		return getProperty(START_INTERNAL_DERBY).equalsIgnoreCase("true");
+	}
+
+	@Override
+	public int getPort() {
+		return Integer.valueOf(getProperty(PORT));
+	}
+
+	@Override
+	public void setCurrentPort(int port) {
+		setProperty(CURRENT_PORT, String.valueOf(port));
+	}
+
+	@Override
+	public int getCurrentPort() {
+		return Integer.valueOf(getProperty(CURRENT_PORT));
+	}
+
+	@Override
+	public int getPoolMaxActive() {
+		return Integer.valueOf(getProperty(POOL_MAX_ACTIVE));
+	}
+
+	@Override
+	public int getPoolMinIdle() {
+		return Integer.valueOf(getProperty(POOL_MIN_IDLE));
+	}
+
+	@Override
+	public int getPoolMaxIdle() {
+		return Integer.valueOf(getProperty(POOL_MAX_IDLE));
+	}
+
+	@Override
+	public String getCategory() {
+		return "general";
+	}
+
+	@Override
+	public Map<String, String> getDefaultPropertyMap() {
+
+		if (defaultPropertyMap == null) {
+			defaultPropertyMap = new HashMap<String, String>();
+			defaultPropertyMap.put(IN_MEMORY, "true");
+			defaultPropertyMap.put(ENABLE_PROVENANCE, "true");
+			defaultPropertyMap.put(PORT, "1527");
+			// defaultPropertyMap.put(DRIVER_CLASS_NAME,
+			// "org.apache.derby.jdbc.ClientDriver");
+			defaultPropertyMap.put(DRIVER_CLASS_NAME,
+					"org.apache.derby.jdbc.EmbeddedDriver");
+			defaultPropertyMap.put(HIBERNATE_DIALECT,
+					"org.hibernate.dialect.DerbyDialect");
+			defaultPropertyMap.put(POOL_MAX_ACTIVE, "50");
+			defaultPropertyMap.put(POOL_MAX_IDLE, "50");
+			defaultPropertyMap.put(POOL_MIN_IDLE, "10");
+			defaultPropertyMap.put(USERNAME, "");
+			defaultPropertyMap.put(PASSWORD, "");
+			defaultPropertyMap.put(JDBC_URI,
+					"jdbc:derby:t2-database;create=true;upgrade=true");
+			defaultPropertyMap.put(START_INTERNAL_DERBY, "false");
+
+			defaultPropertyMap.put(CONNECTOR_TYPE, CONNECTOR_DERBY);
+			defaultPropertyMap.put(EXPOSE_DATANATURE, "false");
+		}
+		return defaultPropertyMap;
+	}
+
+	@Override
+	public String getHibernateDialect() {
+		return getProperty(HIBERNATE_DIALECT);
+	}
+
+	@Override
+	public String getDisplayName() {
+		return "Data and provenance";
+	}
+
+	@Override
+	public String getFilePrefix() {
+		return "DataAndProvenance";
+	}
+
+	@Override
+	public String getUUID() {
+		return "6BD3F5C1-C68D-4893-8D9B-2F46FA1DDB19";
+	}
+
+	@Override
+	public String getConnectorType() {
+		return getProperty(CONNECTOR_TYPE);
+	}
+
+	@Override
+	public String getJDBCUri() {
+		if (CONNECTOR_DERBY.equals(getConnectorType())
+				&& getStartInternalDerbyServer()) {
+			return "jdbc:derby://localhost:" + getCurrentPort()
+					+ "/t2-database;create=true;upgrade=true";
+		} else {
+			return getProperty(JDBC_URI);
+		}
+	}
+
+	@Override
+	public void setJDBCUri(String uri) {
+		setProperty(JDBC_URI, uri);
+	}
+
+	@Override
+	public String getUsername() {
+		return getProperty(USERNAME);
+	}
+
+	@Override
+	public String getPassword() {
+		return getProperty(PASSWORD);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-database-configuration-impl/src/main/java/uk/org/taverna/configuration/database/impl/DatabaseManagerImpl.java
----------------------------------------------------------------------
diff --git a/taverna-database-configuration-impl/src/main/java/uk/org/taverna/configuration/database/impl/DatabaseManagerImpl.java b/taverna-database-configuration-impl/src/main/java/uk/org/taverna/configuration/database/impl/DatabaseManagerImpl.java
new file mode 100644
index 0000000..8a10d24
--- /dev/null
+++ b/taverna-database-configuration-impl/src/main/java/uk/org/taverna/configuration/database/impl/DatabaseManagerImpl.java
@@ -0,0 +1,155 @@
+package uk.org.taverna.configuration.database.impl;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.dbcp.BasicDataSource;
+import org.apache.derby.drda.NetworkServerControl;
+import org.apache.log4j.Logger;
+
+import uk.org.taverna.configuration.database.DatabaseConfiguration;
+import uk.org.taverna.configuration.database.DatabaseManager;
+import uk.org.taverna.configuration.app.ApplicationConfiguration;
+
+/**
+ * A set of utility methods related to basic data management.
+ *
+ * @author Stuart Owen
+ * @author Stian Soiland-Reyes
+ *
+ */
+public class DatabaseManagerImpl implements DatabaseManager {
+
+	private final static Logger logger = Logger.getLogger(DatabaseManagerImpl.class);
+
+	private  NetworkServerControl server;
+
+	private BasicDataSource dataSource;
+
+	private DatabaseConfiguration databaseConfiguration;
+
+	private ApplicationConfiguration applicationConfiguration;
+
+	public DatabaseManagerImpl(ApplicationConfiguration applicationConfiguration, DatabaseConfiguration databaseConfiguration) throws SQLException {
+		this.applicationConfiguration = applicationConfiguration;
+		this.databaseConfiguration = databaseConfiguration;
+		getConnection();
+	}
+
+	@Override
+	public Connection getConnection() throws SQLException {
+		return getDataSource().getConnection();
+	}
+
+	@Override
+	public DataSource getDataSource() {
+		if (dataSource == null) {
+			setupDataSource();
+		}
+		return dataSource;
+	}
+
+	@Override
+	public synchronized void startDerbyNetworkServer() {
+		setDerbyPaths();
+
+        System.setProperty("derby.drda.host","localhost");
+        System.setProperty("derby.drda.minThreads","5");
+        System.setProperty("derby.drda.maxThreads",String.valueOf(databaseConfiguration.getPoolMaxActive()));
+        int port = databaseConfiguration.getPort();
+        int maxPort = port+50;
+
+        try {
+        	System.setProperty("derby.drda.portNumber",String.valueOf(port));
+            if (server==null) server = new NetworkServerControl();
+            while(port<maxPort) { //loop to find another available port on which Derby isn't already running
+            	if (!isRunning()) break;
+            	logger.info("Derby connection port: "+port+" is currently not available for Taverna, trying next value");
+            	port++;
+            	System.setProperty("derby.drda.portNumber",String.valueOf(port));
+            	server = new NetworkServerControl();
+            }
+            server.start(null);
+            databaseConfiguration.setCurrentPort(port);
+        } catch (Exception ex) {
+            logger.error("Error starting up Derby network server",ex);
+        }
+    }
+
+	@Override
+	public void stopDerbyNetworkServer() {
+		try {
+			server.shutdown();
+		} catch (Exception e) {
+			logger.error("Error shutting down Derby network server",e);
+		}
+	}
+
+	@Override
+	public boolean isRunning() {
+		if (server==null) {
+			return false;
+		}
+		else {
+			try {
+				server.ping();
+				return true;
+			} catch (Exception e) {
+				return false;
+			}
+		}
+	}
+
+	private void setupDataSource() {
+		setDerbyPaths();
+
+		dataSource = new BasicDataSource();
+		dataSource.setDriverClassName(databaseConfiguration.getDriverClassName());
+
+		System.setProperty("hibernate.dialect", databaseConfiguration.getHibernateDialect());
+
+		dataSource.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
+		dataSource.setMaxActive(databaseConfiguration.getPoolMaxActive());
+		dataSource.setMinIdle(databaseConfiguration.getPoolMinIdle());
+		dataSource.setMaxIdle(databaseConfiguration.getPoolMaxIdle());
+		dataSource.setDefaultAutoCommit(true);
+		dataSource.setInitialSize(databaseConfiguration.getPoolMinIdle());
+		//Derby blows up if the username of password is empty (even an empty string thats not null).
+		if (databaseConfiguration.getUsername()!=null && databaseConfiguration.getUsername().length()>=1) dataSource.setUsername(databaseConfiguration.getUsername());
+		if (databaseConfiguration.getPassword()!=null && databaseConfiguration.getPassword().length()>=1) dataSource.setPassword(databaseConfiguration.getPassword());
+
+		dataSource.setUrl(databaseConfiguration.getJDBCUri());
+    }
+
+	private void setDerbyPaths() {
+		if (databaseConfiguration.getConnectorType() == DatabaseConfiguration.CONNECTOR_DERBY) {
+			String homeDir = applicationConfiguration.getApplicationHomeDir().getAbsolutePath();
+			System.setProperty("derby.system.home",homeDir);
+			File logFile = new File(applicationConfiguration.getLogDir(), "derby.log");
+			System.setProperty("derby.stream.error.file", logFile.getAbsolutePath());
+		}
+
+	}
+
+	/**
+	 * Sets the databaseConfiguration.
+	 *
+	 * @param databaseConfiguration the new value of databaseConfiguration
+	 */
+	public void setDatabaseConfiguration(DatabaseConfiguration databaseConfiguration) {
+		this.databaseConfiguration = databaseConfiguration;
+	}
+
+	/**
+	 * Sets the applicationConfiguration.
+	 *
+	 * @param applicationConfiguration the new value of applicationConfiguration
+	 */
+	public void setApplicationConfiguration(ApplicationConfiguration applicationConfiguration) {
+		this.applicationConfiguration = applicationConfiguration;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-database-configuration-impl/src/main/resources/META-INF/spring/database-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-database-configuration-impl/src/main/resources/META-INF/spring/database-context-osgi.xml b/taverna-database-configuration-impl/src/main/resources/META-INF/spring/database-context-osgi.xml
new file mode 100644
index 0000000..2eae538
--- /dev/null
+++ b/taverna-database-configuration-impl/src/main/resources/META-INF/spring/database-context-osgi.xml
@@ -0,0 +1,18 @@
+<?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="databaseConfiguration" interface="uk.org.taverna.configuration.database.DatabaseConfiguration" />
+	<service ref="databaseManager" interface="uk.org.taverna.configuration.database.DatabaseManager" />
+
+	<reference id="configurationManager" interface="uk.org.taverna.configuration.ConfigurationManager" />
+	<reference id="applicationConfiguration" interface="uk.org.taverna.configuration.app.ApplicationConfiguration" />
+
+	<!-- <reference id="dataSourceFactory" interface="org.osgi.service.jdbc.DataSourceFactory"
+		filter="(osgi.jdbc.driver.class=org.apache.derby.jdbc.EmbeddedDriver)" /> -->
+
+</beans:beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-database-configuration-impl/src/main/resources/META-INF/spring/database-context.xml
----------------------------------------------------------------------
diff --git a/taverna-database-configuration-impl/src/main/resources/META-INF/spring/database-context.xml b/taverna-database-configuration-impl/src/main/resources/META-INF/spring/database-context.xml
new file mode 100644
index 0000000..f397933
--- /dev/null
+++ b/taverna-database-configuration-impl/src/main/resources/META-INF/spring/database-context.xml
@@ -0,0 +1,20 @@
+<?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="databaseConfiguration"
+		class="uk.org.taverna.configuration.database.impl.DatabaseConfigurationImpl">
+		<constructor-arg name="configurationManager" ref="configurationManager" />
+	</bean>
+
+	<bean id="databaseManager"
+		class="uk.org.taverna.configuration.database.impl.DatabaseManagerImpl">
+		<constructor-arg name="applicationConfiguration" ref="applicationConfiguration" />
+		<constructor-arg name="databaseConfiguration">
+			<ref local="databaseConfiguration" />
+		</constructor-arg>
+	</bean>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-dataflow-activity/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-dataflow-activity/pom.xml b/taverna-dataflow-activity/pom.xml
new file mode 100644
index 0000000..05c7e1d
--- /dev/null
+++ b/taverna-dataflow-activity/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.apache.taverna.engine</groupId>
+		<artifactId>taverna-engine</artifactId>
+		<version>3.1.0-incubating-SNAPSHOT</version>
+	</parent>
+	<artifactId>taverna-dataflow-activity</artifactId>
+	<packaging>bundle</packaging>
+	<name>Apache Taverna Dataflow Activity</name>
+	<dependencies>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-workflowmodel-api</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-reference-api</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-databind</artifactId>
+			<version>2.2.2</version>
+		</dependency>
+		<dependency>
+			<groupId>log4j</groupId>
+			<artifactId>log4j</artifactId>
+			<version>${log4j.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>${junit.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-activity-test-utils</artifactId>
+			<version>${project.parent.version}</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-dataflow-activity/src/main/java/net/sf/taverna/t2/activities/dataflow/DataflowActivity.java
----------------------------------------------------------------------
diff --git a/taverna-dataflow-activity/src/main/java/net/sf/taverna/t2/activities/dataflow/DataflowActivity.java b/taverna-dataflow-activity/src/main/java/net/sf/taverna/t2/activities/dataflow/DataflowActivity.java
new file mode 100644
index 0000000..7ec8e22
--- /dev/null
+++ b/taverna-dataflow-activity/src/main/java/net/sf/taverna/t2/activities/dataflow/DataflowActivity.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.dataflow;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.taverna.t2.facade.FacadeListener;
+import net.sf.taverna.t2.facade.ResultListener;
+import net.sf.taverna.t2.facade.WorkflowInstanceFacade;
+import net.sf.taverna.t2.facade.WorkflowInstanceFacade.State;
+import net.sf.taverna.t2.invocation.TokenOrderException;
+import net.sf.taverna.t2.invocation.WorkflowDataToken;
+import net.sf.taverna.t2.reference.T2Reference;
+import net.sf.taverna.t2.workflowmodel.Dataflow;
+import net.sf.taverna.t2.workflowmodel.InvalidDataflowException;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AbstractAsynchronousActivity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityConfigurationException;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AsynchronousActivityCallback;
+import net.sf.taverna.t2.workflowmodel.processor.activity.NestedDataflow;
+
+import org.apache.log4j.Logger;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * An Activity providing nested Dataflow functionality.
+ *
+ * @author David Withers
+ */
+public class DataflowActivity extends AbstractAsynchronousActivity<JsonNode> implements NestedDataflow {
+
+	public static final String URI = "http://ns.taverna.org.uk/2010/activity/nested-workflow";
+
+	@SuppressWarnings("unused")
+	private static final Logger logger = Logger.getLogger(DataflowActivity.class);
+
+	private Dataflow dataflow;
+
+	private JsonNode json;
+
+	@Override
+	public void configure(JsonNode json) throws ActivityConfigurationException {
+		this.json = json;
+//		dataflow.checkValidity();
+//		buildInputPorts();
+//		buildOutputPorts();
+	}
+
+	@Override
+	public JsonNode getConfiguration() {
+		return json;
+	}
+
+	@Override
+	public void executeAsynch(final Map<String, T2Reference> data,
+			final AsynchronousActivityCallback callback) {
+		callback.requestRun(new Runnable() {
+			
+			Map<String, T2Reference> outputData = new HashMap<String, T2Reference>();
+
+			public void run() {
+
+				final WorkflowInstanceFacade facade;
+				try {
+					facade = getEdits().createWorkflowInstanceFacade(dataflow, callback.getContext(),
+							callback.getParentProcessIdentifier());
+				} catch (InvalidDataflowException ex) {
+					callback.fail("Invalid workflow", ex);
+					return;
+				}
+
+				final ResultListener rl = new ResultListener() {
+
+
+					public void resultTokenProduced(WorkflowDataToken dataToken, String port) {
+						if (dataToken.getIndex().length == 0) {
+							outputData.put(port, dataToken.getData());
+						}
+					}
+				};
+				
+				final FacadeListener fl = new FacadeListener() {
+
+					@Override
+					public void workflowFailed(WorkflowInstanceFacade facade,
+							String message, Throwable t) {
+						callback.fail(message, t);
+					}
+
+					@Override
+					public void stateChange(WorkflowInstanceFacade facade,
+							State oldState, State newState) {
+						if (newState == State.completed) {
+							facade.removeResultListener(rl);
+							facade.removeFacadeListener(this);
+							callback.receiveResult(outputData, new int[]{});
+						}
+					}
+					
+				};
+				
+				facade.addResultListener(rl);
+				facade.addFacadeListener(fl);
+
+				facade.fire();
+
+				for (Map.Entry<String, T2Reference> entry : data.entrySet()) {
+					try {
+						WorkflowDataToken token = new WorkflowDataToken(callback
+								.getParentProcessIdentifier(), new int[] {}, entry.getValue(),
+								callback.getContext());
+						facade.pushData(token, entry.getKey());
+					} catch (TokenOrderException e) {
+						callback.fail("Failed to push data into facade", e);
+					}
+				}
+
+			}
+
+		});
+	}
+
+//	private void buildInputPorts() throws ActivityConfigurationException {
+//		inputPorts.clear();
+//		for (DataflowInputPort dataflowInputPort : dataflow.getInputPorts()) {
+//			addInput(dataflowInputPort.getName(), dataflowInputPort.getDepth(), true,
+//					new ArrayList<Class<? extends ExternalReferenceSPI>>(), null);
+//		}
+//	}
+
+//	private void buildOutputPorts() throws ActivityConfigurationException {
+//		outputPorts.clear();
+//		// granular depth same as depth - no streaming of results
+//		for (DataflowOutputPort dataflowOutputPort : dataflow.getOutputPorts()) {
+//			addOutput(dataflowOutputPort.getName(), dataflowOutputPort.getDepth(),
+//					dataflowOutputPort.getDepth());
+//		}
+//	}
+
+	public Dataflow getNestedDataflow() {
+		return dataflow;
+	}
+
+	@Override
+	public void setNestedDataflow(Dataflow dataflow) {
+		this.dataflow = dataflow;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-dataflow-activity/src/main/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityFactory.java
----------------------------------------------------------------------
diff --git a/taverna-dataflow-activity/src/main/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityFactory.java b/taverna-dataflow-activity/src/main/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityFactory.java
new file mode 100644
index 0000000..1529e00
--- /dev/null
+++ b/taverna-dataflow-activity/src/main/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityFactory.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (C) 2010 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.dataflow;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+
+import net.sf.taverna.t2.workflowmodel.Edits;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityFactory;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * An {@link ActivityFactory} for creating <code>DataflowActivity</code>.
+ *
+ * @author David Withers
+ */
+public class DataflowActivityFactory implements ActivityFactory {
+
+	private Edits edits;
+
+	@Override
+	public DataflowActivity createActivity() {
+		DataflowActivity activity = new DataflowActivity();
+		activity.setEdits(edits);
+		return activity;
+	}
+
+	@Override
+	public URI getActivityType() {
+		return URI.create(DataflowActivity.URI);
+	}
+
+	@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) {
+		return new HashSet<>();
+	}
+
+	@Override
+	public Set<ActivityOutputPort> getOutputPorts(JsonNode configuration) {
+		return new HashSet<>();
+	}
+
+	public void setEdits(Edits edits) {
+		this.edits = edits;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-dataflow-activity/src/main/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityHealthChecker.java
----------------------------------------------------------------------
diff --git a/taverna-dataflow-activity/src/main/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityHealthChecker.java b/taverna-dataflow-activity/src/main/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityHealthChecker.java
new file mode 100644
index 0000000..86cf595
--- /dev/null
+++ b/taverna-dataflow-activity/src/main/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityHealthChecker.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.dataflow;
+
+import java.util.List;
+
+import net.sf.taverna.t2.visit.VisitReport;
+import net.sf.taverna.t2.workflowmodel.health.HealthChecker;
+
+public class DataflowActivityHealthChecker implements HealthChecker<DataflowActivity> {
+
+	public boolean canVisit(Object subject) {
+		return false;
+	}
+
+	public VisitReport visit(DataflowActivity activity, List<Object> ancestors) {
+		return null;
+	}
+
+	public boolean isTimeConsuming() {
+		return true;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-dataflow-activity/src/main/resources/META-INF/services/net.sf.taverna.t2.workflowmodel.health.HealthChecker
----------------------------------------------------------------------
diff --git a/taverna-dataflow-activity/src/main/resources/META-INF/services/net.sf.taverna.t2.workflowmodel.health.HealthChecker b/taverna-dataflow-activity/src/main/resources/META-INF/services/net.sf.taverna.t2.workflowmodel.health.HealthChecker
new file mode 100644
index 0000000..1254008
--- /dev/null
+++ b/taverna-dataflow-activity/src/main/resources/META-INF/services/net.sf.taverna.t2.workflowmodel.health.HealthChecker
@@ -0,0 +1 @@
+net.sf.taverna.t2.activities.dataflow.DataflowActivityHealthChecker
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-dataflow-activity/src/main/resources/META-INF/spring/dataflow-activity-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-dataflow-activity/src/main/resources/META-INF/spring/dataflow-activity-context-osgi.xml b/taverna-dataflow-activity/src/main/resources/META-INF/spring/dataflow-activity-context-osgi.xml
new file mode 100644
index 0000000..480b7e7
--- /dev/null
+++ b/taverna-dataflow-activity/src/main/resources/META-INF/spring/dataflow-activity-context-osgi.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans:beans xmlns="http://www.springframework.org/schema/osgi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:beans="http://www.springframework.org/schema/beans"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans
+                                 http://www.springframework.org/schema/beans/spring-beans.xsd
+                                 http://www.springframework.org/schema/osgi
+                                 http://www.springframework.org/schema/osgi/spring-osgi.xsd">
+
+	<service ref="dataflowActivityHealthChecker" interface="net.sf.taverna.t2.workflowmodel.health.HealthChecker" />
+
+	<service ref="dataflowActivityFactory" interface="net.sf.taverna.t2.workflowmodel.processor.activity.ActivityFactory" />
+
+	<reference id="edits" interface="net.sf.taverna.t2.workflowmodel.Edits" />
+
+</beans:beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-dataflow-activity/src/main/resources/META-INF/spring/dataflow-activity-context.xml
----------------------------------------------------------------------
diff --git a/taverna-dataflow-activity/src/main/resources/META-INF/spring/dataflow-activity-context.xml b/taverna-dataflow-activity/src/main/resources/META-INF/spring/dataflow-activity-context.xml
new file mode 100644
index 0000000..b689bf9
--- /dev/null
+++ b/taverna-dataflow-activity/src/main/resources/META-INF/spring/dataflow-activity-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="dataflowActivityHealthChecker" class="net.sf.taverna.t2.activities.dataflow.DataflowActivityHealthChecker" />
+
+	<bean id="dataflowActivityFactory" class="net.sf.taverna.t2.activities.dataflow.DataflowActivityFactory" >
+		<property name="edits" ref="edits" />
+	</bean>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-dataflow-activity/src/main/resources/schema.json
----------------------------------------------------------------------
diff --git a/taverna-dataflow-activity/src/main/resources/schema.json b/taverna-dataflow-activity/src/main/resources/schema.json
new file mode 100644
index 0000000..3d8de20
--- /dev/null
+++ b/taverna-dataflow-activity/src/main/resources/schema.json
@@ -0,0 +1,19 @@
+{
+    "$schema": "http://json-schema.org/draft-03/schema#",
+    "id": "http://ns.taverna.org.uk/2010/activity/dataflow.schema.json",
+    "title": "Dataflow activity configuration",
+    "type": "object",
+    "properties": {
+        "@context": {
+            "description": "JSON-LD context for interpreting the configuration as RDF",
+            "required": true,
+            "enum": ["http://ns.taverna.org.uk/2010/activity/dataflow.context.json"]
+        },
+        "nestedWorkflow": {
+            "title": "Nested Workflow",
+            "description": "Name of the nested workflow",
+            "type": "string",
+            "required": true
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-dataflow-activity/src/test/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityFactoryTest.java
----------------------------------------------------------------------
diff --git a/taverna-dataflow-activity/src/test/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityFactoryTest.java b/taverna-dataflow-activity/src/test/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityFactoryTest.java
new file mode 100644
index 0000000..5942109
--- /dev/null
+++ b/taverna-dataflow-activity/src/test/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityFactoryTest.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (C) 2010 The University of Manchester   
+ * 
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ * 
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *    
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *    
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.dataflow;
+
+import java.net.URI;
+import net.sf.taverna.t2.workflowmodel.impl.EditsImpl;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * 
+ * @author David Withers
+ */
+public class DataflowActivityFactoryTest {
+
+	private DataflowActivityFactory factory;
+	
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@Before
+	public void setUp() throws Exception {
+		factory = new DataflowActivityFactory();
+                factory.setEdits(new EditsImpl());
+	}
+
+	/**
+	 * Test method for {@link net.sf.taverna.t2.activities.beanshell.BeanshellActivityFactory#createActivity()}.
+	 */
+	@Test
+	public void testCreateActivity() {
+		DataflowActivity createActivity = factory.createActivity();
+		assertNotNull(createActivity);
+	}
+
+	/**
+	 * Test method for {@link net.sf.taverna.t2.activities.beanshell.BeanshellActivityFactory#getActivityType()}.
+	 */
+	@Test
+	public void testGetActivityURI() {
+		assertEquals(URI.create(DataflowActivity.URI), factory.getActivityType());
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-dataflow-activity/src/test/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityTest.java
----------------------------------------------------------------------
diff --git a/taverna-dataflow-activity/src/test/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityTest.java b/taverna-dataflow-activity/src/test/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityTest.java
new file mode 100644
index 0000000..7cd7c97
--- /dev/null
+++ b/taverna-dataflow-activity/src/test/java/net/sf/taverna/t2/activities/dataflow/DataflowActivityTest.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.dataflow;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.taverna.t2.activities.testutils.ActivityInvoker;
+import net.sf.taverna.t2.workflowmodel.Dataflow;
+import net.sf.taverna.t2.workflowmodel.Datalink;
+import net.sf.taverna.t2.workflowmodel.Edits;
+import net.sf.taverna.t2.workflowmodel.impl.EditsImpl;
+import net.sf.taverna.t2.workflowmodel.processor.activity.impl.ActivityInputPortImpl;
+import net.sf.taverna.t2.workflowmodel.processor.activity.impl.ActivityOutputPortImpl;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Dataflow Activity Tests
+ *
+ * @author David Withers
+ */
+public class DataflowActivityTest {
+
+	private Dataflow dataflow;
+
+	private DataflowActivity activity;
+
+	@Before
+	public void setUp() throws Exception {
+		activity = new DataflowActivity();
+		Edits edits = new EditsImpl();
+		activity.setEdits(edits);
+		dataflow = edits.createDataflow();
+		edits.getCreateDataflowInputPortEdit(dataflow, "input", 0, 0).doEdit();
+		edits.getCreateDataflowOutputPortEdit(dataflow, "output").doEdit();
+		Datalink datalink = edits.createDatalink(dataflow.getInputPorts().get(0)
+				.getInternalOutputPort(), dataflow.getOutputPorts().get(0).getInternalInputPort());
+		edits.getConnectDatalinkEdit(datalink).doEdit();
+	}
+
+	@Test
+	public void testConfigureDataflowActivityConfigurationBean() throws Exception {
+		activity.setNestedDataflow(dataflow);
+		assertEquals(dataflow, activity.getNestedDataflow());
+
+		Edits edits = new EditsImpl();
+		dataflow = edits.createDataflow();
+		edits.getAddActivityInputPortEdit(activity, new ActivityInputPortImpl("input", 0)).doEdit();
+		edits.getAddActivityOutputPortEdit(activity, new ActivityOutputPortImpl("output", 0, 0))
+				.doEdit();
+
+		assertEquals(1, activity.getInputPorts().size());
+		assertEquals("input", activity.getInputPorts().iterator().next().getName());
+		assertEquals(1, activity.getOutputPorts().size());
+		assertEquals("output", activity.getOutputPorts().iterator().next().getName());
+
+		Map<String, Object> inputs = new HashMap<String, Object>();
+		inputs.put("input", "aString");
+		Map<String, Class<?>> expectedOutputs = new HashMap<String, Class<?>>();
+		expectedOutputs.put("output", String.class);
+
+		Map<String, Object> outputs = ActivityInvoker.invokeAsyncActivity(activity, inputs,
+				expectedOutputs);
+		assertTrue("there should be an output named output", outputs.containsKey("output"));
+		assertEquals("output should have the value aString", "aString", outputs.get("output"));
+	}
+
+	@Test
+	public void testGetConfiguration() {
+		assertNull("freshly created activity should not contain configuration",
+				activity.getConfiguration());
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-execution-api/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-execution-api/pom.xml b/taverna-execution-api/pom.xml
new file mode 100644
index 0000000..1349766
--- /dev/null
+++ b/taverna-execution-api/pom.xml
@@ -0,0 +1,45 @@
+<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.engine</groupId>
+		<artifactId>taverna-engine</artifactId>
+		<version>3.1.0-incubating-SNAPSHOT</version>
+	</parent>
+	<artifactId>taverna-execution-api</artifactId>
+	<packaging>bundle</packaging>
+	<name>Apache Taverna Platform Execution Service API</name>
+	<description>A Service for executing Taverna workflows</description>
+	<dependencies>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-capability-api</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-report-api</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.language</groupId>
+			<artifactId>taverna-scufl2-api</artifactId>
+			<version>${taverna.language.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.language</groupId>
+			<artifactId>taverna-databundle</artifactId>
+			<version>${taverna.language.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>${junit.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.language</groupId>
+			<artifactId>taverna-robundle</artifactId>
+			<version>${taverna.language.version}</version>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/AbstractExecution.java
----------------------------------------------------------------------
diff --git a/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/AbstractExecution.java b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/AbstractExecution.java
new file mode 100644
index 0000000..c3802ce
--- /dev/null
+++ b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/AbstractExecution.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (C) 2010 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package uk.org.taverna.platform.execution.api;
+
+import java.util.UUID;
+
+import org.purl.wf4ever.robundle.Bundle;
+
+import uk.org.taverna.platform.report.ActivityReport;
+import uk.org.taverna.platform.report.ProcessorReport;
+import uk.org.taverna.platform.report.WorkflowReport;
+import uk.org.taverna.scufl2.api.activity.Activity;
+import uk.org.taverna.scufl2.api.common.Scufl2Tools;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.core.Processor;
+import uk.org.taverna.scufl2.api.core.Workflow;
+import uk.org.taverna.scufl2.api.profiles.ProcessorBinding;
+import uk.org.taverna.scufl2.api.profiles.Profile;
+
+/**
+ * Abstract implementation of an {@link Execution}.
+ *
+ * @author David Withers
+ */
+public abstract class AbstractExecution implements Execution {
+
+	private final String ID;
+	private final WorkflowBundle workflowBundle;
+	private final Bundle dataBundle;
+	private final Workflow workflow;
+	private final Profile profile;
+	private final WorkflowReport workflowReport;
+
+	private final Scufl2Tools scufl2Tools = new Scufl2Tools();
+
+	/**
+	 * Constructs an abstract implementation of an Execution.
+	 *
+	 * @param workflowBundle
+	 *            the <code>WorkflowBundle</code> containing the <code>Workflow</code>s required for
+	 *            execution
+	 * @param workflow
+	 *            the <code>Workflow</code> to execute
+	 * @param profile
+	 *            the <code>Profile</code> to use when executing the <code>Workflow</code>
+	 * @param dataBundle
+	 *            the <code>Bundle</code> containing the data values for the <code>Workflow</code>
+	 * @throws InvalidWorkflowException
+	 *             if the specified workflow is invalid
+	 */
+	public AbstractExecution(WorkflowBundle workflowBundle, Workflow workflow, Profile profile,
+			Bundle dataBundle) {
+		this.workflowBundle = workflowBundle;
+		this.workflow = workflow;
+		this.profile = profile;
+		this.dataBundle = dataBundle;
+		ID = UUID.randomUUID().toString();
+		workflowReport = generateWorkflowReport(workflow);
+	}
+
+	protected abstract WorkflowReport createWorkflowReport(Workflow workflow);
+
+	protected abstract ProcessorReport createProcessorReport(Processor processor);
+
+	protected abstract ActivityReport createActivityReport(Activity activity);
+
+	public WorkflowReport generateWorkflowReport(Workflow workflow) {
+		WorkflowReport workflowReport = createWorkflowReport(workflow);
+		for (Processor processor : workflow.getProcessors()) {
+			ProcessorReport processorReport = createProcessorReport(processor);
+			processorReport.setParentReport(workflowReport);
+			workflowReport.addProcessorReport(processorReport);
+			for (ProcessorBinding processorBinding : scufl2Tools.processorBindingsForProcessor(
+					processor, profile)) {
+				Activity boundActivity = processorBinding.getBoundActivity();
+				ActivityReport activityReport = createActivityReport(boundActivity);
+				activityReport.setParentReport(processorReport);
+				if (scufl2Tools.containsNestedWorkflow(processor, profile)) {
+					Workflow nestedWorkflow = scufl2Tools.nestedWorkflowForProcessor(processor,
+							profile);
+					WorkflowReport nestedWorkflowReport = generateWorkflowReport(nestedWorkflow);
+					nestedWorkflowReport.setParentReport(activityReport);
+					activityReport.setNestedWorkflowReport(nestedWorkflowReport);
+				}
+				processorReport.addActivityReport(activityReport);
+			}
+		}
+		return workflowReport;
+	}
+
+	@Override
+	public String getID() {
+		return ID;
+	}
+
+	@Override
+	public WorkflowBundle getWorkflowBundle() {
+		return workflowBundle;
+	}
+
+	@Override
+	public Bundle getDataBundle() {
+		return dataBundle;
+	}
+
+	@Override
+	public Workflow getWorkflow() {
+		return workflow;
+	}
+
+	@Override
+	public Profile getProfile() {
+		return profile;
+	}
+
+	@Override
+	public WorkflowReport getWorkflowReport() {
+		return workflowReport;
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/AbstractExecutionEnvironment.java
----------------------------------------------------------------------
diff --git a/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/AbstractExecutionEnvironment.java b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/AbstractExecutionEnvironment.java
new file mode 100644
index 0000000..a6475e5
--- /dev/null
+++ b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/AbstractExecutionEnvironment.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (C) 2011 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package uk.org.taverna.platform.execution.api;
+
+import java.net.URI;
+
+/**
+ * A common super type for concrete implementations of <code>ExecutionEnvironment</code>s.
+ *
+ * @author David Withers
+ */
+public abstract class AbstractExecutionEnvironment implements ExecutionEnvironment {
+	private final String ID;
+	private final String name;
+	private final String description;
+	private final ExecutionService executionService;
+
+	public AbstractExecutionEnvironment(String ID, String name, String description,
+			ExecutionService executionService) {
+		this.ID = ID;
+		this.name = name;
+		this.description = description;
+		this.executionService = executionService;
+	}
+
+	@Override
+	public String getID() {
+		return ID;
+	}
+
+	@Override
+	public String getName() {
+		return name;
+	}
+
+	@Override
+	public String getDescription() {
+		return description;
+	}
+
+	@Override
+	public ExecutionService getExecutionService() {
+		return executionService;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		sb.append(ID + "\n");
+		sb.append(name + "\n");
+		sb.append(description + "\n");
+		sb.append("Activities : \n");
+		for (URI uri : getActivityTypes())
+			sb.append("  " + uri + "\n");
+		sb.append("Dispatch Layers : \n");
+		for (URI uri : getDispatchLayerTypes())
+			sb.append("  " + uri + "\n");
+		return sb.toString();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/AbstractExecutionService.java
----------------------------------------------------------------------
diff --git a/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/AbstractExecutionService.java b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/AbstractExecutionService.java
new file mode 100755
index 0000000..f9357df
--- /dev/null
+++ b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/AbstractExecutionService.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (C) 2010 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package uk.org.taverna.platform.execution.api;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.purl.wf4ever.robundle.Bundle;
+
+import uk.org.taverna.platform.report.WorkflowReport;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.core.Workflow;
+import uk.org.taverna.scufl2.api.profiles.Profile;
+
+/**
+ * A common super type for concrete implementations of <code>ExecutionService</code>s.
+ *
+ * @author David Withers
+ */
+public abstract class AbstractExecutionService implements ExecutionService {
+	private final String ID;
+	private final String name;
+	private final String description;
+	private final Map<String, Execution> executionMap;
+
+	public AbstractExecutionService(String ID, String name, String description) {
+		this.ID = ID;
+		this.name = name;
+		this.description = description;
+		executionMap = Collections.synchronizedMap(new HashMap<String, Execution>());
+	}
+
+	@Override
+	public String getID() {
+		return ID;
+	}
+
+	@Override
+	public String getName() {
+		return name;
+	}
+
+	@Override
+	public String getDescription() {
+		return description;
+	}
+
+	@Override
+	public String createExecution(ExecutionEnvironment executionEnvironment,
+			WorkflowBundle workflowBundle, Workflow workflow, Profile profile,
+			Bundle dataBundle) throws InvalidWorkflowException {
+		Execution execution = createExecutionImpl(workflowBundle, workflow, profile, dataBundle);
+		executionMap.put(execution.getID(), execution);
+		return execution.getID();
+	}
+
+	/**
+	 * Creates an implementation of an Execution.
+	 *
+	 * To be implemented by concrete implementations of <code>ExecutionService</code>.
+	 *
+	 * @param workflowBundle
+	 *            the <code>WorkflowBundle</code> containing the <code>Workflow</code>s required for
+	 *            execution
+	 * @param workflow
+	 *            the <code>Workflow</code> to execute
+	 * @param profile
+	 *            the <code>Profile</code> to use when executing the <code>Workflow</code>
+	 * @param dataBundle
+	 *            the <code>Bundle</code> containing the data values for the <code>Workflow</code>
+	 * @return a new Execution implementation
+	 * @throws InvalidWorkflowException
+	 *             if the specified workflow is invalid
+	 */
+	protected abstract Execution createExecutionImpl(
+			WorkflowBundle workflowBundle, Workflow workflow, Profile profile,
+			Bundle dataBundle) throws InvalidWorkflowException;
+
+	@Override
+	public WorkflowReport getWorkflowReport(String executionID)
+			throws InvalidExecutionIdException {
+		return getExecution(executionID).getWorkflowReport();
+	}
+
+	@Override
+	public void delete(String executionID) throws InvalidExecutionIdException {
+		getExecution(executionID).delete();
+		executionMap.remove(executionID);
+	}
+
+	@Override
+	public void start(String executionID) throws InvalidExecutionIdException {
+		getExecution(executionID).start();
+	}
+
+	@Override
+	public void pause(String executionID) throws InvalidExecutionIdException {
+		getExecution(executionID).pause();
+	}
+
+	@Override
+	public void resume(String executionID) throws InvalidExecutionIdException {
+		getExecution(executionID).resume();
+	}
+
+	@Override
+	public void cancel(String executionID) throws InvalidExecutionIdException {
+		getExecution(executionID).cancel();
+	}
+
+	protected Execution getExecution(String executionID)
+			throws InvalidExecutionIdException {
+		Execution execution = executionMap.get(executionID);
+		if (execution == null)
+			throw new InvalidExecutionIdException("Execution ID " + executionID
+					+ " is not valid");
+		return execution;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/Execution.java
----------------------------------------------------------------------
diff --git a/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/Execution.java b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/Execution.java
new file mode 100644
index 0000000..28a982d
--- /dev/null
+++ b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/Execution.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (C) 2010 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package uk.org.taverna.platform.execution.api;
+
+import org.purl.wf4ever.robundle.Bundle;
+
+import uk.org.taverna.platform.report.WorkflowReport;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.core.Workflow;
+import uk.org.taverna.scufl2.api.profiles.Profile;
+
+/**
+ * Interface for a single execution of a Taverna workflow.
+ *
+ * @author David Withers
+ */
+public interface Execution {
+
+	/**
+	 * Returns the identifier for this execution.
+	 *
+	 * @return the identifier for this execution
+	 */
+	public abstract String getID();
+
+	/**
+	 * Returns the <code>WorkflowBundle</code> containing the <code>Workflow</code>s required for execution.
+	 *
+	 * @return the <code>WorkflowBundle</code> containing the <code>Workflow</code>s required for execution
+	 */
+	public abstract WorkflowBundle getWorkflowBundle();
+
+	/**
+	 * Returns the <code>Bundle</code> containing the data values for the <code>Workflow</code>.
+	 *
+	 * @return the <code>Bundle</code> containing the data values for the <code>Workflow</code>
+	 */
+	public abstract Bundle getDataBundle();
+
+	/**
+	 * Returns the <code>Workflow</code> to execute.
+	 *
+	 * @return the <code>Workflow</code> to execute
+	 */
+	public abstract Workflow getWorkflow();
+
+	/**
+	 * Returns the <code>Profile</code> to use when executing the <code>Workflow</code>.
+	 *
+	 * @return the <code>Profile</code> to use when executing the <code>Workflow</code>
+	 */
+	public abstract Profile getProfile();
+
+	/**
+	 * Returns the <code>WorkflowReport</code> for the execution.
+	 *
+	 * @return the <code>WorkflowReport</code> for the execution
+	 */
+	public abstract WorkflowReport getWorkflowReport();
+
+	/**
+	 * Deletes the execution.
+	 */
+	public abstract void delete();
+
+	/**
+	 * Starts the execution.
+	 */
+	public abstract void start();
+
+	/**
+	 * Pauses the execution.
+	 */
+	public abstract void pause();
+
+	/**
+	 * Resumes a paused execution.
+	 */
+	public abstract void resume();
+
+	/**
+	 * Cancels the execution.
+	 */
+	public abstract void cancel();
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/ExecutionEnvironment.java
----------------------------------------------------------------------
diff --git a/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/ExecutionEnvironment.java b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/ExecutionEnvironment.java
new file mode 100644
index 0000000..0408308
--- /dev/null
+++ b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/ExecutionEnvironment.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (C) 2011 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package uk.org.taverna.platform.execution.api;
+
+import java.net.URI;
+import java.util.Set;
+
+import uk.org.taverna.platform.capability.api.ActivityConfigurationException;
+import uk.org.taverna.platform.capability.api.ActivityNotFoundException;
+import uk.org.taverna.platform.capability.api.DispatchLayerConfigurationException;
+import uk.org.taverna.platform.capability.api.DispatchLayerNotFoundException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * The ExecutionEnvironment specifies the capabilities of a workflow execution environment.
+ *
+ * @author David Withers
+ */
+public interface ExecutionEnvironment {
+
+	/**
+	 * Returns the identifier for this ExecutionEnvironment.
+	 *
+	 * @return the identifier for this ExecutionEnvironment
+	 */
+	public String getID();
+
+	/**
+	 * Returns the name of this ExecutionEnvironment.
+	 *
+	 * @return the name of this ExecutionEnvironment
+	 */
+	public String getName();
+
+	/**
+	 * Returns a description of this ExecutionEnvironment.
+	 *
+	 * @return a description of this ExecutionEnvironment
+	 */
+	public String getDescription();
+
+	/**
+	 * Returns the ExecutionService that provides this ExecutionEnvironment.
+	 *
+	 * @return the ExecutionService that provides this ExecutionEnvironment
+	 */
+	public ExecutionService getExecutionService();
+
+	/**
+	 * Returns the activity types available in this ExecutionEnvironment.
+	 *
+	 * @return the activity types available in this ExecutionEnvironment
+	 */
+	public Set<URI> getActivityTypes();
+
+	/**
+	 * Returns true iff an activity exists for the specified URI in this ExecutionEnvironment.
+	 *
+	 * @param uri
+	 *            the activity URI to check
+	 * @return true if an activity exists for the specified URI in this ExecutionEnvironment
+	 */
+	public boolean activityExists(URI uri);
+
+	/**
+	 * Returns a JSON Schema for the configuration required by an activity.
+	 *
+	 * @param uri
+	 *            a URI that identifies an activity
+	 * @return a JSON Schema for the configuration required by an activity
+	 * @throws ActivityNotFoundException
+	 *             if an activity cannot be found for the specified URI
+	 * @throws ActivityConfigurationException
+	 *             if the ConfigurationDefinition cannot be created
+	 */
+	public JsonNode getActivityConfigurationSchema(URI uri)
+			throws ActivityNotFoundException, ActivityConfigurationException;
+
+	/**
+	 * Returns the dispatch layer types available in this ExecutionEnvironment.
+	 *
+	 * @return the dispatch layer types available in this ExecutionEnvironment
+	 */
+	public Set<URI> getDispatchLayerTypes();
+
+	/**
+	 * Returns true iff a dispatch layer exists for the specified URI in this ExecutionEnvironment.
+	 *
+	 * @param uri
+	 *            the dispatch layer URI to check
+	 * @return true if a dispatch layer exists for the specified URI in this ExecutionEnvironment
+	 */
+	public boolean dispatchLayerExists(URI uri);
+
+	/**
+	 * Returns a JSON Schema for the configuration required by a dispatch layer.
+	 *
+	 * @param uri
+	 *            a URI that identifies a dispatch layer
+	 * @return
+	 * @return a JSON Schema for the configuration required by a dispatch layer
+	 * @throws DispatchLayerNotFoundException
+	 *             if a dispatch layer cannot be found for the specified URI
+	 * @throws DispatchLayerConfigurationException
+	 *             if the ConfigurationDefinition cannot be created
+	 */
+	public JsonNode getDispatchLayerConfigurationSchema(URI uri)
+			throws DispatchLayerNotFoundException, DispatchLayerConfigurationException;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/ExecutionEnvironmentService.java
----------------------------------------------------------------------
diff --git a/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/ExecutionEnvironmentService.java b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/ExecutionEnvironmentService.java
new file mode 100644
index 0000000..5559069
--- /dev/null
+++ b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/ExecutionEnvironmentService.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (C) 2011 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package uk.org.taverna.platform.execution.api;
+
+import java.util.Set;
+
+import uk.org.taverna.scufl2.api.profiles.Profile;
+
+/**
+ * Service for finding <code>ExecutionEnvironment</code>s.
+ *
+ * @author David Withers
+ */
+public interface ExecutionEnvironmentService {
+
+	/**
+	 * Returns the available <code>ExecutionEnvironment</code>s.
+	 *
+	 * @return the available <code>ExecutionEnvironment</code>s
+	 */
+	public Set<ExecutionEnvironment> getExecutionEnvironments();
+
+	/**
+	 * Returns the <code>ExecutionEnvironment</code>s that can execute the specified
+	 * <code>Profile</code>.
+	 *
+	 * @param profile
+	 *            the <code>Profile</code> to find <code>ExecutionEnvironment</code>s for
+	 * @return the <code>ExecutionEnvironment</code>s that can execute a workflow with the specified
+	 *         <code>Profile</code>
+	 */
+	public Set<ExecutionEnvironment> getExecutionEnvironments(Profile profile);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/ExecutionService.java
----------------------------------------------------------------------
diff --git a/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/ExecutionService.java b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/ExecutionService.java
new file mode 100755
index 0000000..2ae7067
--- /dev/null
+++ b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/ExecutionService.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (C) 2010 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package uk.org.taverna.platform.execution.api;
+
+import java.util.Set;
+
+import org.purl.wf4ever.robundle.Bundle;
+
+import uk.org.taverna.platform.report.WorkflowReport;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.core.Workflow;
+import uk.org.taverna.scufl2.api.profiles.Profile;
+
+/**
+ * Service for executing Taverna workflows. There may be several <code>ExecutionService</code>s
+ * available that offer different execution environments, e.g. one <code>ExecutionService</code> may
+ * execute workflows on a remote server while another executes workflows on the local machine.
+ *
+ * @author David Withers
+ */
+public interface ExecutionService {
+
+	/**
+	 * Returns the identifier for this ExecutionService.
+	 *
+	 * @return the identifier for this ExecutionService
+	 */
+	public String getID();
+
+	/**
+	 * Returns the name of this ExecutionService.
+	 *
+	 * @return the name of this ExecutionService
+	 */
+	public String getName();
+
+	/**
+	 * Returns a description of this ExecutionService.
+	 *
+	 * @return a description of this ExecutionService
+	 */
+	public String getDescription();
+
+	/**
+	 * Returns the ExecutionEnvironments available for this ExecutionService.
+	 *
+	 * @return the ExecutionEnvironments available for this ExecutionService
+	 */
+	public Set<ExecutionEnvironment> getExecutionEnvironments();
+
+	/**
+	 * Creates a workflow execution and returns its ID.
+	 *
+	 * @param executionEnvironment
+	 *            the {@link ExecutionEnvironment} used to execute the
+	 *            <code>Workflow</code>
+	 * @param workflowBundle
+	 *            the <code>WorkflowBundle</code> containing the workflows required for execution
+	 * @param workflow
+	 *            the workflow to execute
+	 * @param profile
+	 *            the profile to use when executing the workflow
+	 * @param dataBundle
+	 *            the <code>Bundle</code> containing the data values for the <code>Workflow</code>
+	 * @return the ID of the created workflow execution
+	 * @throws InvalidWorkflowException
+	 */
+	public String createExecution(ExecutionEnvironment executionEnvironment, WorkflowBundle workflowBundle, Workflow workflow, Profile profile,
+			Bundle dataBundle)
+			throws InvalidWorkflowException;
+
+	/**
+	 * Returns the workflow report for the specified execution.
+	 *
+	 * @param executionID
+	 *            the ID of the execution
+	 * @return the workflow report for this execution
+	 */
+	public WorkflowReport getWorkflowReport(String executionID) throws InvalidExecutionIdException;
+
+	/**
+	 * Deletes the execution of a workflow.
+	 *
+	 * @param executionID
+	 *            the ID of the execution to delete
+	 * @throws InvalidExecutionIdException
+	 *             if the execution ID is not valid
+	 */
+	public void delete(String executionID) throws InvalidExecutionIdException;
+
+	/**
+	 * Starts the execution of a workflow.
+	 *
+	 * @param executionID
+	 *            the ID of the execution to start
+	 * @throws InvalidExecutionIdException
+	 *             if the execution ID is not valid
+	 */
+	public void start(String executionID) throws InvalidExecutionIdException;
+
+	/**
+	 * Pauses the execution of a workflow.
+	 *
+	 * @param executionID
+	 *            the ID of the execution to pause
+	 * @throws InvalidExecutionIdException
+	 *             if the execution ID is not valid
+	 */
+	public void pause(String executionID) throws InvalidExecutionIdException;
+
+	/**
+	 * Resumes the execution of a paused workflow.
+	 *
+	 * @param executionID
+	 *            the ID of the execution to resume
+	 * @throws InvalidExecutionIdException
+	 *             if the execution ID is not valid
+	 */
+	public void resume(String executionID) throws InvalidExecutionIdException;
+
+	/**
+	 * Cancels the execution of a workflow.
+	 *
+	 * @param executionID
+	 *            the ID of the execution to cancel
+	 * @throws InvalidExecutionIdException
+	 *             if the execution ID is not valid
+	 */
+	public void cancel(String executionID) throws InvalidExecutionIdException;
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/InvalidExecutionIdException.java
----------------------------------------------------------------------
diff --git a/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/InvalidExecutionIdException.java b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/InvalidExecutionIdException.java
new file mode 100644
index 0000000..9cb8ef2
--- /dev/null
+++ b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/InvalidExecutionIdException.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2010 The University of Manchester   
+ * 
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ * 
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *    
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *    
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package uk.org.taverna.platform.execution.api;
+
+/**
+ * Thrown when an executionID is not valid for an ExecutionService.
+ * 
+ * @author David Withers
+ */
+public class InvalidExecutionIdException extends Exception {
+
+	private static final long serialVersionUID = 4086661335641172903L;
+
+	public InvalidExecutionIdException() {
+    	super();
+    }
+
+    public InvalidExecutionIdException(String message) {
+    	super(message);
+    }
+
+    public InvalidExecutionIdException(String message, Throwable cause) {
+    	super(message, cause);
+    }
+
+    public InvalidExecutionIdException(Throwable cause) {
+    	super(cause);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/InvalidWorkflowException.java
----------------------------------------------------------------------
diff --git a/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/InvalidWorkflowException.java b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/InvalidWorkflowException.java
new file mode 100644
index 0000000..b0cc3fa
--- /dev/null
+++ b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/InvalidWorkflowException.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) 2010 The University of Manchester   
+ * 
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ * 
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *    
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *    
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package uk.org.taverna.platform.execution.api;
+
+/**
+ * Thrown when a Workflow fails to validate.
+ * 
+ * @author David Withers
+ */
+public class InvalidWorkflowException extends Exception {
+
+	private static final long serialVersionUID = 7491175798204912590L;
+
+	public InvalidWorkflowException() {
+		super();
+	}
+
+	public InvalidWorkflowException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	public InvalidWorkflowException(String message) {
+		super(message);
+	}
+
+	public InvalidWorkflowException(Throwable cause) {
+		super(cause);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/WorkflowCompiler.java
----------------------------------------------------------------------
diff --git a/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/WorkflowCompiler.java b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/WorkflowCompiler.java
new file mode 100644
index 0000000..70b8fcd
--- /dev/null
+++ b/taverna-execution-api/src/main/java/uk/org/taverna/platform/execution/api/WorkflowCompiler.java
@@ -0,0 +1,36 @@
+package uk.org.taverna.platform.execution.api;
+
+import net.sf.taverna.t2.workflowmodel.Dataflow;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.core.Workflow;
+
+/**
+ * A workflow compilation service converts a workflow (in a
+ * {@link WorkflowBundle}) into a dataflow. Most code should ignore this.
+ * 
+ * @author Donal Fellows
+ */
+public interface WorkflowCompiler {
+	/**
+	 * Convert a workflow into a dataflow. May cache.
+	 * 
+	 * @param workflow
+	 *            the workflow to convert; must not be <tt>null</tt>
+	 * @return the dataflow, which should not be modified.
+	 * @throws InvalidWorkflowException
+	 *             If the compilation fails.
+	 */
+	Dataflow getDataflow(Workflow workflow) throws InvalidWorkflowException;
+	
+	/**
+	 * Convert a workflow bundle into a dataflow. May cache. Only the the
+	 * primary workflow is guaranteed to be converted.
+	 * 
+	 * @param bundle
+	 *            the workflow bundle to convert; must not be <tt>null</tt>
+	 * @return the dataflow, which should not be modified.
+	 * @throws InvalidWorkflowException
+	 *             If the compilation fails.
+	 */
+	Dataflow getDataflow(WorkflowBundle bundle) throws InvalidWorkflowException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/246a16e2/taverna-execution-api/src/test/java/uk/org/taverna/platform/execution/api/AbstractExecutionTest.java
----------------------------------------------------------------------
diff --git a/taverna-execution-api/src/test/java/uk/org/taverna/platform/execution/api/AbstractExecutionTest.java b/taverna-execution-api/src/test/java/uk/org/taverna/platform/execution/api/AbstractExecutionTest.java
new file mode 100644
index 0000000..635527e
--- /dev/null
+++ b/taverna-execution-api/src/test/java/uk/org/taverna/platform/execution/api/AbstractExecutionTest.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (C) 2010 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package uk.org.taverna.platform.execution.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.purl.wf4ever.robundle.Bundle;
+
+import uk.org.taverna.databundle.DataBundles;
+import uk.org.taverna.platform.report.ActivityReport;
+import uk.org.taverna.platform.report.ProcessorReport;
+import uk.org.taverna.platform.report.WorkflowReport;
+import uk.org.taverna.scufl2.api.activity.Activity;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.core.Processor;
+import uk.org.taverna.scufl2.api.core.Workflow;
+import uk.org.taverna.scufl2.api.profiles.Profile;
+
+/**
+ * @author David Withers
+ */
+@Ignore
+public class AbstractExecutionTest {
+	private WorkflowBundle workflowBundle;
+	private Execution execution;
+	private Workflow workflow;
+	private Profile profile;
+	private Bundle dataBundle;
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@Before
+	public void setUp() throws Exception {
+		workflowBundle = new WorkflowBundle();
+		workflow = new Workflow();
+		profile = new Profile();
+		dataBundle = DataBundles.createBundle();
+		execution = new AbstractExecution(workflowBundle, workflow, profile, dataBundle) {
+			@Override
+			public void start() {}
+			@Override
+			public void resume() {}
+			@Override
+			public void pause() {}
+			@Override
+			public void cancel() {}
+			@Override
+			public void delete() {}
+			@Override
+			protected WorkflowReport createWorkflowReport(Workflow workflow) {
+				return new WorkflowReport(workflow) {
+				};
+			}
+			@Override
+			public ProcessorReport createProcessorReport(Processor processor) {
+				return null;
+			}
+			@Override
+			public ActivityReport createActivityReport(Activity activity) {
+				return null;
+			}
+		};
+	}
+
+	/**
+	 * Test method for {@link uk.org.taverna.platform.execution.api.AbstractExecution#getID()}.
+	 */
+	@Test
+	public void testGetID() {
+		assertNotNull(execution.getID());
+		assertEquals(execution.getID(), execution.getID());
+	}
+
+	/**
+	 * Test method for {@link uk.org.taverna.platform.execution.api.AbstractExecution#getWorkflowBundle()}.
+	 */
+	@Test
+	public void testGetWorkflowBundle() {
+		assertEquals(workflowBundle, execution.getWorkflowBundle());
+	}
+
+	/**
+	 * Test method for {@link uk.org.taverna.platform.execution.api.AbstractExecution#getWorkflow()}.
+	 */
+	@Test
+	public void testGetWorkflow() {
+		assertEquals(workflow, execution.getWorkflow());
+	}
+
+	/**
+	 * Test method for {@link uk.org.taverna.platform.execution.api.AbstractExecution#getInputs()}.
+	 */
+	@Test
+	public void testGetInputs() {
+		assertEquals(dataBundle, execution.getDataBundle());
+	}
+
+	/**
+	 * Test method for {@link uk.org.taverna.platform.execution.api.AbstractExecution#getWorkflowReport()}.
+	 */
+	@Test
+	public void testGetWorkflowReport() {
+		assertNotNull(execution.getWorkflowReport());
+	}
+}