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:35:54 UTC

[39/58] [abbrv] incubator-taverna-plugin-component git commit: org.apache.taverna.component.activity

org.apache.taverna.component.activity

Project: http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/commit/40c404c1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/tree/40c404c1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/diff/40c404c1

Branch: refs/heads/master
Commit: 40c404c1d8423d186db2374b675b5669fbc2dd25
Parents: fb982e2
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Sat Feb 21 19:30:27 2015 +0000
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Sat Feb 21 19:30:27 2015 +0000

----------------------------------------------------------------------
 .../taverna/component/ComponentActivity.java    | 152 -----------
 .../ComponentActivityConfigurationBean.java     | 145 -----------
 .../component/ComponentActivityFactory.java     | 125 ----------
 .../ComponentActivityLocalChecker.java          |  52 ----
 .../ComponentActivityUpgradeChecker.java        |  69 -----
 .../component/ComponentExceptionFactory.java    |  27 --
 .../taverna/component/ComponentHealthCheck.java |  24 --
 .../ComponentImplementationException.java       |  26 --
 .../apache/taverna/component/ProxyCallback.java | 250 -------------------
 .../component/activity/ComponentActivity.java   | 152 +++++++++++
 .../ComponentActivityConfigurationBean.java     | 145 +++++++++++
 .../activity/ComponentActivityFactory.java      | 125 ++++++++++
 .../activity/ComponentActivityLocalChecker.java |  52 ++++
 .../ComponentActivityUpgradeChecker.java        |  69 +++++
 .../activity/ComponentExceptionFactory.java     |  27 ++
 .../activity/ComponentHealthCheck.java          |  24 ++
 .../ComponentImplementationException.java       |  26 ++
 .../component/activity/ProxyCallback.java       | 250 +++++++++++++++++++
 .../component/activity/package-info.java        |   8 +
 .../spring/component-activity-context.xml       |   6 +-
 .../component/ComponentActivityTest.java        |   6 +-
 21 files changed, 884 insertions(+), 876 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivity.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivity.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivity.java
deleted file mode 100644
index db10175..0000000
--- a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivity.java
+++ /dev/null
@@ -1,152 +0,0 @@
-package org.apache.taverna.component;
-
-import static net.sf.taverna.t2.workflowmodel.utils.AnnotationTools.getAnnotationString;
-import static net.sf.taverna.t2.workflowmodel.utils.AnnotationTools.setAnnotationString;
-import static org.apache.log4j.Logger.getLogger;
-
-import java.net.MalformedURLException;
-import java.util.Map;
-
-import net.sf.taverna.t2.activities.dataflow.DataflowActivity;
-import net.sf.taverna.t2.annotation.annotationbeans.SemanticAnnotation;
-import net.sf.taverna.t2.invocation.InvocationContext;
-import net.sf.taverna.t2.invocation.impl.InvocationContextImpl;
-import net.sf.taverna.t2.reference.ReferenceService;
-import net.sf.taverna.t2.reference.T2Reference;
-import net.sf.taverna.t2.workflowmodel.Dataflow;
-import net.sf.taverna.t2.workflowmodel.EditException;
-import net.sf.taverna.t2.workflowmodel.Edits;
-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 org.apache.log4j.Logger;
-import org.apache.taverna.component.api.ComponentException;
-import org.apache.taverna.component.api.profile.ExceptionHandling;
-import org.apache.taverna.component.registry.ComponentImplementationCache;
-import org.apache.taverna.component.registry.ComponentUtil;
-import org.apache.taverna.component.utils.AnnotationUtils;
-import org.apache.taverna.component.utils.SystemUtils;
-
-import uk.org.taverna.platform.execution.api.InvalidWorkflowException;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-public class ComponentActivity extends
-		AbstractAsynchronousActivity<JsonNode> {
-	public static final String URI = "http://ns.taverna.org.uk/2010/activity/component";
-	private Logger logger = getLogger(ComponentActivity.class);
-
-	private ComponentUtil util;
-	private ComponentImplementationCache cache;
-	private volatile DataflowActivity componentRealization;
-	private JsonNode json;
-	private ComponentActivityConfigurationBean bean;
-	private SystemUtils system;
-	private AnnotationUtils annUtils;
-	private ComponentExceptionFactory cef;
-	
-	private Dataflow realizingDataflow = null;
-
-	ComponentActivity(ComponentUtil util, ComponentImplementationCache cache,
-			Edits edits, SystemUtils system, AnnotationUtils annUtils, ComponentExceptionFactory exnFactory) {
-		this.util = util;
-		this.cache = cache;
-		this.system = system;
-		this.annUtils = annUtils;
-		setEdits(edits);
-		this.componentRealization = new DataflowActivity();
-		this.cef = exnFactory;
-	}
-
-	@Override
-	public void configure(JsonNode json) throws ActivityConfigurationException {
-		this.json = json;
-		try {
-			bean = new ComponentActivityConfigurationBean(json, util, cache);
-		} catch (MalformedURLException e) {
-			throw new ActivityConfigurationException(
-					"failed to understand configuration", e);
-		}
-		try {
-			configurePorts(bean.getPorts());
-		} catch (ComponentException e) {
-			throw new ActivityConfigurationException(
-					"failed to get component realization", e);
-		}
-	}
-
-	@Override
-	public void executeAsynch(Map<String, T2Reference> inputs,
-			AsynchronousActivityCallback callback) {
-		try {
-			ExceptionHandling exceptionHandling = bean.getExceptionHandling();
-			// InvocationContextImpl newContext = copyInvocationContext(callback);
-
-			getComponentRealization().executeAsynch(inputs, new ProxyCallback(
-					callback, callback.getContext(), exceptionHandling, cef));
-		} catch (ActivityConfigurationException e) {
-			callback.fail("Unable to execute component", e);
-		}
-	}
-
-	@SuppressWarnings("unused")
-	private InvocationContextImpl copyInvocationContext(
-			AsynchronousActivityCallback callback) {
-		InvocationContext originalContext = callback.getContext();
-		ReferenceService rs = originalContext.getReferenceService();
-		InvocationContextImpl newContext = new InvocationContextImpl(rs, null);
-		// for (Object o : originalContext.getEntities(Object.class)) {
-		// newContext.addEntity(o);
-		// }
-		return newContext;
-	}
-
-	@Override
-	public JsonNode getConfiguration() {
-		return json;
-	}
-
-	ComponentActivityConfigurationBean getConfigBean() {
-		return bean;
-	}
-
-	private DataflowActivity getComponentRealization()
-			throws ActivityConfigurationException {
-		synchronized (componentRealization) {
-			try {
-				if (componentRealization.getNestedDataflow() == null) {
-					if (realizingDataflow == null)
-						realizingDataflow = system.compile(util
-								.getVersion(bean).getImplementation());
-					componentRealization.setNestedDataflow(realizingDataflow);
-					copyAnnotations();
-				}
-			} catch (ComponentException e) {
-				logger.error("unable to read workflow", e);
-				throw new ActivityConfigurationException(
-						"unable to read workflow", e);
-			} catch (InvalidWorkflowException e) {
-				logger.error("unable to compile workflow", e);
-				throw new ActivityConfigurationException(
-						"unable to compile workflow", e);
-			}
-		}
-		
-		return componentRealization;
-	}
-
-	private void copyAnnotations() {
-		// FIXME Completely wrong way of doing this!
-		try {
-			//annUtils.getAnnotation(subject, uriForAnnotation)
-			String annotationValue = getAnnotationString(realizingDataflow,
-					SemanticAnnotation.class, null);
-			if (annotationValue != null)
-				setAnnotationString(this, SemanticAnnotation.class,
-						annotationValue, getEdits()).doEdit();
-		} catch (EditException e) {
-			logger.error("failed to set annotation string", e);
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityConfigurationBean.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityConfigurationBean.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityConfigurationBean.java
deleted file mode 100644
index 45448b5..0000000
--- a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityConfigurationBean.java
+++ /dev/null
@@ -1,145 +0,0 @@
-package org.apache.taverna.component;
-
-import static org.apache.log4j.Logger.getLogger;
-import static org.apache.taverna.component.api.config.ComponentPropertyNames.COMPONENT_NAME;
-import static org.apache.taverna.component.api.config.ComponentPropertyNames.COMPONENT_VERSION;
-import static org.apache.taverna.component.api.config.ComponentPropertyNames.FAMILY_NAME;
-import static org.apache.taverna.component.api.config.ComponentPropertyNames.REGISTRY_BASE;
-
-import java.io.Serializable;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean;
-import net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean;
-import net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityPortsDefinitionBean;
-
-import org.apache.log4j.Logger;
-import org.apache.taverna.component.api.Version;
-import org.apache.taverna.component.api.profile.ExceptionHandling;
-import org.apache.taverna.component.registry.ComponentImplementationCache;
-import org.apache.taverna.component.registry.ComponentUtil;
-import org.apache.taverna.component.registry.ComponentVersionIdentification;
-
-import uk.org.taverna.scufl2.api.container.WorkflowBundle;
-import uk.org.taverna.scufl2.api.port.InputWorkflowPort;
-import uk.org.taverna.scufl2.api.port.OutputWorkflowPort;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-/**
- * Component activity configuration bean.
- */
-public class ComponentActivityConfigurationBean extends
-		ComponentVersionIdentification implements Serializable {
-	public static final String ERROR_CHANNEL = "error_channel";
-	public static final List<String> ignorableNames = Arrays
-			.asList(ERROR_CHANNEL);
-	private static final long serialVersionUID = 5774901665863468058L;
-	private static final Logger logger = getLogger(ComponentActivity.class);
-
-	private transient ActivityPortsDefinitionBean ports = null;
-	private transient ExceptionHandling eh;
-	private transient ComponentUtil util;
-	private transient ComponentImplementationCache cache;
-
-	public ComponentActivityConfigurationBean(Version.ID toBeCopied,
-			ComponentUtil util, ComponentImplementationCache cache) {
-		super(toBeCopied);
-		this.util = util;
-		this.cache = cache;
-		try {
-			getPorts();
-		} catch (org.apache.taverna.component.api.ComponentException e) {
-			logger.error("failed to get component realization", e);
-		}
-	}
-
-	public ComponentActivityConfigurationBean(JsonNode json,
-			ComponentUtil util, ComponentImplementationCache cache) throws MalformedURLException {
-		super(getUrl(json), getFamily(json), getComponent(json),
-				getVersion(json));
-		this.util = util;
-		this.cache = cache;
-	}
-
-	private static URL getUrl(JsonNode json) throws MalformedURLException {
-		return new URL(json.get(REGISTRY_BASE).textValue());
-	}
-
-	private static String getFamily(JsonNode json) {
-		return json.get(FAMILY_NAME).textValue();
-	}
-
-	private static String getComponent(JsonNode json) {
-		return json.get(COMPONENT_NAME).textValue();
-	}
-
-	private static Integer getVersion(JsonNode json) {
-		JsonNode node = json.get(COMPONENT_VERSION);
-		if (node == null || !node.isInt())
-			return null;
-		return node.intValue();
-	}
-
-	private ActivityPortsDefinitionBean getPortsDefinition(WorkflowBundle w) {
-		ActivityPortsDefinitionBean result = new ActivityPortsDefinitionBean();
-		List<ActivityInputPortDefinitionBean> inputs = result
-				.getInputPortDefinitions();
-		List<ActivityOutputPortDefinitionBean> outputs = result
-				.getOutputPortDefinitions();
-
-		for (InputWorkflowPort iwp : w.getMainWorkflow().getInputPorts())
-			inputs.add(makeInputDefinition(iwp));
-		for (OutputWorkflowPort owp : w.getMainWorkflow().getOutputPorts())
-			outputs.add(makeOutputDefinition(0, owp.getName()));//FIXME
-
-		try {
-			eh = util.getFamily(getRegistryBase(), getFamilyName())
-					.getComponentProfile().getExceptionHandling();
-			if (eh != null)
-				outputs.add(makeOutputDefinition(1, ERROR_CHANNEL));
-		} catch (org.apache.taverna.component.api.ComponentException e) {
-			logger.error("failed to get exception handling for family", e);
-		}
-		return result;
-	}
-
-	private ActivityInputPortDefinitionBean makeInputDefinition(
-			InputWorkflowPort dip) {
-		ActivityInputPortDefinitionBean activityInputPortDefinitionBean = new ActivityInputPortDefinitionBean();
-		activityInputPortDefinitionBean.setHandledReferenceSchemes(null);
-		activityInputPortDefinitionBean.setMimeTypes((List<String>) null);
-		activityInputPortDefinitionBean.setTranslatedElementType(String.class);
-		activityInputPortDefinitionBean.setAllowsLiteralValues(true);
-		activityInputPortDefinitionBean.setDepth(dip.getDepth());
-		activityInputPortDefinitionBean.setName(dip.getName());
-		return activityInputPortDefinitionBean;
-	}
-
-	private ActivityOutputPortDefinitionBean makeOutputDefinition(int depth,
-			String name) {
-		ActivityOutputPortDefinitionBean activityOutputPortDefinitionBean = new ActivityOutputPortDefinitionBean();
-		activityOutputPortDefinitionBean.setMimeTypes(new ArrayList<String>());
-		activityOutputPortDefinitionBean.setDepth(depth);
-		activityOutputPortDefinitionBean.setGranularDepth(depth);
-		activityOutputPortDefinitionBean.setName(name);
-		return activityOutputPortDefinitionBean;
-	}
-
-	/**
-	 * @return the ports
-	 */
-	public ActivityPortsDefinitionBean getPorts() throws org.apache.taverna.component.api.ComponentException{
-		if (ports == null)
-			ports = getPortsDefinition(cache.getImplementation(this));
-		return ports;
-	}
-
-	public ExceptionHandling getExceptionHandling() {
-		return eh;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityFactory.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityFactory.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityFactory.java
deleted file mode 100644
index 59e893d..0000000
--- a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityFactory.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package org.apache.taverna.component;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-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.ActivityConfigurationException;
-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 net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean;
-import net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean;
-
-import org.apache.taverna.component.api.ComponentException;
-import org.apache.taverna.component.api.Version.ID;
-import org.apache.taverna.component.registry.ComponentImplementationCache;
-import org.apache.taverna.component.registry.ComponentUtil;
-import org.apache.taverna.component.utils.AnnotationUtils;
-import org.apache.taverna.component.utils.SystemUtils;
-import org.springframework.beans.factory.annotation.Required;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-public class ComponentActivityFactory extends ComponentExceptionFactory
-		implements ActivityFactory {
-	private ComponentUtil util;
-	private ComponentImplementationCache cache;
-	private Edits edits;
-	private SystemUtils system;
-	private AnnotationUtils annUtils;
-
-	@Override
-	public ComponentActivity createActivity() {
-		return new ComponentActivity(util, cache, edits, system, annUtils, this);
-	}
-
-	@Override
-	public URI getActivityType() {
-		return URI.create(ComponentActivity.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)
-			throws ActivityConfigurationException {
-		try {
-			Set<ActivityInputPort> activityInputPorts = new HashSet<>();
-			for (ActivityInputPortDefinitionBean ipd : createConfiguration(
-					configuration).getPorts().getInputPortDefinitions())
-				activityInputPorts.add(edits.createActivityInputPort(
-						ipd.getName(), ipd.getDepth(), true, null,
-						ipd.getTranslatedElementType()));
-			return activityInputPorts;
-		} catch (MalformedURLException | ComponentException | RuntimeException e) {
-			throw new ActivityConfigurationException(
-					"failed to get implementation for configuration of inputs",
-					e);
-		}
-	}
-
-	@Override
-	public Set<ActivityOutputPort> getOutputPorts(JsonNode configuration)
-			throws ActivityConfigurationException {
-		try {
-			Set<ActivityOutputPort> activityOutputPorts = new HashSet<>();
-			for (ActivityOutputPortDefinitionBean opd : createConfiguration(
-					configuration).getPorts().getOutputPortDefinitions())
-				activityOutputPorts.add(edits.createActivityOutputPort(
-						opd.getName(), opd.getDepth(), opd.getGranularDepth()));
-			return activityOutputPorts;
-		} catch (MalformedURLException | ComponentException | RuntimeException e) {
-			throw new ActivityConfigurationException(
-					"failed to get implementation for configuration of outputs",
-					e);
-		}
-	}
-
-	public ComponentActivityConfigurationBean createConfiguration(ID id) {
-		return new ComponentActivityConfigurationBean(id, util, cache);
-	}
-
-	public ComponentActivityConfigurationBean createConfiguration(JsonNode json)
-			throws MalformedURLException {
-		return new ComponentActivityConfigurationBean(json, util, cache);
-	}
-
-	@Required
-	public void setComponentUtil(ComponentUtil util) {
-		this.util = util;
-	}
-
-	@Required
-	public void setDataflowCache(ComponentImplementationCache cache) {
-		this.cache = cache;
-	}
-
-	@Required
-	public void setEdits(Edits edits) {
-		this.edits = edits;
-	}
-
-	@Required
-	public void setSystemUtil(SystemUtils system) {
-		this.system = system;
-	}
-
-	@Required
-	public void setAnnotationUtils(AnnotationUtils annUtils) {
-		this.annUtils = annUtils;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityLocalChecker.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityLocalChecker.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityLocalChecker.java
deleted file mode 100644
index 32baaf6..0000000
--- a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityLocalChecker.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.apache.taverna.component;
-
-import static net.sf.taverna.t2.visit.VisitReport.Status.WARNING;
-import static org.apache.taverna.component.ComponentHealthCheck.NON_SHAREABLE;
-
-import java.util.List;
-
-import net.sf.taverna.t2.visit.VisitKind;
-import net.sf.taverna.t2.visit.VisitReport;
-import net.sf.taverna.t2.workflowmodel.health.HealthChecker;
-
-/**
- * Component health checker
- * 
- */
-public class ComponentActivityLocalChecker implements
-		HealthChecker<ComponentActivity> {
-	private static final VisitKind visitKind = ComponentHealthCheck
-			.getInstance();
-
-	@Override
-	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 ComponentActivity where a certain configuration option is
-		 * enabled.
-		 */
-		return o instanceof ComponentActivity;
-	}
-
-	@Override
-	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;
-	}
-
-	@Override
-	public VisitReport visit(ComponentActivity activity, List<Object> ancestry) {
-		if (!activity.getConfigBean().getRegistryBase().getProtocol()
-				.startsWith("http"))
-			return new VisitReport(visitKind, activity,
-					"Local component makes workflow non-shareable",
-					NON_SHAREABLE, WARNING);
-		return null;
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityUpgradeChecker.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityUpgradeChecker.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityUpgradeChecker.java
deleted file mode 100644
index 3304cc4..0000000
--- a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentActivityUpgradeChecker.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * 
- */
-package org.apache.taverna.component;
-
-import static net.sf.taverna.t2.visit.VisitReport.Status.WARNING;
-import static org.apache.log4j.Logger.getLogger;
-import static org.apache.taverna.component.ComponentHealthCheck.OUT_OF_DATE;
-
-import java.util.List;
-
-import net.sf.taverna.t2.visit.VisitKind;
-import net.sf.taverna.t2.visit.VisitReport;
-import net.sf.taverna.t2.workflowmodel.health.HealthChecker;
-
-import org.apache.log4j.Logger;
-import org.apache.taverna.component.api.ComponentException;
-import org.apache.taverna.component.registry.ComponentUtil;
-import org.springframework.beans.factory.annotation.Required;
-
-/**
- * @author alanrw
- * 
- */
-public class ComponentActivityUpgradeChecker implements
-		HealthChecker<ComponentActivity> {
-	private static final String OUTDATED_MSG = "Component out of date";
-	private static final VisitKind visitKind = ComponentHealthCheck
-			.getInstance();
-	private static Logger logger = getLogger(ComponentActivityUpgradeChecker.class);
-	private ComponentUtil utils;
-
-	@Required
-	public void setComponentUtil(ComponentUtil util) {
-		this.utils = util;
-	}
-
-	@Override
-	public boolean canVisit(Object o) {
-		return o instanceof ComponentActivity;
-	}
-
-	@Override
-	public boolean isTimeConsuming() {
-		return false;
-	}
-
-	@Override
-	public VisitReport visit(ComponentActivity activity, List<Object> ancestry) {
-		ComponentActivityConfigurationBean config = activity.getConfigBean();
-		int versionNumber = config.getComponentVersion();
-		int latestVersion = 0;
-
-		try {
-			latestVersion = utils
-					.getComponent(config.getRegistryBase(),
-							config.getFamilyName(), config.getComponentName())
-					.getComponentVersionMap().lastKey();
-		} catch (ComponentException e) {
-			logger.error("failed to get component description", e);
-		}
-
-		if (latestVersion > versionNumber)
-			return new VisitReport(visitKind, activity, OUTDATED_MSG,
-					OUT_OF_DATE, WARNING);
-		return null;
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentExceptionFactory.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentExceptionFactory.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentExceptionFactory.java
deleted file mode 100644
index 7f100dc..0000000
--- a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentExceptionFactory.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * 
- */
-package org.apache.taverna.component;
-
-/**
- * @author alanrw
- * 
- */
-class ComponentExceptionFactory {
-	private static final String UNEXPECTED_ID = "http://ns.taverna.org.uk/2012/component/unexpected";
-
-	ComponentExceptionFactory() {
-	}
-
-	public ComponentImplementationException createComponentException(
-			String exceptionId, String message) {
-		ComponentImplementationException result = new ComponentImplementationException(message);
-		result.setExceptionId(exceptionId);
-		return result;
-	}
-
-	public ComponentImplementationException createUnexpectedComponentException(
-			String message) {
-		return createComponentException(UNEXPECTED_ID, message);
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentHealthCheck.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentHealthCheck.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentHealthCheck.java
deleted file mode 100644
index dee1052..0000000
--- a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentHealthCheck.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.apache.taverna.component;
-
-import net.sf.taverna.t2.visit.VisitKind;
-import net.sf.taverna.t2.visit.Visitor;
-
-public class ComponentHealthCheck extends VisitKind {
-	public static final int NO_PROBLEM = 0;
-	public static final int OUT_OF_DATE = 10;
-	public static final int NON_SHAREABLE = 20;
-	public static final int FAILS_PROFILE = 30;
-
-	@Override
-	public Class<? extends Visitor<?>> getVisitorClass() {
-		return ComponentActivityUpgradeChecker.class;
-	}
-
-	private static class Singleton {
-		private static ComponentHealthCheck instance = new ComponentHealthCheck();
-	}
-
-	public static ComponentHealthCheck getInstance() {
-		return Singleton.instance;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentImplementationException.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentImplementationException.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentImplementationException.java
deleted file mode 100644
index f443f6d..0000000
--- a/taverna-component-activity/src/main/java/org/apache/taverna/component/ComponentImplementationException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * 
- */
-package org.apache.taverna.component;
-
-/**
- * @author alanrw
- * 
- */
-public class ComponentImplementationException extends Exception {
-	public ComponentImplementationException(String string) {
-		super(string);
-		this.setStackTrace(new StackTraceElement[] {});
-	}
-
-	private static final long serialVersionUID = -3844030382222698090L;
-	private String exceptionId;
-
-	public void setExceptionId(String exceptionId) {
-		this.exceptionId = exceptionId;
-	}
-
-	public String getExceptionId() {
-		return exceptionId;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/ProxyCallback.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/ProxyCallback.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/ProxyCallback.java
deleted file mode 100644
index 3e7d2cd..0000000
--- a/taverna-component-activity/src/main/java/org/apache/taverna/component/ProxyCallback.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/**
- * 
- */
-package org.apache.taverna.component;
-
-import static net.sf.taverna.t2.reference.T2ReferenceType.ErrorDocument;
-import static net.sf.taverna.t2.reference.T2ReferenceType.IdentifiedList;
-import static net.sf.taverna.t2.reference.T2ReferenceType.ReferenceSet;
-import static org.apache.log4j.Logger.getLogger;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.xml.ws.Holder;
-
-import net.sf.taverna.t2.invocation.InvocationContext;
-import net.sf.taverna.t2.reference.ErrorDocument;
-import net.sf.taverna.t2.reference.ErrorDocumentService;
-import net.sf.taverna.t2.reference.IdentifiedList;
-import net.sf.taverna.t2.reference.ListService;
-import net.sf.taverna.t2.reference.ReferenceService;
-import net.sf.taverna.t2.reference.T2Reference;
-import net.sf.taverna.t2.workflowmodel.processor.activity.AsynchronousActivityCallback;
-import net.sf.taverna.t2.workflowmodel.processor.dispatch.events.DispatchErrorType;
-
-import org.apache.log4j.Logger;
-import org.apache.taverna.component.api.profile.ExceptionHandling;
-import org.apache.taverna.component.api.profile.ExceptionReplacement;
-import org.apache.taverna.component.api.profile.HandleException;
-
-/**
- * @author alanrw
- * 
- */
-public class ProxyCallback implements AsynchronousActivityCallback {
-	private static final Logger logger = getLogger(ProxyCallback.class);
-
-	private final ComponentExceptionFactory cef;
-	private final AsynchronousActivityCallback proxiedCallback;
-	private final ReferenceService references;
-	private final InvocationContext context;
-	private final ExceptionHandling exceptionHandling;
-	private final ListService lists;
-	private final ErrorDocumentService errors;
-
-	/**
-	 * @param proxiedCallback
-	 * @param invocationContext
-	 * @param exceptionHandling
-	 * @param exnFactory
-	 */
-	ProxyCallback(AsynchronousActivityCallback proxiedCallback,
-			InvocationContext invocationContext,
-			ExceptionHandling exceptionHandling,
-			ComponentExceptionFactory exnFactory) {
-		this.proxiedCallback = proxiedCallback;
-		this.exceptionHandling = exceptionHandling;
-		context = invocationContext;
-		references = context.getReferenceService();
-		lists = references.getListService();
-		errors = references.getErrorDocumentService();
-		cef = exnFactory;
-	}
-
-	@Override
-	public InvocationContext getContext() {
-		return context;
-	}
-
-	@Override
-	public void requestRun(Runnable runMe) {
-		proxiedCallback.requestRun(runMe);
-	}
-
-	@Override
-	public void receiveResult(Map<String, T2Reference> data, int[] index) {
-		if (exceptionHandling == null) {
-			proxiedCallback.receiveResult(data, index);
-			return;
-		}
-
-		List<T2Reference> exceptions = new ArrayList<>();
-		Map<String, T2Reference> replacement = new HashMap<>();
-		for (Entry<String, T2Reference> entry : data.entrySet())
-			replacement.put(entry.getKey(),
-					considerReference(entry.getValue(), exceptions));
-		replacement.put("error_channel",
-				references.register(exceptions, 1, true, context));
-		proxiedCallback.receiveResult(replacement, index);
-	}
-
-	private T2Reference considerReference(T2Reference value,
-			List<T2Reference> exceptions) {
-		if (!value.containsErrors())
-			return value;
-		else if (!value.getReferenceType().equals(IdentifiedList))
-			return replaceErrors(value, value.getDepth(), exceptions);
-		else if (exceptionHandling.failLists())
-			return replaceErrors(findFirstFailure(value), value.getDepth(),
-					exceptions);
-
-		List<T2Reference> replacementList = new ArrayList<>();
-		for (T2Reference subValue : lists.getList(value))
-			replacementList.add(considerReference(subValue, exceptions));
-		return references.register(replacementList, value.getDepth(), true,
-				context);
-	}
-
-	private T2Reference findFirstFailure(T2Reference value) {
-		IdentifiedList<T2Reference> originalList = lists.getList(value);
-		for (T2Reference subValue : originalList) {
-			if (subValue.getReferenceType().equals(ErrorDocument))
-				return subValue;
-			if (subValue.getReferenceType().equals(IdentifiedList))
-				if (subValue.containsErrors())
-					return findFirstFailure(subValue);
-			// No need to consider value
-		}
-		return null;
-	}
-
-	private T2Reference replaceErrors(T2Reference value, int depth,
-			List<T2Reference> exceptions) {
-		ErrorDocument doc = errors.getError(value);
-
-		Holder<HandleException> handleException = new Holder<>();
-		Set<ErrorDocument> toConsider = new HashSet<>();
-		Set<ErrorDocument> considered = new HashSet<>();
-		toConsider.add(doc);
-
-		while (!toConsider.isEmpty())
-			try {
-				ErrorDocument nudoc = remapException(toConsider, considered,
-						handleException);
-				if (nudoc != null) {
-					doc = nudoc;
-					break;
-				}
-			} catch (Exception e) {
-				logger.error("failed to locate exception mapping", e);
-			}
-
-		String exceptionMessage = doc.getExceptionMessage();
-		// An exception that is not mentioned
-		if (handleException.value == null) {
-			ComponentImplementationException newException = cef
-					.createUnexpectedComponentException(exceptionMessage);
-			T2Reference replacement = errors.registerError(exceptionMessage,
-					newException, depth, context).getId();
-			exceptions.add(errors.registerError(exceptionMessage, newException,
-					0, context).getId());
-			return replacement;
-		}
-
-		if (handleException.value.pruneStack())
-			doc.getStackTraceStrings().clear();
-
-		ExceptionReplacement exnReplacement = handleException.value
-				.getReplacement();
-		if (exnReplacement == null) {
-			T2Reference replacement = references.register(doc, depth, true,
-					context);
-			exceptions.add(references.register(doc, 0, true, context));
-			return replacement;
-		}
-
-		ComponentImplementationException newException = cef
-				.createComponentException(exnReplacement.getReplacementId(),
-						exnReplacement.getReplacementMessage());
-		T2Reference replacement = errors.registerError(
-				exnReplacement.getReplacementMessage(), newException, depth,
-				context).getId();
-		exceptions.add(errors.registerError(
-				exnReplacement.getReplacementMessage(), newException, 0,
-				context).getId());
-		return replacement;
-	}
-
-	private ErrorDocument remapException(Set<ErrorDocument> toConsider,
-			Set<ErrorDocument> considered,
-			Holder<HandleException> handleException) {
-		ErrorDocument found = null;
-		ErrorDocument errorDoc = toConsider.iterator().next();
-
-		considered.add(errorDoc);
-		toConsider.remove(errorDoc);
-		String exceptionMessage = errorDoc.getExceptionMessage();
-		for (HandleException he : exceptionHandling.getHandleExceptions()) {
-			if (!he.matches(exceptionMessage))
-				continue;
-			handleException.value = he;
-			found = errorDoc;
-		}
-		if (!errorDoc.getErrorReferences().isEmpty())
-			for (T2Reference subRef : errorDoc.getErrorReferences())
-				for (T2Reference newErrorRef : getErrors(subRef)) {
-					ErrorDocument subDoc = errors.getError(newErrorRef);
-					if (subDoc == null)
-						logger.error("Error document contains references to non-existent sub-errors");
-					else if (!considered.contains(subDoc))
-						toConsider.add(subDoc);
-				}
-		return found;
-	}
-
-	private Set<T2Reference> getErrors(T2Reference ref) {
-		Set<T2Reference> result = new HashSet<>();
-		if (ref.getReferenceType().equals(ReferenceSet)) {
-			// nothing
-		} else if (ref.getReferenceType().equals(IdentifiedList)) {
-			IdentifiedList<T2Reference> originalList = lists.getList(ref);
-			for (T2Reference subValue : originalList)
-				if (subValue.containsErrors())
-					result.addAll(getErrors(subValue));
-		} else
-			result.add(ref);
-		return result;
-	}
-
-	@Override
-	public void receiveCompletion(int[] completionIndex) {
-		proxiedCallback.receiveCompletion(completionIndex);
-	}
-
-	@Override
-	public void fail(String message, Throwable t, DispatchErrorType errorType) {
-		proxiedCallback.fail(message, t, errorType);
-	}
-
-	@Override
-	public void fail(String message, Throwable t) {
-		proxiedCallback.fail(message, t);
-	}
-
-	@Override
-	public void fail(String message) {
-		proxiedCallback.fail(message);
-	}
-
-	@Override
-	public String getParentProcessIdentifier() {
-		// return "";
-		return proxiedCallback.getParentProcessIdentifier();
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivity.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivity.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivity.java
new file mode 100644
index 0000000..aa5550c
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivity.java
@@ -0,0 +1,152 @@
+package org.apache.taverna.component.activity;
+
+import static net.sf.taverna.t2.workflowmodel.utils.AnnotationTools.getAnnotationString;
+import static net.sf.taverna.t2.workflowmodel.utils.AnnotationTools.setAnnotationString;
+import static org.apache.log4j.Logger.getLogger;
+
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import net.sf.taverna.t2.activities.dataflow.DataflowActivity;
+import net.sf.taverna.t2.annotation.annotationbeans.SemanticAnnotation;
+import net.sf.taverna.t2.invocation.InvocationContext;
+import net.sf.taverna.t2.invocation.impl.InvocationContextImpl;
+import net.sf.taverna.t2.reference.ReferenceService;
+import net.sf.taverna.t2.reference.T2Reference;
+import net.sf.taverna.t2.workflowmodel.Dataflow;
+import net.sf.taverna.t2.workflowmodel.EditException;
+import net.sf.taverna.t2.workflowmodel.Edits;
+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 org.apache.log4j.Logger;
+import org.apache.taverna.component.api.ComponentException;
+import org.apache.taverna.component.api.profile.ExceptionHandling;
+import org.apache.taverna.component.registry.ComponentImplementationCache;
+import org.apache.taverna.component.registry.ComponentUtil;
+import org.apache.taverna.component.utils.AnnotationUtils;
+import org.apache.taverna.component.utils.SystemUtils;
+
+import uk.org.taverna.platform.execution.api.InvalidWorkflowException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class ComponentActivity extends
+		AbstractAsynchronousActivity<JsonNode> {
+	public static final String URI = "http://ns.taverna.org.uk/2010/activity/component";
+	private Logger logger = getLogger(ComponentActivity.class);
+
+	private ComponentUtil util;
+	private ComponentImplementationCache cache;
+	private volatile DataflowActivity componentRealization;
+	private JsonNode json;
+	private ComponentActivityConfigurationBean bean;
+	private SystemUtils system;
+	private AnnotationUtils annUtils;
+	private ComponentExceptionFactory cef;
+	
+	private Dataflow realizingDataflow = null;
+
+	ComponentActivity(ComponentUtil util, ComponentImplementationCache cache,
+			Edits edits, SystemUtils system, AnnotationUtils annUtils, ComponentExceptionFactory exnFactory) {
+		this.util = util;
+		this.cache = cache;
+		this.system = system;
+		this.annUtils = annUtils;
+		setEdits(edits);
+		this.componentRealization = new DataflowActivity();
+		this.cef = exnFactory;
+	}
+
+	@Override
+	public void configure(JsonNode json) throws ActivityConfigurationException {
+		this.json = json;
+		try {
+			bean = new ComponentActivityConfigurationBean(json, util, cache);
+		} catch (MalformedURLException e) {
+			throw new ActivityConfigurationException(
+					"failed to understand configuration", e);
+		}
+		try {
+			configurePorts(bean.getPorts());
+		} catch (ComponentException e) {
+			throw new ActivityConfigurationException(
+					"failed to get component realization", e);
+		}
+	}
+
+	@Override
+	public void executeAsynch(Map<String, T2Reference> inputs,
+			AsynchronousActivityCallback callback) {
+		try {
+			ExceptionHandling exceptionHandling = bean.getExceptionHandling();
+			// InvocationContextImpl newContext = copyInvocationContext(callback);
+
+			getComponentRealization().executeAsynch(inputs, new ProxyCallback(
+					callback, callback.getContext(), exceptionHandling, cef));
+		} catch (ActivityConfigurationException e) {
+			callback.fail("Unable to execute component", e);
+		}
+	}
+
+	@SuppressWarnings("unused")
+	private InvocationContextImpl copyInvocationContext(
+			AsynchronousActivityCallback callback) {
+		InvocationContext originalContext = callback.getContext();
+		ReferenceService rs = originalContext.getReferenceService();
+		InvocationContextImpl newContext = new InvocationContextImpl(rs, null);
+		// for (Object o : originalContext.getEntities(Object.class)) {
+		// newContext.addEntity(o);
+		// }
+		return newContext;
+	}
+
+	@Override
+	public JsonNode getConfiguration() {
+		return json;
+	}
+
+	ComponentActivityConfigurationBean getConfigBean() {
+		return bean;
+	}
+
+	private DataflowActivity getComponentRealization()
+			throws ActivityConfigurationException {
+		synchronized (componentRealization) {
+			try {
+				if (componentRealization.getNestedDataflow() == null) {
+					if (realizingDataflow == null)
+						realizingDataflow = system.compile(util
+								.getVersion(bean).getImplementation());
+					componentRealization.setNestedDataflow(realizingDataflow);
+					copyAnnotations();
+				}
+			} catch (ComponentException e) {
+				logger.error("unable to read workflow", e);
+				throw new ActivityConfigurationException(
+						"unable to read workflow", e);
+			} catch (InvalidWorkflowException e) {
+				logger.error("unable to compile workflow", e);
+				throw new ActivityConfigurationException(
+						"unable to compile workflow", e);
+			}
+		}
+		
+		return componentRealization;
+	}
+
+	private void copyAnnotations() {
+		// FIXME Completely wrong way of doing this!
+		try {
+			//annUtils.getAnnotation(subject, uriForAnnotation)
+			String annotationValue = getAnnotationString(realizingDataflow,
+					SemanticAnnotation.class, null);
+			if (annotationValue != null)
+				setAnnotationString(this, SemanticAnnotation.class,
+						annotationValue, getEdits()).doEdit();
+		} catch (EditException e) {
+			logger.error("failed to set annotation string", e);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityConfigurationBean.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityConfigurationBean.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityConfigurationBean.java
new file mode 100644
index 0000000..66429cb
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityConfigurationBean.java
@@ -0,0 +1,145 @@
+package org.apache.taverna.component.activity;
+
+import static org.apache.log4j.Logger.getLogger;
+import static org.apache.taverna.component.api.config.ComponentPropertyNames.COMPONENT_NAME;
+import static org.apache.taverna.component.api.config.ComponentPropertyNames.COMPONENT_VERSION;
+import static org.apache.taverna.component.api.config.ComponentPropertyNames.FAMILY_NAME;
+import static org.apache.taverna.component.api.config.ComponentPropertyNames.REGISTRY_BASE;
+
+import java.io.Serializable;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean;
+import net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean;
+import net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityPortsDefinitionBean;
+
+import org.apache.log4j.Logger;
+import org.apache.taverna.component.api.Version;
+import org.apache.taverna.component.api.profile.ExceptionHandling;
+import org.apache.taverna.component.registry.ComponentImplementationCache;
+import org.apache.taverna.component.registry.ComponentUtil;
+import org.apache.taverna.component.registry.ComponentVersionIdentification;
+
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.port.InputWorkflowPort;
+import uk.org.taverna.scufl2.api.port.OutputWorkflowPort;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * Component activity configuration bean.
+ */
+public class ComponentActivityConfigurationBean extends
+		ComponentVersionIdentification implements Serializable {
+	public static final String ERROR_CHANNEL = "error_channel";
+	public static final List<String> ignorableNames = Arrays
+			.asList(ERROR_CHANNEL);
+	private static final long serialVersionUID = 5774901665863468058L;
+	private static final Logger logger = getLogger(ComponentActivity.class);
+
+	private transient ActivityPortsDefinitionBean ports = null;
+	private transient ExceptionHandling eh;
+	private transient ComponentUtil util;
+	private transient ComponentImplementationCache cache;
+
+	public ComponentActivityConfigurationBean(Version.ID toBeCopied,
+			ComponentUtil util, ComponentImplementationCache cache) {
+		super(toBeCopied);
+		this.util = util;
+		this.cache = cache;
+		try {
+			getPorts();
+		} catch (org.apache.taverna.component.api.ComponentException e) {
+			logger.error("failed to get component realization", e);
+		}
+	}
+
+	public ComponentActivityConfigurationBean(JsonNode json,
+			ComponentUtil util, ComponentImplementationCache cache) throws MalformedURLException {
+		super(getUrl(json), getFamily(json), getComponent(json),
+				getVersion(json));
+		this.util = util;
+		this.cache = cache;
+	}
+
+	private static URL getUrl(JsonNode json) throws MalformedURLException {
+		return new URL(json.get(REGISTRY_BASE).textValue());
+	}
+
+	private static String getFamily(JsonNode json) {
+		return json.get(FAMILY_NAME).textValue();
+	}
+
+	private static String getComponent(JsonNode json) {
+		return json.get(COMPONENT_NAME).textValue();
+	}
+
+	private static Integer getVersion(JsonNode json) {
+		JsonNode node = json.get(COMPONENT_VERSION);
+		if (node == null || !node.isInt())
+			return null;
+		return node.intValue();
+	}
+
+	private ActivityPortsDefinitionBean getPortsDefinition(WorkflowBundle w) {
+		ActivityPortsDefinitionBean result = new ActivityPortsDefinitionBean();
+		List<ActivityInputPortDefinitionBean> inputs = result
+				.getInputPortDefinitions();
+		List<ActivityOutputPortDefinitionBean> outputs = result
+				.getOutputPortDefinitions();
+
+		for (InputWorkflowPort iwp : w.getMainWorkflow().getInputPorts())
+			inputs.add(makeInputDefinition(iwp));
+		for (OutputWorkflowPort owp : w.getMainWorkflow().getOutputPorts())
+			outputs.add(makeOutputDefinition(0, owp.getName()));//FIXME
+
+		try {
+			eh = util.getFamily(getRegistryBase(), getFamilyName())
+					.getComponentProfile().getExceptionHandling();
+			if (eh != null)
+				outputs.add(makeOutputDefinition(1, ERROR_CHANNEL));
+		} catch (org.apache.taverna.component.api.ComponentException e) {
+			logger.error("failed to get exception handling for family", e);
+		}
+		return result;
+	}
+
+	private ActivityInputPortDefinitionBean makeInputDefinition(
+			InputWorkflowPort dip) {
+		ActivityInputPortDefinitionBean activityInputPortDefinitionBean = new ActivityInputPortDefinitionBean();
+		activityInputPortDefinitionBean.setHandledReferenceSchemes(null);
+		activityInputPortDefinitionBean.setMimeTypes((List<String>) null);
+		activityInputPortDefinitionBean.setTranslatedElementType(String.class);
+		activityInputPortDefinitionBean.setAllowsLiteralValues(true);
+		activityInputPortDefinitionBean.setDepth(dip.getDepth());
+		activityInputPortDefinitionBean.setName(dip.getName());
+		return activityInputPortDefinitionBean;
+	}
+
+	private ActivityOutputPortDefinitionBean makeOutputDefinition(int depth,
+			String name) {
+		ActivityOutputPortDefinitionBean activityOutputPortDefinitionBean = new ActivityOutputPortDefinitionBean();
+		activityOutputPortDefinitionBean.setMimeTypes(new ArrayList<String>());
+		activityOutputPortDefinitionBean.setDepth(depth);
+		activityOutputPortDefinitionBean.setGranularDepth(depth);
+		activityOutputPortDefinitionBean.setName(name);
+		return activityOutputPortDefinitionBean;
+	}
+
+	/**
+	 * @return the ports
+	 */
+	public ActivityPortsDefinitionBean getPorts() throws org.apache.taverna.component.api.ComponentException{
+		if (ports == null)
+			ports = getPortsDefinition(cache.getImplementation(this));
+		return ports;
+	}
+
+	public ExceptionHandling getExceptionHandling() {
+		return eh;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityFactory.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityFactory.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityFactory.java
new file mode 100644
index 0000000..4c1b4f4
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityFactory.java
@@ -0,0 +1,125 @@
+package org.apache.taverna.component.activity;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+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.ActivityConfigurationException;
+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 net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean;
+import net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean;
+
+import org.apache.taverna.component.api.ComponentException;
+import org.apache.taverna.component.api.Version.ID;
+import org.apache.taverna.component.registry.ComponentImplementationCache;
+import org.apache.taverna.component.registry.ComponentUtil;
+import org.apache.taverna.component.utils.AnnotationUtils;
+import org.apache.taverna.component.utils.SystemUtils;
+import org.springframework.beans.factory.annotation.Required;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class ComponentActivityFactory extends ComponentExceptionFactory
+		implements ActivityFactory {
+	private ComponentUtil util;
+	private ComponentImplementationCache cache;
+	private Edits edits;
+	private SystemUtils system;
+	private AnnotationUtils annUtils;
+
+	@Override
+	public ComponentActivity createActivity() {
+		return new ComponentActivity(util, cache, edits, system, annUtils, this);
+	}
+
+	@Override
+	public URI getActivityType() {
+		return URI.create(ComponentActivity.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)
+			throws ActivityConfigurationException {
+		try {
+			Set<ActivityInputPort> activityInputPorts = new HashSet<>();
+			for (ActivityInputPortDefinitionBean ipd : createConfiguration(
+					configuration).getPorts().getInputPortDefinitions())
+				activityInputPorts.add(edits.createActivityInputPort(
+						ipd.getName(), ipd.getDepth(), true, null,
+						ipd.getTranslatedElementType()));
+			return activityInputPorts;
+		} catch (MalformedURLException | ComponentException | RuntimeException e) {
+			throw new ActivityConfigurationException(
+					"failed to get implementation for configuration of inputs",
+					e);
+		}
+	}
+
+	@Override
+	public Set<ActivityOutputPort> getOutputPorts(JsonNode configuration)
+			throws ActivityConfigurationException {
+		try {
+			Set<ActivityOutputPort> activityOutputPorts = new HashSet<>();
+			for (ActivityOutputPortDefinitionBean opd : createConfiguration(
+					configuration).getPorts().getOutputPortDefinitions())
+				activityOutputPorts.add(edits.createActivityOutputPort(
+						opd.getName(), opd.getDepth(), opd.getGranularDepth()));
+			return activityOutputPorts;
+		} catch (MalformedURLException | ComponentException | RuntimeException e) {
+			throw new ActivityConfigurationException(
+					"failed to get implementation for configuration of outputs",
+					e);
+		}
+	}
+
+	public ComponentActivityConfigurationBean createConfiguration(ID id) {
+		return new ComponentActivityConfigurationBean(id, util, cache);
+	}
+
+	public ComponentActivityConfigurationBean createConfiguration(JsonNode json)
+			throws MalformedURLException {
+		return new ComponentActivityConfigurationBean(json, util, cache);
+	}
+
+	@Required
+	public void setComponentUtil(ComponentUtil util) {
+		this.util = util;
+	}
+
+	@Required
+	public void setDataflowCache(ComponentImplementationCache cache) {
+		this.cache = cache;
+	}
+
+	@Required
+	public void setEdits(Edits edits) {
+		this.edits = edits;
+	}
+
+	@Required
+	public void setSystemUtil(SystemUtils system) {
+		this.system = system;
+	}
+
+	@Required
+	public void setAnnotationUtils(AnnotationUtils annUtils) {
+		this.annUtils = annUtils;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityLocalChecker.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityLocalChecker.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityLocalChecker.java
new file mode 100644
index 0000000..a1223c2
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityLocalChecker.java
@@ -0,0 +1,52 @@
+package org.apache.taverna.component.activity;
+
+import static net.sf.taverna.t2.visit.VisitReport.Status.WARNING;
+import static org.apache.taverna.component.activity.ComponentHealthCheck.NON_SHAREABLE;
+
+import java.util.List;
+
+import net.sf.taverna.t2.visit.VisitKind;
+import net.sf.taverna.t2.visit.VisitReport;
+import net.sf.taverna.t2.workflowmodel.health.HealthChecker;
+
+/**
+ * Component health checker
+ * 
+ */
+public class ComponentActivityLocalChecker implements
+		HealthChecker<ComponentActivity> {
+	private static final VisitKind visitKind = ComponentHealthCheck
+			.getInstance();
+
+	@Override
+	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 ComponentActivity where a certain configuration option is
+		 * enabled.
+		 */
+		return o instanceof ComponentActivity;
+	}
+
+	@Override
+	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;
+	}
+
+	@Override
+	public VisitReport visit(ComponentActivity activity, List<Object> ancestry) {
+		if (!activity.getConfigBean().getRegistryBase().getProtocol()
+				.startsWith("http"))
+			return new VisitReport(visitKind, activity,
+					"Local component makes workflow non-shareable",
+					NON_SHAREABLE, WARNING);
+		return null;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityUpgradeChecker.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityUpgradeChecker.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityUpgradeChecker.java
new file mode 100644
index 0000000..1d57df3
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentActivityUpgradeChecker.java
@@ -0,0 +1,69 @@
+/**
+ * 
+ */
+package org.apache.taverna.component.activity;
+
+import static net.sf.taverna.t2.visit.VisitReport.Status.WARNING;
+import static org.apache.log4j.Logger.getLogger;
+import static org.apache.taverna.component.activity.ComponentHealthCheck.OUT_OF_DATE;
+
+import java.util.List;
+
+import net.sf.taverna.t2.visit.VisitKind;
+import net.sf.taverna.t2.visit.VisitReport;
+import net.sf.taverna.t2.workflowmodel.health.HealthChecker;
+
+import org.apache.log4j.Logger;
+import org.apache.taverna.component.api.ComponentException;
+import org.apache.taverna.component.registry.ComponentUtil;
+import org.springframework.beans.factory.annotation.Required;
+
+/**
+ * @author alanrw
+ * 
+ */
+public class ComponentActivityUpgradeChecker implements
+		HealthChecker<ComponentActivity> {
+	private static final String OUTDATED_MSG = "Component out of date";
+	private static final VisitKind visitKind = ComponentHealthCheck
+			.getInstance();
+	private static Logger logger = getLogger(ComponentActivityUpgradeChecker.class);
+	private ComponentUtil utils;
+
+	@Required
+	public void setComponentUtil(ComponentUtil util) {
+		this.utils = util;
+	}
+
+	@Override
+	public boolean canVisit(Object o) {
+		return o instanceof ComponentActivity;
+	}
+
+	@Override
+	public boolean isTimeConsuming() {
+		return false;
+	}
+
+	@Override
+	public VisitReport visit(ComponentActivity activity, List<Object> ancestry) {
+		ComponentActivityConfigurationBean config = activity.getConfigBean();
+		int versionNumber = config.getComponentVersion();
+		int latestVersion = 0;
+
+		try {
+			latestVersion = utils
+					.getComponent(config.getRegistryBase(),
+							config.getFamilyName(), config.getComponentName())
+					.getComponentVersionMap().lastKey();
+		} catch (ComponentException e) {
+			logger.error("failed to get component description", e);
+		}
+
+		if (latestVersion > versionNumber)
+			return new VisitReport(visitKind, activity, OUTDATED_MSG,
+					OUT_OF_DATE, WARNING);
+		return null;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentExceptionFactory.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentExceptionFactory.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentExceptionFactory.java
new file mode 100644
index 0000000..ac4b73d
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentExceptionFactory.java
@@ -0,0 +1,27 @@
+/**
+ * 
+ */
+package org.apache.taverna.component.activity;
+
+/**
+ * @author alanrw
+ * 
+ */
+class ComponentExceptionFactory {
+	private static final String UNEXPECTED_ID = "http://ns.taverna.org.uk/2012/component/unexpected";
+
+	ComponentExceptionFactory() {
+	}
+
+	public ComponentImplementationException createComponentException(
+			String exceptionId, String message) {
+		ComponentImplementationException result = new ComponentImplementationException(message);
+		result.setExceptionId(exceptionId);
+		return result;
+	}
+
+	public ComponentImplementationException createUnexpectedComponentException(
+			String message) {
+		return createComponentException(UNEXPECTED_ID, message);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentHealthCheck.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentHealthCheck.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentHealthCheck.java
new file mode 100644
index 0000000..af480da
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentHealthCheck.java
@@ -0,0 +1,24 @@
+package org.apache.taverna.component.activity;
+
+import net.sf.taverna.t2.visit.VisitKind;
+import net.sf.taverna.t2.visit.Visitor;
+
+public class ComponentHealthCheck extends VisitKind {
+	public static final int NO_PROBLEM = 0;
+	public static final int OUT_OF_DATE = 10;
+	public static final int NON_SHAREABLE = 20;
+	public static final int FAILS_PROFILE = 30;
+
+	@Override
+	public Class<? extends Visitor<?>> getVisitorClass() {
+		return ComponentActivityUpgradeChecker.class;
+	}
+
+	private static class Singleton {
+		private static ComponentHealthCheck instance = new ComponentHealthCheck();
+	}
+
+	public static ComponentHealthCheck getInstance() {
+		return Singleton.instance;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentImplementationException.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentImplementationException.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentImplementationException.java
new file mode 100644
index 0000000..a4e7246
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ComponentImplementationException.java
@@ -0,0 +1,26 @@
+/**
+ * 
+ */
+package org.apache.taverna.component.activity;
+
+/**
+ * @author alanrw
+ * 
+ */
+public class ComponentImplementationException extends Exception {
+	public ComponentImplementationException(String string) {
+		super(string);
+		this.setStackTrace(new StackTraceElement[] {});
+	}
+
+	private static final long serialVersionUID = -3844030382222698090L;
+	private String exceptionId;
+
+	public void setExceptionId(String exceptionId) {
+		this.exceptionId = exceptionId;
+	}
+
+	public String getExceptionId() {
+		return exceptionId;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ProxyCallback.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ProxyCallback.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ProxyCallback.java
new file mode 100644
index 0000000..927d63d
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/ProxyCallback.java
@@ -0,0 +1,250 @@
+/**
+ * 
+ */
+package org.apache.taverna.component.activity;
+
+import static net.sf.taverna.t2.reference.T2ReferenceType.ErrorDocument;
+import static net.sf.taverna.t2.reference.T2ReferenceType.IdentifiedList;
+import static net.sf.taverna.t2.reference.T2ReferenceType.ReferenceSet;
+import static org.apache.log4j.Logger.getLogger;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.xml.ws.Holder;
+
+import net.sf.taverna.t2.invocation.InvocationContext;
+import net.sf.taverna.t2.reference.ErrorDocument;
+import net.sf.taverna.t2.reference.ErrorDocumentService;
+import net.sf.taverna.t2.reference.IdentifiedList;
+import net.sf.taverna.t2.reference.ListService;
+import net.sf.taverna.t2.reference.ReferenceService;
+import net.sf.taverna.t2.reference.T2Reference;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AsynchronousActivityCallback;
+import net.sf.taverna.t2.workflowmodel.processor.dispatch.events.DispatchErrorType;
+
+import org.apache.log4j.Logger;
+import org.apache.taverna.component.api.profile.ExceptionHandling;
+import org.apache.taverna.component.api.profile.ExceptionReplacement;
+import org.apache.taverna.component.api.profile.HandleException;
+
+/**
+ * @author alanrw
+ * 
+ */
+public class ProxyCallback implements AsynchronousActivityCallback {
+	private static final Logger logger = getLogger(ProxyCallback.class);
+
+	private final ComponentExceptionFactory cef;
+	private final AsynchronousActivityCallback proxiedCallback;
+	private final ReferenceService references;
+	private final InvocationContext context;
+	private final ExceptionHandling exceptionHandling;
+	private final ListService lists;
+	private final ErrorDocumentService errors;
+
+	/**
+	 * @param proxiedCallback
+	 * @param invocationContext
+	 * @param exceptionHandling
+	 * @param exnFactory
+	 */
+	ProxyCallback(AsynchronousActivityCallback proxiedCallback,
+			InvocationContext invocationContext,
+			ExceptionHandling exceptionHandling,
+			ComponentExceptionFactory exnFactory) {
+		this.proxiedCallback = proxiedCallback;
+		this.exceptionHandling = exceptionHandling;
+		context = invocationContext;
+		references = context.getReferenceService();
+		lists = references.getListService();
+		errors = references.getErrorDocumentService();
+		cef = exnFactory;
+	}
+
+	@Override
+	public InvocationContext getContext() {
+		return context;
+	}
+
+	@Override
+	public void requestRun(Runnable runMe) {
+		proxiedCallback.requestRun(runMe);
+	}
+
+	@Override
+	public void receiveResult(Map<String, T2Reference> data, int[] index) {
+		if (exceptionHandling == null) {
+			proxiedCallback.receiveResult(data, index);
+			return;
+		}
+
+		List<T2Reference> exceptions = new ArrayList<>();
+		Map<String, T2Reference> replacement = new HashMap<>();
+		for (Entry<String, T2Reference> entry : data.entrySet())
+			replacement.put(entry.getKey(),
+					considerReference(entry.getValue(), exceptions));
+		replacement.put("error_channel",
+				references.register(exceptions, 1, true, context));
+		proxiedCallback.receiveResult(replacement, index);
+	}
+
+	private T2Reference considerReference(T2Reference value,
+			List<T2Reference> exceptions) {
+		if (!value.containsErrors())
+			return value;
+		else if (!value.getReferenceType().equals(IdentifiedList))
+			return replaceErrors(value, value.getDepth(), exceptions);
+		else if (exceptionHandling.failLists())
+			return replaceErrors(findFirstFailure(value), value.getDepth(),
+					exceptions);
+
+		List<T2Reference> replacementList = new ArrayList<>();
+		for (T2Reference subValue : lists.getList(value))
+			replacementList.add(considerReference(subValue, exceptions));
+		return references.register(replacementList, value.getDepth(), true,
+				context);
+	}
+
+	private T2Reference findFirstFailure(T2Reference value) {
+		IdentifiedList<T2Reference> originalList = lists.getList(value);
+		for (T2Reference subValue : originalList) {
+			if (subValue.getReferenceType().equals(ErrorDocument))
+				return subValue;
+			if (subValue.getReferenceType().equals(IdentifiedList))
+				if (subValue.containsErrors())
+					return findFirstFailure(subValue);
+			// No need to consider value
+		}
+		return null;
+	}
+
+	private T2Reference replaceErrors(T2Reference value, int depth,
+			List<T2Reference> exceptions) {
+		ErrorDocument doc = errors.getError(value);
+
+		Holder<HandleException> handleException = new Holder<>();
+		Set<ErrorDocument> toConsider = new HashSet<>();
+		Set<ErrorDocument> considered = new HashSet<>();
+		toConsider.add(doc);
+
+		while (!toConsider.isEmpty())
+			try {
+				ErrorDocument nudoc = remapException(toConsider, considered,
+						handleException);
+				if (nudoc != null) {
+					doc = nudoc;
+					break;
+				}
+			} catch (Exception e) {
+				logger.error("failed to locate exception mapping", e);
+			}
+
+		String exceptionMessage = doc.getExceptionMessage();
+		// An exception that is not mentioned
+		if (handleException.value == null) {
+			ComponentImplementationException newException = cef
+					.createUnexpectedComponentException(exceptionMessage);
+			T2Reference replacement = errors.registerError(exceptionMessage,
+					newException, depth, context).getId();
+			exceptions.add(errors.registerError(exceptionMessage, newException,
+					0, context).getId());
+			return replacement;
+		}
+
+		if (handleException.value.pruneStack())
+			doc.getStackTraceStrings().clear();
+
+		ExceptionReplacement exnReplacement = handleException.value
+				.getReplacement();
+		if (exnReplacement == null) {
+			T2Reference replacement = references.register(doc, depth, true,
+					context);
+			exceptions.add(references.register(doc, 0, true, context));
+			return replacement;
+		}
+
+		ComponentImplementationException newException = cef
+				.createComponentException(exnReplacement.getReplacementId(),
+						exnReplacement.getReplacementMessage());
+		T2Reference replacement = errors.registerError(
+				exnReplacement.getReplacementMessage(), newException, depth,
+				context).getId();
+		exceptions.add(errors.registerError(
+				exnReplacement.getReplacementMessage(), newException, 0,
+				context).getId());
+		return replacement;
+	}
+
+	private ErrorDocument remapException(Set<ErrorDocument> toConsider,
+			Set<ErrorDocument> considered,
+			Holder<HandleException> handleException) {
+		ErrorDocument found = null;
+		ErrorDocument errorDoc = toConsider.iterator().next();
+
+		considered.add(errorDoc);
+		toConsider.remove(errorDoc);
+		String exceptionMessage = errorDoc.getExceptionMessage();
+		for (HandleException he : exceptionHandling.getHandleExceptions()) {
+			if (!he.matches(exceptionMessage))
+				continue;
+			handleException.value = he;
+			found = errorDoc;
+		}
+		if (!errorDoc.getErrorReferences().isEmpty())
+			for (T2Reference subRef : errorDoc.getErrorReferences())
+				for (T2Reference newErrorRef : getErrors(subRef)) {
+					ErrorDocument subDoc = errors.getError(newErrorRef);
+					if (subDoc == null)
+						logger.error("Error document contains references to non-existent sub-errors");
+					else if (!considered.contains(subDoc))
+						toConsider.add(subDoc);
+				}
+		return found;
+	}
+
+	private Set<T2Reference> getErrors(T2Reference ref) {
+		Set<T2Reference> result = new HashSet<>();
+		if (ref.getReferenceType().equals(ReferenceSet)) {
+			// nothing
+		} else if (ref.getReferenceType().equals(IdentifiedList)) {
+			IdentifiedList<T2Reference> originalList = lists.getList(ref);
+			for (T2Reference subValue : originalList)
+				if (subValue.containsErrors())
+					result.addAll(getErrors(subValue));
+		} else
+			result.add(ref);
+		return result;
+	}
+
+	@Override
+	public void receiveCompletion(int[] completionIndex) {
+		proxiedCallback.receiveCompletion(completionIndex);
+	}
+
+	@Override
+	public void fail(String message, Throwable t, DispatchErrorType errorType) {
+		proxiedCallback.fail(message, t, errorType);
+	}
+
+	@Override
+	public void fail(String message, Throwable t) {
+		proxiedCallback.fail(message, t);
+	}
+
+	@Override
+	public void fail(String message) {
+		proxiedCallback.fail(message);
+	}
+
+	@Override
+	public String getParentProcessIdentifier() {
+		// return "";
+		return proxiedCallback.getParentProcessIdentifier();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/package-info.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/package-info.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/package-info.java
new file mode 100644
index 0000000..7953ef5
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/activity/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * 
+ */
+/**
+ * @author stain
+ *
+ */
+package org.apache.taverna.component.activity;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/main/resources/META-INF/spring/component-activity-context.xml
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/resources/META-INF/spring/component-activity-context.xml b/taverna-component-activity/src/main/resources/META-INF/spring/component-activity-context.xml
index f1f47a6..c736675 100644
--- a/taverna-component-activity/src/main/resources/META-INF/spring/component-activity-context.xml
+++ b/taverna-component-activity/src/main/resources/META-INF/spring/component-activity-context.xml
@@ -7,16 +7,16 @@
                       http://www.springframework.org/schema/osgi/spring-osgi.xsd">
 
 	<bean id="ComponentLocalHealthChecker"
-		class="org.apache.taverna.component.ComponentActivityLocalChecker" />
+		class="org.apache.taverna.component.activity.ComponentActivityLocalChecker" />
 	<bean id="ComponentUpgradeHealthChecker"
-		class="org.apache.taverna.component.ComponentActivityUpgradeChecker">
+		class="org.apache.taverna.component.activity.ComponentActivityUpgradeChecker">
 		<property name="componentUtil" ref="componentUtil" />
 	</bean>
 	<bean id="baseProfileLocator" class="org.apache.taverna.component.profile.BaseProfileLocator">
 		<property name="appConfig" ref="app-config" />
 	</bean>
 
-	<bean id="componentActivityFactory" class="org.apache.taverna.component.ComponentActivityFactory">
+	<bean id="componentActivityFactory" class="org.apache.taverna.component.activity.ComponentActivityFactory">
 		<property name="componentUtil" ref="componentUtil" />
 		<property name="dataflowCache" ref="cache" />
 		<property name="edits" ref="edits" />

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/40c404c1/taverna-component-activity/src/test/java/org/apache/taverna/component/ComponentActivityTest.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/test/java/org/apache/taverna/component/ComponentActivityTest.java b/taverna-component-activity/src/test/java/org/apache/taverna/component/ComponentActivityTest.java
index 322b848..7ada533 100644
--- a/taverna-component-activity/src/test/java/org/apache/taverna/component/ComponentActivityTest.java
+++ b/taverna-component-activity/src/test/java/org/apache/taverna/component/ComponentActivityTest.java
@@ -1,8 +1,8 @@
 package org.apache.taverna.component;
 
-import org.apache.taverna.component.ComponentActivity;
-import org.apache.taverna.component.ComponentActivityConfigurationBean;
-import org.apache.taverna.component.ComponentActivityFactory;
+import org.apache.taverna.component.activity.ComponentActivity;
+import org.apache.taverna.component.activity.ComponentActivityConfigurationBean;
+import org.apache.taverna.component.activity.ComponentActivityFactory;
 
 
 public class ComponentActivityTest {